aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/connector/cn_test.c4
-rw-r--r--Documentation/dvb/bt8xx.txt64
-rw-r--r--Documentation/dvb/cards.txt37
-rw-r--r--Documentation/dvb/contributors.txt17
-rw-r--r--Documentation/dvb/get_dvb_firmware19
-rw-r--r--Documentation/fb/fbcon.txt152
-rw-r--r--Documentation/feature-removal-schedule.txt29
-rw-r--r--Documentation/filesystems/ext2.txt2
-rw-r--r--Documentation/i2c/busses/i2c-viapro6
-rw-r--r--Documentation/i2c/writing-clients4
-rw-r--r--Documentation/md.txt119
-rw-r--r--Documentation/networking/README.ipw2100132
-rw-r--r--Documentation/networking/README.ipw2200196
-rw-r--r--Documentation/s390/Debugging390.txt2
-rw-r--r--Documentation/sched-arch.txt89
-rw-r--r--Documentation/video4linux/API.html2
-rw-r--r--Documentation/video4linux/CARDLIST.bttv279
-rw-r--r--Documentation/video4linux/CARDLIST.cx8869
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx10
-rw-r--r--Documentation/video4linux/CARDLIST.saa713429
-rw-r--r--Documentation/video4linux/CARDLIST.tuner4
-rw-r--r--Documentation/video4linux/README.cx888
-rw-r--r--Documentation/video4linux/README.saa71342
-rw-r--r--Documentation/video4linux/bttv/Cards18
-rw-r--r--Documentation/video4linux/bttv/README6
-rw-r--r--Documentation/video4linux/bttv/Sound-FAQ12
-rw-r--r--Documentation/video4linux/bttv/Tuners4
-rw-r--r--Documentation/video4linux/lifeview.txt58
-rw-r--r--MAINTAINERS18
-rw-r--r--arch/alpha/kernel/process.c10
-rw-r--r--arch/arm/Kconfig10
-rw-r--r--arch/arm/boot/compressed/misc.c6
-rw-r--r--arch/arm/common/scoop.c6
-rw-r--r--arch/arm/kernel/armksyms.c4
-rw-r--r--arch/arm/kernel/entry-armv.S7
-rw-r--r--arch/arm/kernel/irq.c3
-rw-r--r--arch/arm/kernel/process.c20
-rw-r--r--arch/arm/kernel/smp.c47
-rw-r--r--arch/arm/lib/bitops.h4
-rw-r--r--arch/arm/mach-omap1/leds-h2p2-debug.c1
-rw-r--r--arch/arm/mach-pxa/corgi.c48
-rw-r--r--arch/arm/mach-pxa/poodle.c32
-rw-r--r--arch/arm/mach-pxa/spitz.c95
-rw-r--r--arch/arm/mach-pxa/time.c8
-rw-r--r--arch/arm/mach-pxa/tosa.c152
-rw-r--r--arch/arm/mach-realview/Makefile2
-rw-r--r--arch/arm/mach-realview/core.c5
-rw-r--r--arch/arm/mach-realview/hotplug.c138
-rw-r--r--arch/arm/mach-realview/localtimer.c130
-rw-r--r--arch/arm/mach-realview/platsmp.c15
-rw-r--r--arch/arm/mach-s3c2410/Kconfig8
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c51
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c73
-rw-r--r--arch/arm/mach-s3c2410/mach-rx3715.c13
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2440.c23
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c56
-rw-r--r--arch/arm/mach-sa1100/time.c8
-rw-r--r--arch/arm/plat-omap/ocpi.c1
-rw-r--r--arch/arm26/kernel/process.c12
-rw-r--r--arch/cris/arch-v10/drivers/pcf8563.c1
-rw-r--r--arch/cris/arch-v10/kernel/fasttimer.c1
-rw-r--r--arch/cris/arch-v32/drivers/nandflash.c1
-rw-r--r--arch/cris/arch-v32/drivers/pcf8563.c1
-rw-r--r--arch/cris/arch-v32/kernel/smp.c1
-rw-r--r--arch/cris/kernel/process.c2
-rw-r--r--arch/frv/kernel/process.c6
-rw-r--r--arch/h8300/kernel/process.c28
-rw-r--r--arch/i386/kernel/apm.c20
-rw-r--r--arch/i386/kernel/process.c68
-rw-r--r--arch/i386/kernel/setup.c2
-rw-r--r--arch/i386/kernel/smpboot.c1
-rw-r--r--arch/ia64/ia32/ia32_ioctl.c4
-rw-r--r--arch/ia64/kernel/mca_drv.c3
-rw-r--r--arch/ia64/kernel/process.c34
-rw-r--r--arch/ia64/kernel/smpboot.c1
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c4
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_reg.c2
-rw-r--r--arch/m32r/kernel/process.c2
-rw-r--r--arch/m32r/kernel/smpboot.c1
-rw-r--r--arch/m68k/kernel/process.c2
-rw-r--r--arch/mips/au1000/common/setup.c11
-rw-r--r--arch/mips/configs/ddb5476_defconfig1
-rw-r--r--arch/mips/configs/jmr3927_defconfig1
-rw-r--r--arch/mips/configs/ocelot_3_defconfig1
-rw-r--r--arch/mips/configs/pnx8550-v2pci_defconfig1
-rw-r--r--arch/mips/configs/rbhma4500_defconfig1
-rw-r--r--arch/mips/kernel/ioctl32.c4
-rw-r--r--arch/mips/kernel/process.c2
-rw-r--r--arch/mips/kernel/smp.c4
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/irq.c1
-rw-r--r--arch/parisc/kernel/asm-offsets.c1
-rw-r--r--arch/parisc/kernel/process.c4
-rw-r--r--arch/parisc/kernel/smp.c1
-rw-r--r--arch/powerpc/kernel/smp.c1
-rw-r--r--arch/powerpc/kernel/traps.c4
-rw-r--r--arch/powerpc/kernel/vio.c27
-rw-r--r--arch/powerpc/platforms/iseries/setup.c14
-rw-r--r--arch/powerpc/platforms/pseries/setup.c16
-rw-r--r--arch/ppc/configs/mpc834x_sys_defconfig431
-rw-r--r--arch/ppc/kernel/idle.c25
-rw-r--r--arch/ppc/kernel/smp.c1
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.c23
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.h1
-rw-r--r--arch/ppc/syslib/Makefile2
-rw-r--r--arch/ppc/syslib/mpc83xx_devices.c12
-rw-r--r--arch/ppc/syslib/mpc83xx_sys.c24
-rw-r--r--arch/ppc/syslib/prom.c1
-rw-r--r--arch/ppc/syslib/prom_init.c1
-rw-r--r--arch/ppc64/kernel/idle.c15
-rw-r--r--arch/s390/appldata/appldata_base.c7
-rw-r--r--arch/s390/kernel/debug.c12
-rw-r--r--arch/s390/kernel/process.c24
-rw-r--r--arch/s390/kernel/smp.c1
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/sh/kernel/process.c14
-rw-r--r--arch/sh/kernel/smp.c5
-rw-r--r--arch/sh64/kernel/process.c16
-rw-r--r--arch/sparc/kernel/cpu.c4
-rw-r--r--arch/sparc/kernel/pcic.c2
-rw-r--r--arch/sparc/kernel/process.c35
-rw-r--r--arch/sparc/mm/fault.c2
-rw-r--r--arch/sparc64/kernel/cpu.c4
-rw-r--r--arch/sparc64/kernel/ioctl32.c6
-rw-r--r--arch/sparc64/kernel/process.c24
-rw-r--r--arch/sparc64/kernel/sbus.c2
-rw-r--r--arch/sparc64/kernel/smp.c16
-rw-r--r--arch/sparc64/mm/fault.c4
-rw-r--r--arch/um/drivers/net_kern.c38
-rw-r--r--arch/v850/kernel/process.c16
-rw-r--r--arch/x86_64/ia32/ia32_ioctl.c6
-rw-r--r--arch/x86_64/kernel/process.c69
-rw-r--r--arch/x86_64/kernel/smpboot.c1
-rw-r--r--arch/xtensa/kernel/process.c3
-rw-r--r--arch/xtensa/platform-iss/network.c33
-rw-r--r--drivers/acpi/processor_idle.c37
-rw-r--r--drivers/block/amiflop.c1
-rw-r--r--drivers/block/floppy.c9
-rw-r--r--drivers/block/pktcdvd.c3
-rw-r--r--drivers/bluetooth/bpa10x.c4
-rw-r--r--drivers/bluetooth/hci_usb.c7
-rw-r--r--drivers/char/agp/backend.c9
-rw-r--r--drivers/char/agp/generic.c9
-rw-r--r--drivers/char/agp/i460-agp.c17
-rw-r--r--drivers/char/agp/intel-agp.c5
-rw-r--r--drivers/char/drm/ati_pcigart.c4
-rw-r--r--drivers/char/ip2.c1
-rw-r--r--drivers/char/mwave/tp3780i.c1
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/specialix.c1
-rw-r--r--drivers/char/sysrq.c4
-rw-r--r--drivers/char/tpm/tpm.h1
-rw-r--r--drivers/char/viocons.c1
-rw-r--r--drivers/char/viotape.c1
-rw-r--r--drivers/cpufreq/cpufreq.c24
-rw-r--r--drivers/firmware/dell_rbu.c1
-rw-r--r--drivers/hwmon/w83627hf.c16
-rw-r--r--drivers/i2c/busses/i2c-viapro.c27
-rw-r--r--drivers/i2c/chips/ds1337.c4
-rw-r--r--drivers/ide/Kconfig9
-rw-r--r--drivers/ide/ide-floppy.c6
-rw-r--r--drivers/ide/ide-iops.c6
-rw-r--r--drivers/ide/ide-taskfile.c2
-rw-r--r--drivers/ide/ide.c1
-rw-r--r--drivers/ide/legacy/ide-cs.c7
-rw-r--r--drivers/ide/pci/Makefile1
-rw-r--r--drivers/ide/pci/amd74xx.c3
-rw-r--r--drivers/ide/pci/cs5535.c305
-rw-r--r--drivers/ide/pci/cy82c693.c2
-rw-r--r--drivers/ide/pci/siimage.c9
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c1
-rw-r--r--drivers/input/input.c2
-rw-r--r--drivers/isdn/divert/divert_init.c1
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/divert/isdn_divert.c1
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c1
-rw-r--r--drivers/isdn/hisax/st5481_init.c1
-rw-r--r--drivers/isdn/hysdn/hycapi.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_init.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_net.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c1
-rw-r--r--drivers/isdn/i4l/isdn_common.c1
-rw-r--r--drivers/isdn/icn/icn.h1
-rw-r--r--drivers/isdn/isdnloop/isdnloop.h1
-rw-r--r--drivers/isdn/sc/includes.h1
-rw-r--r--drivers/md/bitmap.c34
-rw-r--r--drivers/md/md.c636
-rw-r--r--drivers/md/multipath.c31
-rw-r--r--drivers/md/raid1.c216
-rw-r--r--drivers/md/raid10.c63
-rw-r--r--drivers/md/raid5.c261
-rw-r--r--drivers/md/raid6main.c40
-rw-r--r--drivers/media/common/ir-common.c4
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c54
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h1
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c1
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig4
-rw-r--r--drivers/media/dvb/bt8xx/dst.c136
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c123
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h5
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c114
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h1
-rw-r--r--drivers/media/dvb/dvb-core/demux.h5
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c118
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h3
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c59
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h5
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c4
-rw-r--r--drivers/media/dvb/frontends/Kconfig8
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c54
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h4
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c26
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.h4
-rw-r--r--drivers/media/dvb/frontends/nxt200x.c1205
-rw-r--r--drivers/media/dvb/frontends/nxt200x.h61
-rw-r--r--drivers/media/dvb/frontends/or51132.c7
-rw-r--r--drivers/media/dvb/frontends/or51211.c8
-rw-r--r--drivers/media/dvb/frontends/stv0299.c100
-rw-r--r--drivers/media/dvb/frontends/stv0299.h3
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c21
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c9
-rw-r--r--drivers/media/dvb/ttpci/av7110.c6
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c3
-rw-r--r--drivers/media/dvb/ttpci/budget.c120
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c5
-rw-r--r--drivers/media/video/Kconfig63
-rw-r--r--drivers/media/video/Makefile5
-rw-r--r--drivers/media/video/arv.c1
-rw-r--r--drivers/media/video/bt832.c89
-rw-r--r--drivers/media/video/bt832.h4
-rw-r--r--drivers/media/video/bttv-cards.c5307
-rw-r--r--drivers/media/video/bttv-driver.c379
-rw-r--r--drivers/media/video/bttv-gpio.c2
-rw-r--r--drivers/media/video/bttv-i2c.c61
-rw-r--r--drivers/media/video/bttv-if.c4
-rw-r--r--drivers/media/video/bttv-risc.c110
-rw-r--r--drivers/media/video/bttv.h282
-rw-r--r--drivers/media/video/bttvp.h14
-rw-r--r--drivers/media/video/cs53l32a.c240
-rw-r--r--drivers/media/video/cx88/Kconfig91
-rw-r--r--drivers/media/video/cx88/Makefile6
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c677
-rw-r--r--drivers/media/video/cx88/cx88-cards.c474
-rw-r--r--drivers/media/video/cx88/cx88-core.c55
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c59
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c22
-rw-r--r--drivers/media/video/cx88/cx88-input.c2
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c25
-rw-r--r--drivers/media/video/cx88/cx88-reg.h12
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c1184
-rw-r--r--drivers/media/video/cx88/cx88-video.c38
-rw-r--r--drivers/media/video/cx88/cx88.h55
-rw-r--r--drivers/media/video/em28xx/Kconfig12
-rw-r--r--drivers/media/video/em28xx/Makefile6
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c292
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c817
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c586
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c184
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c1933
-rw-r--r--drivers/media/video/em28xx/em28xx.h513
-rw-r--r--drivers/media/video/ir-kbd-gpio.c99
-rw-r--r--drivers/media/video/ir-kbd-i2c.c166
-rw-r--r--drivers/media/video/msp3400.c962
-rw-r--r--drivers/media/video/mt20xx.c206
-rw-r--r--drivers/media/video/saa6588.c11
-rw-r--r--drivers/media/video/saa711x.c593
-rw-r--r--drivers/media/video/saa7134/Kconfig68
-rw-r--r--drivers/media/video/saa7134/Makefile9
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c187
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c1047
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c587
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c120
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c370
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c28
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c403
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c375
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h27
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c29
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c23
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c185
-rw-r--r--drivers/media/video/saa7134/saa7134.h62
-rw-r--r--drivers/media/video/tda7432.c17
-rw-r--r--drivers/media/video/tda8290.c681
-rw-r--r--drivers/media/video/tda9875.c57
-rw-r--r--drivers/media/video/tda9887.c163
-rw-r--r--drivers/media/video/tea5767.c8
-rw-r--r--drivers/media/video/tuner-core.c74
-rw-r--r--drivers/media/video/tuner-simple.c143
-rw-r--r--drivers/media/video/tvaudio.c23
-rw-r--r--drivers/media/video/tveeprom.c458
-rw-r--r--drivers/media/video/tvmixer.c54
-rw-r--r--drivers/media/video/tvp5150.c829
-rw-r--r--drivers/media/video/tvp5150_reg.h173
-rw-r--r--drivers/media/video/v4l1-compat.c6
-rw-r--r--drivers/media/video/video-buf.c18
-rw-r--r--drivers/media/video/wm8775.c254
-rw-r--r--drivers/media/video/zr36016.c1
-rw-r--r--drivers/media/video/zr36050.c1
-rw-r--r--drivers/media/video/zr36060.c1
-rw-r--r--drivers/message/fusion/mptbase.c7
-rw-r--r--drivers/message/fusion/mptbase.h3
-rw-r--r--drivers/message/fusion/mptctl.c1
-rw-r--r--drivers/message/fusion/mptctl.h1
-rw-r--r--drivers/message/fusion/mptlan.h1
-rw-r--r--drivers/misc/hdpuftrs/hdpu_cpustate.c1
-rw-r--r--drivers/misc/hdpuftrs/hdpu_nexus.c1
-rw-r--r--drivers/misc/ibmasm/ibmasm.h1
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c1
-rw-r--r--drivers/mtd/devices/pmc551.c1
-rw-r--r--drivers/mtd/maps/ebony.c1
-rw-r--r--drivers/mtd/maps/ocotea.c1
-rw-r--r--drivers/mtd/maps/walnut.c1
-rw-r--r--drivers/mtd/nand/au1550nd.c1
-rw-r--r--drivers/mtd/nand/autcpu12.c1
-rw-r--r--drivers/mtd/onenand/onenand_base.c2
-rw-r--r--drivers/mtd/rfd_ftl.c1
-rw-r--r--drivers/net/Kconfig15
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/b44.c178
-rw-r--r--drivers/net/b44.h75
-rw-r--r--drivers/net/bonding/bond_main.c32
-rw-r--r--drivers/net/bonding/bonding.h7
-rw-r--r--drivers/net/cassini.c1
-rw-r--r--drivers/net/cris/eth_v10.c149
-rw-r--r--drivers/net/dgrs.c16
-rw-r--r--drivers/net/dm9000.c1
-rw-r--r--drivers/net/e100.c6
-rw-r--r--drivers/net/fs_enet/fs_enet.h1
-rw-r--r--drivers/net/gianfar.c1
-rw-r--r--drivers/net/gianfar.h1
-rw-r--r--drivers/net/gianfar_ethtool.c1
-rw-r--r--drivers/net/gianfar_mii.c1
-rw-r--r--drivers/net/hp100.c1
-rw-r--r--drivers/net/ibmveth.c1
-rw-r--r--drivers/net/ioc3-eth.c42
-rw-r--r--drivers/net/irda/donauboe.c14
-rw-r--r--drivers/net/iseries_veth.c1
-rw-r--r--drivers/net/mac8390.c1
-rw-r--r--drivers/net/mv643xx_eth.h1
-rw-r--r--drivers/net/ns83820.c13
-rw-r--r--drivers/net/ppp_async.c17
-rw-r--r--drivers/net/ppp_generic.c88
-rw-r--r--drivers/net/ppp_mppe.c724
-rw-r--r--drivers/net/ppp_mppe.h86
-rw-r--r--drivers/net/s2io.c44
-rw-r--r--drivers/net/sk98lin/h/skdrv1st.h3
-rw-r--r--drivers/net/sk_mca.c1
-rw-r--r--drivers/net/sk_mca.h2
-rw-r--r--drivers/net/skge.c267
-rw-r--r--drivers/net/skge.h2
-rw-r--r--drivers/net/starfire.c1
-rw-r--r--drivers/net/via-velocity.c1
-rw-r--r--drivers/net/wireless/airo.c36
-rw-r--r--drivers/net/wireless/airo_cs.c6
-rw-r--r--drivers/net/wireless/atmel.c2
-rw-r--r--drivers/net/wireless/atmel_cs.c6
-rw-r--r--drivers/net/wireless/hostap/hostap.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c1
-rw-r--r--drivers/net/wireless/ipw2100.c2858
-rw-r--r--drivers/net/wireless/ipw2100.h170
-rw-r--r--drivers/net/wireless/ipw2200.c6610
-rw-r--r--drivers/net/wireless/ipw2200.h575
-rw-r--r--drivers/net/wireless/orinoco.h1
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c13
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.h1
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h1
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c11
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c1
-rw-r--r--drivers/net/wireless/wavelan_cs.c3
-rw-r--r--drivers/net/wireless/wl3501_cs.c3
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c1
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c1
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c140
-rw-r--r--drivers/s390/char/keyboard.h4
-rw-r--r--drivers/s390/cio/qdio.h8
-rw-r--r--drivers/s390/crypto/z90main.c1
-rw-r--r--drivers/s390/net/claw.c1
-rw-r--r--drivers/s390/net/fsm.h6
-rw-r--r--drivers/s390/s390mach.h2
-rw-r--r--drivers/sbus/char/cpwatchdog.c2
-rw-r--r--drivers/sbus/char/display7seg.c2
-rw-r--r--drivers/sbus/char/openprom.c3
-rw-r--r--drivers/sbus/char/rtc.c22
-rw-r--r--drivers/scsi/3w-xxxx.h1
-rw-r--r--drivers/scsi/a2091.c1
-rw-r--r--drivers/scsi/ahci.c2
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h1
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h1
-rw-r--r--drivers/scsi/amiga7xx.c1
-rw-r--r--drivers/scsi/ata_piix.c1
-rw-r--r--drivers/scsi/bvme6000.c1
-rw-r--r--drivers/scsi/gvp11.c1
-rw-r--r--drivers/scsi/ibmmca.c6
-rw-r--r--drivers/scsi/ips.h1
-rw-r--r--drivers/scsi/libata-core.c11
-rw-r--r--drivers/scsi/libata-scsi.c9
-rw-r--r--drivers/scsi/megaraid/mega_common.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c1
-rw-r--r--drivers/scsi/mvme147.c1
-rw-r--r--drivers/scsi/mvme16x.c1
-rw-r--r--drivers/scsi/nsp32.h1
-rw-r--r--drivers/scsi/pci2000.h3
-rw-r--r--drivers/scsi/pdc_adma.c1
-rw-r--r--drivers/scsi/sata_mv.c2
-rw-r--r--drivers/scsi/sata_nv.c1
-rw-r--r--drivers/scsi/sata_promise.c2
-rw-r--r--drivers/scsi/sata_qstor.c1
-rw-r--r--drivers/scsi/sata_sil.c1
-rw-r--r--drivers/scsi/sata_sil24.c2
-rw-r--r--drivers/scsi/sata_sis.c1
-rw-r--r--drivers/scsi/sata_svw.c1
-rw-r--r--drivers/scsi/sata_sx4.c2
-rw-r--r--drivers/scsi/sata_uli.c1
-rw-r--r--drivers/scsi/sata_via.c1
-rw-r--r--drivers/scsi/sata_vsc.c1
-rw-r--r--drivers/scsi/scsi_debug.c4
-rw-r--r--drivers/scsi/sg.c4
-rw-r--r--drivers/scsi/sgiwd93.c1
-rw-r--r--drivers/scsi/wd33c93.c1
-rw-r--r--drivers/telephony/ixj.h1
-rw-r--r--drivers/usb/gadget/dummy_hcd.c1
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.h1
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c1
-rw-r--r--drivers/usb/gadget/rndis.c1
-rw-r--r--drivers/usb/host/hc_crisv10.c1
-rw-r--r--drivers/usb/media/pwc/pwc-if.c1
-rw-r--r--drivers/usb/media/pwc/pwc.h2
-rw-r--r--drivers/usb/media/w9968cf.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.h1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_init.c1
-rw-r--r--drivers/video/Kconfig32
-rw-r--r--drivers/video/amba-clcd.c2
-rw-r--r--drivers/video/backlight/backlight.c1
-rw-r--r--drivers/video/backlight/lcd.c1
-rw-r--r--drivers/video/cfbimgblt.c4
-rw-r--r--drivers/video/console/Kconfig10
-rw-r--r--drivers/video/console/Makefile4
-rw-r--r--drivers/video/console/bitblit.c46
-rw-r--r--drivers/video/console/fbcon.c375
-rw-r--r--drivers/video/console/fbcon.h62
-rw-r--r--drivers/video/console/fbcon_ccw.c428
-rw-r--r--drivers/video/console/fbcon_cw.c412
-rw-r--r--drivers/video/console/fbcon_rotate.c117
-rw-r--r--drivers/video/console/fbcon_rotate.h105
-rw-r--r--drivers/video/console/fbcon_ud.c454
-rw-r--r--drivers/video/console/tileblit.c13
-rw-r--r--drivers/video/fbmem.c299
-rw-r--r--drivers/video/fbsysfs.c67
-rw-r--r--drivers/video/intelfb/intelfbdrv.c1
-rw-r--r--drivers/video/intelfb/intelfbhw.c1
-rw-r--r--drivers/video/modedb.c4
-rw-r--r--drivers/video/savage/savagefb_driver.c10
-rw-r--r--drivers/video/vga16fb.c169
-rw-r--r--drivers/video/vgastate.c5
-rw-r--r--fs/9p/vfs_file.c1
-rw-r--r--fs/adfs/adfs.h1
-rw-r--r--fs/binfmt_misc.c2
-rw-r--r--fs/compat_ioctl.c153
-rw-r--r--fs/exec.c16
-rw-r--r--fs/ext2/CHANGES157
-rw-r--r--fs/ext2/balloc.c73
-rw-r--r--fs/ext2/ialloc.c40
-rw-r--r--fs/ext2/super.c16
-rw-r--r--fs/ext3/balloc.c73
-rw-r--r--fs/ext3/ialloc.c41
-rw-r--r--fs/ext3/super.c17
-rw-r--r--fs/fat/inode.c11
-rw-r--r--fs/hfs/hfs_fs.h1
-rw-r--r--fs/hfs/inode.c1
-rw-r--r--fs/hfsplus/bnode.c1
-rw-r--r--fs/hfsplus/dir.c1
-rw-r--r--fs/hfsplus/extents.c1
-rw-r--r--fs/hfsplus/hfsplus_fs.h1
-rw-r--r--fs/hfsplus/inode.c1
-rw-r--r--fs/hfsplus/super.c1
-rw-r--r--fs/hfsplus/wrapper.c1
-rw-r--r--fs/hostfs/hostfs_kern.c1
-rw-r--r--fs/hpfs/file.c7
-rw-r--r--fs/hugetlbfs/inode.c2
-rw-r--r--fs/inotify.c2
-rw-r--r--fs/jfs/namei.c3
-rw-r--r--fs/namei.c66
-rw-r--r--fs/namespace.c2
-rw-r--r--fs/ncpfs/ioctl.c34
-rw-r--r--fs/open.c14
-rw-r--r--fs/reiserfs/file.c4
-rw-r--r--fs/udf/file.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h1
-rw-r--r--fs/xfs/xfs.h7
-rw-r--r--fs/xfs/xfs_dmapi.h1
-rw-r--r--include/asm-alpha/ide.h4
-rw-r--r--include/asm-arm/arch-realview/entry-macro.S11
-rw-r--r--include/asm-arm/arch-realview/irqs.h3
-rw-r--r--include/asm-arm/arch-realview/platform.h5
-rw-r--r--include/asm-arm/arch-s3c2410/uncompress.h22
-rw-r--r--include/asm-arm/assembler.h9
-rw-r--r--include/asm-arm/hardirq.h1
-rw-r--r--include/asm-arm/hardware/scoop.h10
-rw-r--r--include/asm-arm/mach/flash.h3
-rw-r--r--include/asm-arm/smp.h54
-rw-r--r--include/asm-i386/ide.h6
-rw-r--r--include/asm-powerpc/pmc.h1
-rw-r--r--include/asm-ppc/mpc83xx.h1
-rw-r--r--include/asm-s390/debug.h16
-rw-r--r--include/asm-s390/ebcdic.h2
-rw-r--r--include/asm-s390/io.h8
-rw-r--r--include/asm-s390/lowcore.h2
-rw-r--r--include/asm-s390/mmu_context.h2
-rw-r--r--include/asm-s390/pgtable.h68
-rw-r--r--include/asm-s390/sigp.h6
-rw-r--r--include/asm-s390/smp.h2
-rw-r--r--include/asm-sh/ide.h4
-rw-r--r--include/asm-sh64/ide.h4
-rw-r--r--include/linux/compat_ioctl.h15
-rw-r--r--include/linux/cpu.h5
-rw-r--r--include/linux/eeprom.h136
-rw-r--r--include/linux/fb.h23
-rw-r--r--include/linux/fs.h6
-rw-r--r--include/linux/fs_enet_pd.h1
-rw-r--r--include/linux/genetlink.h51
-rw-r--r--include/linux/i2c-id.h18
-rw-r--r--include/linux/ide.h5
-rw-r--r--include/linux/if_ppp.h7
-rw-r--r--include/linux/if_wanpipe_common.h2
-rw-r--r--include/linux/istallion.h2
-rw-r--r--include/linux/mtd/cfi.h1
-rw-r--r--include/linux/mtd/mtd.h1
-rw-r--r--include/linux/namei.h2
-rw-r--r--include/linux/netfilter/nf_conntrack_common.h159
-rw-r--r--include/linux/netfilter/nf_conntrack_ftp.h44
-rw-r--r--include/linux/netfilter/nf_conntrack_sctp.h27
-rw-r--r--include/linux/netfilter/nf_conntrack_tcp.h56
-rw-r--r--include/linux/netfilter/nf_conntrack_tuple_common.h13
-rw-r--r--include/linux/netfilter/nfnetlink.h2
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h152
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_ftp.h39
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_icmp.h9
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_sctp.h21
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_tcp.h47
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_tuple.h10
-rw-r--r--include/linux/netfilter_ipv6.h1
-rw-r--r--include/linux/netlink.h24
-rw-r--r--include/linux/pci_ids.h3
-rw-r--r--include/linux/phonedev.h1
-rw-r--r--include/linux/ppp-comp.h9
-rw-r--r--include/linux/proc_fs.h1
-rw-r--r--include/linux/raid/bitmap.h11
-rw-r--r--include/linux/raid/md.h5
-rw-r--r--include/linux/raid/md_k.h40
-rw-r--r--include/linux/raid/raid1.h4
-rw-r--r--include/linux/raid/raid5.h2
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/skbuff.h19
-rw-r--r--include/linux/stallion.h2
-rw-r--r--include/linux/sysctl.h40
-rw-r--r--include/linux/videodev.h82
-rw-r--r--include/linux/videodev2.h207
-rw-r--r--include/media/audiochip.h17
-rw-r--r--include/media/id.h35
-rw-r--r--include/media/ir-common.h6
-rw-r--r--include/media/ir-kbd-i2c.h22
-rw-r--r--include/media/saa7146_vv.h2
-rw-r--r--include/media/tuner.h22
-rw-r--r--include/media/video-buf.h4
-rw-r--r--include/net/bluetooth/bluetooth.h4
-rw-r--r--include/net/bluetooth/hci.h116
-rw-r--r--include/net/bluetooth/hci_core.h9
-rw-r--r--include/net/bluetooth/rfcomm.h2
-rw-r--r--include/net/genetlink.h154
-rw-r--r--include/net/ieee80211.h2
-rw-r--r--include/net/ieee80211_crypt.h1
-rw-r--r--include/net/ipv6.h67
-rw-r--r--include/net/netfilter/ipv4/nf_conntrack_icmp.h11
-rw-r--r--include/net/netfilter/ipv4/nf_conntrack_ipv4.h43
-rw-r--r--include/net/netfilter/ipv6/nf_conntrack_icmpv6.h27
-rw-r--r--include/net/netfilter/nf_conntrack.h354
-rw-r--r--include/net/netfilter/nf_conntrack_compat.h108
-rw-r--r--include/net/netfilter/nf_conntrack_core.h76
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h51
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h93
-rw-r--r--include/net/netfilter/nf_conntrack_protocol.h105
-rw-r--r--include/net/netfilter/nf_conntrack_tuple.h190
-rw-r--r--include/net/netlink.h883
-rw-r--r--include/net/sock.h20
-rw-r--r--init/main.c4
-rw-r--r--kernel/cpu.c33
-rw-r--r--kernel/power/main.c2
-rw-r--r--kernel/power/power.h6
-rw-r--r--kernel/power/snapshot.c83
-rw-r--r--kernel/power/swsusp.c210
-rw-r--r--kernel/ptrace.c2
-rw-r--r--kernel/sched.c160
-rw-r--r--kernel/softlockup.c3
-rw-r--r--kernel/sysctl.c136
-rw-r--r--net/802/p8023.c3
-rw-r--r--net/ax25/af_ax25.c6
-rw-r--r--net/ax25/ax25_in.c6
-rw-r--r--net/ax25/ax25_route.c19
-rw-r--r--net/bluetooth/af_bluetooth.c12
-rw-r--r--net/bluetooth/hci_core.c2
-rw-r--r--net/bluetooth/hci_event.c6
-rw-r--r--net/bluetooth/hci_sock.c2
-rw-r--r--net/bluetooth/hci_sysfs.c4
-rw-r--r--net/bluetooth/hidp/core.c4
-rw-r--r--net/bluetooth/l2cap.c98
-rw-r--r--net/bluetooth/rfcomm/core.c124
-rw-r--r--net/bluetooth/rfcomm/sock.c90
-rw-r--r--net/bluetooth/sco.c92
-rw-r--r--net/core/dev_mcast.c3
-rw-r--r--net/core/rtnetlink.c83
-rw-r--r--net/core/skbuff.c15
-rw-r--r--net/core/sock.c3
-rw-r--r--net/dccp/ipv4.c6
-rw-r--r--net/dccp/proto.c3
-rw-r--r--net/decnet/dn_table.c14
-rw-r--r--net/ethernet/pe2.c3
-rw-r--r--net/ieee80211/ieee80211_crypt.c152
-rw-r--r--net/ieee80211/ieee80211_rx.c2
-rw-r--r--net/ieee80211/ieee80211_wx.c14
-rw-r--r--net/ipv4/af_inet.c3
-rw-r--r--net/ipv4/fib_frontend.c3
-rw-r--r--net/ipv4/inet_diag.c9
-rw-r--r--net/ipv4/ip_options.c3
-rw-r--r--net/ipv4/ip_output.c15
-rw-r--r--net/ipv4/ip_sockglue.c12
-rw-r--r--net/ipv4/ipvs/ip_vs_app.c6
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c7
-rw-r--r--net/ipv4/multipath_wrandom.c10
-rw-r--r--net/ipv4/netfilter/Kconfig41
-rw-r--r--net/ipv4/netfilter/Makefile6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c85
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_icmp.c15
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c11
-rw-r--r--net/ipv4/netfilter/ip_nat_helper_pptp.c28
-rw-r--r--net/ipv4/netfilter/ip_nat_snmp_basic.c3
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c12
-rw-r--r--net/ipv4/netfilter/ipt_CONNMARK.c22
-rw-r--r--net/ipv4/netfilter/ipt_NOTRACK.c4
-rw-r--r--net/ipv4/netfilter/ipt_connbytes.c39
-rw-r--r--net/ipv4/netfilter/ipt_connmark.c10
-rw-r--r--net/ipv4/netfilter/ipt_conntrack.c96
-rw-r--r--net/ipv4/netfilter/ipt_helper.c54
-rw-r--r--net/ipv4/netfilter/ipt_state.c6
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c571
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c301
-rw-r--r--net/ipv4/tcp_ipv4.c3
-rw-r--r--net/ipv6/addrconf.c434
-rw-r--r--net/ipv6/ip6_fib.c54
-rw-r--r--net/ipv6/ip6_input.c5
-rw-r--r--net/ipv6/ip6_output.c21
-rw-r--r--net/ipv6/ip6_tunnel.c7
-rw-r--r--net/ipv6/ipcomp6.c3
-rw-r--r--net/ipv6/ipv6_sockglue.c3
-rw-r--r--net/ipv6/ipv6_syms.c2
-rw-r--r--net/ipv6/netfilter/Kconfig14
-rw-r--r--net/ipv6/netfilter/Makefile6
-rw-r--r--net/ipv6/netfilter/ip6t_MARK.c6
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c556
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c272
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c885
-rw-r--r--net/ipv6/raw.c4
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/irda/discovery.c3
-rw-r--r--net/irda/irias_object.c16
-rw-r--r--net/netfilter/Kconfig74
-rw-r--r--net/netfilter/Makefile8
-rw-r--r--net/netfilter/nf_conntrack_core.c1538
-rw-r--r--net/netfilter/nf_conntrack_ftp.c698
-rw-r--r--net/netfilter/nf_conntrack_l3proto_generic.c98
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c85
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c670
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c1162
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c216
-rw-r--r--net/netfilter/nf_conntrack_standalone.c869
-rw-r--r--net/netfilter/nfnetlink.c21
-rw-r--r--net/netlink/Makefile2
-rw-r--r--net/netlink/af_netlink.c97
-rw-r--r--net/netlink/attr.c328
-rw-r--r--net/netlink/genetlink.c579
-rw-r--r--net/rose/rose_route.c6
-rw-r--r--net/sched/cls_fw.c3
-rw-r--r--net/sched/cls_route.c3
-rw-r--r--net/sched/cls_rsvp.h3
-rw-r--r--net/sched/cls_tcindex.c9
-rw-r--r--net/sched/cls_u32.c4
-rw-r--r--net/sched/em_meta.c3
-rw-r--r--net/sched/ematch.c5
-rw-r--r--net/sctp/associola.c4
-rw-r--r--net/sctp/sm_make_chunk.c6
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seal.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_unseal.c2
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c3
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_seal.c3
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_token.c3
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_unseal.c6
-rw-r--r--net/sunrpc/clnt.c32
-rw-r--r--net/sunrpc/rpc_pipe.c6
-rw-r--r--net/sunrpc/svc.c9
-rw-r--r--net/sunrpc/xdr.c3
-rw-r--r--net/unix/af_unix.c2
-rw-r--r--net/wanrouter/af_wanpipe.c20
-rw-r--r--net/wanrouter/wanmain.c12
-rw-r--r--net/xfrm/xfrm_state.c12
-rw-r--r--net/xfrm/xfrm_user.c69
-rw-r--r--scripts/kconfig/Makefile27
-rw-r--r--scripts/kconfig/conf.c37
-rw-r--r--scripts/kconfig/confdata.c112
-rw-r--r--scripts/kconfig/expr.h1
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped1749
-rw-r--r--scripts/kconfig/lkc.h14
-rw-r--r--scripts/kconfig/lkc_proto.h1
-rw-r--r--scripts/kconfig/menu.c15
-rw-r--r--scripts/kconfig/symbol.c80
-rw-r--r--scripts/kconfig/zconf.gperf43
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped231
-rw-r--r--scripts/kconfig/zconf.l96
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped1177
-rw-r--r--scripts/kconfig/zconf.tab.h_shipped125
-rw-r--r--scripts/kconfig/zconf.y315
-rw-r--r--security/selinux/hooks.c3
-rw-r--r--security/selinux/selinuxfs.c45
-rw-r--r--security/selinux/ss/mls.c5
-rw-r--r--sound/drivers/vx/vx_hwdep.c1
-rw-r--r--sound/oss/Kconfig73
-rw-r--r--sound/oss/msnd.c1
-rw-r--r--sound/oss/os.h2
-rw-r--r--sound/oss/rme96xx.c1
-rw-r--r--sound/oss/sh_dac_audio.c1
-rw-r--r--sound/ppc/pmac.h1
744 files changed, 49022 insertions, 16446 deletions
diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c
index b7de82e9c0e0..3e73231695b3 100644
--- a/Documentation/connector/cn_test.c
+++ b/Documentation/connector/cn_test.c
@@ -25,7 +25,7 @@
25#include <linux/skbuff.h> 25#include <linux/skbuff.h>
26#include <linux/timer.h> 26#include <linux/timer.h>
27 27
28#include "connector.h" 28#include <linux/connector.h>
29 29
30static struct cb_id cn_test_id = { 0x123, 0x456 }; 30static struct cb_id cn_test_id = { 0x123, 0x456 };
31static char cn_test_name[] = "cn_test"; 31static char cn_test_name[] = "cn_test";
@@ -104,7 +104,7 @@ static int cn_test_want_notify(void)
104 req->first = cn_test_id.val + 20; 104 req->first = cn_test_id.val + 20;
105 req->range = 10; 105 req->range = 10;
106 106
107 NETLINK_CB(skb).dst_groups = ctl->group; 107 NETLINK_CB(skb).dst_group = ctl->group;
108 //netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC); 108 //netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC);
109 netlink_unicast(nls, skb, 0, 0); 109 netlink_unicast(nls, skb, 0, 0);
110 110
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt
index cb63b7a93c82..df6c05453cb5 100644
--- a/Documentation/dvb/bt8xx.txt
+++ b/Documentation/dvb/bt8xx.txt
@@ -1,5 +1,5 @@
1How to get the Nebula, PCTV and Twinhan DST cards working 1How to get the Nebula, PCTV, FusionHDTV Lite and Twinhan DST cards working
2========================================================= 2==========================================================================
3 3
4This class of cards has a bt878a as the PCI interface, and 4This class of cards has a bt878a as the PCI interface, and
5require the bttv driver. 5require the bttv driver.
@@ -26,27 +26,31 @@ Furthermore you need to enable
26 26
27In general you need to load the bttv driver, which will handle the gpio and 27In 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. 28i2c communication for us, plus the common dvb-bt8xx device driver.
29The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and 29The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110), TwinHan (dst),
30TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver. 30FusionHDTV DVB-T Lite (mt352) and FusionHDTV5 Lite (lgdt330x) are loaded
31automatically by the dvb-bt8xx device driver.
31 32
323a) Nebula / Pinnacle PCTV 333a) Nebula / Pinnacle PCTV / FusionHDTV Lite
33-------------------------- 34---------------------------------------------
34 35
35 $ modprobe bttv (normally bttv is being loaded automatically by kmod) 36 $ modprobe bttv (normally bttv is being loaded automatically by kmod)
36 $ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading) 37 $ modprobe dvb-bt8xx
38
39(or just place dvb-bt8xx in /etc/modules for automatic loading)
37 40
38 41
393b) TwinHan and Clones 423b) TwinHan and Clones
40-------------------------- 43--------------------------
41 44
42 $ modprobe bttv i2c_hw=1 card=0x71 45 $ modprobe bttv card=0x71
43 $ modprobe dvb-bt8xx 46 $ modprobe dvb-bt8xx
44 $ modprobe dst 47 $ modprobe dst
45 48
46The value 0x71 will override the PCI type detection for dvb-bt8xx, 49The value 0x71 will override the PCI type detection for dvb-bt8xx,
47which is necessary for TwinHan cards. 50which is necessary for TwinHan cards. Omission of this parameter might result
51in a system lockup.
48 52
49If you're having an older card (blue color circuit) and card=0x71 locks 53If you're having an older card (blue color PCB) and card=0x71 locks up
50your machine, try using 0x68, too. If that does not work, ask on the 54your machine, try using 0x68, too. If that does not work, ask on the
51mailing list. 55mailing list.
52 56
@@ -64,11 +68,47 @@ verbose=0 means complete disabling of messages
64dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card. 68dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
650x20 means it has a Conditional Access slot. 690x20 means it has a Conditional Access slot.
66 70
67The autodected values are determined bythe cards 'response 71The autodetected values are determined by the cards 'response string'
68string' which you can see in your logs e.g. 72which you can see in your logs e.g.
69 73
70dst_get_device_id: Recognise [DSTMCI] 74dst_get_device_id: Recognise [DSTMCI]
71 75
76If you need to sent in bug reports on the dst, please do send in a complete
77log with the verbose=4 module parameter. For general usage, the default setting
78of verbose=1 is ideal.
79
80
814) Multiple cards
82--------------------------
83
84If you happen to be running multiple cards, it would be advisable to load
85the bttv module with the card id. This would help to solve any module loading
86problems that you might face.
87
88For example, if you have a Twinhan and Clones card along with a FusionHDTV5 Lite
89
90 $ modprobe bttv card=0x71 card=0x87
91
92Here the order of the card id is important and should be the same as that of the
93physical order of the cards. Here card=0x71 represents the Twinhan and clones
94and card=0x87 represents Fusion HDTV5 Lite. These arguments can also be
95specified in decimal, rather than hex:
96
97 $ modprobe bttv card=113 card=135
98
99Some examples of card-id's
100
101Pinnacle Sat 0x5e (94)
102Nebula Digi TV 0x68 (104)
103PC HDTV 0x70 (112)
104Twinhan 0x71 (113)
105FusionHDTV DVB-T Lite 0x80 (128)
106FusionHDTV5 Lite 0x87 (135)
107
108For a full list of card-id's, see the V4L Documentation within the kernel
109source: linux/Documentation/video4linux/CARDLIST.bttv
110
111If you have problems with this please do ask on the mailing list.
72 112
73-- 113--
74Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham 114Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham
diff --git a/Documentation/dvb/cards.txt b/Documentation/dvb/cards.txt
index efdc4ee9d40c..19329cf7b097 100644
--- a/Documentation/dvb/cards.txt
+++ b/Documentation/dvb/cards.txt
@@ -41,6 +41,12 @@ o Frontends drivers:
41 - dib3000mb : DiBcom 3000-MB demodulator 41 - dib3000mb : DiBcom 3000-MB demodulator
42 DVB-S/C/T: 42 DVB-S/C/T:
43 - dst : TwinHan DST Frontend 43 - dst : TwinHan DST Frontend
44 ATSC:
45 - nxt200x : Nxtwave NXT2002 & NXT2004
46 - or51211 : or51211 based (pcHDTV HD2000 card)
47 - or51132 : or51132 based (pcHDTV HD3000 card)
48 - bcm3510 : Broadcom BCM3510
49 - lgdt330x : LG Electronics DT3302 & DT3303
44 50
45 51
46o Cards based on the Phillips saa7146 multimedia PCI bridge chip: 52o Cards based on the Phillips saa7146 multimedia PCI bridge chip:
@@ -62,6 +68,10 @@ o Cards based on the Conexant Bt8xx PCI bridge:
62 - Nebula Electronics DigiTV 68 - Nebula Electronics DigiTV
63 - TwinHan DST 69 - TwinHan DST
64 - Avermedia DVB-T 70 - Avermedia DVB-T
71 - ChainTech digitop DST-1000 DVB-S
72 - pcHDTV HD-2000 TV
73 - DViCO FusionHDTV DVB-T Lite
74 - DViCO FusionHDTV5 Lite
65 75
66o Technotrend / Hauppauge DVB USB devices: 76o Technotrend / Hauppauge DVB USB devices:
67 - Nova USB 77 - Nova USB
@@ -83,3 +93,30 @@ o DiBcom DVB-T USB based devices:
83 - DiBcom USB2.0 DVB-T reference device (non-public) 93 - DiBcom USB2.0 DVB-T reference device (non-public)
84 94
85o Experimental support for the analog module of the Siemens DVB-C PCI card 95o Experimental support for the analog module of the Siemens DVB-C PCI card
96
97o Cards based on the Conexant cx2388x PCI bridge:
98 - ADS Tech Instant TV DVB-T PCI
99 - ATI HDTV Wonder
100 - digitalnow DNTV Live! DVB-T
101 - DViCO FusionHDTV DVB-T1
102 - DViCO FusionHDTV DVB-T Plus
103 - DViCO FusionHDTV3 Gold-Q
104 - DViCO FusionHDTV3 Gold-T
105 - DViCO FusionHDTV5 Gold
106 - Hauppauge Nova-T DVB-T
107 - KWorld/VStream XPert DVB-T
108 - pcHDTV HD3000 HDTV
109 - TerraTec Cinergy 1400 DVB-T
110 - WinFast DTV1000-T
111
112o Cards based on the Phillips saa7134 PCI bridge:
113 - Medion 7134
114 - Pinnacle PCTV 300i DVB-T + PAL
115 - LifeView FlyDVB-T DUO
116 - Typhoon DVB-T Duo Digital/Analog Cardbus
117 - Philips TOUGH DVB-T reference design
118 - Philips EUROPA V3 reference design
119 - Compro Videomate DVB-T300
120 - Compro Videomate DVB-T200
121 - AVerMedia AVerTVHD MCE A180
122
diff --git a/Documentation/dvb/contributors.txt b/Documentation/dvb/contributors.txt
index c9d5ce370701..2cbd2d0f6fdf 100644
--- a/Documentation/dvb/contributors.txt
+++ b/Documentation/dvb/contributors.txt
@@ -75,5 +75,22 @@ Ernst Peinlich <e.peinlich@inode.at>
75Peter Beutner <p.beutner@gmx.net> 75Peter Beutner <p.beutner@gmx.net>
76 for the IR code for the ttusb-dec driver 76 for the IR code for the ttusb-dec driver
77 77
78Wilson Michaels <wilsonmichaels@earthlink.net>
79 for the lgdt330x frontend driver, and various bugfixes
80
81Michael Krufky <mkrufky@m1k.net>
82 for maintaining v4l/dvb inter-tree dependencies
83
84Taylor Jacob <rtjacob@earthlink.net>
85 for the nxt2002 frontend driver
86
87Jean-Francois Thibert <jeanfrancois@sagetv.com>
88 for the nxt2004 frontend driver
89
90Kirk Lapray <kirk.lapray@gmail.com>
91 for the or51211 and or51132 frontend drivers, and
92 for merging the nxt2002 and nxt2004 modules into a
93 single nxt200x frontend driver.
94
78(If you think you should be in this list, but you are not, drop a 95(If you think you should be in this list, but you are not, drop a
79 line to the DVB mailing list) 96 line to the DVB mailing list)
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index a750f0101d9d..be6eb4c75991 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -22,7 +22,7 @@ use File::Temp qw/ tempdir /;
22use IO::Handle; 22use IO::Handle;
23 23
24@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t", 24@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
25 "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", 25 "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
26 "or51211", "or51132_qam", "or51132_vsb"); 26 "or51211", "or51132_qam", "or51132_vsb");
27 27
28# Check args 28# Check args
@@ -252,6 +252,23 @@ sub nxt2002 {
252 $outfile; 252 $outfile;
253} 253}
254 254
255sub nxt2004 {
256 my $sourcefile = "AVerTVHD_MCE_A180_Drv_v1.2.2.16.zip";
257 my $url = "http://www.aver.com/support/Drivers/$sourcefile";
258 my $hash = "111cb885b1e009188346d72acfed024c";
259 my $outfile = "dvb-fe-nxt2004.fw";
260 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
261
262 checkstandard();
263
264 wgetfile($sourcefile, $url);
265 unzip($sourcefile, $tmpdir);
266 verify("$tmpdir/3xHybrid.sys", $hash);
267 extract("$tmpdir/3xHybrid.sys", 465304, 9584, $outfile);
268
269 $outfile;
270}
271
255sub or51211 { 272sub or51211 {
256 my $fwfile = "dvb-fe-or51211.fw"; 273 my $fwfile = "dvb-fe-or51211.fw";
257 my $url = "http://linuxtv.org/downloads/firmware/$fwfile"; 274 my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
diff --git a/Documentation/fb/fbcon.txt b/Documentation/fb/fbcon.txt
new file mode 100644
index 000000000000..08dce0f631bf
--- /dev/null
+++ b/Documentation/fb/fbcon.txt
@@ -0,0 +1,152 @@
1The Framebuffer Console
2=======================
3
4 The framebuffer console (fbcon), as its name implies, is a text
5console running on top of the framebuffer device. It has the functionality of
6any standard text console driver, such as the VGA console, with the added
7features that can be attributed to the graphical nature of the framebuffer.
8
9 In the x86 architecture, the framebuffer console is optional, and
10some even treat it as a toy. For other architectures, it is the only available
11display device, text or graphical.
12
13 What are the features of fbcon? The framebuffer console supports
14high resolutions, varying font types, display rotation, primitive multihead,
15etc. Theoretically, multi-colored fonts, blending, aliasing, and any feature
16made available by the underlying graphics card are also possible.
17
18A. Configuration
19
20 The framebuffer console can be enabled by using your favorite kernel
21configuration tool. It is under Device Drivers->Graphics Support->Support for
22framebuffer devices->Framebuffer Console Support. Select 'y' to compile
23support statically, or 'm' for module support. The module will be fbcon.
24
25 In order for fbcon to activate, at least one framebuffer driver is
26required, so choose from any of the numerous drivers available. For x86
27systems, they almost universally have VGA cards, so vga16fb and vesafb will
28always be available. However, using a chipset-specific driver will give you
29more speed and features, such as the ability to change the video mode
30dynamically.
31
32 To display the penguin logo, choose any logo available in Logo
33Configuration->Boot up logo.
34
35 Also, you will need to select at least one compiled-in fonts, but if
36you don't do anything, the kernel configuration tool will select one for you,
37usually an 8x16 font.
38
39GOTCHA: A common bug report is enabling the framebuffer without enabling the
40framebuffer console. Depending on the driver, you may get a blanked or
41garbled display, but the system still boots to completion. If you are
42fortunate to have a driver that does not alter the graphics chip, then you
43will still get a VGA console.
44
45B. Loading
46
47Possible scenarios:
48
491. Driver and fbcon are compiled statically
50
51 Usually, fbcon will automatically take over your console. The notable
52 exception is vesafb. It needs to be explicitly activated with the
53 vga= boot option parameter.
54
552. Driver is compiled statically, fbcon is compiled as a module
56
57 Depending on the driver, you either get a standard console, or a
58 garbled display, as mentioned above. To get a framebuffer console,
59 do a 'modprobe fbcon'.
60
613. Driver is compiled as a module, fbcon is compiled statically
62
63 You get your standard console. Once the driver is loaded with
64 'modprobe xxxfb', fbcon automatically takes over the console with
65 the possible exception of using the fbcon=map:n option. See below.
66
674. Driver and fbcon are compiled as a module.
68
69 You can load them in any order. Once both are loaded, fbcon will take
70 over the console.
71
72C. Boot options
73
74 The framebuffer console has several, largely unknown, boot options
75 that can change its behavior.
76
771. fbcon=font:<name>
78
79 Select the initial font to use. The value 'name' can be any of the
80 compiled-in fonts: VGA8x16, 7x14, 10x18, VGA8x8, MINI4x6, RomanLarge,
81 SUN8x16, SUN12x22, ProFont6x11, Acorn8x8, PEARL8x8.
82
83 Note, not all drivers can handle font with widths not divisible by 8,
84 such as vga16fb.
85
862. fbcon=scrollback:<value>[k]
87
88 The scrollback buffer is memory that is used to preserve display
89 contents that has already scrolled past your view. This is accessed
90 by using the Shift-PageUp key combination. The value 'value' is any
91 integer. It defaults to 32KB. The 'k' suffix is optional, and will
92 multiply the 'value' by 1024.
93
943. fbcon=map:<0123>
95
96 This is an interesting option. It tells which driver gets mapped to
97 which console. The value '0123' is a sequence that gets repeated until
98 the total length is 64 which is the number of consoles available. In
99 the above example, it is expanded to 012301230123... and the mapping
100 will be:
101
102 tty | 1 2 3 4 5 6 7 8 9 ...
103 fb | 0 1 2 3 0 1 2 3 0 ...
104
105 ('cat /proc/fb' should tell you what the fb numbers are)
106
107 One side effect that may be useful is using a map value that exceeds
108 the number of loaded fb drivers. For example, if only one driver is
109 available, fb0, adding fbcon=map:1 tells fbcon not to take over the
110 console.
111
112 Later on, when you want to map the console the to the framebuffer
113 device, you can use the con2fbmap utility.
114
1154. fbcon=vc:<n1>-<n2>
116
117 This option tells fbcon to take over only a range of consoles as
118 specified by the values 'n1' and 'n2'. The rest of the consoles
119 outside the given range will still be controlled by the standard
120 console driver.
121
122 NOTE: For x86 machines, the standard console is the VGA console which
123 is typically located on the same video card. Thus, the consoles that
124 are controlled by the VGA console will be garbled.
125
1264. fbcon=rotate:<n>
127
128 This option changes the orientation angle of the console display. The
129 value 'n' accepts the following:
130
131 0 - normal orientation (0 degree)
132 1 - clockwise orientation (90 degrees)
133 2 - upside down orientation (180 degrees)
134 3 - counterclockwise orientation (270 degrees)
135
136 The angle can be changed anytime afterwards by 'echoing' the same
137 numbers to any one of the 2 attributes found in
138 /sys/class/graphics/fb{x}
139
140 con_rotate - rotate the display of the active console
141 con_rotate_all - rotate the display of all consoles
142
143 Console rotation will only become available if Console Rotation
144 Support is compiled in your kernel.
145
146 NOTE: This is purely console rotation. Any other applications that
147 use the framebuffer will remain at their 'normal'orientation.
148 Actually, the underlying fb driver is totally ignorant of console
149 rotation.
150
151---
152Antonino Daplas <adaplas@pol.net>
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index decdf9917e0d..429db4bf98ec 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -25,6 +25,13 @@ Who: Adrian Bunk <bunk@stusta.de>
25 25
26--------------------------- 26---------------------------
27 27
28What: drivers depending on OBSOLETE_OSS_DRIVER
29When: January 2006
30Why: OSS drivers with ALSA replacements
31Who: Adrian Bunk <bunk@stusta.de>
32
33---------------------------
34
28What: RCU API moves to EXPORT_SYMBOL_GPL 35What: RCU API moves to EXPORT_SYMBOL_GPL
29When: April 2006 36When: April 2006
30Files: include/linux/rcupdate.h, kernel/rcupdate.c 37Files: include/linux/rcupdate.h, kernel/rcupdate.c
@@ -60,6 +67,21 @@ Who: Jody McIntyre <scjody@steamballoon.com>
60 67
61--------------------------- 68---------------------------
62 69
70What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
71When: July 2006
72Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
73 series. The old API have lots of drawbacks and don't provide enough
74 means to work with all video and audio standards. The newer API is
75 already available on the main drivers and should be used instead.
76 Newer drivers should use v4l_compat_translate_ioctl function to handle
77 old calls, replacing to newer ones.
78 Decoder iocts are using internally to allow video drivers to
79 communicate with video decoders. This should also be improved to allow
80 V4L2 calls being translated into compatible internal ioctls.
81Who: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
82
83---------------------------
84
63What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid 85What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
64When: November 2005 86When: November 2005
65Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c 87Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
@@ -111,3 +133,10 @@ Why: This interface has been obsoleted by the new layer3-independent
111 to link against API-compatible library on top of libnfnetlink_queue 133 to link against API-compatible library on top of libnfnetlink_queue
112 instead of the current 'libipq'. 134 instead of the current 'libipq'.
113Who: Harald Welte <laforge@netfilter.org> 135Who: Harald Welte <laforge@netfilter.org>
136
137---------------------------
138
139What: EXPORT_SYMBOL(lookup_hash)
140When: January 2006
141Why: Too low-level interface. Use lookup_one_len or lookup_create instead.
142Who: Christoph Hellwig <hch@lst.de>
diff --git a/Documentation/filesystems/ext2.txt b/Documentation/filesystems/ext2.txt
index d16334ec48ba..a8edb376b041 100644
--- a/Documentation/filesystems/ext2.txt
+++ b/Documentation/filesystems/ext2.txt
@@ -17,8 +17,6 @@ set using tune2fs(8). Kernel-determined defaults are indicated by (*).
17bsddf (*) Makes `df' act like BSD. 17bsddf (*) Makes `df' act like BSD.
18minixdf Makes `df' act like Minix. 18minixdf Makes `df' act like Minix.
19 19
20check Check block and inode bitmaps at mount time
21 (requires CONFIG_EXT2_CHECK).
22check=none, nocheck (*) Don't do extra checking of bitmaps on mount 20check=none, nocheck (*) Don't do extra checking of bitmaps on mount
23 (check=normal and check=strict options removed) 21 (check=normal and check=strict options removed)
24 22
diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro
index 9363b8bd6109..16775663b9f5 100644
--- a/Documentation/i2c/busses/i2c-viapro
+++ b/Documentation/i2c/busses/i2c-viapro
@@ -7,12 +7,10 @@ Supported adapters:
7 * VIA Technologies, Inc. VT82C686A/B 7 * VIA Technologies, Inc. VT82C686A/B
8 Datasheet: Sometimes available at the VIA website 8 Datasheet: Sometimes available at the VIA website
9 9
10 * VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237 10 * VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237R
11 Datasheet: available on request from Via 11 Datasheet: available on request from VIA
12 12
13Authors: 13Authors:
14 Frodo Looijaard <frodol@dds.nl>,
15 Philip Edelbrock <phil@netroedge.com>,
16 Kyösti Mälkki <kmalkki@cc.hut.fi>, 14 Kyösti Mälkki <kmalkki@cc.hut.fi>,
17 Mark D. Studebaker <mdsxyz123@yahoo.com>, 15 Mark D. Studebaker <mdsxyz123@yahoo.com>,
18 Jean Delvare <khali@linux-fr.org> 16 Jean Delvare <khali@linux-fr.org>
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
index cff7b652588a..d19993cc0604 100644
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -412,7 +412,7 @@ For now, you can ignore the `flags' parameter. It is there for future use.
412 release_region(address,FOO_EXTENT); 412 release_region(address,FOO_EXTENT);
413 /* SENSORS ONLY END */ 413 /* SENSORS ONLY END */
414 ERROR1: 414 ERROR1:
415 kfree(new_client); 415 kfree(data);
416 ERROR0: 416 ERROR0:
417 return err; 417 return err;
418 } 418 }
@@ -443,7 +443,7 @@ much simpler than the attachment code, fortunately!
443 release_region(client->addr,LM78_EXTENT); 443 release_region(client->addr,LM78_EXTENT);
444 /* HYBRID SENSORS CHIP ONLY END */ 444 /* HYBRID SENSORS CHIP ONLY END */
445 445
446 kfree(data); 446 kfree(i2c_get_clientdata(client));
447 return 0; 447 return 0;
448 } 448 }
449 449
diff --git a/Documentation/md.txt b/Documentation/md.txt
index e2b536992a27..23e6cce40f9c 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -116,3 +116,122 @@ and it's role in the array.
116 116
117Once started with RUN_ARRAY, uninitialized spares can be added with 117Once started with RUN_ARRAY, uninitialized spares can be added with
118HOT_ADD_DISK. 118HOT_ADD_DISK.
119
120
121
122MD devices in sysfs
123-------------------
124md devices appear in sysfs (/sys) as regular block devices,
125e.g.
126 /sys/block/md0
127
128Each 'md' device will contain a subdirectory called 'md' which
129contains further md-specific information about the device.
130
131All md devices contain:
132 level
133 a text file indicating the 'raid level'. This may be a standard
134 numerical level prefixed by "RAID-" - e.g. "RAID-5", or some
135 other name such as "linear" or "multipath".
136 If no raid level has been set yet (array is still being
137 assembled), this file will be empty.
138
139 raid_disks
140 a text file with a simple number indicating the number of devices
141 in a fully functional array. If this is not yet known, the file
142 will be empty. If an array is being resized (not currently
143 possible) this will contain the larger of the old and new sizes.
144
145As component devices are added to an md array, they appear in the 'md'
146directory as new directories named
147 dev-XXX
148where XXX is a name that the kernel knows for the device, e.g. hdb1.
149Each directory contains:
150
151 block
152 a symlink to the block device in /sys/block, e.g.
153 /sys/block/md0/md/dev-hdb1/block -> ../../../../block/hdb/hdb1
154
155 super
156 A file containing an image of the superblock read from, or
157 written to, that device.
158
159 state
160 A file recording the current state of the device in the array
161 which can be a comma separated list of
162 faulty - device has been kicked from active use due to
163 a detected fault
164 in_sync - device is a fully in-sync member of the array
165 spare - device is working, but not a full member.
166 This includes spares that are in the process
167 of being recoverred to
168 This list make grow in future.
169
170
171An active md device will also contain and entry for each active device
172in the array. These are named
173
174 rdNN
175
176where 'NN' is the possition in the array, starting from 0.
177So for a 3 drive array there will be rd0, rd1, rd2.
178These are symbolic links to the appropriate 'dev-XXX' entry.
179Thus, for example,
180 cat /sys/block/md*/md/rd*/state
181will show 'in_sync' on every line.
182
183
184
185Active md devices for levels that support data redundancy (1,4,5,6)
186also have
187
188 sync_action
189 a text file that can be used to monitor and control the rebuild
190 process. It contains one word which can be one of:
191 resync - redundancy is being recalculated after unclean
192 shutdown or creation
193 recover - a hot spare is being built to replace a
194 failed/missing device
195 idle - nothing is happening
196 check - A full check of redundancy was requested and is
197 happening. This reads all block and checks
198 them. A repair may also happen for some raid
199 levels.
200 repair - A full check and repair is happening. This is
201 similar to 'resync', but was requested by the
202 user, and the write-intent bitmap is NOT used to
203 optimise the process.
204
205 This file is writable, and each of the strings that could be
206 read are meaningful for writing.
207
208 'idle' will stop an active resync/recovery etc. There is no
209 guarantee that another resync/recovery may not be automatically
210 started again, though some event will be needed to trigger
211 this.
212 'resync' or 'recovery' can be used to restart the
213 corresponding operation if it was stopped with 'idle'.
214 'check' and 'repair' will start the appropriate process
215 providing the current state is 'idle'.
216
217 mismatch_count
218 When performing 'check' and 'repair', and possibly when
219 performing 'resync', md will count the number of errors that are
220 found. The count in 'mismatch_cnt' is the number of sectors
221 that were re-written, or (for 'check') would have been
222 re-written. As most raid levels work in units of pages rather
223 than sectors, this my be larger than the number of actual errors
224 by a factor of the number of sectors in a page.
225
226Each active md device may also have attributes specific to the
227personality module that manages it.
228These are specific to the implementation of the module and could
229change substantially if the implementation changes.
230
231These currently include
232
233 stripe_cache_size (currently raid5 only)
234 number of entries in the stripe cache. This is writable, but
235 there are upper and lower limits (32768, 16). Default is 128.
236 strip_cache_active (currently raid5 only)
237 number of active entries in the stripe cache
diff --git a/Documentation/networking/README.ipw2100 b/Documentation/networking/README.ipw2100
index 2046948b020d..3ab40379d1cf 100644
--- a/Documentation/networking/README.ipw2100
+++ b/Documentation/networking/README.ipw2100
@@ -1,27 +1,82 @@
1 1
2=========================== 2Intel(R) PRO/Wireless 2100 Driver for Linux in support of:
3Intel(R) PRO/Wireless 2100 Network Connection Driver for Linux 3
4Intel(R) PRO/Wireless 2100 Network Connection
5
6Copyright (C) 2003-2005, Intel Corporation
7
4README.ipw2100 8README.ipw2100
5 9
6March 14, 2005 10Version: 1.1.3
11Date : October 17, 2005
7 12
8===========================
9Index 13Index
10--------------------------- 14-----------------------------------------------
110. Introduction 150. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
121. Release 1.1.0 Current Features 161. Introduction
132. Command Line Parameters 172. Release 1.1.3 Current Features
143. Sysfs Helper Files 183. Command Line Parameters
154. Radio Kill Switch 194. Sysfs Helper Files
165. Dynamic Firmware 205. Radio Kill Switch
176. Power Management 216. Dynamic Firmware
187. Support 227. Power Management
198. License 238. Support
20 249. License
21 25
22=========================== 26
230. Introduction 270. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
24------------ ----- ----- ---- --- -- - 28-----------------------------------------------
29
30Important Notice FOR ALL USERS OR DISTRIBUTORS!!!!
31
32Intel wireless LAN adapters are engineered, manufactured, tested, and
33quality checked to ensure that they meet all necessary local and
34governmental regulatory agency requirements for the regions that they
35are designated and/or marked to ship into. Since wireless LANs are
36generally unlicensed devices that share spectrum with radars,
37satellites, and other licensed and unlicensed devices, it is sometimes
38necessary to dynamically detect, avoid, and limit usage to avoid
39interference with these devices. In many instances Intel is required to
40provide test data to prove regional and local compliance to regional and
41governmental regulations before certification or approval to use the
42product is granted. Intel's wireless LAN's EEPROM, firmware, and
43software driver are designed to carefully control parameters that affect
44radio operation and to ensure electromagnetic compliance (EMC). These
45parameters include, without limitation, RF power, spectrum usage,
46channel scanning, and human exposure.
47
48For these reasons Intel cannot permit any manipulation by third parties
49of the software provided in binary format with the wireless WLAN
50adapters (e.g., the EEPROM and firmware). Furthermore, if you use any
51patches, utilities, or code with the Intel wireless LAN adapters that
52have been manipulated by an unauthorized party (i.e., patches,
53utilities, or code (including open source code modifications) which have
54not been validated by Intel), (i) you will be solely responsible for
55ensuring the regulatory compliance of the products, (ii) Intel will bear
56no liability, under any theory of liability for any issues associated
57with the modified products, including without limitation, claims under
58the warranty and/or issues arising from regulatory non-compliance, and
59(iii) Intel will not provide or be required to assist in providing
60support to any third parties for such modified products.
61
62Note: Many regulatory agencies consider Wireless LAN adapters to be
63modules, and accordingly, condition system-level regulatory approval
64upon receipt and review of test data documenting that the antennas and
65system configuration do not cause the EMC and radio operation to be
66non-compliant.
67
68The drivers available for download from SourceForge are provided as a
69part of a development project. Conformance to local regulatory
70requirements is the responsibility of the individual developer. As
71such, if you are interested in deploying or shipping a driver as part of
72solution intended to be used for purposes other than development, please
73obtain a tested driver from Intel Customer Support at:
74
75http://support.intel.com/support/notebook/sb/CS-006408.htm
76
77
781. Introduction
79-----------------------------------------------
25 80
26This document provides a brief overview of the features supported by the 81This document provides a brief overview of the features supported by the
27IPW2100 driver project. The main project website, where the latest 82IPW2100 driver project. The main project website, where the latest
@@ -34,9 +89,8 @@ potential fixes and patches, as well as links to the development mailing list
34for the driver project. 89for the driver project.
35 90
36 91
37=========================== 922. Release 1.1.3 Current Supported Features
381. Release 1.1.0 Current Supported Features 93-----------------------------------------------
39---------------------------
40- Managed (BSS) and Ad-Hoc (IBSS) 94- Managed (BSS) and Ad-Hoc (IBSS)
41- WEP (shared key and open) 95- WEP (shared key and open)
42- Wireless Tools support 96- Wireless Tools support
@@ -51,9 +105,8 @@ on the amount of validation and interoperability testing that has been
51performed on a given feature. 105performed on a given feature.
52 106
53 107
54=========================== 1083. Command Line Parameters
552. Command Line Parameters 109-----------------------------------------------
56---------------------------
57 110
58If the driver is built as a module, the following optional parameters are used 111If the driver is built as a module, the following optional parameters are used
59by entering them on the command line with the modprobe command using this 112by entering them on the command line with the modprobe command using this
@@ -75,9 +128,9 @@ associate boolean associate=0 /* Do NOT auto associate */
75disable boolean disable=1 /* Do not power the HW */ 128disable boolean disable=1 /* Do not power the HW */
76 129
77 130
78=========================== 1314. Sysfs Helper Files
793. Sysfs Helper Files
80--------------------------- 132---------------------------
133-----------------------------------------------
81 134
82There are several ways to control the behavior of the driver. Many of the 135There are several ways to control the behavior of the driver. Many of the
83general capabilities are exposed through the Wireless Tools (iwconfig). There 136general capabilities are exposed through the Wireless Tools (iwconfig). There
@@ -120,9 +173,8 @@ For the device level files, see /sys/bus/pci/drivers/ipw2100:
120 based RF kill from ON -> OFF -> ON, the radio will NOT come back on 173 based RF kill from ON -> OFF -> ON, the radio will NOT come back on
121 174
122 175
123=========================== 1765. Radio Kill Switch
1244. Radio Kill Switch 177-----------------------------------------------
125---------------------------
126Most laptops provide the ability for the user to physically disable the radio. 178Most laptops provide the ability for the user to physically disable the radio.
127Some vendors have implemented this as a physical switch that requires no 179Some vendors have implemented this as a physical switch that requires no
128software to turn the radio off and on. On other laptops, however, the switch 180software to turn the radio off and on. On other laptops, however, the switch
@@ -134,9 +186,8 @@ See the Sysfs helper file 'rf_kill' for determining the state of the RF switch
134on your system. 186on your system.
135 187
136 188
137=========================== 1896. Dynamic Firmware
1385. Dynamic Firmware 190-----------------------------------------------
139---------------------------
140As the firmware is licensed under a restricted use license, it can not be 191As the firmware is licensed under a restricted use license, it can not be
141included within the kernel sources. To enable the IPW2100 you will need a 192included within the kernel sources. To enable the IPW2100 you will need a
142firmware image to load into the wireless NIC's processors. 193firmware image to load into the wireless NIC's processors.
@@ -146,9 +197,8 @@ You can obtain these images from <http://ipw2100.sf.net/firmware.php>.
146See INSTALL for instructions on installing the firmware. 197See INSTALL for instructions on installing the firmware.
147 198
148 199
149=========================== 2007. Power Management
1506. Power Management 201-----------------------------------------------
151---------------------------
152The IPW2100 supports the configuration of the Power Save Protocol 202The IPW2100 supports the configuration of the Power Save Protocol
153through a private wireless extension interface. The IPW2100 supports 203through a private wireless extension interface. The IPW2100 supports
154the following different modes: 204the following different modes:
@@ -200,9 +250,8 @@ xxxx/yyyy will be replaced with 'off' -- the level reported will be the active
200level if `iwconfig eth1 power on` is invoked. 250level if `iwconfig eth1 power on` is invoked.
201 251
202 252
203=========================== 2538. Support
2047. Support 254-----------------------------------------------
205---------------------------
206 255
207For general development information and support, 256For general development information and support,
208go to: 257go to:
@@ -218,9 +267,8 @@ For installation support on the ipw2100 1.1.0 driver on Linux kernels
218 267
219 http://supportmail.intel.com 268 http://supportmail.intel.com
220 269
221=========================== 2709. License
2228. License 271-----------------------------------------------
223---------------------------
224 272
225 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 273 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
226 274
diff --git a/Documentation/networking/README.ipw2200 b/Documentation/networking/README.ipw2200
index 6916080c5f03..c6492d3839fa 100644
--- a/Documentation/networking/README.ipw2200
+++ b/Documentation/networking/README.ipw2200
@@ -1,33 +1,89 @@
1 1
2Intel(R) PRO/Wireless 2915ABG Driver for Linux in support of: 2Intel(R) PRO/Wireless 2915ABG Driver for Linux in support of:
3 3
4Intel(R) PRO/Wireless 2200BG Network Connection 4Intel(R) PRO/Wireless 2200BG Network Connection
5Intel(R) PRO/Wireless 2915ABG Network Connection 5Intel(R) PRO/Wireless 2915ABG Network Connection
6 6
7Note: The Intel(R) PRO/Wireless 2915ABG Driver for Linux and Intel(R) 7Note: The Intel(R) PRO/Wireless 2915ABG Driver for Linux and Intel(R)
8PRO/Wireless 2200BG Driver for Linux is a unified driver that works on 8PRO/Wireless 2200BG Driver for Linux is a unified driver that works on
9both hardware adapters listed above. In this document the Intel(R) 9both hardware adapters listed above. In this document the Intel(R)
10PRO/Wireless 2915ABG Driver for Linux will be used to reference the 10PRO/Wireless 2915ABG Driver for Linux will be used to reference the
11unified driver. 11unified driver.
12 12
13Copyright (C) 2004-2005, Intel Corporation 13Copyright (C) 2004-2005, Intel Corporation
14 14
15README.ipw2200 15README.ipw2200
16 16
17Version: 1.0.0 17Version: 1.0.8
18Date : January 31, 2005 18Date : October 20, 2005
19 19
20 20
21Index 21Index
22----------------------------------------------- 22-----------------------------------------------
230. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
231. Introduction 241. Introduction
241.1. Overview of features 251.1. Overview of features
251.2. Module parameters 261.2. Module parameters
261.3. Wireless Extension Private Methods 271.3. Wireless Extension Private Methods
271.4. Sysfs Helper Files 281.4. Sysfs Helper Files
282. About the Version Numbers 292. Ad-Hoc Networking
293. Support 303. Interacting with Wireless Tools
304. License 313.1. iwconfig mode
324. About the Version Numbers
335. Firmware installation
346. Support
357. License
36
37
380. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
39-----------------------------------------------
40
41Important Notice FOR ALL USERS OR DISTRIBUTORS!!!!
42
43Intel wireless LAN adapters are engineered, manufactured, tested, and
44quality checked to ensure that they meet all necessary local and
45governmental regulatory agency requirements for the regions that they
46are designated and/or marked to ship into. Since wireless LANs are
47generally unlicensed devices that share spectrum with radars,
48satellites, and other licensed and unlicensed devices, it is sometimes
49necessary to dynamically detect, avoid, and limit usage to avoid
50interference with these devices. In many instances Intel is required to
51provide test data to prove regional and local compliance to regional and
52governmental regulations before certification or approval to use the
53product is granted. Intel's wireless LAN's EEPROM, firmware, and
54software driver are designed to carefully control parameters that affect
55radio operation and to ensure electromagnetic compliance (EMC). These
56parameters include, without limitation, RF power, spectrum usage,
57channel scanning, and human exposure.
58
59For these reasons Intel cannot permit any manipulation by third parties
60of the software provided in binary format with the wireless WLAN
61adapters (e.g., the EEPROM and firmware). Furthermore, if you use any
62patches, utilities, or code with the Intel wireless LAN adapters that
63have been manipulated by an unauthorized party (i.e., patches,
64utilities, or code (including open source code modifications) which have
65not been validated by Intel), (i) you will be solely responsible for
66ensuring the regulatory compliance of the products, (ii) Intel will bear
67no liability, under any theory of liability for any issues associated
68with the modified products, including without limitation, claims under
69the warranty and/or issues arising from regulatory non-compliance, and
70(iii) Intel will not provide or be required to assist in providing
71support to any third parties for such modified products.
72
73Note: Many regulatory agencies consider Wireless LAN adapters to be
74modules, and accordingly, condition system-level regulatory approval
75upon receipt and review of test data documenting that the antennas and
76system configuration do not cause the EMC and radio operation to be
77non-compliant.
78
79The drivers available for download from SourceForge are provided as a
80part of a development project. Conformance to local regulatory
81requirements is the responsibility of the individual developer. As
82such, if you are interested in deploying or shipping a driver as part of
83solution intended to be used for purposes other than development, please
84obtain a tested driver from Intel Customer Support at:
85
86http://support.intel.com/support/notebook/sb/CS-006408.htm
31 87
32 88
331. Introduction 891. Introduction
@@ -45,7 +101,7 @@ file.
45 101
461.1. Overview of Features 1021.1. Overview of Features
47----------------------------------------------- 103-----------------------------------------------
48The current release (1.0.0) supports the following features: 104The current release (1.0.8) supports the following features:
49 105
50+ BSS mode (Infrastructure, Managed) 106+ BSS mode (Infrastructure, Managed)
51+ IBSS mode (Ad-Hoc) 107+ IBSS mode (Ad-Hoc)
@@ -56,17 +112,27 @@ The current release (1.0.0) supports the following features:
56+ Full A rate support (2915 only) 112+ Full A rate support (2915 only)
57+ Transmit power control 113+ Transmit power control
58+ S state support (ACPI suspend/resume) 114+ S state support (ACPI suspend/resume)
115
116The following features are currently enabled, but not officially
117supported:
118
119+ WPA
59+ long/short preamble support 120+ long/short preamble support
121+ Monitor mode (aka RFMon)
122
123The distinction between officially supported and enabled is a reflection
124on the amount of validation and interoperability testing that has been
125performed on a given feature.
60 126
61 127
62 128
631.2. Command Line Parameters 1291.2. Command Line Parameters
64----------------------------------------------- 130-----------------------------------------------
65 131
66Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless 132Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless
672915ABG Driver for Linux allows certain configuration options to be 1332915ABG Driver for Linux allows configuration options to be provided
68provided as module parameters. The most common way to specify a module 134as module parameters. The most common way to specify a module parameter
69parameter is via the command line. 135is via the command line.
70 136
71The general form is: 137The general form is:
72 138
@@ -96,14 +162,18 @@ Where the supported parameter are:
96 162
97 debug 163 debug
98 If using a debug build, this is used to control the amount of debug 164 If using a debug build, this is used to control the amount of debug
99 info is logged. See the 'dval' and 'load' script for more info on 165 info is logged. See the 'dvals' and 'load' script for more info on
100 how to use this (the dval and load scripts are provided as part 166 how to use this (the dvals and load scripts are provided as part
101 of the ipw2200 development snapshot releases available from the 167 of the ipw2200 development snapshot releases available from the
102 SourceForge project at http://ipw2200.sf.net) 168 SourceForge project at http://ipw2200.sf.net)
169
170 led
171 Can be used to turn on experimental LED code.
172 0 = Off, 1 = On. Default is 0.
103 173
104 mode 174 mode
105 Can be used to set the default mode of the adapter. 175 Can be used to set the default mode of the adapter.
106 0 = Managed, 1 = Ad-Hoc 176 0 = Managed, 1 = Ad-Hoc, 2 = Monitor
107 177
108 178
1091.3. Wireless Extension Private Methods 1791.3. Wireless Extension Private Methods
@@ -164,8 +234,8 @@ The supported private methods are:
164----------------------------------------------- 234-----------------------------------------------
165 235
166The Linux kernel provides a pseudo file system that can be used to 236The Linux kernel provides a pseudo file system that can be used to
167access various components of the operating system. The Intel(R) 237access various components of the operating system. The Intel(R)
168PRO/Wireless 2915ABG Driver for Linux exposes several configuration 238PRO/Wireless 2915ABG Driver for Linux exposes several configuration
169parameters through this mechanism. 239parameters through this mechanism.
170 240
171An entry in the sysfs can support reading and/or writing. You can 241An entry in the sysfs can support reading and/or writing. You can
@@ -184,13 +254,13 @@ You can set the debug level via:
184 254
185Where $VALUE would be a number in the case of this sysfs entry. The 255Where $VALUE would be a number in the case of this sysfs entry. The
186input to sysfs files does not have to be a number. For example, the 256input to sysfs files does not have to be a number. For example, the
187firmware loader used by hotplug utilizes sysfs entries for transferring 257firmware loader used by hotplug utilizes sysfs entries for transfering
188the firmware image from user space into the driver. 258the firmware image from user space into the driver.
189 259
190The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries 260The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries
191at two levels -- driver level, which apply to all instances of the 261at two levels -- driver level, which apply to all instances of the driver
192driver (in the event that there are more than one device installed) and 262(in the event that there are more than one device installed) and device
193device level, which applies only to the single specific instance. 263level, which applies only to the single specific instance.
194 264
195 265
1961.4.1 Driver Level Sysfs Helper Files 2661.4.1 Driver Level Sysfs Helper Files
@@ -203,6 +273,7 @@ For the driver level files, look in /sys/bus/pci/drivers/ipw2200/
203 This controls the same global as the 'debug' module parameter 273 This controls the same global as the 'debug' module parameter
204 274
205 275
276
2061.4.2 Device Level Sysfs Helper Files 2771.4.2 Device Level Sysfs Helper Files
207----------------------------------------------- 278-----------------------------------------------
208 279
@@ -213,7 +284,7 @@ For the device level files, look in
213For example: 284For example:
214 /sys/bus/pci/drivers/ipw2200/0000:02:01.0 285 /sys/bus/pci/drivers/ipw2200/0000:02:01.0
215 286
216For the device level files, see /sys/bus/pci/[drivers/ipw2200: 287For the device level files, see /sys/bus/pci/drivers/ipw2200:
217 288
218 rf_kill 289 rf_kill
219 read - 290 read -
@@ -231,8 +302,59 @@ For the device level files, see /sys/bus/pci/[drivers/ipw2200:
231 ucode 302 ucode
232 read-only access to the ucode version number 303 read-only access to the ucode version number
233 304
305 led
306 read -
307 0 = LED code disabled
308 1 = LED code enabled
309 write -
310 0 = Disable LED code
311 1 = Enable LED code
312
313 NOTE: The LED code has been reported to hang some systems when
314 running ifconfig and is therefore disabled by default.
315
316
3172. Ad-Hoc Networking
318-----------------------------------------------
319
320When using a device in an Ad-Hoc network, it is useful to understand the
321sequence and requirements for the driver to be able to create, join, or
322merge networks.
323
324The following attempts to provide enough information so that you can
325have a consistent experience while using the driver as a member of an
326Ad-Hoc network.
327
3282.1. Joining an Ad-Hoc Network
329-----------------------------------------------
330
331The easiest way to get onto an Ad-Hoc network is to join one that
332already exists.
234 333
2352. About the Version Numbers 3342.2. Creating an Ad-Hoc Network
335-----------------------------------------------
336
337An Ad-Hoc networks is created using the syntax of the Wireless tool.
338
339For Example:
340iwconfig eth1 mode ad-hoc essid testing channel 2
341
3422.3. Merging Ad-Hoc Networks
343-----------------------------------------------
344
345
3463. Interaction with Wireless Tools
347-----------------------------------------------
348
3493.1 iwconfig mode
350-----------------------------------------------
351
352When configuring the mode of the adapter, all run-time configured parameters
353are reset to the value used when the module was loaded. This includes
354channels, rates, ESSID, etc.
355
356
3574. About the Version Numbers
236----------------------------------------------- 358-----------------------------------------------
237 359
238Due to the nature of open source development projects, there are 360Due to the nature of open source development projects, there are
@@ -259,12 +381,23 @@ available as quickly as possible, unknown anomalies should be expected.
259The major version number will be incremented when significant changes 381The major version number will be incremented when significant changes
260are made to the driver. Currently, there are no major changes planned. 382are made to the driver. Currently, there are no major changes planned.
261 383
3845. Firmware installation
385----------------------------------------------
386
387The driver requires a firmware image, download it and extract the
388files under /lib/firmware (or wherever your hotplug's firmware.agent
389will look for firmware files)
390
391The firmware can be downloaded from the following URL:
262 392
2633. Support 393 http://ipw2200.sf.net/
394
395
3966. Support
264----------------------------------------------- 397-----------------------------------------------
265 398
266For installation support of the 1.0.0 version, you can contact 399For direct support of the 1.0.0 version, you can contact
267http://supportmail.intel.com, or you can use the open source project 400http://supportmail.intel.com, or you can use the open source project
268support. 401support.
269 402
270For general information and support, go to: 403For general information and support, go to:
@@ -272,7 +405,7 @@ For general information and support, go to:
272 http://ipw2200.sf.net/ 405 http://ipw2200.sf.net/
273 406
274 407
2754. License 4087. License
276----------------------------------------------- 409-----------------------------------------------
277 410
278 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 411 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
@@ -297,4 +430,3 @@ For general information and support, go to:
297 James P. Ketrenos <ipw2100-admin@linux.intel.com> 430 James P. Ketrenos <ipw2100-admin@linux.intel.com>
298 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 431 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
299 432
300
diff --git a/Documentation/s390/Debugging390.txt b/Documentation/s390/Debugging390.txt
index adbfe620c061..844c03fe7921 100644
--- a/Documentation/s390/Debugging390.txt
+++ b/Documentation/s390/Debugging390.txt
@@ -871,7 +871,7 @@ by playing with the --adjust-vma parameter to objdump.
871 871
872 872
873 873
874extern inline void spin_lock(spinlock_t *lp) 874static inline void spin_lock(spinlock_t *lp)
875{ 875{
876 a0: 18 34 lr %r3,%r4 876 a0: 18 34 lr %r3,%r4
877 a2: a7 3a 03 bc ahi %r3,956 877 a2: a7 3a 03 bc ahi %r3,956
diff --git a/Documentation/sched-arch.txt b/Documentation/sched-arch.txt
new file mode 100644
index 000000000000..941615a9769b
--- /dev/null
+++ b/Documentation/sched-arch.txt
@@ -0,0 +1,89 @@
1 CPU Scheduler implementation hints for architecture specific code
2
3 Nick Piggin, 2005
4
5Context switch
6==============
71. Runqueue locking
8By default, the switch_to arch function is called with the runqueue
9locked. This is usually not a problem unless switch_to may need to
10take the runqueue lock. This is usually due to a wake up operation in
11the context switch. See include/asm-ia64/system.h for an example.
12
13To request the scheduler call switch_to with the runqueue unlocked,
14you must `#define __ARCH_WANT_UNLOCKED_CTXSW` in a header file
15(typically the one where switch_to is defined).
16
17Unlocked context switches introduce only a very minor performance
18penalty to the core scheduler implementation in the CONFIG_SMP case.
19
202. Interrupt status
21By default, the switch_to arch function is called with interrupts
22disabled. Interrupts may be enabled over the call if it is likely to
23introduce a significant interrupt latency by adding the line
24`#define __ARCH_WANT_INTERRUPTS_ON_CTXSW` in the same place as for
25unlocked context switches. This define also implies
26`__ARCH_WANT_UNLOCKED_CTXSW`. See include/asm-arm/system.h for an
27example.
28
29
30CPU idle
31========
32Your cpu_idle routines need to obey the following rules:
33
341. Preempt should now disabled over idle routines. Should only
35 be enabled to call schedule() then disabled again.
36
372. need_resched/TIF_NEED_RESCHED is only ever set, and will never
38 be cleared until the running task has called schedule(). Idle
39 threads need only ever query need_resched, and may never set or
40 clear it.
41
423. When cpu_idle finds (need_resched() == 'true'), it should call
43 schedule(). It should not call schedule() otherwise.
44
454. The only time interrupts need to be disabled when checking
46 need_resched is if we are about to sleep the processor until
47 the next interrupt (this doesn't provide any protection of
48 need_resched, it prevents losing an interrupt).
49
50 4a. Common problem with this type of sleep appears to be:
51 local_irq_disable();
52 if (!need_resched()) {
53 local_irq_enable();
54 *** resched interrupt arrives here ***
55 __asm__("sleep until next interrupt");
56 }
57
585. TIF_POLLING_NRFLAG can be set by idle routines that do not
59 need an interrupt to wake them up when need_resched goes high.
60 In other words, they must be periodically polling need_resched,
61 although it may be reasonable to do some background work or enter
62 a low CPU priority.
63
64 5a. If TIF_POLLING_NRFLAG is set, and we do decide to enter
65 an interrupt sleep, it needs to be cleared then a memory
66 barrier issued (followed by a test of need_resched with
67 interrupts disabled, as explained in 3).
68
69arch/i386/kernel/process.c has examples of both polling and
70sleeping idle functions.
71
72
73Possible arch/ problems
74=======================
75
76Possible arch problems I found (and either tried to fix or didn't):
77
78h8300 - Is such sleeping racy vs interrupts? (See #4a).
79 The H8/300 manual I found indicates yes, however disabling IRQs
80 over the sleep mean only NMIs can wake it up, so can't fix easily
81 without doing spin waiting.
82
83ia64 - is safe_halt call racy vs interrupts? (does it sleep?) (See #4a)
84
85sh64 - Is sleeping racy vs interrupts? (See #4a)
86
87sparc - IRQs on at this point(?), change local_irq_save to _disable.
88 - TODO: needs secondary CPUs to disable preempt (See #1)
89
diff --git a/Documentation/video4linux/API.html b/Documentation/video4linux/API.html
index 441407b12a9f..afbe9ae7ee96 100644
--- a/Documentation/video4linux/API.html
+++ b/Documentation/video4linux/API.html
@@ -8,7 +8,7 @@ V4L original API</a>
8</td><td> 8</td><td>
9Obsoleted by V4L2 API 9Obsoleted by V4L2 API
10</td></tr><tr><td> 10</td></tr><tr><td>
11<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API.html> 11<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API>
12V4L2 API</a> 12V4L2 API</a>
13</td><td> 13</td><td>
14Should be used for new projects 14Should be used for new projects
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index ec785f9f15a3..2404099996ac 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -1,137 +1,142 @@
1card=0 - *** UNKNOWN/GENERIC *** 1 0 -> *** UNKNOWN/GENERIC ***
2card=1 - MIRO PCTV 2 1 -> MIRO PCTV
3card=2 - Hauppauge (bt848) 3 2 -> Hauppauge (bt848)
4card=3 - STB, Gateway P/N 6000699 (bt848) 4 3 -> STB, Gateway P/N 6000699 (bt848)
5card=4 - Intel Create and Share PCI/ Smart Video Recorder III 5 4 -> Intel Create and Share PCI/ Smart Video Recorder III
6card=5 - Diamond DTV2000 6 5 -> Diamond DTV2000
7card=6 - AVerMedia TVPhone 7 6 -> AVerMedia TVPhone
8card=7 - MATRIX-Vision MV-Delta 8 7 -> MATRIX-Vision MV-Delta
9card=8 - Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26 9 8 -> Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26
10card=9 - IMS/IXmicro TurboTV 10 9 -> IMS/IXmicro TurboTV
11card=10 - Hauppauge (bt878) 11 10 -> Hauppauge (bt878) [0070:13eb,0070:3900,2636:10b4]
12card=11 - MIRO PCTV pro 12 11 -> MIRO PCTV pro
13card=12 - ADS Technologies Channel Surfer TV (bt848) 13 12 -> ADS Technologies Channel Surfer TV (bt848)
14card=13 - AVerMedia TVCapture 98 14 13 -> AVerMedia TVCapture 98 [1461:0002,1461:0004,1461:0300]
15card=14 - Aimslab Video Highway Xtreme (VHX) 15 14 -> Aimslab Video Highway Xtreme (VHX)
16card=15 - Zoltrix TV-Max 16 15 -> Zoltrix TV-Max [a1a0:a0fc]
17card=16 - Prolink Pixelview PlayTV (bt878) 17 16 -> Prolink Pixelview PlayTV (bt878)
18card=17 - Leadtek WinView 601 18 17 -> Leadtek WinView 601
19card=18 - AVEC Intercapture 19 18 -> AVEC Intercapture
20card=19 - Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only) 20 19 -> Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)
21card=20 - CEI Raffles Card 21 20 -> CEI Raffles Card
22card=21 - Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50 22 21 -> Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50
23card=22 - Askey CPH050/ Phoebe Tv Master + FM 23 22 -> Askey CPH050/ Phoebe Tv Master + FM [14ff:3002]
24card=23 - Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878 24 23 -> Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878 [14c7:0101]
25card=24 - Askey CPH05X/06X (bt878) [many vendors] 25 24 -> Askey CPH05X/06X (bt878) [many vendors] [144f:3002,144f:3005,144f:5000,14ff:3000]
26card=25 - Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar 26 25 -> Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar
27card=26 - Hauppauge WinCam newer (bt878) 27 26 -> Hauppauge WinCam newer (bt878)
28card=27 - Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50 28 27 -> Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50
29card=28 - Terratec TerraTV+ Version 1.1 (bt878) 29 28 -> Terratec TerraTV+ Version 1.1 (bt878) [153b:1127,1852:1852]
30card=29 - Imagenation PXC200 30 29 -> Imagenation PXC200 [1295:200a]
31card=30 - Lifeview FlyVideo 98 LR50 31 30 -> Lifeview FlyVideo 98 LR50 [1f7f:1850]
32card=31 - Formac iProTV, Formac ProTV I (bt848) 32 31 -> Formac iProTV, Formac ProTV I (bt848)
33card=32 - Intel Create and Share PCI/ Smart Video Recorder III 33 32 -> Intel Create and Share PCI/ Smart Video Recorder III
34card=33 - Terratec TerraTValue Version Bt878 34 33 -> Terratec TerraTValue Version Bt878 [153b:1117,153b:1118,153b:1119,153b:111a,153b:1134,153b:5018]
35card=34 - Leadtek WinFast 2000/ WinFast 2000 XP 35 34 -> Leadtek WinFast 2000/ WinFast 2000 XP [107d:6606,107d:6609,6606:217d,f6ff:fff6]
36card=35 - Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II 36 35 -> Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II [1851:1850,1851:a050]
37card=36 - Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner 37 36 -> Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner [1852:1852]
38card=37 - Prolink PixelView PlayTV pro 38 37 -> Prolink PixelView PlayTV pro
39card=38 - Askey CPH06X TView99 39 38 -> Askey CPH06X TView99 [144f:3000,144f:a005,a04f:a0fc]
40card=39 - Pinnacle PCTV Studio/Rave 40 39 -> Pinnacle PCTV Studio/Rave [11bd:0012,bd11:1200,bd11:ff00,11bd:ff12]
41card=40 - STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100 41 40 -> STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100 [10b4:2636,10b4:2645,121a:3060]
42card=41 - AVerMedia TVPhone 98 42 41 -> AVerMedia TVPhone 98 [1461:0001,1461:0003]
43card=42 - ProVideo PV951 43 42 -> ProVideo PV951 [aa0c:146c]
44card=43 - Little OnAir TV 44 43 -> Little OnAir TV
45card=44 - Sigma TVII-FM 45 44 -> Sigma TVII-FM
46card=45 - MATRIX-Vision MV-Delta 2 46 45 -> MATRIX-Vision MV-Delta 2
47card=46 - Zoltrix Genie TV/FM 47 46 -> Zoltrix Genie TV/FM [15b0:4000,15b0:400a,15b0:400d,15b0:4010,15b0:4016]
48card=47 - Terratec TV/Radio+ 48 47 -> Terratec TV/Radio+ [153b:1123]
49card=48 - Askey CPH03x/ Dynalink Magic TView 49 48 -> Askey CPH03x/ Dynalink Magic TView
50card=49 - IODATA GV-BCTV3/PCI 50 49 -> IODATA GV-BCTV3/PCI [10fc:4020]
51card=50 - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP 51 50 -> Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP
52card=51 - Eagle Wireless Capricorn2 (bt878A) 52 51 -> Eagle Wireless Capricorn2 (bt878A)
53card=52 - Pinnacle PCTV Studio Pro 53 52 -> Pinnacle PCTV Studio Pro
54card=53 - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS 54 53 -> Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
55card=54 - Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90] 55 54 -> Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]
56card=55 - Askey CPH031/ BESTBUY Easy TV 56 55 -> Askey CPH031/ BESTBUY Easy TV
57card=56 - Lifeview FlyVideo 98FM LR50 57 56 -> Lifeview FlyVideo 98FM LR50 [a051:41a0]
58card=57 - GrandTec 'Grand Video Capture' (Bt848) 58 57 -> GrandTec 'Grand Video Capture' (Bt848) [4344:4142]
59card=58 - Askey CPH060/ Phoebe TV Master Only (No FM) 59 58 -> Askey CPH060/ Phoebe TV Master Only (No FM)
60card=59 - Askey CPH03x TV Capturer 60 59 -> Askey CPH03x TV Capturer
61card=60 - Modular Technology MM100PCTV 61 60 -> Modular Technology MM100PCTV
62card=61 - AG Electronics GMV1 62 61 -> AG Electronics GMV1 [15cb:0101]
63card=62 - Askey CPH061/ BESTBUY Easy TV (bt878) 63 62 -> Askey CPH061/ BESTBUY Easy TV (bt878)
64card=63 - ATI TV-Wonder 64 63 -> ATI TV-Wonder [1002:0001]
65card=64 - ATI TV-Wonder VE 65 64 -> ATI TV-Wonder VE [1002:0003]
66card=65 - Lifeview FlyVideo 2000S LR90 66 65 -> Lifeview FlyVideo 2000S LR90
67card=66 - Terratec TValueRadio 67 66 -> Terratec TValueRadio [153b:1135,153b:ff3b]
68card=67 - IODATA GV-BCTV4/PCI 68 67 -> IODATA GV-BCTV4/PCI [10fc:4050]
69card=68 - 3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA) 69 68 -> 3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA) [121a:3000,10b4:2637]
70card=69 - Active Imaging AIMMS 70 69 -> Active Imaging AIMMS
71card=70 - Prolink Pixelview PV-BT878P+ (Rev.4C,8E) 71 70 -> Prolink Pixelview PV-BT878P+ (Rev.4C,8E)
72card=71 - Lifeview FlyVideo 98EZ (capture only) LR51 72 71 -> Lifeview FlyVideo 98EZ (capture only) LR51 [1851:1851]
73card=72 - Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) 73 72 -> Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) [1554:4011]
74card=73 - Sensoray 311 74 73 -> Sensoray 311 [6000:0311]
75card=74 - RemoteVision MX (RV605) 75 74 -> RemoteVision MX (RV605)
76card=75 - Powercolor MTV878/ MTV878R/ MTV878F 76 75 -> Powercolor MTV878/ MTV878R/ MTV878F
77card=76 - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) 77 76 -> Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) [0e11:0079]
78card=77 - GrandTec Multi Capture Card (Bt878) 78 77 -> GrandTec Multi Capture Card (Bt878)
79card=78 - Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF 79 78 -> Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF [0a01:17de]
80card=79 - DSP Design TCVIDEO 80 79 -> DSP Design TCVIDEO
81card=80 - Hauppauge WinTV PVR 81 80 -> Hauppauge WinTV PVR [0070:4500]
82card=81 - IODATA GV-BCTV5/PCI 82 81 -> IODATA GV-BCTV5/PCI [10fc:4070,10fc:d018]
83card=82 - Osprey 100/150 (878) 83 82 -> Osprey 100/150 (878) [0070:ff00]
84card=83 - Osprey 100/150 (848) 84 83 -> Osprey 100/150 (848)
85card=84 - Osprey 101 (848) 85 84 -> Osprey 101 (848)
86card=85 - Osprey 101/151 86 85 -> Osprey 101/151
87card=86 - Osprey 101/151 w/ svid 87 86 -> Osprey 101/151 w/ svid
88card=87 - Osprey 200/201/250/251 88 87 -> Osprey 200/201/250/251
89card=88 - Osprey 200/250 89 88 -> Osprey 200/250 [0070:ff01]
90card=89 - Osprey 210/220 90 89 -> Osprey 210/220
91card=90 - Osprey 500 91 90 -> Osprey 500 [0070:ff02]
92card=91 - Osprey 540 92 91 -> Osprey 540 [0070:ff04]
93card=92 - Osprey 2000 93 92 -> Osprey 2000 [0070:ff03]
94card=93 - IDS Eagle 94 93 -> IDS Eagle
95card=94 - Pinnacle PCTV Sat 95 94 -> Pinnacle PCTV Sat [11bd:001c]
96card=95 - Formac ProTV II (bt878) 96 95 -> Formac ProTV II (bt878)
97card=96 - MachTV 97 96 -> MachTV
98card=97 - Euresys Picolo 98 97 -> Euresys Picolo
99card=98 - ProVideo PV150 99 98 -> ProVideo PV150 [aa00:1460,aa01:1461,aa02:1462,aa03:1463,aa04:1464,aa05:1465,aa06:1466,aa07:1467]
100card=99 - AD-TVK503 100 99 -> AD-TVK503
101card=100 - Hercules Smart TV Stereo 101100 -> Hercules Smart TV Stereo
102card=101 - Pace TV & Radio Card 102101 -> Pace TV & Radio Card
103card=102 - IVC-200 103102 -> IVC-200 [0000:a155,0001:a155,0002:a155,0003:a155,0100:a155,0101:a155,0102:a155,0103:a155]
104card=103 - Grand X-Guard / Trust 814PCI 104103 -> Grand X-Guard / Trust 814PCI [0304:0102]
105card=104 - Nebula Electronics DigiTV 105104 -> Nebula Electronics DigiTV [0071:0101]
106card=105 - ProVideo PV143 106105 -> ProVideo PV143 [aa00:1430,aa00:1431,aa00:1432,aa00:1433,aa03:1433]
107card=106 - PHYTEC VD-009-X1 MiniDIN (bt878) 107106 -> PHYTEC VD-009-X1 MiniDIN (bt878)
108card=107 - PHYTEC VD-009-X1 Combi (bt878) 108107 -> PHYTEC VD-009-X1 Combi (bt878)
109card=108 - PHYTEC VD-009 MiniDIN (bt878) 109108 -> PHYTEC VD-009 MiniDIN (bt878)
110card=109 - PHYTEC VD-009 Combi (bt878) 110109 -> PHYTEC VD-009 Combi (bt878)
111card=110 - IVC-100 111110 -> IVC-100 [ff00:a132]
112card=111 - IVC-120G 112111 -> IVC-120G [ff00:a182,ff01:a182,ff02:a182,ff03:a182,ff04:a182,ff05:a182,ff06:a182,ff07:a182,ff08:a182,ff09:a182,ff0a:a182,ff0b:a182,ff0c:a182,ff0d:a182,ff0e:a182,ff0f:a182]
113card=112 - pcHDTV HD-2000 TV 113112 -> pcHDTV HD-2000 TV [7063:2000]
114card=113 - Twinhan DST + clones 114113 -> Twinhan DST + clones [11bd:0026,1822:0001,270f:fc00]
115card=114 - Winfast VC100 115114 -> Winfast VC100 [107d:6607]
116card=115 - Teppro TEV-560/InterVision IV-560 116115 -> Teppro TEV-560/InterVision IV-560
117card=116 - SIMUS GVC1100 117116 -> SIMUS GVC1100 [aa6a:82b2]
118card=117 - NGS NGSTV+ 118117 -> NGS NGSTV+
119card=118 - LMLBT4 119118 -> LMLBT4
120card=119 - Tekram M205 PRO 120119 -> Tekram M205 PRO
121card=120 - Conceptronic CONTVFMi 121120 -> Conceptronic CONTVFMi
122card=121 - Euresys Picolo Tetra 122121 -> Euresys Picolo Tetra [1805:0105,1805:0106,1805:0107,1805:0108]
123card=122 - Spirit TV Tuner 123122 -> Spirit TV Tuner
124card=123 - AVerMedia AVerTV DVB-T 771 124123 -> AVerMedia AVerTV DVB-T 771 [1461:0771]
125card=124 - AverMedia AverTV DVB-T 761 125124 -> AverMedia AverTV DVB-T 761 [1461:0761]
126card=125 - MATRIX Vision Sigma-SQ 126125 -> MATRIX Vision Sigma-SQ
127card=126 - MATRIX Vision Sigma-SLC 127126 -> MATRIX Vision Sigma-SLC
128card=127 - APAC Viewcomp 878(AMAX) 128127 -> APAC Viewcomp 878(AMAX)
129card=128 - DViCO FusionHDTV DVB-T Lite 129128 -> DViCO FusionHDTV DVB-T Lite [18ac:db10]
130card=129 - V-Gear MyVCD 130129 -> V-Gear MyVCD
131card=130 - Super TV Tuner 131130 -> Super TV Tuner
132card=131 - Tibet Systems 'Progress DVR' CS16 132131 -> Tibet Systems 'Progress DVR' CS16
133card=132 - Kodicom 4400R (master) 133132 -> Kodicom 4400R (master)
134card=133 - Kodicom 4400R (slave) 134133 -> Kodicom 4400R (slave)
135card=134 - Adlink RTV24 135134 -> Adlink RTV24
136card=135 - DViCO FusionHDTV 5 Lite 136135 -> DViCO FusionHDTV 5 Lite [18ac:d500]
137card=136 - Acorp Y878F 137136 -> Acorp Y878F [9511:1540]
138137 -> Conceptronic CTVFMi v2
139138 -> Prolink Pixelview PV-BT878P+ (Rev.2E)
140139 -> Prolink PixelView PlayTV MPEG2 PV-M4900
141140 -> Osprey 440 [0070:ff07]
142141 -> Asound Skyeye PCTV
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 03deb0726aa4..a1017d1a85d4 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -1,32 +1,37 @@
1card=0 - UNKNOWN/GENERIC 1 0 -> UNKNOWN/GENERIC
2card=1 - Hauppauge WinTV 34xxx models 2 1 -> Hauppauge WinTV 34xxx models [0070:3400,0070:3401]
3card=2 - GDI Black Gold 3 2 -> GDI Black Gold [14c7:0106,14c7:0107]
4card=3 - PixelView 4 3 -> PixelView [1554:4811]
5card=4 - ATI TV Wonder Pro 5 4 -> ATI TV Wonder Pro [1002:00f8]
6card=5 - Leadtek Winfast 2000XP Expert 6 5 -> Leadtek Winfast 2000XP Expert [107d:6611,107d:6613]
7card=6 - AverTV Studio 303 (M126) 7 6 -> AverTV Studio 303 (M126) [1461:000b]
8card=7 - MSI TV-@nywhere Master 8 7 -> MSI TV-@nywhere Master [1462:8606]
9card=8 - Leadtek Winfast DV2000 9 8 -> Leadtek Winfast DV2000 [107d:6620]
10card=9 - Leadtek PVR 2000 10 9 -> Leadtek PVR 2000 [107d:663b,107d:663C]
11card=10 - IODATA GV-VCP3/PCI 11 10 -> IODATA GV-VCP3/PCI [10fc:d003]
12card=11 - Prolink PlayTV PVR 12 11 -> Prolink PlayTV PVR
13card=12 - ASUS PVR-416 13 12 -> ASUS PVR-416 [1043:4823]
14card=13 - MSI TV-@nywhere 14 13 -> MSI TV-@nywhere
15card=14 - KWorld/VStream XPert DVB-T 15 14 -> KWorld/VStream XPert DVB-T [17de:08a6]
16card=15 - DViCO FusionHDTV DVB-T1 16 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00]
17card=16 - KWorld LTV883RF 17 16 -> KWorld LTV883RF
18card=17 - DViCO FusionHDTV 3 Gold-Q 18 17 -> DViCO FusionHDTV 3 Gold-Q [18ac:d810]
19card=18 - Hauppauge Nova-T DVB-T 19 18 -> Hauppauge Nova-T DVB-T [0070:9002]
20card=19 - Conexant DVB-T reference design 20 19 -> Conexant DVB-T reference design [14f1:0187]
21card=20 - Provideo PV259 21 20 -> Provideo PV259 [1540:2580]
22card=21 - DViCO FusionHDTV DVB-T Plus 22 21 -> DViCO FusionHDTV DVB-T Plus [18ac:db10]
23card=22 - digitalnow DNTV Live! DVB-T 23 22 -> pcHDTV HD3000 HDTV [7063:3000]
24card=23 - pcHDTV HD3000 HDTV 24 23 -> digitalnow DNTV Live! DVB-T [17de:a8a6]
25card=24 - Hauppauge WinTV 28xxx (Roslyn) models 25 24 -> Hauppauge WinTV 28xxx (Roslyn) models [0070:2801]
26card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC) 26 25 -> Digital-Logic MICROSPACE Entertainment Center (MEC) [14f1:0342]
27card=26 - IODATA GV/BCTV7E 27 26 -> IODATA GV/BCTV7E [10fc:d035]
28card=27 - PixelView PlayTV Ultra Pro (Stereo) 28 27 -> PixelView PlayTV Ultra Pro (Stereo)
29card=28 - DViCO FusionHDTV 3 Gold-T 29 28 -> DViCO FusionHDTV 3 Gold-T [18ac:d820]
30card=29 - ADS Tech Instant TV DVB-T PCI 30 29 -> ADS Tech Instant TV DVB-T PCI [1421:0334]
31card=30 - TerraTec Cinergy 1400 DVB-T 31 30 -> TerraTec Cinergy 1400 DVB-T [153b:1166]
32card=31 - DViCO FusionHDTV 5 Gold 32 31 -> DViCO FusionHDTV 5 Gold [18ac:d500]
33 32 -> AverMedia UltraTV Media Center PCI 550 [1461:8011]
34 33 -> Kworld V-Stream Xpert DVD
35 34 -> ATI HDTV Wonder [1002:a101]
36 35 -> WinFast DTV1000-T [107d:665f]
37 36 -> AVerTV 303 (M126) [1461:000a]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
new file mode 100644
index 000000000000..a0c7cad20971
--- /dev/null
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -0,0 +1,10 @@
1 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
2 1 -> Unknown EM2820/2840 video grabber (em2820/em2840)
3 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
4 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
5 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200]
6 5 -> MSI VOX USB 2.0 (em2820/em2840) [eb1a:2820]
7 6 -> Terratec Cinergy 200 USB (em2800)
8 7 -> Leadtek Winfast USB II (em2800)
9 8 -> Kworld USB2800 (em2800)
10 9 -> Pinnacle Dazzle DVC 90 (em2820/em2840) [2304:0207]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index dc57225f39be..57c9d631db56 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -6,10 +6,10 @@
6 5 -> SKNet Monster TV [1131:4e85] 6 5 -> SKNet Monster TV [1131:4e85]
7 6 -> Tevion MD 9717 7 6 -> Tevion MD 9717
8 7 -> KNC One TV-Station RDS / Typhoon TV Tuner RDS [1131:fe01,1894:fe01] 8 7 -> KNC One TV-Station RDS / Typhoon TV Tuner RDS [1131:fe01,1894:fe01]
9 8 -> Terratec Cinergy 400 TV [153B:1142] 9 8 -> Terratec Cinergy 400 TV [153b:1142]
10 9 -> Medion 5044 10 9 -> Medion 5044
11 10 -> Kworld/KuroutoShikou SAA7130-TVPCI 11 10 -> Kworld/KuroutoShikou SAA7130-TVPCI
12 11 -> Terratec Cinergy 600 TV [153B:1143] 12 11 -> Terratec Cinergy 600 TV [153b:1143]
13 12 -> Medion 7134 [16be:0003] 13 12 -> Medion 7134 [16be:0003]
14 13 -> Typhoon TV+Radio 90031 14 13 -> Typhoon TV+Radio 90031
15 14 -> ELSA EX-VISION 300TV [1048:226b] 15 14 -> ELSA EX-VISION 300TV [1048:226b]
@@ -36,8 +36,8 @@
36 35 -> AverMedia AverTV Studio 305 [1461:2115] 36 35 -> AverMedia AverTV Studio 305 [1461:2115]
37 36 -> UPMOST PURPLE TV [12ab:0800] 37 36 -> UPMOST PURPLE TV [12ab:0800]
38 37 -> Items MuchTV Plus / IT-005 38 37 -> Items MuchTV Plus / IT-005
39 38 -> Terratec Cinergy 200 TV [153B:1152] 39 38 -> Terratec Cinergy 200 TV [153b:1152]
40 39 -> LifeView FlyTV Platinum Mini [5168:0212] 40 39 -> LifeView FlyTV Platinum Mini [5168:0212,4e42:0212]
41 40 -> Compro VideoMate TV PVR/FM [185b:c100] 41 40 -> Compro VideoMate TV PVR/FM [185b:c100]
42 41 -> Compro VideoMate TV Gold+ [185b:c100] 42 41 -> Compro VideoMate TV Gold+ [185b:c100]
43 42 -> Sabrent SBT-TVFM (saa7130) 43 42 -> Sabrent SBT-TVFM (saa7130)
@@ -46,7 +46,7 @@
46 45 -> Avermedia AVerTV Studio 307 [1461:9715] 46 45 -> Avermedia AVerTV Studio 307 [1461:9715]
47 46 -> AVerMedia Cardbus TV/Radio (E500) [1461:d6ee] 47 46 -> AVerMedia Cardbus TV/Radio (E500) [1461:d6ee]
48 47 -> Terratec Cinergy 400 mobile [153b:1162] 48 47 -> Terratec Cinergy 400 mobile [153b:1162]
49 48 -> Terratec Cinergy 600 TV MK3 [153B:1158] 49 48 -> Terratec Cinergy 600 TV MK3 [153b:1158]
50 49 -> Compro VideoMate Gold+ Pal [185b:c200] 50 49 -> Compro VideoMate Gold+ Pal [185b:c200]
51 50 -> Pinnacle PCTV 300i DVB-T + PAL [11bd:002d] 51 50 -> Pinnacle PCTV 300i DVB-T + PAL [11bd:002d]
52 51 -> ProVideo PV952 [1540:9524] 52 51 -> ProVideo PV952 [1540:9524]
@@ -56,12 +56,27 @@
56 55 -> LifeView FlyDVB-T DUO [5168:0502,5168:0306] 56 55 -> LifeView FlyDVB-T DUO [5168:0502,5168:0306]
57 56 -> Avermedia AVerTV 307 [1461:a70a] 57 56 -> Avermedia AVerTV 307 [1461:a70a]
58 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] 58 57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
59 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370] 59 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370,1421:1370]
60 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 60 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
61 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502] 61 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502]
62 61 -> Philips TOUGH DVB-T reference design [1131:2004] 62 61 -> Philips TOUGH DVB-T reference design [1131:2004]
63 62 -> Compro VideoMate TV Gold+II 63 62 -> Compro VideoMate TV Gold+II
64 63 -> Kworld Xpert TV PVR7134 64 63 -> Kworld Xpert TV PVR7134
65 64 -> FlyTV mini Asus Digimatrix [1043:0210,1043:0210] 65 64 -> FlyTV mini Asus Digimatrix [1043:0210]
66 65 -> V-Stream Studio TV Terminator 66 65 -> V-Stream Studio TV Terminator
67 66 -> Yuan TUN-900 (saa7135) 67 66 -> Yuan TUN-900 (saa7135)
68 67 -> Beholder BeholdTV 409 FM [0000:4091]
69 68 -> GoTView 7135 PCI [5456:7135]
70 69 -> Philips EUROPA V3 reference design [1131:2004]
71 70 -> Compro Videomate DVB-T300 [185b:c900]
72 71 -> Compro Videomate DVB-T200 [185b:c901]
73 72 -> RTD Embedded Technologies VFG7350 [1435:7350]
74 73 -> RTD Embedded Technologies VFG7330 [1435:7330]
75 74 -> LifeView FlyTV Platinum Mini2 [14c0:1212]
76 75 -> AVerMedia AVerTVHD MCE A180 [1461:1044]
77 76 -> SKNet MonsterTV Mobile [1131:4ee9]
78 77 -> Pinnacle PCTV 110i (saa7133) [11bd:002e]
79 78 -> ASUSTeK P7131 Dual [1043:4862]
80 79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
81 80 -> ASUS Digimatrix TV [1043:0210]
82 81 -> Philips Tiger reference design [1131:2018]
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index f5876be658a6..ec840ca6f455 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -53,7 +53,7 @@ tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3)
53tuner=52 - Thomson DDT 7610 (ATSC/NTSC) 53tuner=52 - Thomson DDT 7610 (ATSC/NTSC)
54tuner=53 - Philips FQ1286 54tuner=53 - Philips FQ1286
55tuner=54 - tda8290+75 55tuner=54 - tda8290+75
56tuner=55 - LG PAL (TAPE series) 56tuner=55 - TCL 2002MB
57tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4) 57tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4)
58tuner=57 - Philips FQ1236A MK4 58tuner=57 - Philips FQ1236A MK4
59tuner=58 - Ymec TVision TVF-8531MF/8831MF/8731MF 59tuner=58 - Ymec TVision TVF-8531MF/8831MF/8731MF
@@ -65,3 +65,5 @@ tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner
65tuner=64 - LG TDVS-H062F/TUA6034 65tuner=64 - LG TDVS-H062F/TUA6034
66tuner=65 - Ymec TVF66T5-B/DFF 66tuner=65 - Ymec TVF66T5-B/DFF
67tuner=66 - LG NTSC (TALN mini series) 67tuner=66 - LG NTSC (TALN mini series)
68tuner=67 - Philips TD1316 Hybrid Tuner
69tuner=68 - Philips TUV1236D ATSC/NTSC dual in
diff --git a/Documentation/video4linux/README.cx88 b/Documentation/video4linux/README.cx88
index 897ab834839a..06a33a4f52fd 100644
--- a/Documentation/video4linux/README.cx88
+++ b/Documentation/video4linux/README.cx88
@@ -17,9 +17,9 @@ audio
17 - The chip specs for the on-chip TV sound decoder are next 17 - The chip specs for the on-chip TV sound decoder are next
18 to useless :-/ 18 to useless :-/
19 - Neverless the builtin TV sound decoder starts working now, 19 - Neverless the builtin TV sound decoder starts working now,
20 at least for PAL-BG. Other TV norms need other code ... 20 at least for PAL-BG. Other TV norms need other code ...
21 FOR ANY REPORTS ON THIS PLEASE MENTION THE TV NORM YOU ARE 21 FOR ANY REPORTS ON THIS PLEASE MENTION THE TV NORM YOU ARE
22 USING. 22 USING.
23 - Most tuner chips do provide mono sound, which may or may not 23 - Most tuner chips do provide mono sound, which may or may not
24 be useable depending on the board design. With the Hauppauge 24 be useable depending on the board design. With the Hauppauge
25 cards it works, so there is mono sound available as fallback. 25 cards it works, so there is mono sound available as fallback.
@@ -65,5 +65,5 @@ Have fun,
65 65
66 Gerd 66 Gerd
67 67
68-- 68--
69Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 69Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
diff --git a/Documentation/video4linux/README.saa7134 b/Documentation/video4linux/README.saa7134
index 1f788e498eff..b911f0871874 100644
--- a/Documentation/video4linux/README.saa7134
+++ b/Documentation/video4linux/README.saa7134
@@ -78,5 +78,5 @@ Have fun,
78 78
79 Gerd 79 Gerd
80 80
81-- 81--
82Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 82Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
diff --git a/Documentation/video4linux/bttv/Cards b/Documentation/video4linux/bttv/Cards
index 8f1941ede4da..d3389655ad96 100644
--- a/Documentation/video4linux/bttv/Cards
+++ b/Documentation/video4linux/bttv/Cards
@@ -149,11 +149,11 @@ Lifeview Flyvideo Series:
149 2) There is a print on the PCB: 149 2) There is a print on the PCB:
150 LR25 = Flyvideo (Zoran ZR36120, SAA7110A) 150 LR25 = Flyvideo (Zoran ZR36120, SAA7110A)
151 LR26 Rev.N = Flyvideo II (Bt848) 151 LR26 Rev.N = Flyvideo II (Bt848)
152 Rev.O = Flyvideo II (Bt878) 152 Rev.O = Flyvideo II (Bt878)
153 LR37 Rev.C = Flyvideo EZ (Capture only, ZR36120 + SAA7110) 153 LR37 Rev.C = Flyvideo EZ (Capture only, ZR36120 + SAA7110)
154 LR38 Rev.A1= Flyvideo II EZ (Bt848 capture only) 154 LR38 Rev.A1= Flyvideo II EZ (Bt848 capture only)
155 LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID) 155 LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID)
156 Rev.W = Flyvideo 98 (no eeprom) 156 Rev.W = Flyvideo 98 (no eeprom)
157 LR51 Rev.E = Flyvideo 98 EZ (capture only) 157 LR51 Rev.E = Flyvideo 98 EZ (capture only)
158 LR90 = Flyvideo 2000 (Bt878) 158 LR90 = Flyvideo 2000 (Bt878)
159 Flyvideo 2000S (Bt878) w/Stereo TV (Package incl. LR91 daughterboard) 159 Flyvideo 2000S (Bt878) w/Stereo TV (Package incl. LR91 daughterboard)
@@ -163,7 +163,7 @@ Lifeview Flyvideo Series:
163 LR136 = Flyvideo 2100/3100 (Low profile, SAA7130/SAA7134) 163 LR136 = Flyvideo 2100/3100 (Low profile, SAA7130/SAA7134)
164 LR137 = Flyvideo DV2000/DV3000 (SAA7130/SAA7134 + IEEE1394) 164 LR137 = Flyvideo DV2000/DV3000 (SAA7130/SAA7134 + IEEE1394)
165 LR138 Rev.C= Flyvideo 2000 (SAA7130) 165 LR138 Rev.C= Flyvideo 2000 (SAA7130)
166 or Flyvideo 3000 (SAA7134) w/Stereo TV 166 or Flyvideo 3000 (SAA7134) w/Stereo TV
167 These exist in variations w/FM and w/Remote sometimes denoted 167 These exist in variations w/FM and w/Remote sometimes denoted
168 by suffixes "FM" and "R". 168 by suffixes "FM" and "R".
169 3) You have a laptop (miniPCI card): 169 3) You have a laptop (miniPCI card):
@@ -197,7 +197,7 @@ Typhoon TV card series:
197 50680 "TV Tuner Pal BG" (blue package)= Pixelview PV-BT878P+ (Rev 9B) 197 50680 "TV Tuner Pal BG" (blue package)= Pixelview PV-BT878P+ (Rev 9B)
198 50681 "TV Tuner PCI Pal I" (variant of 50680) 198 50681 "TV Tuner PCI Pal I" (variant of 50680)
199 50682 "TView TV/FM Tuner Pal BG" = Flyvideo 98FM (LR50 Rev.Q) 199 50682 "TView TV/FM Tuner Pal BG" = Flyvideo 98FM (LR50 Rev.Q)
200 Note: The package has a picture of CPH05x (which would be a real TView) 200 Note: The package has a picture of CPH05x (which would be a real TView)
201 50683 "TV Tuner PCI SECAM" (variant of 50680) 201 50683 "TV Tuner PCI SECAM" (variant of 50680)
202 50684 "TV Tuner Pal BG" = Pixelview 878TV(Rev.3D) 202 50684 "TV Tuner Pal BG" = Pixelview 878TV(Rev.3D)
203 50686 "TV Tuner" = KNC1 TV Station 203 50686 "TV Tuner" = KNC1 TV Station
@@ -418,9 +418,9 @@ Lifetec/Medion/Tevion/Aldi
418-------------------------- 418--------------------------
419 LT9306/MD9306 = CPH061 419 LT9306/MD9306 = CPH061
420 LT9415/MD9415 = LR90 Rev.F or Rev.G 420 LT9415/MD9415 = LR90 Rev.F or Rev.G
421 MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H) 421 MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H)
422 MD9717 = KNC One (Rev D4, saa7134, FM1216 MK2 tuner) 422 MD9717 = KNC One (Rev D4, saa7134, FM1216 MK2 tuner)
423 MD5044 = KNC One (Rev D4, saa7134, FM1216ME MK3 tuner) 423 MD5044 = KNC One (Rev D4, saa7134, FM1216ME MK3 tuner)
424 424
425Modular Technologies (www.modulartech.com) UK 425Modular Technologies (www.modulartech.com) UK
426--------------------------------------------- 426---------------------------------------------
@@ -453,10 +453,10 @@ Technisat
453 Discos ADR PC-Karte ISA (no TV!) 453 Discos ADR PC-Karte ISA (no TV!)
454 Discos ADR PC-Karte PCI (probably no TV?) 454 Discos ADR PC-Karte PCI (probably no TV?)
455 Techni-PC-Sat (Sat. analog) 455 Techni-PC-Sat (Sat. analog)
456 Rev 1.2 (zr36120, vpx3220, stv0030, saa5246, BSJE3-494A) 456 Rev 1.2 (zr36120, vpx3220, stv0030, saa5246, BSJE3-494A)
457 Mediafocus I (zr36120/zr36125, drp3510, Sat. analog + ADR Radio) 457 Mediafocus I (zr36120/zr36125, drp3510, Sat. analog + ADR Radio)
458 Mediafocus II (saa7146, Sat. analog) 458 Mediafocus II (saa7146, Sat. analog)
459 SatADR Rev 2.1 (saa7146a, saa7113h, stv0056a, msp3400c, drp3510a, BSKE3-307A) 459 SatADR Rev 2.1 (saa7146a, saa7113h, stv0056a, msp3400c, drp3510a, BSKE3-307A)
460 SkyStar 1 DVB (AV7110) = Technotrend Premium 460 SkyStar 1 DVB (AV7110) = Technotrend Premium
461 SkyStar 2 DVB (B2C2) (=Sky2PC) 461 SkyStar 2 DVB (B2C2) (=Sky2PC)
462 462
diff --git a/Documentation/video4linux/bttv/README b/Documentation/video4linux/bttv/README
index a72f4c94fb0b..7ca2154c2bf5 100644
--- a/Documentation/video4linux/bttv/README
+++ b/Documentation/video4linux/bttv/README
@@ -42,9 +42,9 @@ bttv uses the PCI Subsystem ID to autodetect the card type. lspci lists
42the Subsystem ID in the second line, looks like this: 42the Subsystem ID in the second line, looks like this:
43 43
4400:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02) 4400:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02)
45 Subsystem: Hauppauge computer works Inc. WinTV/GO 45 Subsystem: Hauppauge computer works Inc. WinTV/GO
46 Flags: bus master, medium devsel, latency 32, IRQ 5 46 Flags: bus master, medium devsel, latency 32, IRQ 5
47 Memory at e2000000 (32-bit, prefetchable) [size=4K] 47 Memory at e2000000 (32-bit, prefetchable) [size=4K]
48 48
49only bt878-based cards can have a subsystem ID (which does not mean 49only bt878-based cards can have a subsystem ID (which does not mean
50that every card really has one). bt848 cards can't have a Subsystem 50that every card really has one). bt848 cards can't have a Subsystem
diff --git a/Documentation/video4linux/bttv/Sound-FAQ b/Documentation/video4linux/bttv/Sound-FAQ
index b8c9c2605ce2..1e6328f91083 100644
--- a/Documentation/video4linux/bttv/Sound-FAQ
+++ b/Documentation/video4linux/bttv/Sound-FAQ
@@ -61,8 +61,8 @@ line for your board. The important fields are these two:
61struct tvcard 61struct tvcard
62{ 62{
63 [ ... ] 63 [ ... ]
64 u32 gpiomask; 64 u32 gpiomask;
65 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */ 65 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
66}; 66};
67 67
68gpiomask specifies which pins are used to control the audio mux chip. 68gpiomask specifies which pins are used to control the audio mux chip.
@@ -126,11 +126,11 @@ muxsel - video mux, input->registervalue mapping
126pll - same as pll= insmod option 126pll - same as pll= insmod option
127tuner_type - same as tuner= insmod option 127tuner_type - same as tuner= insmod option
128*_modulename - hint whenever some card needs this or that audio 128*_modulename - hint whenever some card needs this or that audio
129 module loaded to work properly. 129 module loaded to work properly.
130has_radio - whenever this TV card has a radio tuner. 130has_radio - whenever this TV card has a radio tuner.
131no_msp34xx - "1" disables loading of msp3400.o module 131no_msp34xx - "1" disables loading of msp3400.o module
132no_tda9875 - "1" disables loading of tda9875.o module 132no_tda9875 - "1" disables loading of tda9875.o module
133needs_tvaudio - set to "1" to load tvaudio.o module 133needs_tvaudio - set to "1" to load tvaudio.o module
134 134
135If some config item is specified both from the tvcards array and as 135If some config item is specified both from the tvcards array and as
136insmod option, the insmod option takes precedence. 136insmod option, the insmod option takes precedence.
@@ -144,5 +144,5 @@ Good luck,
144 144
145PS: If you have a new working entry, mail it to me. 145PS: If you have a new working entry, mail it to me.
146 146
147-- 147--
148Gerd Knorr <kraxel@bytesex.org> 148Gerd Knorr <kraxel@bytesex.org>
diff --git a/Documentation/video4linux/bttv/Tuners b/Documentation/video4linux/bttv/Tuners
index d18fbc70c0e0..0a371d349542 100644
--- a/Documentation/video4linux/bttv/Tuners
+++ b/Documentation/video4linux/bttv/Tuners
@@ -21,7 +21,7 @@ SAMSUNG Tuner identification: (e.g. TCPM9091PD27)
21 J= NTSC-Japan 21 J= NTSC-Japan
22 L= Secam LL 22 L= Secam LL
23 M= BG+I+DK 23 M= BG+I+DK
24 N= NTSC 24 N= NTSC
25 Q= BG+I+DK+LL 25 Q= BG+I+DK+LL
26 [89]: ? 26 [89]: ?
27 [125]: 27 [125]:
@@ -96,7 +96,7 @@ LG Innotek Tuner:
96 TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69) 96 TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69)
97 TADC-M201D: PAL D/K+B/G+I (L,143/425) (sound control at I2C address 0xc8) 97 TADC-M201D: PAL D/K+B/G+I (L,143/425) (sound control at I2C address 0xc8)
98 TADC-T003F: NTSC Taiwan (L,175/410?; 2-B, C-W+11, W+12-69) 98 TADC-T003F: NTSC Taiwan (L,175/410?; 2-B, C-W+11, W+12-69)
99 Suffix: 99 Suffix:
100 P= Standard phono female socket 100 P= Standard phono female socket
101 D= IEC female socket 101 D= IEC female socket
102 F= F-connector 102 F= F-connector
diff --git a/Documentation/video4linux/lifeview.txt b/Documentation/video4linux/lifeview.txt
index b07ea79c2b7e..05f9eb57aac9 100644
--- a/Documentation/video4linux/lifeview.txt
+++ b/Documentation/video4linux/lifeview.txt
@@ -10,33 +10,33 @@ bt878:
10------------------------------------------------------------------------------ 10------------------------------------------------------------------------------
11 11
12saa7134: 12saa7134:
13 /* LifeView FlyTV Platinum FM (LR214WF) */ 13 /* LifeView FlyTV Platinum FM (LR214WF) */
14 /* "Peter Missel <peter.missel@onlinehome.de> */ 14 /* "Peter Missel <peter.missel@onlinehome.de> */
15 .name = "LifeView FlyTV Platinum FM", 15 .name = "LifeView FlyTV Platinum FM",
16 /* GP27 MDT2005 PB4 pin 10 */ 16 /* GP27 MDT2005 PB4 pin 10 */
17 /* GP26 MDT2005 PB3 pin 9 */ 17 /* GP26 MDT2005 PB3 pin 9 */
18 /* GP25 MDT2005 PB2 pin 8 */ 18 /* GP25 MDT2005 PB2 pin 8 */
19 /* GP23 MDT2005 PB1 pin 7 */ 19 /* GP23 MDT2005 PB1 pin 7 */
20 /* GP22 MDT2005 PB0 pin 6 */ 20 /* GP22 MDT2005 PB0 pin 6 */
21 /* GP21 MDT2005 PB5 pin 11 */ 21 /* GP21 MDT2005 PB5 pin 11 */
22 /* GP20 MDT2005 PB6 pin 12 */ 22 /* GP20 MDT2005 PB6 pin 12 */
23 /* GP19 MDT2005 PB7 pin 13 */ 23 /* GP19 MDT2005 PB7 pin 13 */
24 /* nc MDT2005 PA3 pin 2 */ 24 /* nc MDT2005 PA3 pin 2 */
25 /* Remote MDT2005 PA2 pin 1 */ 25 /* Remote MDT2005 PA2 pin 1 */
26 /* GP18 MDT2005 PA1 pin 18 */ 26 /* GP18 MDT2005 PA1 pin 18 */
27 /* nc MDT2005 PA0 pin 17 strap low */ 27 /* nc MDT2005 PA0 pin 17 strap low */
28 28
29 /* GP17 Strap "GP7"=High */ 29 /* GP17 Strap "GP7"=High */
30 /* GP16 Strap "GP6"=High 30 /* GP16 Strap "GP6"=High
31 0=Radio 1=TV 31 0=Radio 1=TV
32 Drives SA630D ENCH1 and HEF4052 A1 pins 32 Drives SA630D ENCH1 and HEF4052 A1 pins
33 to do FM radio through SIF input */ 33 to do FM radio through SIF input */
34 /* GP15 nc */ 34 /* GP15 nc */
35 /* GP14 nc */ 35 /* GP14 nc */
36 /* GP13 nc */ 36 /* GP13 nc */
37 /* GP12 Strap "GP5" = High */ 37 /* GP12 Strap "GP5" = High */
38 /* GP11 Strap "GP4" = High */ 38 /* GP11 Strap "GP4" = High */
39 /* GP10 Strap "GP3" = High */ 39 /* GP10 Strap "GP3" = High */
40 /* GP09 Strap "GP2" = Low */ 40 /* GP09 Strap "GP2" = Low */
41 /* GP08 Strap "GP1" = Low */ 41 /* GP08 Strap "GP1" = Low */
42 /* GP07.00 nc */ 42 /* GP07.00 nc */
diff --git a/MAINTAINERS b/MAINTAINERS
index 995bfd8e6e7f..5541f9970b87 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1330,6 +1330,24 @@ M: john.ronciak@intel.com
1330W: http://sourceforge.net/projects/e1000/ 1330W: http://sourceforge.net/projects/e1000/
1331S: Supported 1331S: Supported
1332 1332
1333INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
1334P: Yi Zhu
1335M: yi.zhu@intel.com
1336P: James Ketrenos
1337M: jketreno@linux.intel.com
1338L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
1339W: http://ipw2100.sourceforge.net
1340S: Supported
1341
1342INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
1343P: Yi Zhu
1344M: yi.zhu@intel.com
1345P: James Ketrenos
1346M: jketreno@linux.intel.com
1347L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
1348W: http://ipw2200.sourceforge.net
1349S: Supported
1350
1333IOC3 DRIVER 1351IOC3 DRIVER
1334P: Ralf Baechle 1352P: Ralf Baechle
1335M: ralf@linux-mips.org 1353M: ralf@linux-mips.org
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index eb20c3afff58..a8682612abc0 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -43,21 +43,17 @@
43#include "proto.h" 43#include "proto.h"
44#include "pci_impl.h" 44#include "pci_impl.h"
45 45
46void default_idle(void)
47{
48 barrier();
49}
50
51void 46void
52cpu_idle(void) 47cpu_idle(void)
53{ 48{
49 set_thread_flag(TIF_POLLING_NRFLAG);
50
54 while (1) { 51 while (1) {
55 void (*idle)(void) = default_idle;
56 /* FIXME -- EV6 and LCA45 know how to power down 52 /* FIXME -- EV6 and LCA45 know how to power down
57 the CPU. */ 53 the CPU. */
58 54
59 while (!need_resched()) 55 while (!need_resched())
60 idle(); 56 cpu_relax();
61 schedule(); 57 schedule();
62 } 58 }
63} 59}
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 91d5ef3397be..ec77721507cb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -356,6 +356,16 @@ config HOTPLUG_CPU
356 Say Y here to experiment with turning CPUs off and on. CPUs 356 Say Y here to experiment with turning CPUs off and on. CPUs
357 can be controlled through /sys/devices/system/cpu. 357 can be controlled through /sys/devices/system/cpu.
358 358
359config LOCAL_TIMERS
360 bool "Use local timer interrupts"
361 depends on SMP && REALVIEW_MPCORE
362 default y
363 help
364 Enable support for local timers on SMP platforms, rather then the
365 legacy IPI broadcast method. Local timers allows the system
366 accounting to be spread across the timer interval, preventing a
367 "thundering herd" at every timer tick.
368
359config PREEMPT 369config PREEMPT
360 bool "Preemptible Kernel (EXPERIMENTAL)" 370 bool "Preemptible Kernel (EXPERIMENTAL)"
361 depends on EXPERIMENTAL 371 depends on EXPERIMENTAL
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 50f13eec6cd7..5ab94584baee 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -283,8 +283,14 @@ void flush_window(void)
283 putstr("."); 283 putstr(".");
284} 284}
285 285
286#ifndef arch_error
287#define arch_error(x)
288#endif
289
286static void error(char *x) 290static void error(char *x)
287{ 291{
292 arch_error(x);
293
288 putstr("\n\n"); 294 putstr("\n\n");
289 putstr(x); 295 putstr(x);
290 putstr("\n\n -- System halted"); 296 putstr("\n\n -- System halted");
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index bb4eff614413..c7fdf390cef9 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -19,12 +19,6 @@
19 19
20#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) 20#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))
21 21
22/* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c
23 There is no easy way to link multiple scoop devices into one
24 single entity for the pxa2xx_pcmcia device */
25int scoop_num;
26struct scoop_pcmcia_dev *scoop_devs;
27
28struct scoop_dev { 22struct scoop_dev {
29 void *base; 23 void *base;
30 spinlock_t scoop_lock; 24 spinlock_t scoop_lock;
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 7b17a87a3311..7a3261f0bf79 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -9,6 +9,7 @@
9 */ 9 */
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/string.h> 11#include <linux/string.h>
12#include <linux/cryptohash.h>
12#include <linux/delay.h> 13#include <linux/delay.h>
13#include <linux/in6.h> 14#include <linux/in6.h>
14#include <linux/syscalls.h> 15#include <linux/syscalls.h>
@@ -126,6 +127,9 @@ EXPORT_SYMBOL(__put_user_2);
126EXPORT_SYMBOL(__put_user_4); 127EXPORT_SYMBOL(__put_user_4);
127EXPORT_SYMBOL(__put_user_8); 128EXPORT_SYMBOL(__put_user_8);
128 129
130 /* crypto hash */
131EXPORT_SYMBOL(sha_transform);
132
129 /* gcc lib functions */ 133 /* gcc lib functions */
130EXPORT_SYMBOL(__ashldi3); 134EXPORT_SYMBOL(__ashldi3);
131EXPORT_SYMBOL(__ashrdi3); 135EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index a511ec5b11a3..d9fb819bf7cc 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -47,6 +47,13 @@
47 movne r0, sp 47 movne r0, sp
48 adrne lr, 1b 48 adrne lr, 1b
49 bne do_IPI 49 bne do_IPI
50
51#ifdef CONFIG_LOCAL_TIMERS
52 test_for_ltirq r0, r6, r5, lr
53 movne r0, sp
54 adrne lr, 1b
55 bne do_local_timer
56#endif
50#endif 57#endif
51 58
52 .endm 59 .endm
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 9def4404e1f2..d7099dbbb879 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -264,6 +264,7 @@ unlock:
264#endif 264#endif
265#ifdef CONFIG_SMP 265#ifdef CONFIG_SMP
266 show_ipi_list(p); 266 show_ipi_list(p);
267 show_local_irqs(p);
267#endif 268#endif
268 seq_printf(p, "Err: %10lu\n", irq_err_count); 269 seq_printf(p, "Err: %10lu\n", irq_err_count);
269 } 270 }
@@ -995,7 +996,7 @@ void __init init_irq_proc(void)
995 struct proc_dir_entry *dir; 996 struct proc_dir_entry *dir;
996 int irq; 997 int irq;
997 998
998 dir = proc_mkdir("irq", 0); 999 dir = proc_mkdir("irq", NULL);
999 if (!dir) 1000 if (!dir)
1000 return; 1001 return;
1001 1002
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index ba298277becd..30494aab829a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -86,12 +86,16 @@ EXPORT_SYMBOL(pm_power_off);
86 */ 86 */
87void default_idle(void) 87void default_idle(void)
88{ 88{
89 local_irq_disable(); 89 if (hlt_counter)
90 if (!need_resched() && !hlt_counter) { 90 cpu_relax();
91 timer_dyn_reprogram(); 91 else {
92 arch_idle(); 92 local_irq_disable();
93 if (!need_resched()) {
94 timer_dyn_reprogram();
95 arch_idle();
96 }
97 local_irq_enable();
93 } 98 }
94 local_irq_enable();
95} 99}
96 100
97/* 101/*
@@ -116,13 +120,13 @@ void cpu_idle(void)
116 120
117 if (!idle) 121 if (!idle)
118 idle = default_idle; 122 idle = default_idle;
119 preempt_disable();
120 leds_event(led_idle_start); 123 leds_event(led_idle_start);
121 while (!need_resched()) 124 while (!need_resched())
122 idle(); 125 idle();
123 leds_event(led_idle_end); 126 leds_event(led_idle_end);
124 preempt_enable(); 127 preempt_enable_no_resched();
125 schedule(); 128 schedule();
129 preempt_disable();
126 } 130 }
127} 131}
128 132
@@ -355,7 +359,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
355 struct thread_info *thread = p->thread_info; 359 struct thread_info *thread = p->thread_info;
356 struct pt_regs *childregs; 360 struct pt_regs *childregs;
357 361
358 childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1; 362 childregs = (void *)thread + THREAD_START_SP - sizeof(*regs);
359 *childregs = *regs; 363 *childregs = *regs;
360 childregs->ARM_r0 = 0; 364 childregs->ARM_r0 = 0;
361 childregs->ARM_sp = stack_start; 365 childregs->ARM_sp = stack_start;
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index edb5a406922f..e55ea952f7aa 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -142,7 +142,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
142 ret = -EIO; 142 ret = -EIO;
143 } 143 }
144 144
145 secondary_data.stack = 0; 145 secondary_data.stack = NULL;
146 secondary_data.pgdir = 0; 146 secondary_data.pgdir = 0;
147 147
148 *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0); 148 *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0);
@@ -185,6 +185,11 @@ int __cpuexit __cpu_disable(void)
185 migrate_irqs(); 185 migrate_irqs();
186 186
187 /* 187 /*
188 * Stop the local timer for this CPU.
189 */
190 local_timer_stop(cpu);
191
192 /*
188 * Flush user cache and TLB mappings, and then remove this CPU 193 * Flush user cache and TLB mappings, and then remove this CPU
189 * from the vm mask set of all processes. 194 * from the vm mask set of all processes.
190 */ 195 */
@@ -251,7 +256,9 @@ void __cpuexit cpu_die(void)
251asmlinkage void __cpuinit secondary_start_kernel(void) 256asmlinkage void __cpuinit secondary_start_kernel(void)
252{ 257{
253 struct mm_struct *mm = &init_mm; 258 struct mm_struct *mm = &init_mm;
254 unsigned int cpu = smp_processor_id(); 259 unsigned int cpu;
260
261 cpu = smp_processor_id();
255 262
256 printk("CPU%u: Booted secondary processor\n", cpu); 263 printk("CPU%u: Booted secondary processor\n", cpu);
257 264
@@ -268,6 +275,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
268 local_flush_tlb_all(); 275 local_flush_tlb_all();
269 276
270 cpu_init(); 277 cpu_init();
278 preempt_disable();
271 279
272 /* 280 /*
273 * Give the platform a chance to do its own initialisation. 281 * Give the platform a chance to do its own initialisation.
@@ -290,6 +298,11 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
290 cpu_set(cpu, cpu_online_map); 298 cpu_set(cpu, cpu_online_map);
291 299
292 /* 300 /*
301 * Setup local timer for this CPU.
302 */
303 local_timer_setup(cpu);
304
305 /*
293 * OK, it's off to the idle thread for us 306 * OK, it's off to the idle thread for us
294 */ 307 */
295 cpu_idle(); 308 cpu_idle();
@@ -359,8 +372,8 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg)
359 * You must not call this function with disabled interrupts, from a 372 * You must not call this function with disabled interrupts, from a
360 * hardware interrupt handler, nor from a bottom half handler. 373 * hardware interrupt handler, nor from a bottom half handler.
361 */ 374 */
362int smp_call_function_on_cpu(void (*func)(void *info), void *info, int retry, 375static int smp_call_function_on_cpu(void (*func)(void *info), void *info,
363 int wait, cpumask_t callmap) 376 int retry, int wait, cpumask_t callmap)
364{ 377{
365 struct smp_call_struct data; 378 struct smp_call_struct data;
366 unsigned long timeout; 379 unsigned long timeout;
@@ -454,6 +467,18 @@ void show_ipi_list(struct seq_file *p)
454 seq_putc(p, '\n'); 467 seq_putc(p, '\n');
455} 468}
456 469
470void show_local_irqs(struct seq_file *p)
471{
472 unsigned int cpu;
473
474 seq_printf(p, "LOC: ");
475
476 for_each_present_cpu(cpu)
477 seq_printf(p, "%10u ", irq_stat[cpu].local_timer_irqs);
478
479 seq_putc(p, '\n');
480}
481
457static void ipi_timer(struct pt_regs *regs) 482static void ipi_timer(struct pt_regs *regs)
458{ 483{
459 int user = user_mode(regs); 484 int user = user_mode(regs);
@@ -464,6 +489,18 @@ static void ipi_timer(struct pt_regs *regs)
464 irq_exit(); 489 irq_exit();
465} 490}
466 491
492#ifdef CONFIG_LOCAL_TIMERS
493asmlinkage void do_local_timer(struct pt_regs *regs)
494{
495 int cpu = smp_processor_id();
496
497 if (local_timer_ack()) {
498 irq_stat[cpu].local_timer_irqs++;
499 ipi_timer(regs);
500 }
501}
502#endif
503
467/* 504/*
468 * ipi_call_function - handle IPI from smp_call_function() 505 * ipi_call_function - handle IPI from smp_call_function()
469 * 506 *
@@ -515,7 +552,7 @@ static void ipi_cpu_stop(unsigned int cpu)
515 * 552 *
516 * Bit 0 - Inter-processor function call 553 * Bit 0 - Inter-processor function call
517 */ 554 */
518void do_IPI(struct pt_regs *regs) 555asmlinkage void do_IPI(struct pt_regs *regs)
519{ 556{
520 unsigned int cpu = smp_processor_id(); 557 unsigned int cpu = smp_processor_id();
521 struct ipi_data *ipi = &per_cpu(ipi_data, cpu); 558 struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index f35d91fbe117..b8c14e936697 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -34,7 +34,7 @@
34 and r2, r0, #7 34 and r2, r0, #7
35 mov r3, #1 35 mov r3, #1
36 mov r3, r3, lsl r2 36 mov r3, r3, lsl r2
37 save_and_disable_irqs ip, r2 37 save_and_disable_irqs ip
38 ldrb r2, [r1, r0, lsr #3] 38 ldrb r2, [r1, r0, lsr #3]
39 \instr r2, r2, r3 39 \instr r2, r2, r3
40 strb r2, [r1, r0, lsr #3] 40 strb r2, [r1, r0, lsr #3]
@@ -54,7 +54,7 @@
54 add r1, r1, r0, lsr #3 54 add r1, r1, r0, lsr #3
55 and r3, r0, #7 55 and r3, r0, #7
56 mov r0, #1 56 mov r0, #1
57 save_and_disable_irqs ip, r2 57 save_and_disable_irqs ip
58 ldrb r2, [r1] 58 ldrb r2, [r1]
59 tst r2, r0, lsl r3 59 tst r2, r0, lsl r3
60 \instr r2, r2, r0, lsl r3 60 \instr r2, r2, r0, lsl r3
diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c
index be283cda63dd..399010c14036 100644
--- a/arch/arm/mach-omap1/leds-h2p2-debug.c
+++ b/arch/arm/mach-omap1/leds-h2p2-debug.c
@@ -13,7 +13,6 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/kernel_stat.h> 14#include <linux/kernel_stat.h>
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/version.h>
17 16
18#include <asm/io.h> 17#include <asm/io.h>
19#include <asm/hardware.h> 18#include <asm/hardware.h>
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index eb5f6d744a4a..100fb31b5156 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -62,6 +62,37 @@ static struct scoop_config corgi_scoop_setup = {
62 .io_out = CORGI_SCOOP_IO_OUT, 62 .io_out = CORGI_SCOOP_IO_OUT,
63}; 63};
64 64
65struct platform_device corgiscoop_device = {
66 .name = "sharp-scoop",
67 .id = -1,
68 .dev = {
69 .platform_data = &corgi_scoop_setup,
70 },
71 .num_resources = ARRAY_SIZE(corgi_scoop_resources),
72 .resource = corgi_scoop_resources,
73};
74
75static void corgi_pcmcia_init(void)
76{
77 /* Setup default state of GPIO outputs
78 before we enable them as outputs. */
79 GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
80 GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
81 GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
82 GPIO_bit(GPIO53_nPCE_2);
83
84 pxa_gpio_mode(GPIO48_nPOE_MD);
85 pxa_gpio_mode(GPIO49_nPWE_MD);
86 pxa_gpio_mode(GPIO50_nPIOR_MD);
87 pxa_gpio_mode(GPIO51_nPIOW_MD);
88 pxa_gpio_mode(GPIO55_nPREG_MD);
89 pxa_gpio_mode(GPIO56_nPWAIT_MD);
90 pxa_gpio_mode(GPIO57_nIOIS16_MD);
91 pxa_gpio_mode(GPIO52_nPCE_1_MD);
92 pxa_gpio_mode(GPIO53_nPCE_2_MD);
93 pxa_gpio_mode(GPIO54_pSKTSEL_MD);
94}
95
65static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { 96static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
66{ 97{
67 .dev = &corgiscoop_device.dev, 98 .dev = &corgiscoop_device.dev,
@@ -71,16 +102,14 @@ static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
71}, 102},
72}; 103};
73 104
74struct platform_device corgiscoop_device = { 105static struct scoop_pcmcia_config corgi_pcmcia_config = {
75 .name = "sharp-scoop", 106 .devs = &corgi_pcmcia_scoop[0],
76 .id = -1, 107 .num_devs = 1,
77 .dev = { 108 .pcmcia_init = corgi_pcmcia_init,
78 .platform_data = &corgi_scoop_setup,
79 },
80 .num_resources = ARRAY_SIZE(corgi_scoop_resources),
81 .resource = corgi_scoop_resources,
82}; 109};
83 110
111EXPORT_SYMBOL(corgiscoop_device);
112
84 113
85/* 114/*
86 * Corgi SSP Device 115 * Corgi SSP Device
@@ -294,8 +323,7 @@ static void __init corgi_init(void)
294 pxa_set_mci_info(&corgi_mci_platform_data); 323 pxa_set_mci_info(&corgi_mci_platform_data);
295 pxa_set_ficp_info(&corgi_ficp_platform_data); 324 pxa_set_ficp_info(&corgi_ficp_platform_data);
296 325
297 scoop_num = 1; 326 platform_scoop_config = &corgi_pcmcia_config;
298 scoop_devs = &corgi_pcmcia_scoop[0];
299 327
300 platform_add_devices(devices, ARRAY_SIZE(devices)); 328 platform_add_devices(devices, ARRAY_SIZE(devices));
301} 329}
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index ad6a13f95a62..eef3de26ad37 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -65,6 +65,27 @@ struct platform_device poodle_scoop_device = {
65 .resource = poodle_scoop_resources, 65 .resource = poodle_scoop_resources,
66}; 66};
67 67
68static void poodle_pcmcia_init(void)
69{
70 /* Setup default state of GPIO outputs
71 before we enable them as outputs. */
72 GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
73 GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
74 GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
75 GPIO_bit(GPIO53_nPCE_2);
76
77 pxa_gpio_mode(GPIO48_nPOE_MD);
78 pxa_gpio_mode(GPIO49_nPWE_MD);
79 pxa_gpio_mode(GPIO50_nPIOR_MD);
80 pxa_gpio_mode(GPIO51_nPIOW_MD);
81 pxa_gpio_mode(GPIO55_nPREG_MD);
82 pxa_gpio_mode(GPIO56_nPWAIT_MD);
83 pxa_gpio_mode(GPIO57_nIOIS16_MD);
84 pxa_gpio_mode(GPIO52_nPCE_1_MD);
85 pxa_gpio_mode(GPIO53_nPCE_2_MD);
86 pxa_gpio_mode(GPIO54_pSKTSEL_MD);
87}
88
68static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { 89static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
69{ 90{
70 .dev = &poodle_scoop_device.dev, 91 .dev = &poodle_scoop_device.dev,
@@ -74,6 +95,14 @@ static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
74}, 95},
75}; 96};
76 97
98static struct scoop_pcmcia_config poodle_pcmcia_config = {
99 .devs = &poodle_pcmcia_scoop[0],
100 .num_devs = 1,
101 .pcmcia_init = poodle_pcmcia_init,
102};
103
104EXPORT_SYMBOL(poodle_scoop_device);
105
77 106
78/* LoCoMo device */ 107/* LoCoMo device */
79static struct resource locomo_resources[] = { 108static struct resource locomo_resources[] = {
@@ -268,8 +297,7 @@ static void __init poodle_init(void)
268 pxa_set_mci_info(&poodle_mci_platform_data); 297 pxa_set_mci_info(&poodle_mci_platform_data);
269 pxa_set_ficp_info(&poodle_ficp_platform_data); 298 pxa_set_ficp_info(&poodle_ficp_platform_data);
270 299
271 scoop_num = 1; 300 platform_scoop_config = &poodle_pcmcia_config;
272 scoop_devs = &poodle_pcmcia_scoop[0];
273 301
274 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 302 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
275 if (ret) { 303 if (ret) {
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 6c6878cd2207..4e9a699ee428 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -104,6 +104,66 @@ struct platform_device spitzscoop2_device = {
104 .resource = spitz_scoop2_resources, 104 .resource = spitz_scoop2_resources,
105}; 105};
106 106
107#define SPITZ_PWR_SD 0x01
108#define SPITZ_PWR_CF 0x02
109
110/* Power control is shared with between one of the CF slots and SD */
111static void spitz_card_pwr_ctrl(int device, unsigned short new_cpr)
112{
113 unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR);
114
115 if (new_cpr & 0x0007) {
116 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
117 if (!(cpr & 0x0002) && !(cpr & 0x0004))
118 mdelay(5);
119 if (device == SPITZ_PWR_CF)
120 cpr |= 0x0002;
121 if (device == SPITZ_PWR_SD)
122 cpr |= 0x0004;
123 write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
124 } else {
125 if (device == SPITZ_PWR_CF)
126 cpr &= ~0x0002;
127 if (device == SPITZ_PWR_SD)
128 cpr &= ~0x0004;
129 write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
130 if (!(cpr & 0x0002) && !(cpr & 0x0004)) {
131 mdelay(1);
132 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
133 }
134 }
135}
136
137static void spitz_pcmcia_init(void)
138{
139 /* Setup default state of GPIO outputs
140 before we enable them as outputs. */
141 GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
142 GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
143 GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO54_nPCE_2);
144 GPSR(GPIO85_nPCE_1) = GPIO_bit(GPIO85_nPCE_1);
145
146 pxa_gpio_mode(GPIO48_nPOE_MD);
147 pxa_gpio_mode(GPIO49_nPWE_MD);
148 pxa_gpio_mode(GPIO50_nPIOR_MD);
149 pxa_gpio_mode(GPIO51_nPIOW_MD);
150 pxa_gpio_mode(GPIO55_nPREG_MD);
151 pxa_gpio_mode(GPIO56_nPWAIT_MD);
152 pxa_gpio_mode(GPIO57_nIOIS16_MD);
153 pxa_gpio_mode(GPIO85_nPCE_1_MD);
154 pxa_gpio_mode(GPIO54_nPCE_2_MD);
155 pxa_gpio_mode(GPIO104_pSKTSEL_MD);
156}
157
158static void spitz_pcmcia_pwr(struct device *scoop, unsigned short cpr, int nr)
159{
160 /* Only need to override behaviour for slot 0 */
161 if (nr == 0)
162 spitz_card_pwr_ctrl(SPITZ_PWR_CF, cpr);
163 else
164 write_scoop_reg(scoop, SCOOP_CPR, cpr);
165}
166
107static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { 167static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
108{ 168{
109 .dev = &spitzscoop_device.dev, 169 .dev = &spitzscoop_device.dev,
@@ -117,6 +177,16 @@ static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
117}, 177},
118}; 178};
119 179
180static struct scoop_pcmcia_config spitz_pcmcia_config = {
181 .devs = &spitz_pcmcia_scoop[0],
182 .num_devs = 2,
183 .pcmcia_init = spitz_pcmcia_init,
184 .power_ctrl = spitz_pcmcia_pwr,
185};
186
187EXPORT_SYMBOL(spitzscoop_device);
188EXPORT_SYMBOL(spitzscoop2_device);
189
120 190
121/* 191/*
122 * Spitz SSP Device 192 * Spitz SSP Device
@@ -235,27 +305,14 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in
235 return 0; 305 return 0;
236} 306}
237 307
238/* Power control is shared with one of the CF slots so we have a mess */
239static void spitz_mci_setpower(struct device *dev, unsigned int vdd) 308static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
240{ 309{
241 struct pxamci_platform_data* p_d = dev->platform_data; 310 struct pxamci_platform_data* p_d = dev->platform_data;
242 311
243 unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); 312 if (( 1 << vdd) & p_d->ocr_mask)
244 313 spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0004);
245 if (( 1 << vdd) & p_d->ocr_mask) { 314 else
246 /* printk(KERN_DEBUG "%s: on\n", __FUNCTION__); */ 315 spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0000);
247 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
248 mdelay(2);
249 write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | 0x04);
250 } else {
251 /* printk(KERN_DEBUG "%s: off\n", __FUNCTION__); */
252 write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr & ~0x04);
253
254 if (!(cpr | 0x02)) {
255 mdelay(1);
256 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
257 }
258 }
259} 316}
260 317
261static int spitz_mci_get_ro(struct device *dev) 318static int spitz_mci_get_ro(struct device *dev)
@@ -351,8 +408,8 @@ static void __init common_init(void)
351 408
352static void __init spitz_init(void) 409static void __init spitz_init(void)
353{ 410{
354 scoop_num = 2; 411 platform_scoop_config = &spitz_pcmcia_config;
355 scoop_devs = &spitz_pcmcia_scoop[0]; 412
356 spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity; 413 spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity;
357 414
358 common_init(); 415 common_init();
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 7dad3f1465e0..b9b2057349eb 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -132,11 +132,13 @@ static void __init pxa_timer_init(void)
132 tv.tv_sec = pxa_get_rtc_time(); 132 tv.tv_sec = pxa_get_rtc_time();
133 do_settimeofday(&tv); 133 do_settimeofday(&tv);
134 134
135 OSMR0 = 0; /* set initial match at 0 */ 135 OIER = 0; /* disable any timer interrupts */
136 OSCR = LATCH*2; /* push OSCR out of the way */
137 OSMR0 = LATCH; /* set initial match */
136 OSSR = 0xf; /* clear status on all timers */ 138 OSSR = 0xf; /* clear status on all timers */
137 setup_irq(IRQ_OST0, &pxa_timer_irq); 139 setup_irq(IRQ_OST0, &pxa_timer_irq);
138 OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ 140 OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */
139 OSCR = 0; /* initialize free-running timer, force first match */ 141 OSCR = 0; /* initialize free-running timer */
140} 142}
141 143
142#ifdef CONFIG_NO_IDLE_HZ 144#ifdef CONFIG_NO_IDLE_HZ
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 400609f8b6a8..c312054dfb88 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -98,6 +98,9 @@ struct platform_device tosascoop_jc_device = {
98 .resource = tosa_scoop_jc_resources, 98 .resource = tosa_scoop_jc_resources,
99}; 99};
100 100
101/*
102 * PCMCIA
103 */
101static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = { 104static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = {
102{ 105{
103 .dev = &tosascoop_device.dev, 106 .dev = &tosascoop_device.dev,
@@ -111,16 +114,155 @@ static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = {
111}, 114},
112}; 115};
113 116
117static void tosa_pcmcia_init(void)
118{
119 /* Setup default state of GPIO outputs
120 before we enable them as outputs. */
121 GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
122 GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) |
123 GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) |
124 GPIO_bit(GPIO53_nPCE_2);
125
126 pxa_gpio_mode(GPIO48_nPOE_MD);
127 pxa_gpio_mode(GPIO49_nPWE_MD);
128 pxa_gpio_mode(GPIO50_nPIOR_MD);
129 pxa_gpio_mode(GPIO51_nPIOW_MD);
130 pxa_gpio_mode(GPIO55_nPREG_MD);
131 pxa_gpio_mode(GPIO56_nPWAIT_MD);
132 pxa_gpio_mode(GPIO57_nIOIS16_MD);
133 pxa_gpio_mode(GPIO52_nPCE_1_MD);
134 pxa_gpio_mode(GPIO53_nPCE_2_MD);
135 pxa_gpio_mode(GPIO54_pSKTSEL_MD);
136}
137
138static struct scoop_pcmcia_config tosa_pcmcia_config = {
139 .devs = &tosa_pcmcia_scoop[0],
140 .num_devs = 2,
141 .pcmcia_init = tosa_pcmcia_init,
142};
143
144/*
145 * USB Device Controller
146 */
147static void tosa_udc_command(int cmd)
148{
149 switch(cmd) {
150 case PXA2XX_UDC_CMD_CONNECT:
151 set_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP);
152 break;
153 case PXA2XX_UDC_CMD_DISCONNECT:
154 reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP);
155 break;
156 }
157}
158
159static int tosa_udc_is_connected(void)
160{
161 return ((GPLR(TOSA_GPIO_USB_IN) & GPIO_bit(TOSA_GPIO_USB_IN)) == 0);
162}
163
164
165static struct pxa2xx_udc_mach_info udc_info __initdata = {
166 .udc_command = tosa_udc_command,
167 .udc_is_connected = tosa_udc_is_connected,
168};
169
170/*
171 * MMC/SD Device
172 */
173static struct pxamci_platform_data tosa_mci_platform_data;
174
175static int tosa_mci_init(struct device *dev, irqreturn_t (*tosa_detect_int)(int, void *, struct pt_regs *), void *data)
176{
177 int err;
178
179 /* setup GPIO for PXA25x MMC controller */
180 pxa_gpio_mode(GPIO6_MMCCLK_MD);
181 pxa_gpio_mode(GPIO8_MMCCS0_MD);
182 pxa_gpio_mode(TOSA_GPIO_nSD_DETECT | GPIO_IN);
183
184 tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
185
186 err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, SA_INTERRUPT,
187 "MMC/SD card detect", data);
188 if (err) {
189 printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
190 return -1;
191 }
192
193 set_irq_type(TOSA_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
194
195 return 0;
196}
197
198static void tosa_mci_setpower(struct device *dev, unsigned int vdd)
199{
200 struct pxamci_platform_data* p_d = dev->platform_data;
201
202 if (( 1 << vdd) & p_d->ocr_mask) {
203 set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON);
204 } else {
205 reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON);
206 }
207}
208
209static int tosa_mci_get_ro(struct device *dev)
210{
211 return (read_scoop_reg(&tosascoop_device.dev, SCOOP_GPWR)&TOSA_SCOOP_SD_WP);
212}
213
214static void tosa_mci_exit(struct device *dev, void *data)
215{
216 free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
217}
218
219static struct pxamci_platform_data tosa_mci_platform_data = {
220 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
221 .init = tosa_mci_init,
222 .get_ro = tosa_mci_get_ro,
223 .setpower = tosa_mci_setpower,
224 .exit = tosa_mci_exit,
225};
226
227/*
228 * Irda
229 */
230static void tosa_irda_transceiver_mode(struct device *dev, int mode)
231{
232 if (mode & IR_OFF) {
233 reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN);
234 pxa_gpio_mode(GPIO47_STTXD|GPIO_DFLT_LOW);
235 pxa_gpio_mode(GPIO47_STTXD|GPIO_OUT);
236 } else {
237 pxa_gpio_mode(GPIO47_STTXD_MD);
238 set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN);
239 }
240}
241
242static struct pxaficp_platform_data tosa_ficp_platform_data = {
243 .transceiver_cap = IR_SIRMODE | IR_OFF,
244 .transceiver_mode = tosa_irda_transceiver_mode,
245};
246
247/*
248 * Tosa Keyboard
249 */
250static struct platform_device tosakbd_device = {
251 .name = "tosa-keyboard",
252 .id = -1,
253};
114 254
115static struct platform_device *devices[] __initdata = { 255static struct platform_device *devices[] __initdata = {
116 &tosascoop_device, 256 &tosascoop_device,
117 &tosascoop_jc_device, 257 &tosascoop_jc_device,
258 &tosakbd_device,
118}; 259};
119 260
120static void __init tosa_init(void) 261static void __init tosa_init(void)
121{ 262{
122 pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN); 263 pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN);
123 pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN); 264 pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN);
265 pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN);
124 266
125 /* setup sleep mode values */ 267 /* setup sleep mode values */
126 PWER = 0x00000002; 268 PWER = 0x00000002;
@@ -131,13 +273,15 @@ static void __init tosa_init(void)
131 PGSR2 = 0x00014000; 273 PGSR2 = 0x00014000;
132 PCFR |= PCFR_OPDE; 274 PCFR |= PCFR_OPDE;
133 275
134 // enable batt_fault 276 /* enable batt_fault */
135 PMCR = 0x01; 277 PMCR = 0x01;
136 278
137 platform_add_devices(devices, ARRAY_SIZE(devices)); 279 pxa_set_mci_info(&tosa_mci_platform_data);
280 pxa_set_udc_info(&udc_info);
281 pxa_set_ficp_info(&tosa_ficp_platform_data);
282 platform_scoop_config = &tosa_pcmcia_config;
138 283
139 scoop_num = 2; 284 platform_add_devices(devices, ARRAY_SIZE(devices));
140 scoop_devs = &tosa_pcmcia_scoop[0];
141} 285}
142 286
143static void __init fixup_tosa(struct machine_desc *desc, 287static void __init fixup_tosa(struct machine_desc *desc,
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
index 011a85c10627..36e76ba937fc 100644
--- a/arch/arm/mach-realview/Makefile
+++ b/arch/arm/mach-realview/Makefile
@@ -5,3 +5,5 @@
5obj-y := core.o clock.o 5obj-y := core.o clock.o
6obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o 6obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o
7obj-$(CONFIG_SMP) += platsmp.o headsmp.o 7obj-$(CONFIG_SMP) += platsmp.o headsmp.o
8obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
9obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 482eb512ebe8..e2c6fa23d3cd 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -550,6 +550,11 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_reg
550 550
551 timer_tick(regs); 551 timer_tick(regs);
552 552
553#if defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS)
554 smp_send_timer();
555 update_process_times(user_mode(regs));
556#endif
557
553 write_sequnlock(&xtime_lock); 558 write_sequnlock(&xtime_lock);
554 559
555 return IRQ_HANDLED; 560 return IRQ_HANDLED;
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
new file mode 100644
index 000000000000..09748cbcd10e
--- /dev/null
+++ b/arch/arm/mach-realview/hotplug.c
@@ -0,0 +1,138 @@
1/*
2 * linux/arch/arm/mach-realview/hotplug.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/smp.h>
14#include <linux/completion.h>
15
16extern volatile int pen_release;
17
18static DECLARE_COMPLETION(cpu_killed);
19
20static inline void cpu_enter_lowpower(void)
21{
22 unsigned int v;
23
24 asm volatile( "mcr p15, 0, %1, c7, c14, 0\n"
25 " mcr p15, 0, %1, c7, c5, 0\n"
26 " mcr p15, 0, %1, c7, c10, 4\n"
27 /*
28 * Turn off coherency
29 */
30 " mrc p15, 0, %0, c1, c0, 1\n"
31 " bic %0, %0, #0x20\n"
32 " mcr p15, 0, %0, c1, c0, 1\n"
33 " mrc p15, 0, %0, c1, c0, 0\n"
34 " bic %0, %0, #0x04\n"
35 " mcr p15, 0, %0, c1, c0, 0\n"
36 : "=&r" (v)
37 : "r" (0)
38 : "cc");
39}
40
41static inline void cpu_leave_lowpower(void)
42{
43 unsigned int v;
44
45 asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
46 " orr %0, %0, #0x04\n"
47 " mcr p15, 0, %0, c1, c0, 0\n"
48 " mrc p15, 0, %0, c1, c0, 1\n"
49 " orr %0, %0, #0x20\n"
50 " mcr p15, 0, %0, c1, c0, 1\n"
51 : "=&r" (v)
52 :
53 : "cc");
54}
55
56static inline void platform_do_lowpower(unsigned int cpu)
57{
58 /*
59 * there is no power-control hardware on this platform, so all
60 * we can do is put the core into WFI; this is safe as the calling
61 * code will have already disabled interrupts
62 */
63 for (;;) {
64 /*
65 * here's the WFI
66 */
67 asm(".word 0xe320f003\n"
68 :
69 :
70 : "memory", "cc");
71
72 if (pen_release == cpu) {
73 /*
74 * OK, proper wakeup, we're done
75 */
76 break;
77 }
78
79 /*
80 * getting here, means that we have come out of WFI without
81 * having been woken up - this shouldn't happen
82 *
83 * The trouble is, letting people know about this is not really
84 * possible, since we are currently running incoherently, and
85 * therefore cannot safely call printk() or anything else
86 */
87#ifdef DEBUG
88 printk("CPU%u: spurious wakeup call\n", cpu);
89#endif
90 }
91}
92
93int platform_cpu_kill(unsigned int cpu)
94{
95 return wait_for_completion_timeout(&cpu_killed, 5000);
96}
97
98/*
99 * platform-specific code to shutdown a CPU
100 *
101 * Called with IRQs disabled
102 */
103void platform_cpu_die(unsigned int cpu)
104{
105#ifdef DEBUG
106 unsigned int this_cpu = hard_smp_processor_id();
107
108 if (cpu != this_cpu) {
109 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
110 this_cpu, cpu);
111 BUG();
112 }
113#endif
114
115 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
116 complete(&cpu_killed);
117
118 /*
119 * we're ready for shutdown now, so do it
120 */
121 cpu_enter_lowpower();
122 platform_do_lowpower(cpu);
123
124 /*
125 * bring this CPU back into the world of cache
126 * coherency, and then restore interrupts
127 */
128 cpu_leave_lowpower();
129}
130
131int mach_cpu_disable(unsigned int cpu)
132{
133 /*
134 * we don't allow CPU 0 to be shutdown (it is still too special
135 * e.g. clock tick interrupts)
136 */
137 return cpu == 0 ? -EPERM : 0;
138}
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
new file mode 100644
index 000000000000..5e917e37d095
--- /dev/null
+++ b/arch/arm/mach-realview/localtimer.c
@@ -0,0 +1,130 @@
1/*
2 * linux/arch/arm/mach-realview/localtimer.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/smp.h>
16
17#include <asm/mach/time.h>
18#include <asm/hardware/arm_twd.h>
19#include <asm/hardware/gic.h>
20#include <asm/hardware.h>
21#include <asm/io.h>
22#include <asm/irq.h>
23
24#include "core.h"
25
26#define TWD_BASE(cpu) (__io_address(REALVIEW_TWD_BASE) + \
27 ((cpu) * REALVIEW_TWD_SIZE))
28
29static unsigned long mpcore_timer_rate;
30
31/*
32 * local_timer_ack: checks for a local timer interrupt.
33 *
34 * If a local timer interrupt has occured, acknowledge and return 1.
35 * Otherwise, return 0.
36 */
37int local_timer_ack(void)
38{
39 void __iomem *base = TWD_BASE(smp_processor_id());
40
41 if (__raw_readl(base + TWD_TIMER_INTSTAT)) {
42 __raw_writel(1, base + TWD_TIMER_INTSTAT);
43 return 1;
44 }
45
46 return 0;
47}
48
49void __cpuinit local_timer_setup(unsigned int cpu)
50{
51 void __iomem *base = TWD_BASE(cpu);
52 unsigned int load, offset;
53 u64 waitjiffies;
54 unsigned int count;
55
56 /*
57 * If this is the first time round, we need to work out how fast
58 * the timer ticks
59 */
60 if (mpcore_timer_rate == 0) {
61 printk("Calibrating local timer... ");
62
63 /* Wait for a tick to start */
64 waitjiffies = get_jiffies_64() + 1;
65
66 while (get_jiffies_64() < waitjiffies)
67 udelay(10);
68
69 /* OK, now the tick has started, let's get the timer going */
70 waitjiffies += 5;
71
72 /* enable, no interrupt or reload */
73 __raw_writel(0x1, base + TWD_TIMER_CONTROL);
74
75 /* maximum value */
76 __raw_writel(0xFFFFFFFFU, base + TWD_TIMER_COUNTER);
77
78 while (get_jiffies_64() < waitjiffies)
79 udelay(10);
80
81 count = __raw_readl(base + TWD_TIMER_COUNTER);
82
83 mpcore_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
84
85 printk("%lu.%02luMHz.\n", mpcore_timer_rate / 1000000,
86 (mpcore_timer_rate / 100000) % 100);
87 }
88
89 load = mpcore_timer_rate / HZ;
90
91 __raw_writel(load, base + TWD_TIMER_LOAD);
92 __raw_writel(0x7, base + TWD_TIMER_CONTROL);
93
94 /*
95 * Now maneuver our local tick into the right part of the jiffy.
96 * Start by working out where within the tick our local timer
97 * interrupt should go.
98 */
99 offset = ((mpcore_timer_rate / HZ) / (NR_CPUS + 1)) * (cpu + 1);
100
101 /*
102 * gettimeoffset() will return a number of us since the last tick.
103 * Convert this number of us to a local timer tick count.
104 * Be careful of integer overflow whilst keeping maximum precision.
105 *
106 * with HZ=100 and 1MHz (fpga) ~ 1GHz processor:
107 * load = 1 ~ 10,000
108 * mpcore_timer_rate/10000 = 100 ~ 100,000
109 *
110 * so the multiply value will be less than 10^9 always.
111 */
112 load = (system_timer->offset() * (mpcore_timer_rate / 10000)) / 100;
113
114 /* Add on our offset to get the load value */
115 load = (load + offset) % (mpcore_timer_rate / HZ);
116
117 __raw_writel(load, base + TWD_TIMER_COUNTER);
118
119 /* Make sure our local interrupt controller has this enabled */
120 __raw_writel(1 << IRQ_LOCALTIMER,
121 __io_address(REALVIEW_GIC_DIST_BASE) + GIC_DIST_ENABLE_SET);
122}
123
124/*
125 * take a local timer down
126 */
127void __cpuexit local_timer_stop(unsigned int cpu)
128{
129 __raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL);
130}
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 9844644d0fb5..0c7d4ac9a7b3 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -32,7 +32,7 @@ static unsigned int __init get_core_count(void)
32{ 32{
33 unsigned int ncores; 33 unsigned int ncores;
34 34
35 ncores = __raw_readl(IO_ADDRESS(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG); 35 ncores = __raw_readl(__io_address(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG);
36 36
37 return (ncores & 0x03) + 1; 37 return (ncores & 0x03) + 1;
38} 38}
@@ -133,12 +133,12 @@ static void __init poke_milo(void)
133#if 1 133#if 1
134#define REALVIEW_SYS_FLAGSS_OFFSET 0x30 134#define REALVIEW_SYS_FLAGSS_OFFSET 0x30
135 __raw_writel(virt_to_phys(realview_secondary_startup), 135 __raw_writel(virt_to_phys(realview_secondary_startup),
136 (IO_ADDRESS(REALVIEW_SYS_BASE) + 136 __io_address(REALVIEW_SYS_BASE) +
137 REALVIEW_SYS_FLAGSS_OFFSET)); 137 REALVIEW_SYS_FLAGSS_OFFSET);
138#define REALVIEW_SYS_FLAGSC_OFFSET 0x34 138#define REALVIEW_SYS_FLAGSC_OFFSET 0x34
139 __raw_writel(3, 139 __raw_writel(3,
140 (IO_ADDRESS(REALVIEW_SYS_BASE) + 140 __io_address(REALVIEW_SYS_BASE) +
141 REALVIEW_SYS_FLAGSC_OFFSET)); 141 REALVIEW_SYS_FLAGSC_OFFSET);
142#endif 142#endif
143 143
144 mb(); 144 mb();
@@ -175,6 +175,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
175 max_cpus = ncores; 175 max_cpus = ncores;
176 176
177 /* 177 /*
178 * Enable the local timer for primary CPU
179 */
180 local_timer_setup(cpu);
181
182 /*
178 * Initialise the possible/present maps. 183 * Initialise the possible/present maps.
179 * cpu_possible_map describes the set of CPUs which may be present 184 * cpu_possible_map describes the set of CPUs which may be present
180 * cpu_present_map describes the set of CPUs populated 185 * cpu_present_map describes the set of CPUs populated
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index c796bcdd6158..0b9d7ca49ec1 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -121,6 +121,14 @@ config S3C2410_BOOT_WATCHDOG
121 system resets depends on the value of PCLK. The timeout on an 121 system resets depends on the value of PCLK. The timeout on an
122 200MHz s3c2410 should be about 30 seconds. 122 200MHz s3c2410 should be about 30 seconds.
123 123
124config S3C2410_BOOT_ERROR_RESET
125 bool "S3C2410 Reboot on decompression error"
126 depends on ARCH_S3C2410
127 help
128 Say y here to use the watchdog to reset the system if the
129 kernel decompressor detects an error during decompression.
130
131
124comment "S3C2410 Setup" 132comment "S3C2410 Setup"
125 133
126config S3C2410_DMA 134config S3C2410_DMA
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index 8390b685c2b6..0f81fc0c2f7f 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -56,8 +56,16 @@
56static struct map_desc anubis_iodesc[] __initdata = { 56static struct map_desc anubis_iodesc[] __initdata = {
57 /* ISA IO areas */ 57 /* ISA IO areas */
58 58
59 { (u32)S3C24XX_VA_ISA_BYTE, 0x0, SZ_16M, MT_DEVICE }, 59 {
60 { (u32)S3C24XX_VA_ISA_WORD, 0x0, SZ_16M, MT_DEVICE }, 60 .virtual = (u32)S3C24XX_VA_ISA_BYTE,
61 .pfn = __phys_to_pfn(0x0),
62 .length = SZ_4M,
63 .type = MT_DEVICE
64 }, {
65 .virtual = (u32)S3C24XX_VA_ISA_WORD,
66 .pfn = __phys_to_pfn(0x0),
67 .length = SZ_4M, MT_DEVICE
68 },
61 69
62 /* we could possibly compress the next set down into a set of smaller tables 70 /* we could possibly compress the next set down into a set of smaller tables
63 * pagetables, but that would mean using an L2 section, and it still means 71 * pagetables, but that would mean using an L2 section, and it still means
@@ -66,16 +74,41 @@ static struct map_desc anubis_iodesc[] __initdata = {
66 74
67 /* CPLD control registers */ 75 /* CPLD control registers */
68 76
69 { (u32)ANUBIS_VA_CTRL1, ANUBIS_PA_CTRL1, SZ_4K, MT_DEVICE }, 77 {
70 { (u32)ANUBIS_VA_CTRL2, ANUBIS_PA_CTRL2, SZ_4K, MT_DEVICE }, 78 .virtual = (u32)ANUBIS_VA_CTRL1,
79 .pfn = __phys_to_pfn(ANUBIS_PA_CTRL1),
80 .length = SZ_4K,
81 .type = MT_DEVICE
82 }, {
83 .virtual = (u32)ANUBIS_VA_CTRL2,
84 .pfn = __phys_to_pfn(ANUBIS_PA_CTRL2),
85 .length = SZ_4K,
86 .type =MT_DEVICE
87 },
71 88
72 /* IDE drives */ 89 /* IDE drives */
73 90
74 { (u32)ANUBIS_IDEPRI, S3C2410_CS3, SZ_1M, MT_DEVICE }, 91 {
75 { (u32)ANUBIS_IDEPRIAUX, S3C2410_CS3+(1<<26), SZ_1M, MT_DEVICE }, 92 .virtual = (u32)ANUBIS_IDEPRI,
76 93 .pfn = __phys_to_pfn(S3C2410_CS3),
77 { (u32)ANUBIS_IDESEC, S3C2410_CS4, SZ_1M, MT_DEVICE }, 94 .length = SZ_1M,
78 { (u32)ANUBIS_IDESECAUX, S3C2410_CS4+(1<<26), SZ_1M, MT_DEVICE }, 95 .type = MT_DEVICE
96 }, {
97 .virtual = (u32)ANUBIS_IDEPRIAUX,
98 .pfn = __phys_to_pfn(S3C2410_CS3+(1<<26)),
99 .length = SZ_1M,
100 .type = MT_DEVICE
101 }, {
102 .virtual = (u32)ANUBIS_IDESEC,
103 .pfn = __phys_to_pfn(S3C2410_CS4),
104 .length = SZ_1M,
105 .type = MT_DEVICE
106 }, {
107 .virtual = (u32)ANUBIS_IDESECAUX,
108 .pfn = __phys_to_pfn(S3C2410_CS4+(1<<26)),
109 .length = SZ_1M,
110 .type = MT_DEVICE
111 },
79}; 112};
80 113
81#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK 114#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 0b71c896bbd1..1be2567a7486 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -89,32 +89,63 @@
89 89
90/* macros to modify the physical addresses for io space */ 90/* macros to modify the physical addresses for io space */
91 91
92#define PA_CS2(item) ((item) + S3C2410_CS2) 92#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
93#define PA_CS3(item) ((item) + S3C2410_CS3) 93#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
94#define PA_CS4(item) ((item) + S3C2410_CS4) 94#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
95#define PA_CS5(item) ((item) + S3C2410_CS5) 95#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
96 96
97static struct map_desc bast_iodesc[] __initdata = { 97static struct map_desc bast_iodesc[] __initdata = {
98 /* ISA IO areas */ 98 /* ISA IO areas */
99 99 {
100 { (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, 100 .virtual = (u32)S3C24XX_VA_ISA_BYTE,
101 { (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, 101 .pfn = PA_CS2(BAST_PA_ISAIO),
102 102 .length = SZ_16M,
103 /* we could possibly compress the next set down into a set of smaller tables 103 .type = MT_DEVICE,
104 * pagetables, but that would mean using an L2 section, and it still means 104 }, {
105 * we cannot actually feed the same register to an LDR due to 16K spacing 105 .virtual = (u32)S3C24XX_VA_ISA_WORD,
106 */ 106 .pfn = PA_CS3(BAST_PA_ISAIO),
107 107 .length = SZ_16M,
108 .type = MT_DEVICE,
109 },
108 /* bast CPLD control registers, and external interrupt controls */ 110 /* bast CPLD control registers, and external interrupt controls */
109 { (u32)BAST_VA_CTRL1, BAST_PA_CTRL1, SZ_1M, MT_DEVICE }, 111 {
110 { (u32)BAST_VA_CTRL2, BAST_PA_CTRL2, SZ_1M, MT_DEVICE }, 112 .virtual = (u32)BAST_VA_CTRL1,
111 { (u32)BAST_VA_CTRL3, BAST_PA_CTRL3, SZ_1M, MT_DEVICE }, 113 .pfn = __phys_to_pfn(BAST_PA_CTRL1),
112 { (u32)BAST_VA_CTRL4, BAST_PA_CTRL4, SZ_1M, MT_DEVICE }, 114 .length = SZ_1M,
113 115 .type = MT_DEVICE,
116 }, {
117 .virtual = (u32)BAST_VA_CTRL2,
118 .pfn = __phys_to_pfn(BAST_PA_CTRL2),
119 .length = SZ_1M,
120 .type = MT_DEVICE,
121 }, {
122 .virtual = (u32)BAST_VA_CTRL3,
123 .pfn = __phys_to_pfn(BAST_PA_CTRL3),
124 .length = SZ_1M,
125 .type = MT_DEVICE,
126 }, {
127 .virtual = (u32)BAST_VA_CTRL4,
128 .pfn = __phys_to_pfn(BAST_PA_CTRL4),
129 .length = SZ_1M,
130 .type = MT_DEVICE,
131 },
114 /* PC104 IRQ mux */ 132 /* PC104 IRQ mux */
115 { (u32)BAST_VA_PC104_IRQREQ, BAST_PA_PC104_IRQREQ, SZ_1M, MT_DEVICE }, 133 {
116 { (u32)BAST_VA_PC104_IRQRAW, BAST_PA_PC104_IRQRAW, SZ_1M, MT_DEVICE }, 134 .virtual = (u32)BAST_VA_PC104_IRQREQ,
117 { (u32)BAST_VA_PC104_IRQMASK, BAST_PA_PC104_IRQMASK, SZ_1M, MT_DEVICE }, 135 .pfn = __phys_to_pfn(BAST_PA_PC104_IRQREQ),
136 .length = SZ_1M,
137 .type = MT_DEVICE,
138 }, {
139 .virtual = (u32)BAST_VA_PC104_IRQRAW,
140 .pfn = __phys_to_pfn(BAST_PA_PC104_IRQRAW),
141 .length = SZ_1M,
142 .type = MT_DEVICE,
143 }, {
144 .virtual = (u32)BAST_VA_PC104_IRQMASK,
145 .pfn = __phys_to_pfn(BAST_PA_PC104_IRQMASK),
146 .length = SZ_1M,
147 .type = MT_DEVICE,
148 },
118 149
119 /* peripheral space... one for each of fast/slow/byte/16bit */ 150 /* peripheral space... one for each of fast/slow/byte/16bit */
120 /* note, ide is only decoded in word space, even though some registers 151 /* note, ide is only decoded in word space, even though some registers
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
index 24d69019a843..f8d86d1e16b6 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -56,8 +56,17 @@
56static struct map_desc rx3715_iodesc[] __initdata = { 56static struct map_desc rx3715_iodesc[] __initdata = {
57 /* dump ISA space somewhere unused */ 57 /* dump ISA space somewhere unused */
58 58
59 { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS3, SZ_16M, MT_DEVICE }, 59 {
60 { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS3, SZ_16M, MT_DEVICE }, 60 .virtual = (u32)S3C24XX_VA_ISA_WORD,
61 .pfn = __phys_to_pfn(S3C2410_CS3),
62 .length = SZ_1M,
63 .type = MT_DEVICE,
64 }, {
65 .virtual = (u32)S3C24XX_VA_ISA_BYTE,
66 .pfn = __phys_to_pfn(S3C2410_CS3),
67 .length = SZ_1M,
68 .type = MT_DEVICE,
69 },
61}; 70};
62 71
63 72
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index d666c621ad06..4e31118533e6 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -58,8 +58,27 @@
58static struct map_desc smdk2440_iodesc[] __initdata = { 58static struct map_desc smdk2440_iodesc[] __initdata = {
59 /* ISA IO Space map (memory space selected by A24) */ 59 /* ISA IO Space map (memory space selected by A24) */
60 60
61 { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS2, SZ_16M, MT_DEVICE }, 61 {
62 { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS2, SZ_16M, MT_DEVICE }, 62 .virtual = (u32)S3C24XX_VA_ISA_WORD,
63 .pfn = __phys_to_pfn(S3C2410_CS2),
64 .length = 0x10000,
65 .type = MT_DEVICE,
66 }, {
67 .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
68 .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
69 .length = SZ_4M,
70 .type = MT_DEVICE,
71 }, {
72 .virtual = (u32)S3C24XX_VA_ISA_BYTE,
73 .pfn = __phys_to_pfn(S3C2410_CS2),
74 .length = 0x10000,
75 .type = MT_DEVICE,
76 }, {
77 .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
78 .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
79 .length = SZ_4M,
80 .type = MT_DEVICE,
81 }
63}; 82};
64 83
65#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK 84#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 46b259673c18..ae7e099bf6c8 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -74,27 +74,47 @@
74 74
75/* macros to modify the physical addresses for io space */ 75/* macros to modify the physical addresses for io space */
76 76
77#define PA_CS2(item) ((item) + S3C2410_CS2) 77#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
78#define PA_CS3(item) ((item) + S3C2410_CS3) 78#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
79#define PA_CS4(item) ((item) + S3C2410_CS4) 79#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
80#define PA_CS5(item) ((item) + S3C2410_CS5) 80#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
81 81
82static struct map_desc vr1000_iodesc[] __initdata = { 82static struct map_desc vr1000_iodesc[] __initdata = {
83 /* ISA IO areas */ 83 /* ISA IO areas */
84 84 {
85 { (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, 85 .virtual = (u32)S3C24XX_VA_ISA_BYTE,
86 { (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, 86 .pfn = PA_CS2(BAST_PA_ISAIO),
87 87 .length = SZ_16M,
88 /* we could possibly compress the next set down into a set of smaller tables 88 .type = MT_DEVICE,
89 * pagetables, but that would mean using an L2 section, and it still means 89 }, {
90 * we cannot actually feed the same register to an LDR due to 16K spacing 90 .virtual = (u32)S3C24XX_VA_ISA_WORD,
91 */ 91 .pfn = PA_CS3(BAST_PA_ISAIO),
92 92 .length = SZ_16M,
93 /* bast CPLD control registers, and external interrupt controls */ 93 .type = MT_DEVICE,
94 { (u32)VR1000_VA_CTRL1, VR1000_PA_CTRL1, SZ_1M, MT_DEVICE }, 94 },
95 { (u32)VR1000_VA_CTRL2, VR1000_PA_CTRL2, SZ_1M, MT_DEVICE }, 95
96 { (u32)VR1000_VA_CTRL3, VR1000_PA_CTRL3, SZ_1M, MT_DEVICE }, 96 /* CPLD control registers, and external interrupt controls */
97 { (u32)VR1000_VA_CTRL4, VR1000_PA_CTRL4, SZ_1M, MT_DEVICE }, 97 {
98 .virtual = (u32)VR1000_VA_CTRL1,
99 .pfn = __phys_to_pfn(VR1000_PA_CTRL1),
100 .length = SZ_1M,
101 .type = MT_DEVICE,
102 }, {
103 .virtual = (u32)VR1000_VA_CTRL2,
104 .pfn = __phys_to_pfn(VR1000_PA_CTRL2),
105 .length = SZ_1M,
106 .type = MT_DEVICE,
107 }, {
108 .virtual = (u32)VR1000_VA_CTRL3,
109 .pfn = __phys_to_pfn(VR1000_PA_CTRL3),
110 .length = SZ_1M,
111 .type = MT_DEVICE,
112 }, {
113 .virtual = (u32)VR1000_VA_CTRL4,
114 .pfn = __phys_to_pfn(VR1000_PA_CTRL4),
115 .length = SZ_1M,
116 .type = MT_DEVICE,
117 },
98 118
99 /* peripheral space... one for each of fast/slow/byte/16bit */ 119 /* peripheral space... one for each of fast/slow/byte/16bit */
100 /* note, ide is only decoded in word space, even though some registers 120 /* note, ide is only decoded in word space, even though some registers
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 47e0420623fc..e4b435e634e4 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -124,11 +124,13 @@ static void __init sa1100_timer_init(void)
124 tv.tv_sec = sa1100_get_rtc_time(); 124 tv.tv_sec = sa1100_get_rtc_time();
125 do_settimeofday(&tv); 125 do_settimeofday(&tv);
126 126
127 OSMR0 = 0; /* set initial match at 0 */ 127 OIER = 0; /* disable any timer interrupts */
128 OSCR = LATCH*2; /* push OSCR out of the way */
129 OSMR0 = LATCH; /* set initial match */
128 OSSR = 0xf; /* clear status on all timers */ 130 OSSR = 0xf; /* clear status on all timers */
129 setup_irq(IRQ_OST0, &sa1100_timer_irq); 131 setup_irq(IRQ_OST0, &sa1100_timer_irq);
130 OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ 132 OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */
131 OSCR = 0; /* initialize free-running timer, force first match */ 133 OSCR = 0; /* initialize free-running timer */
132} 134}
133 135
134#ifdef CONFIG_NO_IDLE_HZ 136#ifdef CONFIG_NO_IDLE_HZ
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
index 1fb16f9edfd5..2ede2ee8cae4 100644
--- a/arch/arm/plat-omap/ocpi.c
+++ b/arch/arm/plat-omap/ocpi.c
@@ -25,7 +25,6 @@
25 25
26#include <linux/config.h> 26#include <linux/config.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/version.h>
29#include <linux/types.h> 28#include <linux/types.h>
30#include <linux/errno.h> 29#include <linux/errno.h>
31#include <linux/kernel.h> 30#include <linux/kernel.h>
diff --git a/arch/arm26/kernel/process.c b/arch/arm26/kernel/process.c
index 9eb9964d32a7..15833a0057dd 100644
--- a/arch/arm26/kernel/process.c
+++ b/arch/arm26/kernel/process.c
@@ -74,15 +74,13 @@ __setup("hlt", hlt_setup);
74void cpu_idle(void) 74void cpu_idle(void)
75{ 75{
76 /* endless idle loop with no priority at all */ 76 /* endless idle loop with no priority at all */
77 preempt_disable();
78 while (1) { 77 while (1) {
79 while (!need_resched()) { 78 while (!need_resched())
80 local_irq_disable(); 79 cpu_relax();
81 if (!need_resched() && !hlt_counter) 80 preempt_enable_no_resched();
82 local_irq_enable(); 81 schedule();
83 } 82 preempt_disable();
84 } 83 }
85 schedule();
86} 84}
87 85
88static char reboot_mode = 'h'; 86static char reboot_mode = 'h';
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
index 201f4c90d961..f2c55742e90c 100644
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ b/arch/cris/arch-v10/drivers/pcf8563.c
@@ -19,7 +19,6 @@
19 */ 19 */
20 20
21#include <linux/config.h> 21#include <linux/config.h>
22#include <linux/version.h>
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/kernel.h> 23#include <linux/kernel.h>
25#include <linux/types.h> 24#include <linux/types.h>
diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c
index 094ff45ae85b..cac05a5e514c 100644
--- a/arch/cris/arch-v10/kernel/fasttimer.c
+++ b/arch/cris/arch-v10/kernel/fasttimer.c
@@ -112,7 +112,6 @@
112#include <asm/rtc.h> 112#include <asm/rtc.h>
113 113
114#include <linux/config.h> 114#include <linux/config.h>
115#include <linux/version.h>
116 115
117#include <asm/arch/svinto.h> 116#include <asm/arch/svinto.h>
118#include <asm/fasttimer.h> 117#include <asm/fasttimer.h>
diff --git a/arch/cris/arch-v32/drivers/nandflash.c b/arch/cris/arch-v32/drivers/nandflash.c
index fc2a619b035d..93ddea4d9564 100644
--- a/arch/cris/arch-v32/drivers/nandflash.c
+++ b/arch/cris/arch-v32/drivers/nandflash.c
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/version.h>
18#include <linux/slab.h> 17#include <linux/slab.h>
19#include <linux/init.h> 18#include <linux/init.h>
20#include <linux/module.h> 19#include <linux/module.h>
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
index f894580b648b..d788bda3578c 100644
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -18,7 +18,6 @@
18 */ 18 */
19 19
20#include <linux/config.h> 20#include <linux/config.h>
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/kernel.h> 22#include <linux/kernel.h>
24#include <linux/types.h> 23#include <linux/types.h>
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 957f551ba5ce..13867f4fad16 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -161,6 +161,7 @@ void __init smp_callin(void)
161 REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask); 161 REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask);
162 unmask_irq(IPI_INTR_VECT); 162 unmask_irq(IPI_INTR_VECT);
163 unmask_irq(TIMER_INTR_VECT); 163 unmask_irq(TIMER_INTR_VECT);
164 preempt_disable();
164 local_irq_enable(); 165 local_irq_enable();
165 166
166 cpu_set(cpu, cpu_online_map); 167 cpu_set(cpu, cpu_online_map);
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c
index 949a0e40e03c..7c80afb10460 100644
--- a/arch/cris/kernel/process.c
+++ b/arch/cris/kernel/process.c
@@ -218,7 +218,9 @@ void cpu_idle (void)
218 idle = default_idle; 218 idle = default_idle;
219 idle(); 219 idle();
220 } 220 }
221 preempt_enable_no_resched();
221 schedule(); 222 schedule();
223 preempt_disable();
222 } 224 }
223} 225}
224 226
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index 3001b82b1514..54a452136f00 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -77,16 +77,20 @@ void (*idle)(void) = core_sleep_idle;
77 */ 77 */
78void cpu_idle(void) 78void cpu_idle(void)
79{ 79{
80 int cpu = smp_processor_id();
81
80 /* endless idle loop with no priority at all */ 82 /* endless idle loop with no priority at all */
81 while (1) { 83 while (1) {
82 while (!need_resched()) { 84 while (!need_resched()) {
83 irq_stat[smp_processor_id()].idle_timestamp = jiffies; 85 irq_stat[cpu].idle_timestamp = jiffies;
84 86
85 if (!frv_dma_inprogress && idle) 87 if (!frv_dma_inprogress && idle)
86 idle(); 88 idle();
87 } 89 }
88 90
91 preempt_enable_no_resched();
89 schedule(); 92 schedule();
93 preempt_disable();
90 } 94 }
91} 95}
92 96
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index 27f1fce64ce4..fe21adf3e75e 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -53,22 +53,18 @@ asmlinkage void ret_from_fork(void);
53#if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM) 53#if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM)
54void default_idle(void) 54void default_idle(void)
55{ 55{
56 while(1) { 56 local_irq_disable();
57 if (!need_resched()) { 57 if (!need_resched()) {
58 local_irq_enable(); 58 local_irq_enable();
59 __asm__("sleep"); 59 /* XXX: race here! What if need_resched() gets set now? */
60 local_irq_disable(); 60 __asm__("sleep");
61 } 61 } else
62 schedule(); 62 local_irq_enable();
63 }
64} 63}
65#else 64#else
66void default_idle(void) 65void default_idle(void)
67{ 66{
68 while(1) { 67 cpu_relax();
69 if (need_resched())
70 schedule();
71 }
72} 68}
73#endif 69#endif
74void (*idle)(void) = default_idle; 70void (*idle)(void) = default_idle;
@@ -81,7 +77,13 @@ void (*idle)(void) = default_idle;
81 */ 77 */
82void cpu_idle(void) 78void cpu_idle(void)
83{ 79{
84 idle(); 80 while (1) {
81 while (!need_resched())
82 idle();
83 preempt_enable_no_resched();
84 schedule();
85 preempt_disable();
86 }
85} 87}
86 88
87void machine_restart(char * __unused) 89void machine_restart(char * __unused)
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 86e80c551478..003548b8735f 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -769,8 +769,26 @@ static int set_system_power_state(u_short state)
769static int apm_do_idle(void) 769static int apm_do_idle(void)
770{ 770{
771 u32 eax; 771 u32 eax;
772 u8 ret = 0;
773 int idled = 0;
774 int polling;
775
776 polling = test_thread_flag(TIF_POLLING_NRFLAG);
777 if (polling) {
778 clear_thread_flag(TIF_POLLING_NRFLAG);
779 smp_mb__after_clear_bit();
780 }
781 if (!need_resched()) {
782 idled = 1;
783 ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax);
784 }
785 if (polling)
786 set_thread_flag(TIF_POLLING_NRFLAG);
787
788 if (!idled)
789 return 0;
772 790
773 if (apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax)) { 791 if (ret) {
774 static unsigned long t; 792 static unsigned long t;
775 793
776 /* This always fails on some SMP boards running UP kernels. 794 /* This always fails on some SMP boards running UP kernels.
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 7a14fdfd3af9..1cb261f225d5 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -99,14 +99,22 @@ EXPORT_SYMBOL(enable_hlt);
99 */ 99 */
100void default_idle(void) 100void default_idle(void)
101{ 101{
102 local_irq_enable();
103
102 if (!hlt_counter && boot_cpu_data.hlt_works_ok) { 104 if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
103 local_irq_disable(); 105 clear_thread_flag(TIF_POLLING_NRFLAG);
104 if (!need_resched()) 106 smp_mb__after_clear_bit();
105 safe_halt(); 107 while (!need_resched()) {
106 else 108 local_irq_disable();
107 local_irq_enable(); 109 if (!need_resched())
110 safe_halt();
111 else
112 local_irq_enable();
113 }
114 set_thread_flag(TIF_POLLING_NRFLAG);
108 } else { 115 } else {
109 cpu_relax(); 116 while (!need_resched())
117 cpu_relax();
110 } 118 }
111} 119}
112#ifdef CONFIG_APM_MODULE 120#ifdef CONFIG_APM_MODULE
@@ -120,29 +128,14 @@ EXPORT_SYMBOL(default_idle);
120 */ 128 */
121static void poll_idle (void) 129static void poll_idle (void)
122{ 130{
123 int oldval;
124
125 local_irq_enable(); 131 local_irq_enable();
126 132
127 /* 133 asm volatile(
128 * Deal with another CPU just having chosen a thread to 134 "2:"
129 * run here: 135 "testl %0, %1;"
130 */ 136 "rep; nop;"
131 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 137 "je 2b;"
132 138 : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
133 if (!oldval) {
134 set_thread_flag(TIF_POLLING_NRFLAG);
135 asm volatile(
136 "2:"
137 "testl %0, %1;"
138 "rep; nop;"
139 "je 2b;"
140 : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
141
142 clear_thread_flag(TIF_POLLING_NRFLAG);
143 } else {
144 set_need_resched();
145 }
146} 139}
147 140
148#ifdef CONFIG_HOTPLUG_CPU 141#ifdef CONFIG_HOTPLUG_CPU
@@ -179,7 +172,9 @@ static inline void play_dead(void)
179 */ 172 */
180void cpu_idle(void) 173void cpu_idle(void)
181{ 174{
182 int cpu = raw_smp_processor_id(); 175 int cpu = smp_processor_id();
176
177 set_thread_flag(TIF_POLLING_NRFLAG);
183 178
184 /* endless idle loop with no priority at all */ 179 /* endless idle loop with no priority at all */
185 while (1) { 180 while (1) {
@@ -201,7 +196,9 @@ void cpu_idle(void)
201 __get_cpu_var(irq_stat).idle_timestamp = jiffies; 196 __get_cpu_var(irq_stat).idle_timestamp = jiffies;
202 idle(); 197 idle();
203 } 198 }
199 preempt_enable_no_resched();
204 schedule(); 200 schedule();
201 preempt_disable();
205 } 202 }
206} 203}
207 204
@@ -244,15 +241,12 @@ static void mwait_idle(void)
244{ 241{
245 local_irq_enable(); 242 local_irq_enable();
246 243
247 if (!need_resched()) { 244 while (!need_resched()) {
248 set_thread_flag(TIF_POLLING_NRFLAG); 245 __monitor((void *)&current_thread_info()->flags, 0, 0);
249 do { 246 smp_mb();
250 __monitor((void *)&current_thread_info()->flags, 0, 0); 247 if (need_resched())
251 if (need_resched()) 248 break;
252 break; 249 __mwait(0, 0);
253 __mwait(0, 0);
254 } while (!need_resched());
255 clear_thread_flag(TIF_POLLING_NRFLAG);
256 } 250 }
257} 251}
258 252
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index b48ac635f3c1..fdfcb0cba9b4 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -129,9 +129,7 @@ struct drive_info_struct { char dummy[32]; } drive_info;
129EXPORT_SYMBOL(drive_info); 129EXPORT_SYMBOL(drive_info);
130#endif 130#endif
131struct screen_info screen_info; 131struct screen_info screen_info;
132#ifdef CONFIG_VT
133EXPORT_SYMBOL(screen_info); 132EXPORT_SYMBOL(screen_info);
134#endif
135struct apm_info apm_info; 133struct apm_info apm_info;
136EXPORT_SYMBOL(apm_info); 134EXPORT_SYMBOL(apm_info);
137struct sys_desc_table_struct { 135struct sys_desc_table_struct {
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 47ec76794d02..bc5a9d97466b 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -485,6 +485,7 @@ static void __devinit start_secondary(void *unused)
485 * things done here to the most necessary things. 485 * things done here to the most necessary things.
486 */ 486 */
487 cpu_init(); 487 cpu_init();
488 preempt_disable();
488 smp_callin(); 489 smp_callin();
489 while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) 490 while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
490 rep_nop(); 491 rep_nop();
diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c
index 164b211f4174..88739394f6df 100644
--- a/arch/ia64/ia32/ia32_ioctl.c
+++ b/arch/ia64/ia32/ia32_ioctl.c
@@ -29,10 +29,8 @@
29#define CODE 29#define CODE
30#include "compat_ioctl.c" 30#include "compat_ioctl.c"
31 31
32typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
33
34#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) 32#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl)
35#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL }, 33#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
36#define IOCTL_TABLE_START \ 34#define IOCTL_TABLE_START \
37 struct ioctl_trans ioctl_start[] = { 35 struct ioctl_trans ioctl_start[] = {
38#define IOCTL_TABLE_END \ 36#define IOCTL_TABLE_END \
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index f081c60ab206..eb39bc9c133b 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -88,7 +88,7 @@ mca_page_isolate(unsigned long paddr)
88 if (!ia64_phys_addr_valid(paddr)) 88 if (!ia64_phys_addr_valid(paddr))
89 return ISOLATE_NONE; 89 return ISOLATE_NONE;
90 90
91 if (!pfn_valid(paddr)) 91 if (!pfn_valid(paddr >> PAGE_SHIFT))
92 return ISOLATE_NONE; 92 return ISOLATE_NONE;
93 93
94 /* convert physical address to physical page number */ 94 /* convert physical address to physical page number */
@@ -108,6 +108,7 @@ mca_page_isolate(unsigned long paddr)
108 return ISOLATE_NG; 108 return ISOLATE_NG;
109 109
110 /* add attribute 'Reserved' and register the page */ 110 /* add attribute 'Reserved' and register the page */
111 get_page(p);
111 SetPageReserved(p); 112 SetPageReserved(p);
112 page_isolate[num_page_isolate++] = p; 113 page_isolate[num_page_isolate++] = p;
113 114
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 051e050359e4..640d6908f8ec 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -197,11 +197,15 @@ void
197default_idle (void) 197default_idle (void)
198{ 198{
199 local_irq_enable(); 199 local_irq_enable();
200 while (!need_resched()) 200 while (!need_resched()) {
201 if (can_do_pal_halt) 201 if (can_do_pal_halt) {
202 safe_halt(); 202 local_irq_disable();
203 else 203 if (!need_resched())
204 safe_halt();
205 local_irq_enable();
206 } else
204 cpu_relax(); 207 cpu_relax();
208 }
205} 209}
206 210
207#ifdef CONFIG_HOTPLUG_CPU 211#ifdef CONFIG_HOTPLUG_CPU
@@ -263,16 +267,16 @@ void __attribute__((noreturn))
263cpu_idle (void) 267cpu_idle (void)
264{ 268{
265 void (*mark_idle)(int) = ia64_mark_idle; 269 void (*mark_idle)(int) = ia64_mark_idle;
270 int cpu = smp_processor_id();
271 set_thread_flag(TIF_POLLING_NRFLAG);
266 272
267 /* endless idle loop with no priority at all */ 273 /* endless idle loop with no priority at all */
268 while (1) { 274 while (1) {
275 if (!need_resched()) {
276 void (*idle)(void);
269#ifdef CONFIG_SMP 277#ifdef CONFIG_SMP
270 if (!need_resched())
271 min_xtp(); 278 min_xtp();
272#endif 279#endif
273 while (!need_resched()) {
274 void (*idle)(void);
275
276 if (__get_cpu_var(cpu_idle_state)) 280 if (__get_cpu_var(cpu_idle_state))
277 __get_cpu_var(cpu_idle_state) = 0; 281 __get_cpu_var(cpu_idle_state) = 0;
278 282
@@ -284,17 +288,17 @@ cpu_idle (void)
284 if (!idle) 288 if (!idle)
285 idle = default_idle; 289 idle = default_idle;
286 (*idle)(); 290 (*idle)();
287 } 291 if (mark_idle)
288 292 (*mark_idle)(0);
289 if (mark_idle)
290 (*mark_idle)(0);
291
292#ifdef CONFIG_SMP 293#ifdef CONFIG_SMP
293 normal_xtp(); 294 normal_xtp();
294#endif 295#endif
296 }
297 preempt_enable_no_resched();
295 schedule(); 298 schedule();
299 preempt_disable();
296 check_pgt_cache(); 300 check_pgt_cache();
297 if (cpu_is_offline(smp_processor_id())) 301 if (cpu_is_offline(cpu))
298 play_dead(); 302 play_dead();
299 } 303 }
300} 304}
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 400a48987124..8f44e7d2df66 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -399,6 +399,7 @@ start_secondary (void *unused)
399 Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id()); 399 Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id());
400 efi_map_pal_code(); 400 efi_map_pal_code();
401 cpu_init(); 401 cpu_init();
402 preempt_disable();
402 smp_callin(); 403 smp_callin();
403 404
404 cpu_idle(); 405 cpu_idle();
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 7b03b8084ffc..1f500c81002c 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -212,13 +212,13 @@ void pcibr_target_interrupt(struct sn_irq_info *sn_irq_info)
212 pdi_pcibus_info; 212 pdi_pcibus_info;
213 213
214 /* Disable the device's IRQ */ 214 /* Disable the device's IRQ */
215 pcireg_intr_enable_bit_clr(pcibus_info, bit); 215 pcireg_intr_enable_bit_clr(pcibus_info, (1 << bit));
216 216
217 /* Change the device's IRQ */ 217 /* Change the device's IRQ */
218 pcireg_intr_addr_addr_set(pcibus_info, bit, xtalk_addr); 218 pcireg_intr_addr_addr_set(pcibus_info, bit, xtalk_addr);
219 219
220 /* Re-enable the device's IRQ */ 220 /* Re-enable the device's IRQ */
221 pcireg_intr_enable_bit_set(pcibus_info, bit); 221 pcireg_intr_enable_bit_set(pcibus_info, (1 << bit));
222 222
223 pcibr_force_interrupt(sn_irq_info); 223 pcibr_force_interrupt(sn_irq_info);
224 } 224 }
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
index 4f718c3e93d3..5d534091262c 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
@@ -131,7 +131,7 @@ void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits)
131 __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits); 131 __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits);
132 break; 132 break;
133 case PCIBR_BRIDGETYPE_PIC: 133 case PCIBR_BRIDGETYPE_PIC:
134 __sn_clrq_relaxed(&ptr->pic.p_int_enable, ~bits); 134 __sn_clrq_relaxed(&ptr->pic.p_int_enable, bits);
135 break; 135 break;
136 default: 136 default:
137 panic 137 panic
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index ea13a8f4d8b0..cc4b571e5db7 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -104,7 +104,9 @@ void cpu_idle (void)
104 104
105 idle(); 105 idle();
106 } 106 }
107 preempt_enable_no_resched();
107 schedule(); 108 schedule();
109 preempt_disable();
108 } 110 }
109} 111}
110 112
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index 640d592ea072..b90c54169fa5 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -426,6 +426,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
426int __init start_secondary(void *unused) 426int __init start_secondary(void *unused)
427{ 427{
428 cpu_init(); 428 cpu_init();
429 preempt_disable();
429 smp_callin(); 430 smp_callin();
430 while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) 431 while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
431 cpu_relax(); 432 cpu_relax();
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 11b1b90ba6ba..13d109328a42 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -102,7 +102,9 @@ void cpu_idle(void)
102 while (1) { 102 while (1) {
103 while (!need_resched()) 103 while (!need_resched())
104 idle(); 104 idle();
105 preempt_enable_no_resched();
105 schedule(); 106 schedule();
107 preempt_disable();
106 } 108 }
107} 109}
108 110
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index 1ef15d5ef943..4f21f42d096b 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -111,17 +111,6 @@ void __init plat_setup(void)
111 } 111 }
112#endif 112#endif
113 113
114#ifdef CONFIG_FB_E1356
115 if ((argptr = strstr(argptr, "video=")) == NULL) {
116 argptr = prom_getcmdline();
117#ifdef CONFIG_MIPS_PB1000
118 strcat(argptr, " video=e1356fb:system:pb1000,mmunalign:1");
119#else
120 strcat(argptr, " video=e1356fb:system:pb1500");
121#endif
122 }
123#endif
124
125#ifdef CONFIG_FB_XPERT98 114#ifdef CONFIG_FB_XPERT98
126 if ((argptr = strstr(argptr, "video=")) == NULL) { 115 if ((argptr = strstr(argptr, "video=")) == NULL) {
127 argptr = prom_getcmdline(); 116 argptr = prom_getcmdline();
diff --git a/arch/mips/configs/ddb5476_defconfig b/arch/mips/configs/ddb5476_defconfig
index b260e51eb517..326f3aa63741 100644
--- a/arch/mips/configs/ddb5476_defconfig
+++ b/arch/mips/configs/ddb5476_defconfig
@@ -658,7 +658,6 @@ CONFIG_FB=y
658# CONFIG_FB_SMIVGX is not set 658# CONFIG_FB_SMIVGX is not set
659# CONFIG_FB_CYBLA is not set 659# CONFIG_FB_CYBLA is not set
660# CONFIG_FB_TRIDENT is not set 660# CONFIG_FB_TRIDENT is not set
661# CONFIG_FB_E1356 is not set
662# CONFIG_FB_S1D13XXX is not set 661# CONFIG_FB_S1D13XXX is not set
663# CONFIG_FB_VIRTUAL is not set 662# CONFIG_FB_VIRTUAL is not set
664 663
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index 9a728c2d8fd5..6390a753e80b 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -628,7 +628,6 @@ CONFIG_FB=y
628# CONFIG_FB_SMIVGX is not set 628# CONFIG_FB_SMIVGX is not set
629# CONFIG_FB_CYBLA is not set 629# CONFIG_FB_CYBLA is not set
630# CONFIG_FB_TRIDENT is not set 630# CONFIG_FB_TRIDENT is not set
631# CONFIG_FB_E1356 is not set
632# CONFIG_FB_S1D13XXX is not set 631# CONFIG_FB_S1D13XXX is not set
633# CONFIG_FB_VIRTUAL is not set 632# CONFIG_FB_VIRTUAL is not set
634 633
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index ffb23fcab862..f18d05c2ca77 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -758,7 +758,6 @@ CONFIG_FB_MODE_HELPERS=y
758# CONFIG_FB_SMIVGX is not set 758# CONFIG_FB_SMIVGX is not set
759# CONFIG_FB_CYBLA is not set 759# CONFIG_FB_CYBLA is not set
760# CONFIG_FB_TRIDENT is not set 760# CONFIG_FB_TRIDENT is not set
761# CONFIG_FB_E1356 is not set
762# CONFIG_FB_S1D13XXX is not set 761# CONFIG_FB_S1D13XXX is not set
763# CONFIG_FB_VIRTUAL is not set 762# CONFIG_FB_VIRTUAL is not set
764 763
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
index 05e65206a7b4..37bd8d5c865d 100644
--- a/arch/mips/configs/pnx8550-v2pci_defconfig
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -897,7 +897,6 @@ CONFIG_FB=y
897# CONFIG_FB_SMIVGX is not set 897# CONFIG_FB_SMIVGX is not set
898# CONFIG_FB_CYBLA is not set 898# CONFIG_FB_CYBLA is not set
899# CONFIG_FB_TRIDENT is not set 899# CONFIG_FB_TRIDENT is not set
900# CONFIG_FB_E1356 is not set
901# CONFIG_FB_S1D13XXX is not set 900# CONFIG_FB_S1D13XXX is not set
902# CONFIG_FB_VIRTUAL is not set 901# CONFIG_FB_VIRTUAL is not set
903 902
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 2bc61ca4ba08..897420d39053 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -876,7 +876,6 @@ CONFIG_FB_ATY_CT=y
876# CONFIG_FB_SMIVGX is not set 876# CONFIG_FB_SMIVGX is not set
877# CONFIG_FB_CYBLA is not set 877# CONFIG_FB_CYBLA is not set
878# CONFIG_FB_TRIDENT is not set 878# CONFIG_FB_TRIDENT is not set
879# CONFIG_FB_E1356 is not set
880# CONFIG_FB_S1D13XXX is not set 879# CONFIG_FB_S1D13XXX is not set
881# CONFIG_FB_VIRTUAL is not set 880# CONFIG_FB_VIRTUAL is not set
882 881
diff --git a/arch/mips/kernel/ioctl32.c b/arch/mips/kernel/ioctl32.c
index ed9b2da510be..9ea1fc748864 100644
--- a/arch/mips/kernel/ioctl32.c
+++ b/arch/mips/kernel/ioctl32.c
@@ -26,10 +26,8 @@ long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
26#define CODE 26#define CODE
27#include "compat_ioctl.c" 27#include "compat_ioctl.c"
28 28
29typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
30
31#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) 29#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl)
32#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL }, 30#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
33#define IOCTL_TABLE_START \ 31#define IOCTL_TABLE_START \
34 struct ioctl_trans ioctl_start[] = { 32 struct ioctl_trans ioctl_start[] = {
35#define IOCTL_TABLE_END \ 33#define IOCTL_TABLE_END \
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 4fe3d5715c41..dd725779d91f 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -52,7 +52,9 @@ ATTRIB_NORET void cpu_idle(void)
52 while (!need_resched()) 52 while (!need_resched())
53 if (cpu_wait) 53 if (cpu_wait)
54 (*cpu_wait)(); 54 (*cpu_wait)();
55 preempt_enable_no_resched();
55 schedule(); 56 schedule();
57 preempt_disable();
56 } 58 }
57} 59}
58 60
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index fcacf1aae98a..25472fcaf715 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -82,7 +82,7 @@ extern ATTRIB_NORET void cpu_idle(void);
82 */ 82 */
83asmlinkage void start_secondary(void) 83asmlinkage void start_secondary(void)
84{ 84{
85 unsigned int cpu = smp_processor_id(); 85 unsigned int cpu;
86 86
87 cpu_probe(); 87 cpu_probe();
88 cpu_report(); 88 cpu_report();
@@ -95,6 +95,8 @@ asmlinkage void start_secondary(void)
95 */ 95 */
96 96
97 calibrate_delay(); 97 calibrate_delay();
98 preempt_disable();
99 cpu = smp_processor_id();
98 cpu_data[cpu].udelay_val = loops_per_jiffy; 100 cpu_data[cpu].udelay_val = loops_per_jiffy;
99 101
100 prom_smp_finish(); 102 prom_smp_finish();
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
index 230f5a93c2e6..9cd9c0fe2265 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
@@ -84,7 +84,6 @@ IRQ Device
84#include <asm/ptrace.h> 84#include <asm/ptrace.h>
85#include <asm/reboot.h> 85#include <asm/reboot.h>
86#include <asm/time.h> 86#include <asm/time.h>
87#include <linux/version.h>
88#include <linux/bootmem.h> 87#include <linux/bootmem.h>
89#include <asm/tx4938/rbtx4938.h> 88#include <asm/tx4938/rbtx4938.h>
90 89
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index 1ad44f92d6e4..e23c4e1e3a25 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -30,7 +30,6 @@
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/sched.h> 31#include <linux/sched.h>
32#include <linux/thread_info.h> 32#include <linux/thread_info.h>
33#include <linux/version.h>
34#include <linux/ptrace.h> 33#include <linux/ptrace.h>
35#include <linux/hardirq.h> 34#include <linux/hardirq.h>
36 35
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 7fdca87ef647..fee4f1f09adc 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -88,11 +88,15 @@ void default_idle(void)
88 */ 88 */
89void cpu_idle(void) 89void cpu_idle(void)
90{ 90{
91 set_thread_flag(TIF_POLLING_NRFLAG);
92
91 /* endless idle loop with no priority at all */ 93 /* endless idle loop with no priority at all */
92 while (1) { 94 while (1) {
93 while (!need_resched()) 95 while (!need_resched())
94 barrier(); 96 barrier();
97 preempt_enable_no_resched();
95 schedule(); 98 schedule();
99 preempt_disable();
96 check_pgt_cache(); 100 check_pgt_cache();
97 } 101 }
98} 102}
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 5db3be4e2704..a9ecf6465784 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -463,6 +463,7 @@ void __init smp_callin(void)
463#endif 463#endif
464 464
465 smp_cpu_init(slave_id); 465 smp_cpu_init(slave_id);
466 preempt_disable();
466 467
467#if 0 /* NOT WORKING YET - see entry.S */ 468#if 0 /* NOT WORKING YET - see entry.S */
468 istack = (void *)__get_free_pages(GFP_KERNEL,ISTACK_ORDER); 469 istack = (void *)__get_free_pages(GFP_KERNEL,ISTACK_ORDER);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 5c330c3366e4..36d67a8d7cbb 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -510,6 +510,7 @@ int __devinit start_secondary(void *unused)
510 510
511 smp_store_cpu_info(cpu); 511 smp_store_cpu_info(cpu);
512 set_dec(tb_ticks_per_jiffy); 512 set_dec(tb_ticks_per_jiffy);
513 preempt_disable();
513 cpu_callin_map[cpu] = 1; 514 cpu_callin_map[cpu] = 1;
514 515
515 smp_ops->setup_cpu(cpu); 516 smp_ops->setup_cpu(cpu);
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 32f215825e8d..0578f8387603 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -887,10 +887,6 @@ void altivec_unavailable_exception(struct pt_regs *regs)
887 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); 887 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
888} 888}
889 889
890#ifdef CONFIG_PPC64
891extern perf_irq_t perf_irq;
892#endif
893
894#if defined(CONFIG_PPC64) || defined(CONFIG_E500) 890#if defined(CONFIG_PPC64) || defined(CONFIG_E500)
895void performance_monitor_exception(struct pt_regs *regs) 891void performance_monitor_exception(struct pt_regs *regs)
896{ 892{
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 97082a4203ad..71a6addf9f7f 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -21,6 +21,7 @@
21#include <asm/iommu.h> 21#include <asm/iommu.h>
22#include <asm/dma.h> 22#include <asm/dma.h>
23#include <asm/vio.h> 23#include <asm/vio.h>
24#include <asm/prom.h>
24 25
25static const struct vio_device_id *vio_match_device( 26static const struct vio_device_id *vio_match_device(
26 const struct vio_device_id *, const struct vio_dev *); 27 const struct vio_device_id *, const struct vio_dev *);
@@ -265,7 +266,33 @@ static int vio_bus_match(struct device *dev, struct device_driver *drv)
265 return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL); 266 return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
266} 267}
267 268
269static int vio_hotplug(struct device *dev, char **envp, int num_envp,
270 char *buffer, int buffer_size)
271{
272 const struct vio_dev *vio_dev = to_vio_dev(dev);
273 char *cp;
274 int length;
275
276 if (!num_envp)
277 return -ENOMEM;
278
279 if (!vio_dev->dev.platform_data)
280 return -ENODEV;
281 cp = (char *)get_property(vio_dev->dev.platform_data, "compatible", &length);
282 if (!cp)
283 return -ENODEV;
284
285 envp[0] = buffer;
286 length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s",
287 vio_dev->type, cp);
288 if (buffer_size - length <= 0)
289 return -ENOMEM;
290 envp[1] = NULL;
291 return 0;
292}
293
268struct bus_type vio_bus_type = { 294struct bus_type vio_bus_type = {
269 .name = "vio", 295 .name = "vio",
296 .hotplug = vio_hotplug,
270 .match = vio_bus_match, 297 .match = vio_bus_match,
271}; 298};
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index d3e4bf756c83..7f8f0cda6a74 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -694,20 +694,19 @@ static void iseries_shared_idle(void)
694 if (hvlpevent_is_pending()) 694 if (hvlpevent_is_pending())
695 process_iSeries_events(); 695 process_iSeries_events();
696 696
697 preempt_enable_no_resched();
697 schedule(); 698 schedule();
699 preempt_disable();
698 } 700 }
699} 701}
700 702
701static void iseries_dedicated_idle(void) 703static void iseries_dedicated_idle(void)
702{ 704{
703 long oldval; 705 long oldval;
706 set_thread_flag(TIF_POLLING_NRFLAG);
704 707
705 while (1) { 708 while (1) {
706 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 709 if (!need_resched()) {
707
708 if (!oldval) {
709 set_thread_flag(TIF_POLLING_NRFLAG);
710
711 while (!need_resched()) { 710 while (!need_resched()) {
712 ppc64_runlatch_off(); 711 ppc64_runlatch_off();
713 HMT_low(); 712 HMT_low();
@@ -720,13 +719,12 @@ static void iseries_dedicated_idle(void)
720 } 719 }
721 720
722 HMT_medium(); 721 HMT_medium();
723 clear_thread_flag(TIF_POLLING_NRFLAG);
724 } else {
725 set_need_resched();
726 } 722 }
727 723
728 ppc64_runlatch_on(); 724 ppc64_runlatch_on();
725 preempt_enable_no_resched();
729 schedule(); 726 schedule();
727 preempt_disable();
730 } 728 }
731} 729}
732 730
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index e78c39368841..a093a0d4dd69 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -469,6 +469,7 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
469 * more. 469 * more.
470 */ 470 */
471 clear_thread_flag(TIF_POLLING_NRFLAG); 471 clear_thread_flag(TIF_POLLING_NRFLAG);
472 smp_mb__after_clear_bit();
472 473
473 /* 474 /*
474 * SMT dynamic mode. Cede will result in this thread going 475 * SMT dynamic mode. Cede will result in this thread going
@@ -481,6 +482,7 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
481 cede_processor(); 482 cede_processor();
482 else 483 else
483 local_irq_enable(); 484 local_irq_enable();
485 set_thread_flag(TIF_POLLING_NRFLAG);
484 } else { 486 } else {
485 /* 487 /*
486 * Give the HV an opportunity at the processor, since we are 488 * Give the HV an opportunity at the processor, since we are
@@ -492,11 +494,11 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
492 494
493static void pseries_dedicated_idle(void) 495static void pseries_dedicated_idle(void)
494{ 496{
495 long oldval;
496 struct paca_struct *lpaca = get_paca(); 497 struct paca_struct *lpaca = get_paca();
497 unsigned int cpu = smp_processor_id(); 498 unsigned int cpu = smp_processor_id();
498 unsigned long start_snooze; 499 unsigned long start_snooze;
499 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); 500 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
501 set_thread_flag(TIF_POLLING_NRFLAG);
500 502
501 while (1) { 503 while (1) {
502 /* 504 /*
@@ -505,10 +507,7 @@ static void pseries_dedicated_idle(void)
505 */ 507 */
506 lpaca->lppaca.idle = 1; 508 lpaca->lppaca.idle = 1;
507 509
508 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 510 if (!need_resched()) {
509 if (!oldval) {
510 set_thread_flag(TIF_POLLING_NRFLAG);
511
512 start_snooze = __get_tb() + 511 start_snooze = __get_tb() +
513 *smt_snooze_delay * tb_ticks_per_usec; 512 *smt_snooze_delay * tb_ticks_per_usec;
514 513
@@ -531,15 +530,14 @@ static void pseries_dedicated_idle(void)
531 } 530 }
532 531
533 HMT_medium(); 532 HMT_medium();
534 clear_thread_flag(TIF_POLLING_NRFLAG);
535 } else {
536 set_need_resched();
537 } 533 }
538 534
539 lpaca->lppaca.idle = 0; 535 lpaca->lppaca.idle = 0;
540 ppc64_runlatch_on(); 536 ppc64_runlatch_on();
541 537
538 preempt_enable_no_resched();
542 schedule(); 539 schedule();
540 preempt_disable();
543 541
544 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 542 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
545 cpu_die(); 543 cpu_die();
@@ -583,7 +581,9 @@ static void pseries_shared_idle(void)
583 lpaca->lppaca.idle = 0; 581 lpaca->lppaca.idle = 0;
584 ppc64_runlatch_on(); 582 ppc64_runlatch_on();
585 583
584 preempt_enable_no_resched();
586 schedule(); 585 schedule();
586 preempt_disable();
587 587
588 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 588 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
589 cpu_die(); 589 cpu_die();
diff --git a/arch/ppc/configs/mpc834x_sys_defconfig b/arch/ppc/configs/mpc834x_sys_defconfig
index 4a5522ca8207..673dc64ebcb1 100644
--- a/arch/ppc/configs/mpc834x_sys_defconfig
+++ b/arch/ppc/configs/mpc834x_sys_defconfig
@@ -1,16 +1,17 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-rc4 3# Linux kernel version: 2.6.14
4# Thu Feb 17 16:12:23 2005 4# Mon Nov 7 15:38:29 2005
5# 5#
6CONFIG_MMU=y 6CONFIG_MMU=y
7CONFIG_GENERIC_HARDIRQS=y 7CONFIG_GENERIC_HARDIRQS=y
8CONFIG_RWSEM_XCHGADD_ALGORITHM=y 8CONFIG_RWSEM_XCHGADD_ALGORITHM=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y 9CONFIG_GENERIC_CALIBRATE_DELAY=y
10CONFIG_HAVE_DEC_LOCK=y
11CONFIG_PPC=y 10CONFIG_PPC=y
12CONFIG_PPC32=y 11CONFIG_PPC32=y
13CONFIG_GENERIC_NVRAM=y 12CONFIG_GENERIC_NVRAM=y
13CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
14CONFIG_ARCH_MAY_HAVE_PC_FDC=y
14 15
15# 16#
16# Code maturity level options 17# Code maturity level options
@@ -18,23 +19,28 @@ CONFIG_GENERIC_NVRAM=y
18CONFIG_EXPERIMENTAL=y 19CONFIG_EXPERIMENTAL=y
19CONFIG_CLEAN_COMPILE=y 20CONFIG_CLEAN_COMPILE=y
20CONFIG_BROKEN_ON_SMP=y 21CONFIG_BROKEN_ON_SMP=y
22CONFIG_INIT_ENV_ARG_LIMIT=32
21 23
22# 24#
23# General setup 25# General setup
24# 26#
25CONFIG_LOCALVERSION="" 27CONFIG_LOCALVERSION=""
28CONFIG_LOCALVERSION_AUTO=y
26CONFIG_SWAP=y 29CONFIG_SWAP=y
27CONFIG_SYSVIPC=y 30CONFIG_SYSVIPC=y
28# CONFIG_POSIX_MQUEUE is not set 31# CONFIG_POSIX_MQUEUE is not set
29# CONFIG_BSD_PROCESS_ACCT is not set 32# CONFIG_BSD_PROCESS_ACCT is not set
30CONFIG_SYSCTL=y 33CONFIG_SYSCTL=y
31# CONFIG_AUDIT is not set 34# CONFIG_AUDIT is not set
32CONFIG_LOG_BUF_SHIFT=14
33# CONFIG_HOTPLUG is not set 35# CONFIG_HOTPLUG is not set
34CONFIG_KOBJECT_UEVENT=y 36CONFIG_KOBJECT_UEVENT=y
35# CONFIG_IKCONFIG is not set 37# CONFIG_IKCONFIG is not set
38CONFIG_INITRAMFS_SOURCE=""
36CONFIG_EMBEDDED=y 39CONFIG_EMBEDDED=y
37# CONFIG_KALLSYMS is not set 40# CONFIG_KALLSYMS is not set
41CONFIG_PRINTK=y
42CONFIG_BUG=y
43CONFIG_BASE_FULL=y
38CONFIG_FUTEX=y 44CONFIG_FUTEX=y
39# CONFIG_EPOLL is not set 45# CONFIG_EPOLL is not set
40# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 46# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +50,7 @@ CONFIG_CC_ALIGN_LABELS=0
44CONFIG_CC_ALIGN_LOOPS=0 50CONFIG_CC_ALIGN_LOOPS=0
45CONFIG_CC_ALIGN_JUMPS=0 51CONFIG_CC_ALIGN_JUMPS=0
46# CONFIG_TINY_SHMEM is not set 52# CONFIG_TINY_SHMEM is not set
53CONFIG_BASE_SMALL=0
47 54
48# 55#
49# Loadable module support 56# Loadable module support
@@ -59,34 +66,84 @@ CONFIG_6xx=y
59# CONFIG_POWER3 is not set 66# CONFIG_POWER3 is not set
60# CONFIG_POWER4 is not set 67# CONFIG_POWER4 is not set
61# CONFIG_8xx is not set 68# CONFIG_8xx is not set
69# CONFIG_E200 is not set
62# CONFIG_E500 is not set 70# CONFIG_E500 is not set
71CONFIG_PPC_FPU=y
72# CONFIG_KEXEC is not set
63# CONFIG_CPU_FREQ is not set 73# CONFIG_CPU_FREQ is not set
74# CONFIG_WANT_EARLY_SERIAL is not set
64CONFIG_PPC_GEN550=y 75CONFIG_PPC_GEN550=y
65CONFIG_83xx=y
66
67#
68# Freescale 83xx options
69#
70CONFIG_MPC834x_SYS=y
71CONFIG_MPC834x=y
72CONFIG_PPC_STD_MMU=y 76CONFIG_PPC_STD_MMU=y
73 77
74# 78#
75# Platform options 79# Platform options
76# 80#
81# CONFIG_PPC_MULTIPLATFORM is not set
82# CONFIG_APUS is not set
83# CONFIG_KATANA is not set
84# CONFIG_WILLOW is not set
85# CONFIG_CPCI690 is not set
86# CONFIG_POWERPMC250 is not set
87# CONFIG_CHESTNUT is not set
88# CONFIG_SPRUCE is not set
89# CONFIG_HDPU is not set
90# CONFIG_EV64260 is not set
91# CONFIG_LOPEC is not set
92# CONFIG_MVME5100 is not set
93# CONFIG_PPLUS is not set
94# CONFIG_PRPMC750 is not set
95# CONFIG_PRPMC800 is not set
96# CONFIG_SANDPOINT is not set
97# CONFIG_RADSTONE_PPC7D is not set
98# CONFIG_PAL4 is not set
99# CONFIG_GEMINI is not set
100# CONFIG_EST8260 is not set
101# CONFIG_SBC82xx is not set
102# CONFIG_SBS8260 is not set
103# CONFIG_RPX8260 is not set
104# CONFIG_TQM8260 is not set
105# CONFIG_ADS8272 is not set
106# CONFIG_PQ2FADS is not set
107# CONFIG_LITE5200 is not set
108CONFIG_MPC834x_SYS=y
109# CONFIG_EV64360 is not set
110CONFIG_83xx=y
111CONFIG_MPC834x=y
77# CONFIG_SMP is not set 112# CONFIG_SMP is not set
78# CONFIG_PREEMPT is not set
79# CONFIG_HIGHMEM is not set 113# CONFIG_HIGHMEM is not set
114# CONFIG_HZ_100 is not set
115CONFIG_HZ_250=y
116# CONFIG_HZ_1000 is not set
117CONFIG_HZ=250
118CONFIG_PREEMPT_NONE=y
119# CONFIG_PREEMPT_VOLUNTARY is not set
120# CONFIG_PREEMPT is not set
121CONFIG_SELECT_MEMORY_MODEL=y
122CONFIG_FLATMEM_MANUAL=y
123# CONFIG_DISCONTIGMEM_MANUAL is not set
124# CONFIG_SPARSEMEM_MANUAL is not set
125CONFIG_FLATMEM=y
126CONFIG_FLAT_NODE_MEM_MAP=y
127# CONFIG_SPARSEMEM_STATIC is not set
128CONFIG_SPLIT_PTLOCK_CPUS=4
80CONFIG_BINFMT_ELF=y 129CONFIG_BINFMT_ELF=y
81# CONFIG_BINFMT_MISC is not set 130# CONFIG_BINFMT_MISC is not set
82# CONFIG_CMDLINE_BOOL is not set 131# CONFIG_CMDLINE_BOOL is not set
132# CONFIG_PM is not set
133# CONFIG_SOFTWARE_SUSPEND is not set
134CONFIG_SECCOMP=y
135CONFIG_ISA_DMA_API=y
83 136
84# 137#
85# Bus options 138# Bus options
86# 139#
87CONFIG_GENERIC_ISA_DMA=y 140CONFIG_GENERIC_ISA_DMA=y
88# CONFIG_PCI is not set 141# CONFIG_PPC_I8259 is not set
89# CONFIG_PCI_DOMAINS is not set 142CONFIG_PPC_INDIRECT_PCI=y
143CONFIG_PCI=y
144CONFIG_PCI_DOMAINS=y
145# CONFIG_MPC83xx_PCI2 is not set
146CONFIG_PCI_LEGACY_PROC=y
90 147
91# 148#
92# PCCARD (PCMCIA/CardBus) support 149# PCCARD (PCMCIA/CardBus) support
@@ -94,10 +151,6 @@ CONFIG_GENERIC_ISA_DMA=y
94# CONFIG_PCCARD is not set 151# CONFIG_PCCARD is not set
95 152
96# 153#
97# PC-card bridges
98#
99
100#
101# Advanced setup 154# Advanced setup
102# 155#
103# CONFIG_ADVANCED_OPTIONS is not set 156# CONFIG_ADVANCED_OPTIONS is not set
@@ -112,6 +165,75 @@ CONFIG_TASK_SIZE=0x80000000
112CONFIG_BOOT_LOAD=0x00800000 165CONFIG_BOOT_LOAD=0x00800000
113 166
114# 167#
168# Networking
169#
170CONFIG_NET=y
171
172#
173# Networking options
174#
175CONFIG_PACKET=y
176# CONFIG_PACKET_MMAP is not set
177CONFIG_UNIX=y
178# CONFIG_NET_KEY is not set
179CONFIG_INET=y
180CONFIG_IP_MULTICAST=y
181# CONFIG_IP_ADVANCED_ROUTER is not set
182CONFIG_IP_FIB_HASH=y
183CONFIG_IP_PNP=y
184CONFIG_IP_PNP_DHCP=y
185CONFIG_IP_PNP_BOOTP=y
186# CONFIG_IP_PNP_RARP is not set
187# CONFIG_NET_IPIP is not set
188# CONFIG_NET_IPGRE is not set
189# CONFIG_IP_MROUTE is not set
190# CONFIG_ARPD is not set
191CONFIG_SYN_COOKIES=y
192# CONFIG_INET_AH is not set
193# CONFIG_INET_ESP is not set
194# CONFIG_INET_IPCOMP is not set
195# CONFIG_INET_TUNNEL is not set
196CONFIG_INET_DIAG=y
197CONFIG_INET_TCP_DIAG=y
198# CONFIG_TCP_CONG_ADVANCED is not set
199CONFIG_TCP_CONG_BIC=y
200# CONFIG_IPV6 is not set
201# CONFIG_NETFILTER is not set
202
203#
204# DCCP Configuration (EXPERIMENTAL)
205#
206# CONFIG_IP_DCCP is not set
207
208#
209# SCTP Configuration (EXPERIMENTAL)
210#
211# CONFIG_IP_SCTP is not set
212# CONFIG_ATM is not set
213# CONFIG_BRIDGE is not set
214# CONFIG_VLAN_8021Q is not set
215# CONFIG_DECNET is not set
216# CONFIG_LLC2 is not set
217# CONFIG_IPX is not set
218# CONFIG_ATALK is not set
219# CONFIG_X25 is not set
220# CONFIG_LAPB is not set
221# CONFIG_NET_DIVERT is not set
222# CONFIG_ECONET is not set
223# CONFIG_WAN_ROUTER is not set
224# CONFIG_NET_SCHED is not set
225# CONFIG_NET_CLS_ROUTE is not set
226
227#
228# Network testing
229#
230# CONFIG_NET_PKTGEN is not set
231# CONFIG_HAMRADIO is not set
232# CONFIG_IRDA is not set
233# CONFIG_BT is not set
234# CONFIG_IEEE80211 is not set
235
236#
115# Device Drivers 237# Device Drivers
116# 238#
117 239
@@ -123,6 +245,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
123# CONFIG_FW_LOADER is not set 245# CONFIG_FW_LOADER is not set
124 246
125# 247#
248# Connector - unified userspace <-> kernelspace linker
249#
250# CONFIG_CONNECTOR is not set
251
252#
126# Memory Technology Devices (MTD) 253# Memory Technology Devices (MTD)
127# 254#
128# CONFIG_MTD is not set 255# CONFIG_MTD is not set
@@ -140,15 +267,19 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
140# Block devices 267# Block devices
141# 268#
142# CONFIG_BLK_DEV_FD is not set 269# CONFIG_BLK_DEV_FD is not set
270# CONFIG_BLK_CPQ_DA is not set
271# CONFIG_BLK_CPQ_CISS_DA is not set
272# CONFIG_BLK_DEV_DAC960 is not set
273# CONFIG_BLK_DEV_UMEM is not set
143# CONFIG_BLK_DEV_COW_COMMON is not set 274# CONFIG_BLK_DEV_COW_COMMON is not set
144CONFIG_BLK_DEV_LOOP=y 275CONFIG_BLK_DEV_LOOP=y
145# CONFIG_BLK_DEV_CRYPTOLOOP is not set 276# CONFIG_BLK_DEV_CRYPTOLOOP is not set
146# CONFIG_BLK_DEV_NBD is not set 277# CONFIG_BLK_DEV_NBD is not set
278# CONFIG_BLK_DEV_SX8 is not set
147CONFIG_BLK_DEV_RAM=y 279CONFIG_BLK_DEV_RAM=y
148CONFIG_BLK_DEV_RAM_COUNT=16 280CONFIG_BLK_DEV_RAM_COUNT=16
149CONFIG_BLK_DEV_RAM_SIZE=32768 281CONFIG_BLK_DEV_RAM_SIZE=32768
150CONFIG_BLK_DEV_INITRD=y 282CONFIG_BLK_DEV_INITRD=y
151CONFIG_INITRAMFS_SOURCE=""
152# CONFIG_LBD is not set 283# CONFIG_LBD is not set
153# CONFIG_CDROM_PKTCDVD is not set 284# CONFIG_CDROM_PKTCDVD is not set
154 285
@@ -159,6 +290,11 @@ CONFIG_IOSCHED_NOOP=y
159CONFIG_IOSCHED_AS=y 290CONFIG_IOSCHED_AS=y
160CONFIG_IOSCHED_DEADLINE=y 291CONFIG_IOSCHED_DEADLINE=y
161CONFIG_IOSCHED_CFQ=y 292CONFIG_IOSCHED_CFQ=y
293CONFIG_DEFAULT_AS=y
294# CONFIG_DEFAULT_DEADLINE is not set
295# CONFIG_DEFAULT_CFQ is not set
296# CONFIG_DEFAULT_NOOP is not set
297CONFIG_DEFAULT_IOSCHED="anticipatory"
162# CONFIG_ATA_OVER_ETH is not set 298# CONFIG_ATA_OVER_ETH is not set
163 299
164# 300#
@@ -169,6 +305,7 @@ CONFIG_IOSCHED_CFQ=y
169# 305#
170# SCSI device support 306# SCSI device support
171# 307#
308# CONFIG_RAID_ATTRS is not set
172# CONFIG_SCSI is not set 309# CONFIG_SCSI is not set
173 310
174# 311#
@@ -179,110 +316,116 @@ CONFIG_IOSCHED_CFQ=y
179# 316#
180# Fusion MPT device support 317# Fusion MPT device support
181# 318#
319# CONFIG_FUSION is not set
182 320
183# 321#
184# IEEE 1394 (FireWire) support 322# IEEE 1394 (FireWire) support
185# 323#
324# CONFIG_IEEE1394 is not set
186 325
187# 326#
188# I2O device support 327# I2O device support
189# 328#
329# CONFIG_I2O is not set
190 330
191# 331#
192# Macintosh device drivers 332# Macintosh device drivers
193# 333#
194 334
195# 335#
196# Networking support 336# Network device support
197# 337#
198CONFIG_NET=y 338CONFIG_NETDEVICES=y
199 339# CONFIG_DUMMY is not set
200# 340# CONFIG_BONDING is not set
201# Networking options 341# CONFIG_EQUALIZER is not set
202# 342# CONFIG_TUN is not set
203CONFIG_PACKET=y
204# CONFIG_PACKET_MMAP is not set
205# CONFIG_NETLINK_DEV is not set
206CONFIG_UNIX=y
207# CONFIG_NET_KEY is not set
208CONFIG_INET=y
209CONFIG_IP_MULTICAST=y
210# CONFIG_IP_ADVANCED_ROUTER is not set
211CONFIG_IP_PNP=y
212CONFIG_IP_PNP_DHCP=y
213CONFIG_IP_PNP_BOOTP=y
214# CONFIG_IP_PNP_RARP is not set
215# CONFIG_NET_IPIP is not set
216# CONFIG_NET_IPGRE is not set
217# CONFIG_IP_MROUTE is not set
218# CONFIG_ARPD is not set
219CONFIG_SYN_COOKIES=y
220# CONFIG_INET_AH is not set
221# CONFIG_INET_ESP is not set
222# CONFIG_INET_IPCOMP is not set
223# CONFIG_INET_TUNNEL is not set
224CONFIG_IP_TCPDIAG=y
225# CONFIG_IP_TCPDIAG_IPV6 is not set
226# CONFIG_IPV6 is not set
227# CONFIG_NETFILTER is not set
228 343
229# 344#
230# SCTP Configuration (EXPERIMENTAL) 345# ARCnet devices
231# 346#
232# CONFIG_IP_SCTP is not set 347# CONFIG_ARCNET is not set
233# CONFIG_ATM is not set
234# CONFIG_BRIDGE is not set
235# CONFIG_VLAN_8021Q is not set
236# CONFIG_DECNET is not set
237# CONFIG_LLC2 is not set
238# CONFIG_IPX is not set
239# CONFIG_ATALK is not set
240# CONFIG_X25 is not set
241# CONFIG_LAPB is not set
242# CONFIG_NET_DIVERT is not set
243# CONFIG_ECONET is not set
244# CONFIG_WAN_ROUTER is not set
245 348
246# 349#
247# QoS and/or fair queueing 350# PHY device support
248# 351#
249# CONFIG_NET_SCHED is not set 352CONFIG_PHYLIB=y
250# CONFIG_NET_CLS_ROUTE is not set
251 353
252# 354#
253# Network testing 355# MII PHY device drivers
254# 356#
255# CONFIG_NET_PKTGEN is not set 357CONFIG_MARVELL_PHY=y
256# CONFIG_NETPOLL is not set 358# CONFIG_DAVICOM_PHY is not set
257# CONFIG_NET_POLL_CONTROLLER is not set 359# CONFIG_QSEMI_PHY is not set
258# CONFIG_HAMRADIO is not set 360# CONFIG_LXT_PHY is not set
259# CONFIG_IRDA is not set 361# CONFIG_CICADA_PHY is not set
260# CONFIG_BT is not set
261CONFIG_NETDEVICES=y
262# CONFIG_DUMMY is not set
263# CONFIG_BONDING is not set
264# CONFIG_EQUALIZER is not set
265# CONFIG_TUN is not set
266 362
267# 363#
268# Ethernet (10 or 100Mbit) 364# Ethernet (10 or 100Mbit)
269# 365#
270CONFIG_NET_ETHERNET=y 366CONFIG_NET_ETHERNET=y
271CONFIG_MII=y 367CONFIG_MII=y
368# CONFIG_HAPPYMEAL is not set
369# CONFIG_SUNGEM is not set
370# CONFIG_CASSINI is not set
371# CONFIG_NET_VENDOR_3COM is not set
372
373#
374# Tulip family network device support
375#
376# CONFIG_NET_TULIP is not set
377# CONFIG_HP100 is not set
378CONFIG_NET_PCI=y
379# CONFIG_PCNET32 is not set
380# CONFIG_AMD8111_ETH is not set
381# CONFIG_ADAPTEC_STARFIRE is not set
382# CONFIG_B44 is not set
383# CONFIG_FORCEDETH is not set
384# CONFIG_DGRS is not set
385# CONFIG_EEPRO100 is not set
386CONFIG_E100=y
387# CONFIG_FEALNX is not set
388# CONFIG_NATSEMI is not set
389# CONFIG_NE2K_PCI is not set
390# CONFIG_8139CP is not set
391# CONFIG_8139TOO is not set
392# CONFIG_SIS900 is not set
393# CONFIG_EPIC100 is not set
394# CONFIG_SUNDANCE is not set
395# CONFIG_TLAN is not set
396# CONFIG_VIA_RHINE is not set
272 397
273# 398#
274# Ethernet (1000 Mbit) 399# Ethernet (1000 Mbit)
275# 400#
401# CONFIG_ACENIC is not set
402# CONFIG_DL2K is not set
403CONFIG_E1000=y
404# CONFIG_E1000_NAPI is not set
405# CONFIG_NS83820 is not set
406# CONFIG_HAMACHI is not set
407# CONFIG_YELLOWFIN is not set
408# CONFIG_R8169 is not set
409# CONFIG_SIS190 is not set
410# CONFIG_SKGE is not set
411# CONFIG_SK98LIN is not set
412# CONFIG_VIA_VELOCITY is not set
413# CONFIG_TIGON3 is not set
414# CONFIG_BNX2 is not set
276CONFIG_GIANFAR=y 415CONFIG_GIANFAR=y
277# CONFIG_GFAR_NAPI is not set 416# CONFIG_GFAR_NAPI is not set
278 417
279# 418#
280# Ethernet (10000 Mbit) 419# Ethernet (10000 Mbit)
281# 420#
421# CONFIG_CHELSIO_T1 is not set
422# CONFIG_IXGB is not set
423# CONFIG_S2IO is not set
282 424
283# 425#
284# Token Ring devices 426# Token Ring devices
285# 427#
428# CONFIG_TR is not set
286 429
287# 430#
288# Wireless LAN (non-hamradio) 431# Wireless LAN (non-hamradio)
@@ -293,10 +436,14 @@ CONFIG_GIANFAR=y
293# Wan interfaces 436# Wan interfaces
294# 437#
295# CONFIG_WAN is not set 438# CONFIG_WAN is not set
439# CONFIG_FDDI is not set
440# CONFIG_HIPPI is not set
296# CONFIG_PPP is not set 441# CONFIG_PPP is not set
297# CONFIG_SLIP is not set 442# CONFIG_SLIP is not set
298# CONFIG_SHAPER is not set 443# CONFIG_SHAPER is not set
299# CONFIG_NETCONSOLE is not set 444# CONFIG_NETCONSOLE is not set
445# CONFIG_NETPOLL is not set
446# CONFIG_NET_POLL_CONTROLLER is not set
300 447
301# 448#
302# ISDN subsystem 449# ISDN subsystem
@@ -323,14 +470,6 @@ CONFIG_INPUT=y
323# CONFIG_INPUT_EVBUG is not set 470# CONFIG_INPUT_EVBUG is not set
324 471
325# 472#
326# Input I/O drivers
327#
328# CONFIG_GAMEPORT is not set
329CONFIG_SOUND_GAMEPORT=y
330# CONFIG_SERIO is not set
331# CONFIG_SERIO_I8042 is not set
332
333#
334# Input Device Drivers 473# Input Device Drivers
335# 474#
336# CONFIG_INPUT_KEYBOARD is not set 475# CONFIG_INPUT_KEYBOARD is not set
@@ -340,6 +479,12 @@ CONFIG_SOUND_GAMEPORT=y
340# CONFIG_INPUT_MISC is not set 479# CONFIG_INPUT_MISC is not set
341 480
342# 481#
482# Hardware I/O ports
483#
484# CONFIG_SERIO is not set
485# CONFIG_GAMEPORT is not set
486
487#
343# Character devices 488# Character devices
344# 489#
345# CONFIG_VT is not set 490# CONFIG_VT is not set
@@ -358,6 +503,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
358# 503#
359CONFIG_SERIAL_CORE=y 504CONFIG_SERIAL_CORE=y
360CONFIG_SERIAL_CORE_CONSOLE=y 505CONFIG_SERIAL_CORE_CONSOLE=y
506# CONFIG_SERIAL_JSM is not set
361CONFIG_UNIX98_PTYS=y 507CONFIG_UNIX98_PTYS=y
362CONFIG_LEGACY_PTYS=y 508CONFIG_LEGACY_PTYS=y
363CONFIG_LEGACY_PTY_COUNT=256 509CONFIG_LEGACY_PTY_COUNT=256
@@ -376,6 +522,7 @@ CONFIG_GEN_RTC=y
376# CONFIG_GEN_RTC_X is not set 522# CONFIG_GEN_RTC_X is not set
377# CONFIG_DTLK is not set 523# CONFIG_DTLK is not set
378# CONFIG_R3964 is not set 524# CONFIG_R3964 is not set
525# CONFIG_APPLICOM is not set
379 526
380# 527#
381# Ftape, the floppy tape device driver 528# Ftape, the floppy tape device driver
@@ -385,6 +532,12 @@ CONFIG_GEN_RTC=y
385# CONFIG_RAW_DRIVER is not set 532# CONFIG_RAW_DRIVER is not set
386 533
387# 534#
535# TPM devices
536#
537# CONFIG_TCG_TPM is not set
538# CONFIG_TELCLOCK is not set
539
540#
388# I2C support 541# I2C support
389# 542#
390CONFIG_I2C=y 543CONFIG_I2C=y
@@ -400,23 +553,68 @@ CONFIG_I2C_CHARDEV=y
400# 553#
401# I2C Hardware Bus support 554# I2C Hardware Bus support
402# 555#
403# CONFIG_I2C_ISA is not set 556# CONFIG_I2C_ALI1535 is not set
557# CONFIG_I2C_ALI1563 is not set
558# CONFIG_I2C_ALI15X3 is not set
559# CONFIG_I2C_AMD756 is not set
560# CONFIG_I2C_AMD8111 is not set
561# CONFIG_I2C_I801 is not set
562# CONFIG_I2C_I810 is not set
563# CONFIG_I2C_PIIX4 is not set
404CONFIG_I2C_MPC=y 564CONFIG_I2C_MPC=y
565# CONFIG_I2C_NFORCE2 is not set
405# CONFIG_I2C_PARPORT_LIGHT is not set 566# CONFIG_I2C_PARPORT_LIGHT is not set
567# CONFIG_I2C_PROSAVAGE is not set
568# CONFIG_I2C_SAVAGE4 is not set
569# CONFIG_SCx200_ACB is not set
570# CONFIG_I2C_SIS5595 is not set
571# CONFIG_I2C_SIS630 is not set
572# CONFIG_I2C_SIS96X is not set
573# CONFIG_I2C_VIA is not set
574# CONFIG_I2C_VIAPRO is not set
575# CONFIG_I2C_VOODOO3 is not set
406# CONFIG_I2C_PCA_ISA is not set 576# CONFIG_I2C_PCA_ISA is not set
407 577
408# 578#
409# Hardware Sensors Chip support 579# Miscellaneous I2C Chip support
580#
581# CONFIG_SENSORS_DS1337 is not set
582# CONFIG_SENSORS_DS1374 is not set
583# CONFIG_SENSORS_EEPROM is not set
584# CONFIG_SENSORS_PCF8574 is not set
585# CONFIG_SENSORS_PCA9539 is not set
586# CONFIG_SENSORS_PCF8591 is not set
587# CONFIG_SENSORS_RTC8564 is not set
588# CONFIG_SENSORS_M41T00 is not set
589# CONFIG_SENSORS_MAX6875 is not set
590# CONFIG_RTC_X1205_I2C is not set
591# CONFIG_I2C_DEBUG_CORE is not set
592# CONFIG_I2C_DEBUG_ALGO is not set
593# CONFIG_I2C_DEBUG_BUS is not set
594# CONFIG_I2C_DEBUG_CHIP is not set
595
596#
597# Dallas's 1-wire bus
598#
599# CONFIG_W1 is not set
600
601#
602# Hardware Monitoring support
410# 603#
411# CONFIG_I2C_SENSOR is not set 604CONFIG_HWMON=y
605# CONFIG_HWMON_VID is not set
412# CONFIG_SENSORS_ADM1021 is not set 606# CONFIG_SENSORS_ADM1021 is not set
413# CONFIG_SENSORS_ADM1025 is not set 607# CONFIG_SENSORS_ADM1025 is not set
414# CONFIG_SENSORS_ADM1026 is not set 608# CONFIG_SENSORS_ADM1026 is not set
415# CONFIG_SENSORS_ADM1031 is not set 609# CONFIG_SENSORS_ADM1031 is not set
610# CONFIG_SENSORS_ADM9240 is not set
416# CONFIG_SENSORS_ASB100 is not set 611# CONFIG_SENSORS_ASB100 is not set
612# CONFIG_SENSORS_ATXP1 is not set
417# CONFIG_SENSORS_DS1621 is not set 613# CONFIG_SENSORS_DS1621 is not set
418# CONFIG_SENSORS_FSCHER is not set 614# CONFIG_SENSORS_FSCHER is not set
615# CONFIG_SENSORS_FSCPOS is not set
419# CONFIG_SENSORS_GL518SM is not set 616# CONFIG_SENSORS_GL518SM is not set
617# CONFIG_SENSORS_GL520SM is not set
420# CONFIG_SENSORS_IT87 is not set 618# CONFIG_SENSORS_IT87 is not set
421# CONFIG_SENSORS_LM63 is not set 619# CONFIG_SENSORS_LM63 is not set
422# CONFIG_SENSORS_LM75 is not set 620# CONFIG_SENSORS_LM75 is not set
@@ -427,33 +625,26 @@ CONFIG_I2C_MPC=y
427# CONFIG_SENSORS_LM85 is not set 625# CONFIG_SENSORS_LM85 is not set
428# CONFIG_SENSORS_LM87 is not set 626# CONFIG_SENSORS_LM87 is not set
429# CONFIG_SENSORS_LM90 is not set 627# CONFIG_SENSORS_LM90 is not set
628# CONFIG_SENSORS_LM92 is not set
430# CONFIG_SENSORS_MAX1619 is not set 629# CONFIG_SENSORS_MAX1619 is not set
431# CONFIG_SENSORS_PC87360 is not set 630# CONFIG_SENSORS_PC87360 is not set
432# CONFIG_SENSORS_SMSC47B397 is not set 631# CONFIG_SENSORS_SIS5595 is not set
433# CONFIG_SENSORS_SMSC47M1 is not set 632# CONFIG_SENSORS_SMSC47M1 is not set
633# CONFIG_SENSORS_SMSC47B397 is not set
634# CONFIG_SENSORS_VIA686A is not set
434# CONFIG_SENSORS_W83781D is not set 635# CONFIG_SENSORS_W83781D is not set
636# CONFIG_SENSORS_W83792D is not set
435# CONFIG_SENSORS_W83L785TS is not set 637# CONFIG_SENSORS_W83L785TS is not set
436# CONFIG_SENSORS_W83627HF is not set 638# CONFIG_SENSORS_W83627HF is not set
639# CONFIG_SENSORS_W83627EHF is not set
640# CONFIG_HWMON_DEBUG_CHIP is not set
437 641
438# 642#
439# Other I2C Chip support 643# Misc devices
440#
441# CONFIG_SENSORS_EEPROM is not set
442# CONFIG_SENSORS_PCF8574 is not set
443# CONFIG_SENSORS_PCF8591 is not set
444# CONFIG_SENSORS_RTC8564 is not set
445# CONFIG_I2C_DEBUG_CORE is not set
446# CONFIG_I2C_DEBUG_ALGO is not set
447# CONFIG_I2C_DEBUG_BUS is not set
448# CONFIG_I2C_DEBUG_CHIP is not set
449
450#
451# Dallas's 1-wire bus
452# 644#
453# CONFIG_W1 is not set
454 645
455# 646#
456# Misc devices 647# Multimedia Capabilities Port drivers
457# 648#
458 649
459# 650#
@@ -479,11 +670,12 @@ CONFIG_I2C_MPC=y
479# 670#
480# USB support 671# USB support
481# 672#
482# CONFIG_USB_ARCH_HAS_HCD is not set 673CONFIG_USB_ARCH_HAS_HCD=y
483# CONFIG_USB_ARCH_HAS_OHCI is not set 674CONFIG_USB_ARCH_HAS_OHCI=y
675# CONFIG_USB is not set
484 676
485# 677#
486# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information 678# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
487# 679#
488 680
489# 681#
@@ -502,10 +694,15 @@ CONFIG_I2C_MPC=y
502# CONFIG_INFINIBAND is not set 694# CONFIG_INFINIBAND is not set
503 695
504# 696#
697# SN Devices
698#
699
700#
505# File systems 701# File systems
506# 702#
507CONFIG_EXT2_FS=y 703CONFIG_EXT2_FS=y
508# CONFIG_EXT2_FS_XATTR is not set 704# CONFIG_EXT2_FS_XATTR is not set
705# CONFIG_EXT2_FS_XIP is not set
509CONFIG_EXT3_FS=y 706CONFIG_EXT3_FS=y
510CONFIG_EXT3_FS_XATTR=y 707CONFIG_EXT3_FS_XATTR=y
511# CONFIG_EXT3_FS_POSIX_ACL is not set 708# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -515,17 +712,16 @@ CONFIG_JBD=y
515CONFIG_FS_MBCACHE=y 712CONFIG_FS_MBCACHE=y
516# CONFIG_REISERFS_FS is not set 713# CONFIG_REISERFS_FS is not set
517# CONFIG_JFS_FS is not set 714# CONFIG_JFS_FS is not set
518 715# CONFIG_FS_POSIX_ACL is not set
519#
520# XFS support
521#
522# CONFIG_XFS_FS is not set 716# CONFIG_XFS_FS is not set
523# CONFIG_MINIX_FS is not set 717# CONFIG_MINIX_FS is not set
524# CONFIG_ROMFS_FS is not set 718# CONFIG_ROMFS_FS is not set
719CONFIG_INOTIFY=y
525# CONFIG_QUOTA is not set 720# CONFIG_QUOTA is not set
526CONFIG_DNOTIFY=y 721CONFIG_DNOTIFY=y
527# CONFIG_AUTOFS_FS is not set 722# CONFIG_AUTOFS_FS is not set
528# CONFIG_AUTOFS4_FS is not set 723# CONFIG_AUTOFS4_FS is not set
724# CONFIG_FUSE_FS is not set
529 725
530# 726#
531# CD-ROM/DVD Filesystems 727# CD-ROM/DVD Filesystems
@@ -546,12 +742,10 @@ CONFIG_DNOTIFY=y
546CONFIG_PROC_FS=y 742CONFIG_PROC_FS=y
547CONFIG_PROC_KCORE=y 743CONFIG_PROC_KCORE=y
548CONFIG_SYSFS=y 744CONFIG_SYSFS=y
549# CONFIG_DEVFS_FS is not set
550# CONFIG_DEVPTS_FS_XATTR is not set
551CONFIG_TMPFS=y 745CONFIG_TMPFS=y
552# CONFIG_TMPFS_XATTR is not set
553# CONFIG_HUGETLB_PAGE is not set 746# CONFIG_HUGETLB_PAGE is not set
554CONFIG_RAMFS=y 747CONFIG_RAMFS=y
748# CONFIG_RELAYFS_FS is not set
555 749
556# 750#
557# Miscellaneous filesystems 751# Miscellaneous filesystems
@@ -580,6 +774,7 @@ CONFIG_NFS_FS=y
580# CONFIG_NFSD is not set 774# CONFIG_NFSD is not set
581CONFIG_ROOT_NFS=y 775CONFIG_ROOT_NFS=y
582CONFIG_LOCKD=y 776CONFIG_LOCKD=y
777CONFIG_NFS_COMMON=y
583CONFIG_SUNRPC=y 778CONFIG_SUNRPC=y
584# CONFIG_RPCSEC_GSS_KRB5 is not set 779# CONFIG_RPCSEC_GSS_KRB5 is not set
585# CONFIG_RPCSEC_GSS_SPKM3 is not set 780# CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -588,6 +783,7 @@ CONFIG_SUNRPC=y
588# CONFIG_NCP_FS is not set 783# CONFIG_NCP_FS is not set
589# CONFIG_CODA_FS is not set 784# CONFIG_CODA_FS is not set
590# CONFIG_AFS_FS is not set 785# CONFIG_AFS_FS is not set
786# CONFIG_9P_FS is not set
591 787
592# 788#
593# Partition Types 789# Partition Types
@@ -614,6 +810,7 @@ CONFIG_PARTITION_ADVANCED=y
614# Library routines 810# Library routines
615# 811#
616# CONFIG_CRC_CCITT is not set 812# CONFIG_CRC_CCITT is not set
813# CONFIG_CRC16 is not set
617CONFIG_CRC32=y 814CONFIG_CRC32=y
618# CONFIG_LIBCRC32C is not set 815# CONFIG_LIBCRC32C is not set
619 816
@@ -625,7 +822,9 @@ CONFIG_CRC32=y
625# 822#
626# Kernel hacking 823# Kernel hacking
627# 824#
825# CONFIG_PRINTK_TIME is not set
628# CONFIG_DEBUG_KERNEL is not set 826# CONFIG_DEBUG_KERNEL is not set
827CONFIG_LOG_BUF_SHIFT=14
629# CONFIG_SERIAL_TEXT_DEBUG is not set 828# CONFIG_SERIAL_TEXT_DEBUG is not set
630 829
631# 830#
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index 11e5b44713f7..821a75e45602 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -53,10 +53,6 @@ void default_idle(void)
53 } 53 }
54#endif 54#endif
55 } 55 }
56 if (need_resched())
57 schedule();
58 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
59 cpu_die();
60} 56}
61 57
62/* 58/*
@@ -64,11 +60,22 @@ void default_idle(void)
64 */ 60 */
65void cpu_idle(void) 61void cpu_idle(void)
66{ 62{
67 for (;;) 63 int cpu = smp_processor_id();
68 if (ppc_md.idle != NULL) 64
69 ppc_md.idle(); 65 for (;;) {
70 else 66 while (!need_resched()) {
71 default_idle(); 67 if (ppc_md.idle != NULL)
68 ppc_md.idle();
69 else
70 default_idle();
71 }
72
73 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
74 cpu_die();
75 preempt_enable_no_resched();
76 schedule();
77 preempt_disable();
78 }
72} 79}
73 80
74#if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx) 81#if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx)
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index bc5bf1124836..43b8fc2ca591 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -341,6 +341,7 @@ int __devinit start_secondary(void *unused)
341 cpu = smp_processor_id(); 341 cpu = smp_processor_id();
342 smp_store_cpu_info(cpu); 342 smp_store_cpu_info(cpu);
343 set_dec(tb_ticks_per_jiffy); 343 set_dec(tb_ticks_per_jiffy);
344 preempt_disable();
344 cpu_callin_map[cpu] = 1; 345 cpu_callin_map[cpu] = 1;
345 346
346 printk("CPU %d done callin...\n", cpu); 347 printk("CPU %d done callin...\n", cpu);
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index 79b3f533d0a3..98edc75f4105 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -51,6 +51,9 @@
51 51
52#include <syslib/ppc83xx_setup.h> 52#include <syslib/ppc83xx_setup.h>
53 53
54static const char *GFAR_PHY_0 = "phy0:0";
55static const char *GFAR_PHY_1 = "phy0:1";
56
54#ifndef CONFIG_PCI 57#ifndef CONFIG_PCI
55unsigned long isa_io_base = 0; 58unsigned long isa_io_base = 0;
56unsigned long isa_mem_base = 0; 59unsigned long isa_mem_base = 0;
@@ -97,6 +100,7 @@ mpc834x_sys_setup_arch(void)
97 bd_t *binfo = (bd_t *) __res; 100 bd_t *binfo = (bd_t *) __res;
98 unsigned int freq; 101 unsigned int freq;
99 struct gianfar_platform_data *pdata; 102 struct gianfar_platform_data *pdata;
103 struct gianfar_mdio_data *mdata;
100 104
101 /* get the core frequency */ 105 /* get the core frequency */
102 freq = binfo->bi_intfreq; 106 freq = binfo->bi_intfreq;
@@ -111,24 +115,27 @@ mpc834x_sys_setup_arch(void)
111#endif 115#endif
112 mpc83xx_early_serial_map(); 116 mpc83xx_early_serial_map();
113 117
118 /* setup the board related info for the MDIO bus */
119 mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC83xx_MDIO);
120
121 mdata->irq[0] = MPC83xx_IRQ_EXT1;
122 mdata->irq[1] = MPC83xx_IRQ_EXT2;
123 mdata->irq[2] = -1;
124 mdata->irq[31] = -1;
125 mdata->paddr += binfo->bi_immr_base;
126
114 /* setup the board related information for the enet controllers */ 127 /* setup the board related information for the enet controllers */
115 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1); 128 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1);
116 if (pdata) { 129 if (pdata) {
117 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; 130 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
118 pdata->interruptPHY = MPC83xx_IRQ_EXT1; 131 pdata->bus_id = GFAR_PHY_0;
119 pdata->phyid = 0;
120 /* fixup phy address */
121 pdata->phy_reg_addr += binfo->bi_immr_base;
122 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); 132 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
123 } 133 }
124 134
125 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2); 135 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2);
126 if (pdata) { 136 if (pdata) {
127 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; 137 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
128 pdata->interruptPHY = MPC83xx_IRQ_EXT2; 138 pdata->bus_id = GFAR_PHY_1;
129 pdata->phyid = 1;
130 /* fixup phy address */
131 pdata->phy_reg_addr += binfo->bi_immr_base;
132 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); 139 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
133 } 140 }
134 141
diff --git a/arch/ppc/platforms/85xx/stx_gp3.h b/arch/ppc/platforms/85xx/stx_gp3.h
index 95fdf4b0680b..7bcc6c35a417 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.h
+++ b/arch/ppc/platforms/85xx/stx_gp3.h
@@ -21,6 +21,7 @@
21 21
22#include <linux/config.h> 22#include <linux/config.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/seq_file.h>
24#include <asm/ppcboot.h> 25#include <asm/ppcboot.h>
25 26
26#define BOARD_CCSRBAR ((uint)0xe0000000) 27#define BOARD_CCSRBAR ((uint)0xe0000000)
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 5bd33baac243..5b7f2b80e56e 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -33,7 +33,6 @@ obj-$(CONFIG_PPC4xx_DMA) += ppc4xx_dma.o
33obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o 33obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o
34ifeq ($(CONFIG_40x),y) 34ifeq ($(CONFIG_40x),y)
35obj-$(CONFIG_PCI) += pci_auto.o ppc405_pci.o 35obj-$(CONFIG_PCI) += pci_auto.o ppc405_pci.o
36obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o
37endif 36endif
38endif 37endif
39obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ 38obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
@@ -96,6 +95,7 @@ obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \
96ifeq ($(CONFIG_85xx),y) 95ifeq ($(CONFIG_85xx),y)
97obj-$(CONFIG_PCI) += pci_auto.o 96obj-$(CONFIG_PCI) += pci_auto.o
98endif 97endif
98obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o
99obj-$(CONFIG_83xx) += ipic.o ppc83xx_setup.o ppc_sys.o \ 99obj-$(CONFIG_83xx) += ipic.o ppc83xx_setup.o ppc_sys.o \
100 mpc83xx_sys.o mpc83xx_devices.o 100 mpc83xx_sys.o mpc83xx_devices.o
101ifeq ($(CONFIG_83xx),y) 101ifeq ($(CONFIG_83xx),y)
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index dbf8acac507f..f43fbf9a9389 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -27,18 +27,20 @@
27 * what IMMRBAR is, will get fixed up by mach_mpc83xx_fixup 27 * what IMMRBAR is, will get fixed up by mach_mpc83xx_fixup
28 */ 28 */
29 29
30struct gianfar_mdio_data mpc83xx_mdio_pdata = {
31 .paddr = 0x24520,
32};
33
30static struct gianfar_platform_data mpc83xx_tsec1_pdata = { 34static struct gianfar_platform_data mpc83xx_tsec1_pdata = {
31 .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | 35 .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
32 FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | 36 FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
33 FSL_GIANFAR_DEV_HAS_MULTI_INTR, 37 FSL_GIANFAR_DEV_HAS_MULTI_INTR,
34 .phy_reg_addr = 0x24000,
35}; 38};
36 39
37static struct gianfar_platform_data mpc83xx_tsec2_pdata = { 40static struct gianfar_platform_data mpc83xx_tsec2_pdata = {
38 .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | 41 .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
39 FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | 42 FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
40 FSL_GIANFAR_DEV_HAS_MULTI_INTR, 43 FSL_GIANFAR_DEV_HAS_MULTI_INTR,
41 .phy_reg_addr = 0x24000,
42}; 44};
43 45
44static struct fsl_i2c_platform_data mpc83xx_fsl_i2c1_pdata = { 46static struct fsl_i2c_platform_data mpc83xx_fsl_i2c1_pdata = {
@@ -220,6 +222,12 @@ struct platform_device ppc_sys_platform_devices[] = {
220 }, 222 },
221 }, 223 },
222 }, 224 },
225 [MPC83xx_MDIO] = {
226 .name = "fsl-gianfar_mdio",
227 .id = 0,
228 .dev.platform_data = &mpc83xx_mdio_pdata,
229 .num_resources = 0,
230 },
223}; 231};
224 232
225static int __init mach_mpc83xx_fixup(struct platform_device *pdev) 233static int __init mach_mpc83xx_fixup(struct platform_device *pdev)
diff --git a/arch/ppc/syslib/mpc83xx_sys.c b/arch/ppc/syslib/mpc83xx_sys.c
index 29aa63350025..da743446789b 100644
--- a/arch/ppc/syslib/mpc83xx_sys.c
+++ b/arch/ppc/syslib/mpc83xx_sys.c
@@ -24,72 +24,72 @@ struct ppc_sys_spec ppc_sys_specs[] = {
24 .ppc_sys_name = "8349E", 24 .ppc_sys_name = "8349E",
25 .mask = 0xFFFF0000, 25 .mask = 0xFFFF0000,
26 .value = 0x80500000, 26 .value = 0x80500000,
27 .num_devices = 8, 27 .num_devices = 9,
28 .device_list = (enum ppc_sys_devices[]) 28 .device_list = (enum ppc_sys_devices[])
29 { 29 {
30 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 30 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
31 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2, 31 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2,
32 MPC83xx_USB2_DR, MPC83xx_USB2_MPH 32 MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
33 }, 33 },
34 }, 34 },
35 { 35 {
36 .ppc_sys_name = "8349", 36 .ppc_sys_name = "8349",
37 .mask = 0xFFFF0000, 37 .mask = 0xFFFF0000,
38 .value = 0x80510000, 38 .value = 0x80510000,
39 .num_devices = 7, 39 .num_devices = 8,
40 .device_list = (enum ppc_sys_devices[]) 40 .device_list = (enum ppc_sys_devices[])
41 { 41 {
42 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 42 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
43 MPC83xx_IIC2, MPC83xx_DUART, 43 MPC83xx_IIC2, MPC83xx_DUART,
44 MPC83xx_USB2_DR, MPC83xx_USB2_MPH 44 MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
45 }, 45 },
46 }, 46 },
47 { 47 {
48 .ppc_sys_name = "8347E", 48 .ppc_sys_name = "8347E",
49 .mask = 0xFFFF0000, 49 .mask = 0xFFFF0000,
50 .value = 0x80520000, 50 .value = 0x80520000,
51 .num_devices = 8, 51 .num_devices = 9,
52 .device_list = (enum ppc_sys_devices[]) 52 .device_list = (enum ppc_sys_devices[])
53 { 53 {
54 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 54 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
55 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2, 55 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2,
56 MPC83xx_USB2_DR, MPC83xx_USB2_MPH 56 MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
57 }, 57 },
58 }, 58 },
59 { 59 {
60 .ppc_sys_name = "8347", 60 .ppc_sys_name = "8347",
61 .mask = 0xFFFF0000, 61 .mask = 0xFFFF0000,
62 .value = 0x80530000, 62 .value = 0x80530000,
63 .num_devices = 7, 63 .num_devices = 8,
64 .device_list = (enum ppc_sys_devices[]) 64 .device_list = (enum ppc_sys_devices[])
65 { 65 {
66 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 66 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
67 MPC83xx_IIC2, MPC83xx_DUART, 67 MPC83xx_IIC2, MPC83xx_DUART,
68 MPC83xx_USB2_DR, MPC83xx_USB2_MPH 68 MPC83xx_USB2_DR, MPC83xx_USB2_MPH, MPC83xx_MDIO
69 }, 69 },
70 }, 70 },
71 { 71 {
72 .ppc_sys_name = "8343E", 72 .ppc_sys_name = "8343E",
73 .mask = 0xFFFF0000, 73 .mask = 0xFFFF0000,
74 .value = 0x80540000, 74 .value = 0x80540000,
75 .num_devices = 7, 75 .num_devices = 8,
76 .device_list = (enum ppc_sys_devices[]) 76 .device_list = (enum ppc_sys_devices[])
77 { 77 {
78 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 78 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
79 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2, 79 MPC83xx_IIC2, MPC83xx_DUART, MPC83xx_SEC2,
80 MPC83xx_USB2_DR, 80 MPC83xx_USB2_DR, MPC83xx_MDIO
81 }, 81 },
82 }, 82 },
83 { 83 {
84 .ppc_sys_name = "8343", 84 .ppc_sys_name = "8343",
85 .mask = 0xFFFF0000, 85 .mask = 0xFFFF0000,
86 .value = 0x80550000, 86 .value = 0x80550000,
87 .num_devices = 6, 87 .num_devices = 7,
88 .device_list = (enum ppc_sys_devices[]) 88 .device_list = (enum ppc_sys_devices[])
89 { 89 {
90 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1, 90 MPC83xx_TSEC1, MPC83xx_TSEC2, MPC83xx_IIC1,
91 MPC83xx_IIC2, MPC83xx_DUART, 91 MPC83xx_IIC2, MPC83xx_DUART,
92 MPC83xx_USB2_DR, 92 MPC83xx_USB2_DR, MPC83xx_MDIO
93 }, 93 },
94 }, 94 },
95 { /* default match */ 95 { /* default match */
diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c
index 03b1fc9b9501..af4deace49e0 100644
--- a/arch/ppc/syslib/prom.c
+++ b/arch/ppc/syslib/prom.c
@@ -13,7 +13,6 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/string.h> 14#include <linux/string.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/version.h>
17#include <linux/threads.h> 16#include <linux/threads.h>
18#include <linux/spinlock.h> 17#include <linux/spinlock.h>
19#include <linux/ioport.h> 18#include <linux/ioport.h>
diff --git a/arch/ppc/syslib/prom_init.c b/arch/ppc/syslib/prom_init.c
index 7f15136830f4..df14422ae1c6 100644
--- a/arch/ppc/syslib/prom_init.c
+++ b/arch/ppc/syslib/prom_init.c
@@ -9,7 +9,6 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/string.h> 10#include <linux/string.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/version.h>
13#include <linux/threads.h> 12#include <linux/threads.h>
14#include <linux/spinlock.h> 13#include <linux/spinlock.h>
15#include <linux/ioport.h> 14#include <linux/ioport.h>
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
index 8fec27469802..715bc0e71e0f 100644
--- a/arch/ppc64/kernel/idle.c
+++ b/arch/ppc64/kernel/idle.c
@@ -34,15 +34,11 @@ extern void power4_idle(void);
34 34
35void default_idle(void) 35void default_idle(void)
36{ 36{
37 long oldval;
38 unsigned int cpu = smp_processor_id(); 37 unsigned int cpu = smp_processor_id();
38 set_thread_flag(TIF_POLLING_NRFLAG);
39 39
40 while (1) { 40 while (1) {
41 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 41 if (!need_resched()) {
42
43 if (!oldval) {
44 set_thread_flag(TIF_POLLING_NRFLAG);
45
46 while (!need_resched() && !cpu_is_offline(cpu)) { 42 while (!need_resched() && !cpu_is_offline(cpu)) {
47 ppc64_runlatch_off(); 43 ppc64_runlatch_off();
48 44
@@ -55,13 +51,12 @@ void default_idle(void)
55 } 51 }
56 52
57 HMT_medium(); 53 HMT_medium();
58 clear_thread_flag(TIF_POLLING_NRFLAG);
59 } else {
60 set_need_resched();
61 } 54 }
62 55
63 ppc64_runlatch_on(); 56 ppc64_runlatch_on();
57 preempt_enable_no_resched();
64 schedule(); 58 schedule();
59 preempt_disable();
65 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 60 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
66 cpu_die(); 61 cpu_die();
67 } 62 }
@@ -77,7 +72,9 @@ void native_idle(void)
77 72
78 if (need_resched()) { 73 if (need_resched()) {
79 ppc64_runlatch_on(); 74 ppc64_runlatch_on();
75 preempt_enable_no_resched();
80 schedule(); 76 schedule();
77 preempt_disable();
81 } 78 }
82 79
83 if (cpu_is_offline(smp_processor_id()) && 80 if (cpu_is_offline(smp_processor_id()) &&
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index c9f2f60cfa58..dee6ab54984d 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -592,12 +592,15 @@ int appldata_register_ops(struct appldata_ops *ops)
592 */ 592 */
593void appldata_unregister_ops(struct appldata_ops *ops) 593void appldata_unregister_ops(struct appldata_ops *ops)
594{ 594{
595 void *table;
595 spin_lock(&appldata_ops_lock); 596 spin_lock(&appldata_ops_lock);
596 unregister_sysctl_table(ops->sysctl_header);
597 list_del(&ops->list); 597 list_del(&ops->list);
598 kfree(ops->ctl_table); 598 /* at that point any incoming access will fail */
599 table = ops->ctl_table;
599 ops->ctl_table = NULL; 600 ops->ctl_table = NULL;
600 spin_unlock(&appldata_ops_lock); 601 spin_unlock(&appldata_ops_lock);
602 unregister_sysctl_table(ops->sysctl_header);
603 kfree(table);
601 P_INFO("%s-ops unregistered!\n", ops->name); 604 P_INFO("%s-ops unregistered!\n", ops->name);
602} 605}
603/********************** module-ops management <END> **************************/ 606/********************** module-ops management <END> **************************/
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index bc59282da762..896d39d0e4ce 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -486,7 +486,7 @@ out:
486 * - goto next entry in p_info 486 * - goto next entry in p_info
487 */ 487 */
488 488
489extern inline int 489static inline int
490debug_next_entry(file_private_info_t *p_info) 490debug_next_entry(file_private_info_t *p_info)
491{ 491{
492 debug_info_t *id; 492 debug_info_t *id;
@@ -800,7 +800,7 @@ debug_set_level(debug_info_t* id, int new_level)
800 * - set active entry to next in the ring buffer 800 * - set active entry to next in the ring buffer
801 */ 801 */
802 802
803extern inline void 803static inline void
804proceed_active_entry(debug_info_t * id) 804proceed_active_entry(debug_info_t * id)
805{ 805{
806 if ((id->active_entries[id->active_area] += id->entry_size) 806 if ((id->active_entries[id->active_area] += id->entry_size)
@@ -817,7 +817,7 @@ proceed_active_entry(debug_info_t * id)
817 * - set active area to next in the ring buffer 817 * - set active area to next in the ring buffer
818 */ 818 */
819 819
820extern inline void 820static inline void
821proceed_active_area(debug_info_t * id) 821proceed_active_area(debug_info_t * id)
822{ 822{
823 id->active_area++; 823 id->active_area++;
@@ -828,7 +828,7 @@ proceed_active_area(debug_info_t * id)
828 * get_active_entry: 828 * get_active_entry:
829 */ 829 */
830 830
831extern inline debug_entry_t* 831static inline debug_entry_t*
832get_active_entry(debug_info_t * id) 832get_active_entry(debug_info_t * id)
833{ 833{
834 return (debug_entry_t *) (((char *) id->areas[id->active_area] 834 return (debug_entry_t *) (((char *) id->areas[id->active_area]
@@ -841,7 +841,7 @@ get_active_entry(debug_info_t * id)
841 * - set timestamp, caller address, cpu number etc. 841 * - set timestamp, caller address, cpu number etc.
842 */ 842 */
843 843
844extern inline void 844static inline void
845debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, 845debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level,
846 int exception) 846 int exception)
847{ 847{
@@ -971,7 +971,7 @@ debug_entry_t
971 * counts arguments in format string for sprintf view 971 * counts arguments in format string for sprintf view
972 */ 972 */
973 973
974extern inline int 974static inline int
975debug_count_numargs(char *string) 975debug_count_numargs(char *string)
976{ 976{
977 int numargs=0; 977 int numargs=0;
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 9f3dff6c0b72..78b64fe5e7c2 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -99,15 +99,15 @@ void default_idle(void)
99{ 99{
100 int cpu, rc; 100 int cpu, rc;
101 101
102 /* CPU is going idle. */
103 cpu = smp_processor_id();
104
102 local_irq_disable(); 105 local_irq_disable();
103 if (need_resched()) { 106 if (need_resched()) {
104 local_irq_enable(); 107 local_irq_enable();
105 schedule(); 108 return;
106 return; 109 }
107 }
108 110
109 /* CPU is going idle. */
110 cpu = smp_processor_id();
111 rc = notifier_call_chain(&idle_chain, CPU_IDLE, (void *)(long) cpu); 111 rc = notifier_call_chain(&idle_chain, CPU_IDLE, (void *)(long) cpu);
112 if (rc != NOTIFY_OK && rc != NOTIFY_DONE) 112 if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
113 BUG(); 113 BUG();
@@ -120,7 +120,7 @@ void default_idle(void)
120 __ctl_set_bit(8, 15); 120 __ctl_set_bit(8, 15);
121 121
122#ifdef CONFIG_HOTPLUG_CPU 122#ifdef CONFIG_HOTPLUG_CPU
123 if (cpu_is_offline(smp_processor_id())) 123 if (cpu_is_offline(cpu))
124 cpu_die(); 124 cpu_die();
125#endif 125#endif
126 126
@@ -139,8 +139,14 @@ void default_idle(void)
139 139
140void cpu_idle(void) 140void cpu_idle(void)
141{ 141{
142 for (;;) 142 for (;;) {
143 default_idle(); 143 while (!need_resched())
144 default_idle();
145
146 preempt_enable_no_resched();
147 schedule();
148 preempt_disable();
149 }
144} 150}
145 151
146void show_regs(struct pt_regs *regs) 152void show_regs(struct pt_regs *regs)
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index e13c87b446b2..5856b3fda6bf 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -533,6 +533,7 @@ int __devinit start_secondary(void *cpuvoid)
533{ 533{
534 /* Setup the cpu */ 534 /* Setup the cpu */
535 cpu_init(); 535 cpu_init();
536 preempt_disable();
536 /* init per CPU timer */ 537 /* init per CPU timer */
537 init_cpu_timer(); 538 init_cpu_timer();
538#ifdef CONFIG_VIRT_TIMER 539#ifdef CONFIG_VIRT_TIMER
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 64e32da77754..fb2607c369ed 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -160,7 +160,7 @@ static void do_sigsegv(struct pt_regs *regs, unsigned long error_code,
160 * 11 Page translation -> Not present (nullification) 160 * 11 Page translation -> Not present (nullification)
161 * 3b Region third trans. -> Not present (nullification) 161 * 3b Region third trans. -> Not present (nullification)
162 */ 162 */
163extern inline void 163static inline void
164do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) 164do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
165{ 165{
166 struct task_struct *tsk; 166 struct task_struct *tsk;
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 6dce9d0b81f8..fd4f240b833d 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -51,28 +51,24 @@ void enable_hlt(void)
51 51
52EXPORT_SYMBOL(enable_hlt); 52EXPORT_SYMBOL(enable_hlt);
53 53
54void default_idle(void) 54void cpu_idle(void)
55{ 55{
56 /* endless idle loop with no priority at all */ 56 /* endless idle loop with no priority at all */
57 while (1) { 57 while (1) {
58 if (hlt_counter) { 58 if (hlt_counter) {
59 while (1) 59 while (!need_resched())
60 if (need_resched()) 60 cpu_relax();
61 break;
62 } else { 61 } else {
63 while (!need_resched()) 62 while (!need_resched())
64 cpu_sleep(); 63 cpu_sleep();
65 } 64 }
66 65
66 preempt_enable_no_resched();
67 schedule(); 67 schedule();
68 preempt_disable();
68 } 69 }
69} 70}
70 71
71void cpu_idle(void)
72{
73 default_idle();
74}
75
76void machine_restart(char * __unused) 72void machine_restart(char * __unused)
77{ 73{
78 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ 74 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 5ecefc02896a..59e49b18252c 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -112,7 +112,9 @@ int __cpu_up(unsigned int cpu)
112 112
113int start_secondary(void *unused) 113int start_secondary(void *unused)
114{ 114{
115 unsigned int cpu = smp_processor_id(); 115 unsigned int cpu;
116
117 cpu = smp_processor_id();
116 118
117 atomic_inc(&init_mm.mm_count); 119 atomic_inc(&init_mm.mm_count);
118 current->active_mm = &init_mm; 120 current->active_mm = &init_mm;
@@ -120,6 +122,7 @@ int start_secondary(void *unused)
120 smp_store_cpu_info(cpu); 122 smp_store_cpu_info(cpu);
121 123
122 __smp_slave_init(cpu); 124 __smp_slave_init(cpu);
125 preempt_disable();
123 per_cpu_trap_init(); 126 per_cpu_trap_init();
124 127
125 atomic_inc(&cpus_booted); 128 atomic_inc(&cpus_booted);
diff --git a/arch/sh64/kernel/process.c b/arch/sh64/kernel/process.c
index efde41c0cd66..b95d04141855 100644
--- a/arch/sh64/kernel/process.c
+++ b/arch/sh64/kernel/process.c
@@ -307,23 +307,19 @@ __setup("hlt", hlt_setup);
307 307
308static inline void hlt(void) 308static inline void hlt(void)
309{ 309{
310 if (hlt_counter)
311 return;
312
313 __asm__ __volatile__ ("sleep" : : : "memory"); 310 __asm__ __volatile__ ("sleep" : : : "memory");
314} 311}
315 312
316/* 313/*
317 * The idle loop on a uniprocessor SH.. 314 * The idle loop on a uniprocessor SH..
318 */ 315 */
319void default_idle(void) 316void cpu_idle(void)
320{ 317{
321 /* endless idle loop with no priority at all */ 318 /* endless idle loop with no priority at all */
322 while (1) { 319 while (1) {
323 if (hlt_counter) { 320 if (hlt_counter) {
324 while (1) 321 while (!need_resched())
325 if (need_resched()) 322 cpu_relax();
326 break;
327 } else { 323 } else {
328 local_irq_disable(); 324 local_irq_disable();
329 while (!need_resched()) { 325 while (!need_resched()) {
@@ -334,13 +330,11 @@ void default_idle(void)
334 } 330 }
335 local_irq_enable(); 331 local_irq_enable();
336 } 332 }
333 preempt_enable_no_resched();
337 schedule(); 334 schedule();
335 preempt_disable();
338 } 336 }
339}
340 337
341void cpu_idle(void)
342{
343 default_idle();
344} 338}
345 339
346void machine_restart(char * __unused) 340void machine_restart(char * __unused)
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 6a4ebc62193e..d7bfc61d2879 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -75,7 +75,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
75 { 9, 3, "Fujitsu or Weitek on-chip FPU"}, 75 { 9, 3, "Fujitsu or Weitek on-chip FPU"},
76}; 76};
77 77
78#define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info)) 78#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
79 79
80struct cpu_iu_info linux_sparc_chips[] = { 80struct cpu_iu_info linux_sparc_chips[] = {
81 /* Sun4/100, 4/200, SLC */ 81 /* Sun4/100, 4/200, SLC */
@@ -120,7 +120,7 @@ struct cpu_iu_info linux_sparc_chips[] = {
120 { 0xf, 0, "UNKNOWN CPU-VENDOR/TYPE"}, 120 { 0xf, 0, "UNKNOWN CPU-VENDOR/TYPE"},
121}; 121};
122 122
123#define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info)) 123#define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips)
124 124
125char *sparc_cpu_type; 125char *sparc_cpu_type;
126char *sparc_fpu_type; 126char *sparc_fpu_type;
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 25e31d5ec99b..cccfc12802ed 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -143,7 +143,7 @@ static struct pcic_ca2irq pcic_i_jk[] = {
143 * as several PROMs may be installed on the same physical board. 143 * as several PROMs may be installed on the same physical board.
144 */ 144 */
145#define SN2L_INIT(name, map) \ 145#define SN2L_INIT(name, map) \
146 { name, map, sizeof(map)/sizeof(struct pcic_ca2irq) } 146 { name, map, ARRAY_SIZE(map) }
147 147
148static struct pcic_sn2list pcic_known_sysnames[] = { 148static struct pcic_sn2list pcic_known_sysnames[] = {
149 SN2L_INIT("SUNW,JavaEngine1", pcic_i_je1a), /* JE1, PROM 2.32 */ 149 SN2L_INIT("SUNW,JavaEngine1", pcic_i_je1a), /* JE1, PROM 2.32 */
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 29e72b57d4fd..ea8647411462 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -67,13 +67,6 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
67struct task_struct *last_task_used_math = NULL; 67struct task_struct *last_task_used_math = NULL;
68struct thread_info *current_set[NR_CPUS]; 68struct thread_info *current_set[NR_CPUS];
69 69
70/*
71 * default_idle is new in 2.5. XXX Review, currently stolen from sparc64.
72 */
73void default_idle(void)
74{
75}
76
77#ifndef CONFIG_SMP 70#ifndef CONFIG_SMP
78 71
79#define SUN4C_FAULT_HIGH 100 72#define SUN4C_FAULT_HIGH 100
@@ -92,12 +85,11 @@ void cpu_idle(void)
92 static unsigned long fps; 85 static unsigned long fps;
93 unsigned long now; 86 unsigned long now;
94 unsigned long faults; 87 unsigned long faults;
95 unsigned long flags;
96 88
97 extern unsigned long sun4c_kernel_faults; 89 extern unsigned long sun4c_kernel_faults;
98 extern void sun4c_grow_kernel_ring(void); 90 extern void sun4c_grow_kernel_ring(void);
99 91
100 local_irq_save(flags); 92 local_irq_disable();
101 now = jiffies; 93 now = jiffies;
102 count -= (now - last_jiffies); 94 count -= (now - last_jiffies);
103 last_jiffies = now; 95 last_jiffies = now;
@@ -113,14 +105,19 @@ void cpu_idle(void)
113 sun4c_grow_kernel_ring(); 105 sun4c_grow_kernel_ring();
114 } 106 }
115 } 107 }
116 local_irq_restore(flags); 108 local_irq_enable();
117 } 109 }
118 110
119 while((!need_resched()) && pm_idle) { 111 if (pm_idle) {
120 (*pm_idle)(); 112 while (!need_resched())
113 (*pm_idle)();
114 } else {
115 while (!need_resched())
116 cpu_relax();
121 } 117 }
122 118 preempt_enable_no_resched();
123 schedule(); 119 schedule();
120 preempt_disable();
124 check_pgt_cache(); 121 check_pgt_cache();
125 } 122 }
126} 123}
@@ -130,13 +127,15 @@ void cpu_idle(void)
130/* This is being executed in task 0 'user space'. */ 127/* This is being executed in task 0 'user space'. */
131void cpu_idle(void) 128void cpu_idle(void)
132{ 129{
130 set_thread_flag(TIF_POLLING_NRFLAG);
133 /* endless idle loop with no priority at all */ 131 /* endless idle loop with no priority at all */
134 while(1) { 132 while(1) {
135 if(need_resched()) { 133 while (!need_resched())
136 schedule(); 134 cpu_relax();
137 check_pgt_cache(); 135 preempt_enable_no_resched();
138 } 136 schedule();
139 barrier(); /* or else gcc optimizes... */ 137 preempt_disable();
138 check_pgt_cache();
140 } 139 }
141} 140}
142 141
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 2bbd53f3cafb..9eeed3347df3 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -33,8 +33,6 @@
33#include <asm/kdebug.h> 33#include <asm/kdebug.h>
34#include <asm/uaccess.h> 34#include <asm/uaccess.h>
35 35
36#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
37
38extern int prom_node_root; 36extern int prom_node_root;
39 37
40/* At boot time we determine these two values necessary for setting 38/* At boot time we determine these two values necessary for setting
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c
index 77ef5df4e5a7..00eed88ef2e8 100644
--- a/arch/sparc64/kernel/cpu.c
+++ b/arch/sparc64/kernel/cpu.c
@@ -43,7 +43,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
43 { 0x3e, 0x22, 0, "UltraSparc IIIi+ integrated FPU"}, 43 { 0x3e, 0x22, 0, "UltraSparc IIIi+ integrated FPU"},
44}; 44};
45 45
46#define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info)) 46#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
47 47
48struct cpu_iu_info linux_sparc_chips[] = { 48struct cpu_iu_info linux_sparc_chips[] = {
49 { 0x17, 0x10, "TI UltraSparc I (SpitFire)"}, 49 { 0x17, 0x10, "TI UltraSparc I (SpitFire)"},
@@ -59,7 +59,7 @@ struct cpu_iu_info linux_sparc_chips[] = {
59 { 0x3e, 0x22, "TI UltraSparc IIIi+ (Serrano)"}, 59 { 0x3e, 0x22, "TI UltraSparc IIIi+ (Serrano)"},
60}; 60};
61 61
62#define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info)) 62#define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips)
63 63
64char *sparc_cpu_type = "cpu-oops"; 64char *sparc_cpu_type = "cpu-oops";
65char *sparc_fpu_type = "fpu-oops"; 65char *sparc_fpu_type = "fpu-oops";
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index 92e26304de90..e62214354bb5 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -92,10 +92,8 @@ static int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg)
92 return sys_ioctl (fd, FBIOSCURSOR, (unsigned long)p); 92 return sys_ioctl (fd, FBIOSCURSOR, (unsigned long)p);
93} 93}
94 94
95typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
96
97#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) 95#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl)
98#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL }, 96#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
99#define IOCTL_TABLE_START \ 97#define IOCTL_TABLE_START \
100 struct ioctl_trans ioctl_start[] = { 98 struct ioctl_trans ioctl_start[] = {
101#define IOCTL_TABLE_END \ 99#define IOCTL_TABLE_END \
@@ -116,8 +114,6 @@ COMPATIBLE_IOCTL(FBIOGCURPOS)
116COMPATIBLE_IOCTL(FBIOGCURMAX) 114COMPATIBLE_IOCTL(FBIOGCURMAX)
117/* Little k */ 115/* Little k */
118/* Little v, the video4linux ioctls */ 116/* Little v, the video4linux ioctls */
119COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
120COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
121/* And these ioctls need translation */ 117/* And these ioctls need translation */
122/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */ 118/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
123HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap) 119HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap)
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 7d10b0397091..02f9dec1d459 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -74,7 +74,9 @@ void cpu_idle(void)
74 while (!need_resched()) 74 while (!need_resched())
75 barrier(); 75 barrier();
76 76
77 preempt_enable_no_resched();
77 schedule(); 78 schedule();
79 preempt_disable();
78 check_pgt_cache(); 80 check_pgt_cache();
79 } 81 }
80} 82}
@@ -83,21 +85,31 @@ void cpu_idle(void)
83 85
84/* 86/*
85 * the idle loop on a UltraMultiPenguin... 87 * the idle loop on a UltraMultiPenguin...
88 *
89 * TIF_POLLING_NRFLAG is set because we do not sleep the cpu
90 * inside of the idler task, so an interrupt is not needed
91 * to get a clean fast response.
92 *
93 * XXX Reverify this assumption... -DaveM
94 *
95 * Addendum: We do want it to do something for the signal
96 * delivery case, we detect that by just seeing
97 * if we are trying to send this to an idler or not.
86 */ 98 */
87#define idle_me_harder() (cpu_data(smp_processor_id()).idle_volume += 1)
88#define unidle_me() (cpu_data(smp_processor_id()).idle_volume = 0)
89void cpu_idle(void) 99void cpu_idle(void)
90{ 100{
101 cpuinfo_sparc *cpuinfo = &local_cpu_data();
91 set_thread_flag(TIF_POLLING_NRFLAG); 102 set_thread_flag(TIF_POLLING_NRFLAG);
103
92 while(1) { 104 while(1) {
93 if (need_resched()) { 105 if (need_resched()) {
94 unidle_me(); 106 cpuinfo->idle_volume = 0;
95 clear_thread_flag(TIF_POLLING_NRFLAG); 107 preempt_enable_no_resched();
96 schedule(); 108 schedule();
97 set_thread_flag(TIF_POLLING_NRFLAG); 109 preempt_disable();
98 check_pgt_cache(); 110 check_pgt_cache();
99 } 111 }
100 idle_me_harder(); 112 cpuinfo->idle_volume++;
101 113
102 /* The store ordering is so that IRQ handlers on 114 /* The store ordering is so that IRQ handlers on
103 * other cpus see our increasing idleness for the buddy 115 * other cpus see our increasing idleness for the buddy
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index e09ddf927655..96b825055668 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -790,7 +790,7 @@ static unsigned long sysio_irq_offsets[] = {
790 790
791#undef bogon 791#undef bogon
792 792
793#define NUM_SYSIO_OFFSETS (sizeof(sysio_irq_offsets) / sizeof(sysio_irq_offsets[0])) 793#define NUM_SYSIO_OFFSETS ARRAY_SIZE(sysio_irq_offsets)
794 794
795/* Convert Interrupt Mapping register pointer to associated 795/* Convert Interrupt Mapping register pointer to associated
796 * Interrupt Clear register pointer, SYSIO specific version. 796 * Interrupt Clear register pointer, SYSIO specific version.
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 5d90ee9aebf1..797a65493fb8 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -168,6 +168,9 @@ void __init smp_callin(void)
168 rmb(); 168 rmb();
169 169
170 cpu_set(cpuid, cpu_online_map); 170 cpu_set(cpuid, cpu_online_map);
171
172 /* idle thread is expected to have preempt disabled */
173 preempt_disable();
171} 174}
172 175
173void cpu_panic(void) 176void cpu_panic(void)
@@ -1149,20 +1152,9 @@ void __init smp_cpus_done(unsigned int max_cpus)
1149 (bogosum/(5000/HZ))%100); 1152 (bogosum/(5000/HZ))%100);
1150} 1153}
1151 1154
1152/* This needn't do anything as we do not sleep the cpu
1153 * inside of the idler task, so an interrupt is not needed
1154 * to get a clean fast response.
1155 *
1156 * XXX Reverify this assumption... -DaveM
1157 *
1158 * Addendum: We do want it to do something for the signal
1159 * delivery case, we detect that by just seeing
1160 * if we are trying to send this to an idler or not.
1161 */
1162void smp_send_reschedule(int cpu) 1155void smp_send_reschedule(int cpu)
1163{ 1156{
1164 if (cpu_data(cpu).idle_volume == 0) 1157 smp_receive_signal(cpu);
1165 smp_receive_signal(cpu);
1166} 1158}
1167 1159
1168/* This is a nop because we capture all other cpus 1160/* This is a nop because we capture all other cpus
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 31fbc67719a1..6f0539aa44d0 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -30,8 +30,6 @@
30#include <asm/sections.h> 30#include <asm/sections.h>
31#include <asm/kdebug.h> 31#include <asm/kdebug.h>
32 32
33#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
34
35/* 33/*
36 * To debug kernel to catch accesses to certain virtual/physical addresses. 34 * To debug kernel to catch accesses to certain virtual/physical addresses.
37 * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints. 35 * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints.
@@ -109,7 +107,7 @@ static void bad_kernel_pc(struct pt_regs *regs)
109 * this. Additionally, to prevent kswapd from ripping ptes from 107 * this. Additionally, to prevent kswapd from ripping ptes from
110 * under us, raise interrupts around the time that we look at the 108 * under us, raise interrupts around the time that we look at the
111 * pte, kswapd will have to wait to get his smp ipi response from 109 * pte, kswapd will have to wait to get his smp ipi response from
112 * us. This saves us having to get page_table_lock. 110 * us. vmtruncate likewise. This saves us having to get pte lock.
113 */ 111 */
114static unsigned int get_user_insn(unsigned long tpc) 112static unsigned int get_user_insn(unsigned long tpc)
115{ 113{
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index fe865d9a3721..4cf31a2ae19c 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -243,34 +243,18 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
243 return err; 243 return err;
244} 244}
245 245
246static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 246static void uml_net_get_drvinfo(struct net_device *dev,
247{ 247 struct ethtool_drvinfo *info)
248 static const struct ethtool_drvinfo info = { 248{
249 .cmd = ETHTOOL_GDRVINFO, 249 strcpy(info->driver, DRIVER_NAME);
250 .driver = DRIVER_NAME, 250 strcpy(info->version, "42");
251 .version = "42",
252 };
253 void *useraddr;
254 u32 ethcmd;
255
256 switch (cmd) {
257 case SIOCETHTOOL:
258 useraddr = ifr->ifr_data;
259 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
260 return -EFAULT;
261 switch (ethcmd) {
262 case ETHTOOL_GDRVINFO:
263 if (copy_to_user(useraddr, &info, sizeof(info)))
264 return -EFAULT;
265 return 0;
266 default:
267 return -EOPNOTSUPP;
268 }
269 default:
270 return -EINVAL;
271 }
272} 251}
273 252
253static struct ethtool_ops uml_net_ethtool_ops = {
254 .get_drvinfo = uml_net_get_drvinfo,
255 .get_link = ethtool_op_get_link,
256};
257
274void uml_net_user_timer_expire(unsigned long _conn) 258void uml_net_user_timer_expire(unsigned long _conn)
275{ 259{
276#ifdef undef 260#ifdef undef
@@ -359,7 +343,7 @@ static int eth_configure(int n, void *init, char *mac,
359 dev->tx_timeout = uml_net_tx_timeout; 343 dev->tx_timeout = uml_net_tx_timeout;
360 dev->set_mac_address = uml_net_set_mac; 344 dev->set_mac_address = uml_net_set_mac;
361 dev->change_mtu = uml_net_change_mtu; 345 dev->change_mtu = uml_net_change_mtu;
362 dev->do_ioctl = uml_net_ioctl; 346 dev->ethtool_ops = &uml_net_ethtool_ops;
363 dev->watchdog_timeo = (HZ >> 1); 347 dev->watchdog_timeo = (HZ >> 1);
364 dev->irq = UM_ETH_IRQ; 348 dev->irq = UM_ETH_IRQ;
365 349
diff --git a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c
index 9c708c32c1f0..39cf247cdae4 100644
--- a/arch/v850/kernel/process.c
+++ b/arch/v850/kernel/process.c
@@ -36,11 +36,8 @@ extern void ret_from_fork (void);
36/* The idle loop. */ 36/* The idle loop. */
37void default_idle (void) 37void default_idle (void)
38{ 38{
39 while (1) { 39 while (! need_resched ())
40 while (! need_resched ()) 40 asm ("halt; nop; nop; nop; nop; nop" ::: "cc");
41 asm ("halt; nop; nop; nop; nop; nop" ::: "cc");
42 schedule ();
43 }
44} 41}
45 42
46void (*idle)(void) = default_idle; 43void (*idle)(void) = default_idle;
@@ -54,7 +51,14 @@ void (*idle)(void) = default_idle;
54void cpu_idle (void) 51void cpu_idle (void)
55{ 52{
56 /* endless idle loop with no priority at all */ 53 /* endless idle loop with no priority at all */
57 (*idle) (); 54 while (1) {
55 while (!need_resched())
56 (*idle) ();
57
58 preempt_enable_no_resched();
59 schedule();
60 preempt_disable();
61 }
58} 62}
59 63
60/* 64/*
diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
index 4ba0e293d5e5..e335bd0b637d 100644
--- a/arch/x86_64/ia32/ia32_ioctl.c
+++ b/arch/x86_64/ia32/ia32_ioctl.c
@@ -64,12 +64,6 @@ struct ioctl_trans ioctl_start[] = {
64#include <linux/compat_ioctl.h> 64#include <linux/compat_ioctl.h>
65#define DECLARES 65#define DECLARES
66#include "compat_ioctl.c" 66#include "compat_ioctl.c"
67COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS)
68COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
69COMPATIBLE_IOCTL(BLKRASET)
70COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */
71COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */
72COMPATIBLE_IOCTL(FIOQSIZE)
73 67
74/* And these ioctls need translation */ 68/* And these ioctls need translation */
75/* realtime device */ 69/* realtime device */
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index b5a89c0bdf59..59be85d9a4bc 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -86,12 +86,22 @@ EXPORT_SYMBOL(enable_hlt);
86 */ 86 */
87void default_idle(void) 87void default_idle(void)
88{ 88{
89 local_irq_enable();
90
89 if (!atomic_read(&hlt_counter)) { 91 if (!atomic_read(&hlt_counter)) {
90 local_irq_disable(); 92 clear_thread_flag(TIF_POLLING_NRFLAG);
91 if (!need_resched()) 93 smp_mb__after_clear_bit();
92 safe_halt(); 94 while (!need_resched()) {
93 else 95 local_irq_disable();
94 local_irq_enable(); 96 if (!need_resched())
97 safe_halt();
98 else
99 local_irq_enable();
100 }
101 set_thread_flag(TIF_POLLING_NRFLAG);
102 } else {
103 while (!need_resched())
104 cpu_relax();
95 } 105 }
96} 106}
97 107
@@ -102,30 +112,16 @@ void default_idle(void)
102 */ 112 */
103static void poll_idle (void) 113static void poll_idle (void)
104{ 114{
105 int oldval;
106
107 local_irq_enable(); 115 local_irq_enable();
108 116
109 /* 117 asm volatile(
110 * Deal with another CPU just having chosen a thread to 118 "2:"
111 * run here: 119 "testl %0,%1;"
112 */ 120 "rep; nop;"
113 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 121 "je 2b;"
114 122 : :
115 if (!oldval) { 123 "i" (_TIF_NEED_RESCHED),
116 set_thread_flag(TIF_POLLING_NRFLAG); 124 "m" (current_thread_info()->flags));
117 asm volatile(
118 "2:"
119 "testl %0,%1;"
120 "rep; nop;"
121 "je 2b;"
122 : :
123 "i" (_TIF_NEED_RESCHED),
124 "m" (current_thread_info()->flags));
125 clear_thread_flag(TIF_POLLING_NRFLAG);
126 } else {
127 set_need_resched();
128 }
129} 125}
130 126
131void cpu_idle_wait(void) 127void cpu_idle_wait(void)
@@ -187,6 +183,8 @@ static inline void play_dead(void)
187 */ 183 */
188void cpu_idle (void) 184void cpu_idle (void)
189{ 185{
186 set_thread_flag(TIF_POLLING_NRFLAG);
187
190 /* endless idle loop with no priority at all */ 188 /* endless idle loop with no priority at all */
191 while (1) { 189 while (1) {
192 while (!need_resched()) { 190 while (!need_resched()) {
@@ -204,7 +202,9 @@ void cpu_idle (void)
204 idle(); 202 idle();
205 } 203 }
206 204
205 preempt_enable_no_resched();
207 schedule(); 206 schedule();
207 preempt_disable();
208 } 208 }
209} 209}
210 210
@@ -219,15 +219,12 @@ static void mwait_idle(void)
219{ 219{
220 local_irq_enable(); 220 local_irq_enable();
221 221
222 if (!need_resched()) { 222 while (!need_resched()) {
223 set_thread_flag(TIF_POLLING_NRFLAG); 223 __monitor((void *)&current_thread_info()->flags, 0, 0);
224 do { 224 smp_mb();
225 __monitor((void *)&current_thread_info()->flags, 0, 0); 225 if (need_resched())
226 if (need_resched()) 226 break;
227 break; 227 __mwait(0, 0);
228 __mwait(0, 0);
229 } while (!need_resched());
230 clear_thread_flag(TIF_POLLING_NRFLAG);
231 } 228 }
232} 229}
233 230
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 4b5b088ec102..c4e59bbdc187 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -472,6 +472,7 @@ void __cpuinit start_secondary(void)
472 * things done here to the most necessary things. 472 * things done here to the most necessary things.
473 */ 473 */
474 cpu_init(); 474 cpu_init();
475 preempt_disable();
475 smp_callin(); 476 smp_callin();
476 477
477 /* otherwise gcc will move up the smp_processor_id before the cpu_init */ 478 /* otherwise gcc will move up the smp_processor_id before the cpu_init */
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 08ef6d82ee51..6a44b54ae817 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -96,8 +96,9 @@ void cpu_idle(void)
96 while (1) { 96 while (1) {
97 while (!need_resched()) 97 while (!need_resched())
98 platform_idle(); 98 platform_idle();
99 preempt_enable(); 99 preempt_enable_no_resched();
100 schedule(); 100 schedule();
101 preempt_disable();
101 } 102 }
102} 103}
103 104
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
index 0682ffd38175..96b9bb4a478d 100644
--- a/arch/xtensa/platform-iss/network.c
+++ b/arch/xtensa/platform-iss/network.c
@@ -611,38 +611,6 @@ static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
611 return -EINVAL; 611 return -EINVAL;
612} 612}
613 613
614static int iss_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
615{
616#if 0
617 static const struct ethtool_drvinfo info = {
618 .cmd = ETHTOOL_GDRVINFO,
619 .driver = DRIVER_NAME,
620 .version = "42",
621 };
622 void *useraddr;
623 u32 ethcmd;
624
625 switch (cmd) {
626 case SIOCETHTOOL:
627 useraddr = ifr->ifr_data;
628 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
629 return -EFAULT;
630
631 switch (ethcmd) {
632 case ETHTOOL_GDRVINFO:
633 if (copy_to_user(useraddr, &info, sizeof(info)))
634 return -EFAULT;
635 return 0;
636 default:
637 return -EOPNOTSUPP;
638 }
639 default:
640 return -EINVAL;
641 }
642#endif
643 return -EINVAL;
644}
645
646void iss_net_user_timer_expire(unsigned long _conn) 614void iss_net_user_timer_expire(unsigned long _conn)
647{ 615{
648} 616}
@@ -730,7 +698,6 @@ static int iss_net_configure(int index, char *init)
730 dev->tx_timeout = iss_net_tx_timeout; 698 dev->tx_timeout = iss_net_tx_timeout;
731 dev->set_mac_address = iss_net_set_mac; 699 dev->set_mac_address = iss_net_set_mac;
732 dev->change_mtu = iss_net_change_mtu; 700 dev->change_mtu = iss_net_change_mtu;
733 dev->do_ioctl = iss_net_ioctl;
734 dev->watchdog_timeo = (HZ >> 1); 701 dev->watchdog_timeo = (HZ >> 1);
735 dev->irq = -1; 702 dev->irq = -1;
736 703
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 161db4acfb91..573b6a97bb1f 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -167,6 +167,19 @@ acpi_processor_power_activate(struct acpi_processor *pr,
167 return; 167 return;
168} 168}
169 169
170static void acpi_safe_halt(void)
171{
172 int polling = test_thread_flag(TIF_POLLING_NRFLAG);
173 if (polling) {
174 clear_thread_flag(TIF_POLLING_NRFLAG);
175 smp_mb__after_clear_bit();
176 }
177 if (!need_resched())
178 safe_halt();
179 if (polling)
180 set_thread_flag(TIF_POLLING_NRFLAG);
181}
182
170static atomic_t c3_cpu_count; 183static atomic_t c3_cpu_count;
171 184
172static void acpi_processor_idle(void) 185static void acpi_processor_idle(void)
@@ -177,7 +190,7 @@ static void acpi_processor_idle(void)
177 int sleep_ticks = 0; 190 int sleep_ticks = 0;
178 u32 t1, t2 = 0; 191 u32 t1, t2 = 0;
179 192
180 pr = processors[raw_smp_processor_id()]; 193 pr = processors[smp_processor_id()];
181 if (!pr) 194 if (!pr)
182 return; 195 return;
183 196
@@ -197,8 +210,13 @@ static void acpi_processor_idle(void)
197 } 210 }
198 211
199 cx = pr->power.state; 212 cx = pr->power.state;
200 if (!cx) 213 if (!cx) {
201 goto easy_out; 214 if (pm_idle_save)
215 pm_idle_save();
216 else
217 acpi_safe_halt();
218 return;
219 }
202 220
203 /* 221 /*
204 * Check BM Activity 222 * Check BM Activity
@@ -278,7 +296,8 @@ static void acpi_processor_idle(void)
278 if (pm_idle_save) 296 if (pm_idle_save)
279 pm_idle_save(); 297 pm_idle_save();
280 else 298 else
281 safe_halt(); 299 acpi_safe_halt();
300
282 /* 301 /*
283 * TBD: Can't get time duration while in C1, as resumes 302 * TBD: Can't get time duration while in C1, as resumes
284 * go to an ISR rather than here. Need to instrument 303 * go to an ISR rather than here. Need to instrument
@@ -414,16 +433,6 @@ static void acpi_processor_idle(void)
414 */ 433 */
415 if (next_state != pr->power.state) 434 if (next_state != pr->power.state)
416 acpi_processor_power_activate(pr, next_state); 435 acpi_processor_power_activate(pr, next_state);
417
418 return;
419
420 easy_out:
421 /* do C1 instead of busy loop */
422 if (pm_idle_save)
423 pm_idle_save();
424 else
425 safe_halt();
426 return;
427} 436}
428 437
429static int acpi_processor_set_power_policy(struct acpi_processor *pr) 438static int acpi_processor_set_power_policy(struct acpi_processor *pr)
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 1468e8cf712d..0acbfff8ad28 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1816,7 +1816,6 @@ out_blkdev:
1816} 1816}
1817 1817
1818#ifdef MODULE 1818#ifdef MODULE
1819#include <linux/version.h>
1820 1819
1821int init_module(void) 1820int init_module(void)
1822{ 1821{
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 5eadbb9d4d71..28002de783b6 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3714,6 +3714,12 @@ static int floppy_open(struct inode *inode, struct file *filp)
3714 USETF(FD_VERIFY); 3714 USETF(FD_VERIFY);
3715 } 3715 }
3716 3716
3717 /* set underlying gendisk policy to reflect real ro/rw status */
3718 if (UTESTF(FD_DISK_WRITABLE))
3719 inode->i_bdev->bd_disk->policy = 0;
3720 else
3721 inode->i_bdev->bd_disk->policy = 1;
3722
3717 if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL))) 3723 if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3718 goto out2; 3724 goto out2;
3719 3725
@@ -3770,8 +3776,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
3770 /* Allow ioctls if we have write-permissions even if read-only open. 3776 /* Allow ioctls if we have write-permissions even if read-only open.
3771 * Needed so that programs such as fdrawcmd still can work on write 3777 * Needed so that programs such as fdrawcmd still can work on write
3772 * protected disks */ 3778 * protected disks */
3773 if (filp->f_mode & 2 3779 if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
3774 || permission(filp->f_dentry->d_inode, 2, NULL) == 0)
3775 filp->private_data = (void *)8; 3780 filp->private_data = (void *)8;
3776 3781
3777 if (UFDCS->rawcmd == 1) 3782 if (UFDCS->rawcmd == 1)
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index a280e679b1ca..59e5982a5db3 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -511,14 +511,11 @@ static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio)
511 */ 511 */
512static void pkt_iosched_process_queue(struct pktcdvd_device *pd) 512static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
513{ 513{
514 request_queue_t *q;
515 514
516 if (atomic_read(&pd->iosched.attention) == 0) 515 if (atomic_read(&pd->iosched.attention) == 0)
517 return; 516 return;
518 atomic_set(&pd->iosched.attention, 0); 517 atomic_set(&pd->iosched.attention, 0);
519 518
520 q = bdev_get_queue(pd->bdev);
521
522 for (;;) { 519 for (;;) {
523 struct bio *bio; 520 struct bio *bio;
524 int reads_queued, writes_queued; 521 int reads_queued, writes_queued;
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index ecbeb7eaba8e..394796315adc 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -84,8 +84,8 @@ struct bpa10x_data {
84 84
85struct hci_vendor_hdr { 85struct hci_vendor_hdr {
86 __u8 type; 86 __u8 type;
87 __u16 snum; 87 __le16 snum;
88 __u16 dlen; 88 __le16 dlen;
89} __attribute__ ((packed)); 89} __attribute__ ((packed));
90 90
91static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count) 91static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count)
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index f510b25b2c59..057cb2b6e6d1 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -65,6 +65,7 @@
65#endif 65#endif
66 66
67static int ignore = 0; 67static int ignore = 0;
68static int ignore_dga = 0;
68static int ignore_csr = 0; 69static int ignore_csr = 0;
69static int ignore_sniffer = 0; 70static int ignore_sniffer = 0;
70static int reset = 0; 71static int reset = 0;
@@ -841,6 +842,9 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
841 if (ignore || id->driver_info & HCI_IGNORE) 842 if (ignore || id->driver_info & HCI_IGNORE)
842 return -ENODEV; 843 return -ENODEV;
843 844
845 if (ignore_dga && id->driver_info & HCI_DIGIANSWER)
846 return -ENODEV;
847
844 if (ignore_csr && id->driver_info & HCI_CSR) 848 if (ignore_csr && id->driver_info & HCI_CSR)
845 return -ENODEV; 849 return -ENODEV;
846 850
@@ -1070,6 +1074,9 @@ module_exit(hci_usb_exit);
1070module_param(ignore, bool, 0644); 1074module_param(ignore, bool, 0644);
1071MODULE_PARM_DESC(ignore, "Ignore devices from the matching table"); 1075MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
1072 1076
1077module_param(ignore_dga, bool, 0644);
1078MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
1079
1073module_param(ignore_csr, bool, 0644); 1080module_param(ignore_csr, bool, 0644);
1074MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001"); 1081MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
1075 1082
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 73f333f491bd..27bca34b4a65 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -147,6 +147,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
147 printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); 147 printk(KERN_ERR PFX "unable to get memory for scratch page.\n");
148 return -ENOMEM; 148 return -ENOMEM;
149 } 149 }
150 flush_agp_mappings();
150 151
151 bridge->scratch_page_real = virt_to_gart(addr); 152 bridge->scratch_page_real = virt_to_gart(addr);
152 bridge->scratch_page = 153 bridge->scratch_page =
@@ -187,9 +188,11 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
187 return 0; 188 return 0;
188 189
189err_out: 190err_out:
190 if (bridge->driver->needs_scratch_page) 191 if (bridge->driver->needs_scratch_page) {
191 bridge->driver->agp_destroy_page( 192 bridge->driver->agp_destroy_page(
192 gart_to_virt(bridge->scratch_page_real)); 193 gart_to_virt(bridge->scratch_page_real));
194 flush_agp_mappings();
195 }
193 if (got_gatt) 196 if (got_gatt)
194 bridge->driver->free_gatt_table(bridge); 197 bridge->driver->free_gatt_table(bridge);
195 if (got_keylist) { 198 if (got_keylist) {
@@ -211,9 +214,11 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
211 bridge->key_list = NULL; 214 bridge->key_list = NULL;
212 215
213 if (bridge->driver->agp_destroy_page && 216 if (bridge->driver->agp_destroy_page &&
214 bridge->driver->needs_scratch_page) 217 bridge->driver->needs_scratch_page) {
215 bridge->driver->agp_destroy_page( 218 bridge->driver->agp_destroy_page(
216 gart_to_virt(bridge->scratch_page_real)); 219 gart_to_virt(bridge->scratch_page_real));
220 flush_agp_mappings();
221 }
217} 222}
218 223
219/* When we remove the global variable agp_bridge from all drivers 224/* When we remove the global variable agp_bridge from all drivers
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index c4a38715c6f9..5567ce8d72b0 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -57,7 +57,8 @@ int map_page_into_agp(struct page *page)
57{ 57{
58 int i; 58 int i;
59 i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE); 59 i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE);
60 global_flush_tlb(); 60 /* Caller's responsibility to call global_flush_tlb() for
61 * performance reasons */
61 return i; 62 return i;
62} 63}
63EXPORT_SYMBOL_GPL(map_page_into_agp); 64EXPORT_SYMBOL_GPL(map_page_into_agp);
@@ -66,7 +67,8 @@ int unmap_page_from_agp(struct page *page)
66{ 67{
67 int i; 68 int i;
68 i = change_page_attr(page, 1, PAGE_KERNEL); 69 i = change_page_attr(page, 1, PAGE_KERNEL);
69 global_flush_tlb(); 70 /* Caller's responsibility to call global_flush_tlb() for
71 * performance reasons */
70 return i; 72 return i;
71} 73}
72EXPORT_SYMBOL_GPL(unmap_page_from_agp); 74EXPORT_SYMBOL_GPL(unmap_page_from_agp);
@@ -153,6 +155,7 @@ void agp_free_memory(struct agp_memory *curr)
153 for (i = 0; i < curr->page_count; i++) { 155 for (i = 0; i < curr->page_count; i++) {
154 curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); 156 curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]));
155 } 157 }
158 flush_agp_mappings();
156 } 159 }
157 agp_free_key(curr->key); 160 agp_free_key(curr->key);
158 vfree(curr->memory); 161 vfree(curr->memory);
@@ -210,7 +213,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
210 new->memory[i] = virt_to_gart(addr); 213 new->memory[i] = virt_to_gart(addr);
211 new->page_count++; 214 new->page_count++;
212 } 215 }
213 new->bridge = bridge; 216 new->bridge = bridge;
214 217
215 flush_agp_mappings(); 218 flush_agp_mappings();
216 219
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 58944cd271ea..34a444658ffe 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -111,8 +111,10 @@ static int i460_fetch_size (void)
111 111
112 if (i460.io_page_shift != I460_IO_PAGE_SHIFT) { 112 if (i460.io_page_shift != I460_IO_PAGE_SHIFT) {
113 printk(KERN_ERR PFX 113 printk(KERN_ERR PFX
114 "I/O (GART) page-size %ZuKB doesn't match expected size %ZuKB\n", 114 "I/O (GART) page-size %luKB doesn't match expected "
115 1UL << (i460.io_page_shift - 10), 1UL << (I460_IO_PAGE_SHIFT)); 115 "size %luKB\n",
116 1UL << (i460.io_page_shift - 10),
117 1UL << (I460_IO_PAGE_SHIFT));
116 return 0; 118 return 0;
117 } 119 }
118 120
@@ -514,9 +516,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
514{ 516{
515 void *page; 517 void *page;
516 518
517 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) 519 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
518 page = agp_generic_alloc_page(agp_bridge); 520 page = agp_generic_alloc_page(agp_bridge);
519 else 521 global_flush_tlb();
522 } else
520 /* Returning NULL would cause problems */ 523 /* Returning NULL would cause problems */
521 /* AK: really dubious code. */ 524 /* AK: really dubious code. */
522 page = (void *)~0UL; 525 page = (void *)~0UL;
@@ -525,8 +528,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
525 528
526static void i460_destroy_page (void *page) 529static void i460_destroy_page (void *page)
527{ 530{
528 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) 531 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
529 agp_generic_destroy_page(page); 532 agp_generic_destroy_page(page);
533 global_flush_tlb();
534 }
530} 535}
531 536
532#endif /* I460_LARGE_IO_PAGES */ 537#endif /* I460_LARGE_IO_PAGES */
@@ -536,7 +541,7 @@ static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
536{ 541{
537 /* Make sure the returned address is a valid GATT entry */ 542 /* Make sure the returned address is a valid GATT entry */
538 return bridge->driver->masks[0].mask 543 return bridge->driver->masks[0].mask
539 | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12); 544 | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
540} 545}
541 546
542struct agp_bridge_driver intel_i460_driver = { 547struct agp_bridge_driver intel_i460_driver = {
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index bf4cc9ffd5b1..027161ab88e9 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -270,6 +270,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
270 270
271 switch (pg_count) { 271 switch (pg_count) {
272 case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge); 272 case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge);
273 global_flush_tlb();
273 break; 274 break;
274 case 4: 275 case 4:
275 /* kludge to get 4 physical pages for ARGB cursor */ 276 /* kludge to get 4 physical pages for ARGB cursor */
@@ -330,9 +331,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
330 if(curr->type == AGP_PHYS_MEMORY) { 331 if(curr->type == AGP_PHYS_MEMORY) {
331 if (curr->page_count == 4) 332 if (curr->page_count == 4)
332 i8xx_destroy_pages(gart_to_virt(curr->memory[0])); 333 i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
333 else 334 else {
334 agp_bridge->driver->agp_destroy_page( 335 agp_bridge->driver->agp_destroy_page(
335 gart_to_virt(curr->memory[0])); 336 gart_to_virt(curr->memory[0]));
337 global_flush_tlb();
338 }
336 vfree(curr->memory); 339 vfree(curr->memory);
337 } 340 }
338 kfree(curr); 341 kfree(curr);
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index 6d3fec160bff..efff0eec618c 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -203,10 +203,10 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
203 203
204 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { 204 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
205 if (gart_info->is_pcie) 205 if (gart_info->is_pcie)
206 *pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc; 206 *pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
207 else 207 else
208 *pci_gart = cpu_to_le32(page_base); 208 *pci_gart = cpu_to_le32(page_base);
209 *pci_gart++; 209 pci_gart++;
210 page_base += ATI_PCIGART_PAGE_SIZE; 210 page_base += ATI_PCIGART_PAGE_SIZE;
211 } 211 }
212 } 212 }
diff --git a/drivers/char/ip2.c b/drivers/char/ip2.c
index 6cd12f23aa58..7cadfc6ef352 100644
--- a/drivers/char/ip2.c
+++ b/drivers/char/ip2.c
@@ -7,7 +7,6 @@
7// 7//
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/version.h>
11#include <linux/init.h> 10#include <linux/init.h>
12#include <linux/wait.h> 11#include <linux/wait.h>
13 12
diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c
index d6c72e0934e2..cc3e54dd7234 100644
--- a/drivers/char/mwave/tp3780i.c
+++ b/drivers/char/mwave/tp3780i.c
@@ -46,7 +46,6 @@
46* First release to the public 46* First release to the public
47*/ 47*/
48 48
49#include <linux/version.h>
50#include <linux/interrupt.h> 49#include <linux/interrupt.h>
51#include <linux/kernel.h> 50#include <linux/kernel.h>
52#include <linux/ptrace.h> 51#include <linux/ptrace.h>
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 3b965a651da4..26448f176803 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -38,7 +38,6 @@
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/module.h> 40#include <linux/module.h>
41#include <linux/version.h>
42#include <linux/autoconf.h> 41#include <linux/autoconf.h>
43#include <linux/errno.h> 42#include <linux/errno.h>
44#include <linux/signal.h> 43#include <linux/signal.h>
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 352547eabf7b..0bbfce43031c 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -90,7 +90,6 @@
90#include <linux/fcntl.h> 90#include <linux/fcntl.h>
91#include <linux/major.h> 91#include <linux/major.h>
92#include <linux/delay.h> 92#include <linux/delay.h>
93#include <linux/version.h>
94#include <linux/pci.h> 93#include <linux/pci.h>
95#include <linux/init.h> 94#include <linux/init.h>
96#include <asm/uaccess.h> 95#include <asm/uaccess.h>
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index feb25158c8ee..145275ebdd7e 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -354,7 +354,7 @@ struct sysrq_key_op *__sysrq_get_key_op (int key) {
354 return op_p; 354 return op_p;
355} 355}
356 356
357void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p) { 357static void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p) {
358 int i; 358 int i;
359 359
360 i = sysrq_key_table_key2index(key); 360 i = sysrq_key_table_key2index(key);
@@ -419,7 +419,7 @@ void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
419 __handle_sysrq(key, pt_regs, tty, 1); 419 __handle_sysrq(key, pt_regs, tty, 1);
420} 420}
421 421
422int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p, 422static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
423 struct sysrq_key_op *remove_op_p) { 423 struct sysrq_key_op *remove_op_p) {
424 424
425 int retval; 425 int retval;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 99a60496ecc6..9293bcc4dc62 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/version.h>
23#include <linux/pci.h> 22#include <linux/pci.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <linux/fs.h> 24#include <linux/fs.h>
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index 98601c7d04a9..4d75c261f98a 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -26,7 +26,6 @@
26 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */ 27 */
28#include <linux/config.h> 28#include <linux/config.h>
29#include <linux/version.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
32#include <linux/errno.h> 31#include <linux/errno.h>
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 867cc4e418c7..60aabdb4a046 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -32,7 +32,6 @@
32 * iseries/vio.h 32 * iseries/vio.h
33 */ 33 */
34#include <linux/config.h> 34#include <linux/config.h>
35#include <linux/version.h>
36#include <linux/module.h> 35#include <linux/module.h>
37#include <linux/kernel.h> 36#include <linux/kernel.h>
38#include <linux/errno.h> 37#include <linux/errno.h>
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 25acf478c9e8..23a63207d747 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -38,7 +38,6 @@ static struct cpufreq_driver *cpufreq_driver;
38static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; 38static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
39static DEFINE_SPINLOCK(cpufreq_driver_lock); 39static DEFINE_SPINLOCK(cpufreq_driver_lock);
40 40
41
42/* internal prototypes */ 41/* internal prototypes */
43static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); 42static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
44static void handle_update(void *data); 43static void handle_update(void *data);
@@ -1115,24 +1114,21 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
1115 int retval = -EINVAL; 1114 int retval = -EINVAL;
1116 1115
1117 /* 1116 /*
1118 * Converted the lock_cpu_hotplug to preempt_disable() 1117 * If we are already in context of hotplug thread, we dont need to
1119 * and preempt_enable(). This is a bit kludgy and relies on how cpu 1118 * acquire the hotplug lock. Otherwise acquire cpucontrol to prevent
1120 * hotplug works. All we need is a guarantee that cpu hotplug won't make 1119 * hotplug from removing this cpu that we are working on.
1121 * progress on any cpu. Once we do preempt_disable(), this would ensure
1122 * that hotplug threads don't get onto this cpu, thereby delaying
1123 * the cpu remove process.
1124 *
1125 * We removed the lock_cpu_hotplug since we need to call this function
1126 * via cpu hotplug callbacks, which result in locking the cpu hotplug
1127 * thread itself. Agree this is not very clean, cpufreq community
1128 * could improve this if required. - Ashok Raj <ashok.raj@intel.com>
1129 */ 1120 */
1130 preempt_disable(); 1121 if (!current_in_cpu_hotplug())
1122 lock_cpu_hotplug();
1123
1131 dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu, 1124 dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
1132 target_freq, relation); 1125 target_freq, relation);
1133 if (cpu_online(policy->cpu) && cpufreq_driver->target) 1126 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1134 retval = cpufreq_driver->target(policy, target_freq, relation); 1127 retval = cpufreq_driver->target(policy, target_freq, relation);
1135 preempt_enable(); 1128
1129 if (!current_in_cpu_hotplug())
1130 unlock_cpu_hotplug();
1131
1136 return retval; 1132 return retval;
1137} 1133}
1138EXPORT_SYMBOL_GPL(__cpufreq_driver_target); 1134EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index ba17292eb290..6d83299e7c9b 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -34,7 +34,6 @@
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details. 35 * GNU General Public License for more details.
36 */ 36 */
37#include <linux/version.h>
38#include <linux/config.h> 37#include <linux/config.h>
39#include <linux/init.h> 38#include <linux/init.h>
40#include <linux/module.h> 39#include <linux/module.h>
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 70ef926c3bd8..4e9a04e1f08e 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -180,11 +180,10 @@ superio_exit(void)
180#define W83781D_REG_BANK 0x4E 180#define W83781D_REG_BANK 0x4E
181 181
182#define W83781D_REG_CONFIG 0x40 182#define W83781D_REG_CONFIG 0x40
183#define W83781D_REG_ALARM1 0x41 183#define W83781D_REG_ALARM1 0x459
184#define W83781D_REG_ALARM2 0x42 184#define W83781D_REG_ALARM2 0x45A
185#define W83781D_REG_ALARM3 0x450 185#define W83781D_REG_ALARM3 0x45B
186 186
187#define W83781D_REG_IRQ 0x4C
188#define W83781D_REG_BEEP_CONFIG 0x4D 187#define W83781D_REG_BEEP_CONFIG 0x4D
189#define W83781D_REG_BEEP_INTS1 0x56 188#define W83781D_REG_BEEP_INTS1 0x56
190#define W83781D_REG_BEEP_INTS2 0x57 189#define W83781D_REG_BEEP_INTS2 0x57
@@ -1370,13 +1369,6 @@ static void w83627hf_init_client(struct i2c_client *client)
1370 W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); 1369 W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
1371 } 1370 }
1372 } 1371 }
1373
1374 /* enable comparator mode for temp2 and temp3 so
1375 alarm indication will work correctly */
1376 i = w83627hf_read_value(client, W83781D_REG_IRQ);
1377 if (!(i & 0x40))
1378 w83627hf_write_value(client, W83781D_REG_IRQ,
1379 i | 0x40);
1380 } 1372 }
1381 1373
1382 /* Start monitoring */ 1374 /* Start monitoring */
@@ -1400,7 +1392,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
1400 /* skip missing sensors */ 1392 /* skip missing sensors */
1401 if (((data->type == w83697hf) && (i == 1)) || 1393 if (((data->type == w83697hf) && (i == 1)) ||
1402 ((data->type == w83627thf || data->type == w83637hf) 1394 ((data->type == w83627thf || data->type == w83637hf)
1403 && (i == 4 || i == 5))) 1395 && (i == 5 || i == 6)))
1404 continue; 1396 continue;
1405 data->in[i] = 1397 data->in[i] =
1406 w83627hf_read_value(client, W83781D_REG_IN(i)); 1398 w83627hf_read_value(client, W83781D_REG_IN(i));
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index c9366b504833..a2237d4b2cf2 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -142,19 +142,18 @@ static int vt596_transaction(u8 size)
142 /* Make sure the SMBus host is ready to start transmitting */ 142 /* Make sure the SMBus host is ready to start transmitting */
143 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 143 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
144 dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " 144 dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). "
145 "Resetting... ", temp); 145 "Resetting...\n", temp);
146 146
147 outb_p(temp, SMBHSTSTS); 147 outb_p(temp, SMBHSTSTS);
148 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 148 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
149 printk("Failed! (0x%02x)\n", temp); 149 dev_err(&vt596_adapter.dev, "SMBus reset failed! "
150 "(0x%02x)\n", temp);
150 return -1; 151 return -1;
151 } else {
152 printk("Successful!\n");
153 } 152 }
154 } 153 }
155 154
156 /* Start the transaction by setting bit 6 */ 155 /* Start the transaction by setting bit 6 */
157 outb_p(0x40 | (size & 0x3C), SMBHSTCNT); 156 outb_p(0x40 | size, SMBHSTCNT);
158 157
159 /* We will always wait for a fraction of a second */ 158 /* We will always wait for a fraction of a second */
160 do { 159 do {
@@ -171,7 +170,7 @@ static int vt596_transaction(u8 size)
171 if (temp & 0x10) { 170 if (temp & 0x10) {
172 result = -1; 171 result = -1;
173 dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", 172 dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n",
174 inb_p(SMBHSTCNT) & 0x3C); 173 size);
175 } 174 }
176 175
177 if (temp & 0x08) { 176 if (temp & 0x08) {
@@ -180,11 +179,13 @@ static int vt596_transaction(u8 size)
180 } 179 }
181 180
182 if (temp & 0x04) { 181 if (temp & 0x04) {
182 int read = inb_p(SMBHSTADD) & 0x01;
183 result = -1; 183 result = -1;
184 /* Quick commands are used to probe for chips, so 184 /* The quick and receive byte commands are used to probe
185 errors are expected, and we don't want to frighten the 185 for chips, so errors are expected, and we don't want
186 user. */ 186 to frighten the user. */
187 if ((inb_p(SMBHSTCNT) & 0x3C) != VT596_QUICK) 187 if (!((size == VT596_QUICK && !read) ||
188 (size == VT596_BYTE && read)))
188 dev_err(&vt596_adapter.dev, "Transaction error!\n"); 189 dev_err(&vt596_adapter.dev, "Transaction error!\n");
189 } 190 }
190 191
@@ -462,9 +463,9 @@ static void __exit i2c_vt596_exit(void)
462 } 463 }
463} 464}
464 465
465MODULE_AUTHOR( 466MODULE_AUTHOR("Kyosti Malkki <kmalkki@cc.hut.fi>, "
466 "Frodo Looijaard <frodol@dds.nl> and " 467 "Mark D. Studebaker <mdsxyz123@yahoo.com> and "
467 "Philip Edelbrock <phil@netroedge.com>"); 468 "Jean Delvare <khali@linux-fr.org>");
468MODULE_DESCRIPTION("vt82c596 SMBus driver"); 469MODULE_DESCRIPTION("vt82c596 SMBus driver");
469MODULE_LICENSE("GPL"); 470MODULE_LICENSE("GPL");
470 471
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
index 01b037007410..02682fb794c8 100644
--- a/drivers/i2c/chips/ds1337.c
+++ b/drivers/i2c/chips/ds1337.c
@@ -164,9 +164,9 @@ static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt)
164 buf[1] = BIN2BCD(dt->tm_sec); 164 buf[1] = BIN2BCD(dt->tm_sec);
165 buf[2] = BIN2BCD(dt->tm_min); 165 buf[2] = BIN2BCD(dt->tm_min);
166 buf[3] = BIN2BCD(dt->tm_hour); 166 buf[3] = BIN2BCD(dt->tm_hour);
167 buf[4] = BIN2BCD(dt->tm_wday) + 1; 167 buf[4] = BIN2BCD(dt->tm_wday + 1);
168 buf[5] = BIN2BCD(dt->tm_mday); 168 buf[5] = BIN2BCD(dt->tm_mday);
169 buf[6] = BIN2BCD(dt->tm_mon) + 1; 169 buf[6] = BIN2BCD(dt->tm_mon + 1);
170 val = dt->tm_year; 170 val = dt->tm_year;
171 if (val >= 100) { 171 if (val >= 100) {
172 val -= 100; 172 val -= 100;
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index a737886e39d1..42e5b8175cbf 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -539,6 +539,15 @@ config BLK_DEV_CS5530
539 539
540 It is safe to say Y to this question. 540 It is safe to say Y to this question.
541 541
542config BLK_DEV_CS5535
543 tristate "AMD CS5535 chipset support"
544 depends on X86 && !X86_64
545 help
546 Include support for UDMA on the NSC/AMD CS5535 companion chipset.
547 This will automatically be detected and configured if found.
548
549 It is safe to say Y to this question.
550
542config BLK_DEV_HPT34X 551config BLK_DEV_HPT34X
543 tristate "HPT34X chipset support" 552 tristate "HPT34X chipset support"
544 help 553 help
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index e83f54d37f96..f615ab759962 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -2038,11 +2038,9 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
2038 struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); 2038 struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
2039 ide_drive_t *drive = floppy->drive; 2039 ide_drive_t *drive = floppy->drive;
2040 void __user *argp = (void __user *)arg; 2040 void __user *argp = (void __user *)arg;
2041 int err = generic_ide_ioctl(drive, file, bdev, cmd, arg); 2041 int err;
2042 int prevent = (arg) ? 1 : 0; 2042 int prevent = (arg) ? 1 : 0;
2043 idefloppy_pc_t pc; 2043 idefloppy_pc_t pc;
2044 if (err != -EINVAL)
2045 return err;
2046 2044
2047 switch (cmd) { 2045 switch (cmd) {
2048 case CDROMEJECT: 2046 case CDROMEJECT:
@@ -2094,7 +2092,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
2094 case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: 2092 case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
2095 return idefloppy_get_format_progress(drive, argp); 2093 return idefloppy_get_format_progress(drive, argp);
2096 } 2094 }
2097 return -EINVAL; 2095 return generic_ide_ioctl(drive, file, bdev, cmd, arg);
2098} 2096}
2099 2097
2100static int idefloppy_media_changed(struct gendisk *disk) 2098static int idefloppy_media_changed(struct gendisk *disk)
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 0b0aa4f51628..af7af958ab3e 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -104,8 +104,6 @@ void default_hwif_iops (ide_hwif_t *hwif)
104 hwif->INSL = ide_insl; 104 hwif->INSL = ide_insl;
105} 105}
106 106
107EXPORT_SYMBOL(default_hwif_iops);
108
109/* 107/*
110 * MMIO operations, typically used for SATA controllers 108 * MMIO operations, typically used for SATA controllers
111 */ 109 */
@@ -329,8 +327,6 @@ void default_hwif_transport(ide_hwif_t *hwif)
329 hwif->atapi_output_bytes = atapi_output_bytes; 327 hwif->atapi_output_bytes = atapi_output_bytes;
330} 328}
331 329
332EXPORT_SYMBOL(default_hwif_transport);
333
334/* 330/*
335 * Beginning of Taskfile OPCODE Library and feature sets. 331 * Beginning of Taskfile OPCODE Library and feature sets.
336 */ 332 */
@@ -529,8 +525,6 @@ int wait_for_ready (ide_drive_t *drive, int timeout)
529 return 0; 525 return 0;
530} 526}
531 527
532EXPORT_SYMBOL(wait_for_ready);
533
534/* 528/*
535 * This routine busy-waits for the drive status to be not "busy". 529 * This routine busy-waits for the drive status to be not "busy".
536 * It then checks the status for all of the "good" bits and none 530 * It then checks the status for all of the "good" bits and none
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 7ec18fa3b5ff..54f9639c2a8c 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -161,8 +161,6 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
161 return ide_stopped; 161 return ide_stopped;
162} 162}
163 163
164EXPORT_SYMBOL(do_rw_taskfile);
165
166/* 164/*
167 * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. 165 * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
168 */ 166 */
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 9fe19808d815..8af179b531c3 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -803,6 +803,7 @@ found:
803 hwif->irq = hw->irq; 803 hwif->irq = hw->irq;
804 hwif->noprobe = 0; 804 hwif->noprobe = 0;
805 hwif->chipset = hw->chipset; 805 hwif->chipset = hw->chipset;
806 hwif->gendev.parent = hw->dev;
806 807
807 if (!initializing) { 808 if (!initializing) {
808 probe_hwif_init_with_fixup(hwif, fixup); 809 probe_hwif_init_with_fixup(hwif, fixup);
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 1dafffa7e513..ef79805218e4 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -182,13 +182,14 @@ static void ide_detach(dev_link_t *link)
182 182
183} /* ide_detach */ 183} /* ide_detach */
184 184
185static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq) 185static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
186{ 186{
187 hw_regs_t hw; 187 hw_regs_t hw;
188 memset(&hw, 0, sizeof(hw)); 188 memset(&hw, 0, sizeof(hw));
189 ide_init_hwif_ports(&hw, io, ctl, NULL); 189 ide_init_hwif_ports(&hw, io, ctl, NULL);
190 hw.irq = irq; 190 hw.irq = irq;
191 hw.chipset = ide_pci; 191 hw.chipset = ide_pci;
192 hw.dev = &handle->dev;
192 return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave); 193 return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave);
193} 194}
194 195
@@ -327,12 +328,12 @@ static void ide_config(dev_link_t *link)
327 328
328 /* retry registration in case device is still spinning up */ 329 /* retry registration in case device is still spinning up */
329 for (hd = -1, i = 0; i < 10; i++) { 330 for (hd = -1, i = 0; i < 10; i++) {
330 hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ); 331 hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, handle);
331 if (hd >= 0) break; 332 if (hd >= 0) break;
332 if (link->io.NumPorts1 == 0x20) { 333 if (link->io.NumPorts1 == 0x20) {
333 outb(0x02, ctl_base + 0x10); 334 outb(0x02, ctl_base + 0x10);
334 hd = idecs_register(io_base + 0x10, ctl_base + 0x10, 335 hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
335 link->irq.AssignedIRQ); 336 link->irq.AssignedIRQ, handle);
336 if (hd >= 0) { 337 if (hd >= 0) {
337 io_base += 0x10; 338 io_base += 0x10;
338 ctl_base += 0x10; 339 ctl_base += 0x10;
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index af46226c1796..f35d684edc25 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o
6obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o 6obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o
7obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o 7obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o
8obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o 8obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
9obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o
9obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o 10obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
10obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o 11obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
11obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o 12obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 844a6c9fb949..21965e5ef25e 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -74,6 +74,7 @@ static struct amd_ide_chip {
74 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, 74 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 },
75 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, 75 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 },
76 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, 76 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 },
77 { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 },
77 { 0 } 78 { 0 }
78}; 79};
79 80
@@ -491,6 +492,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
491 /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), 492 /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
492 /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), 493 /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"),
493 /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), 494 /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"),
495 /* 17 */ DECLARE_AMD_DEV("AMD5536"),
494}; 496};
495 497
496static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) 498static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -527,6 +529,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
527 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, 529 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
528 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, 530 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
529 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, 531 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
532 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
530 { 0, }, 533 { 0, },
531}; 534};
532MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); 535MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
new file mode 100644
index 000000000000..6eb305197f3c
--- /dev/null
+++ b/drivers/ide/pci/cs5535.c
@@ -0,0 +1,305 @@
1/*
2 * linux/drivers/ide/pci/cs5535.c
3 *
4 * Copyright (C) 2004-2005 Advanced Micro Devices, Inc.
5 *
6 * History:
7 * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com>
8 * - Reworked tuneproc, set_drive, misc mods to prep for mainline
9 * - Work was sponsored by CIS (M) Sdn Bhd.
10 * Ported to Kernel 2.6.11 on June 26, 2005 by
11 * Wolfgang Zuleger <wolfgang.zuleger@gmx.de>
12 * Alexander Kiausch <alex.kiausch@t-online.de>
13 * Originally developed by AMD for 2.4/2.6
14 *
15 * Development of this chipset driver was funded
16 * by the nice folks at National Semiconductor/AMD.
17 *
18 * This program is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License version 2 as published by
20 * the Free Software Foundation.
21 *
22 * Documentation:
23 * CS5535 documentation available from AMD
24 */
25
26#include <linux/config.h>
27#include <linux/module.h>
28#include <linux/pci.h>
29#include <linux/ide.h>
30
31#include "ide-timing.h"
32
33#define MSR_ATAC_BASE 0x51300000
34#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0)
35#define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01)
36#define ATAC_GLD_MSR_SMI (MSR_ATAC_BASE+0x02)
37#define ATAC_GLD_MSR_ERROR (MSR_ATAC_BASE+0x03)
38#define ATAC_GLD_MSR_PM (MSR_ATAC_BASE+0x04)
39#define ATAC_GLD_MSR_DIAG (MSR_ATAC_BASE+0x05)
40#define ATAC_IO_BAR (MSR_ATAC_BASE+0x08)
41#define ATAC_RESET (MSR_ATAC_BASE+0x10)
42#define ATAC_CH0D0_PIO (MSR_ATAC_BASE+0x20)
43#define ATAC_CH0D0_DMA (MSR_ATAC_BASE+0x21)
44#define ATAC_CH0D1_PIO (MSR_ATAC_BASE+0x22)
45#define ATAC_CH0D1_DMA (MSR_ATAC_BASE+0x23)
46#define ATAC_PCI_ABRTERR (MSR_ATAC_BASE+0x24)
47#define ATAC_BM0_CMD_PRIM 0x00
48#define ATAC_BM0_STS_PRIM 0x02
49#define ATAC_BM0_PRD 0x04
50#define CS5535_CABLE_DETECT 0x48
51
52/* Format I PIO settings. We seperate out cmd and data for safer timings */
53
54static unsigned int cs5535_pio_cmd_timings[5] =
55{ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 };
56static unsigned int cs5535_pio_dta_timings[5] =
57{ 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131 };
58
59static unsigned int cs5535_mwdma_timings[3] =
60{ 0x7F0FFFF3, 0x7F035352, 0x7f024241 };
61
62static unsigned int cs5535_udma_timings[5] =
63{ 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 };
64
65/* Macros to check if the register is the reset value - reset value is an
66 invalid timing and indicates the register has not been set previously */
67
68#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL) == 0x00009172 )
69#define CS5535_BAD_DMA(timings) ( (timings & 0x000FFFFF) == 0x00077771 )
70
71/****
72 * cs5535_set_speed - Configure the chipset to the new speed
73 * @drive: Drive to set up
74 * @speed: desired speed
75 *
76 * cs5535_set_speed() configures the chipset to a new speed.
77 */
78static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
79{
80
81 u32 reg = 0, dummy;
82 int unit = drive->select.b.unit;
83
84
85 /* Set the PIO timings */
86 if ((speed & XFER_MODE) == XFER_PIO) {
87 u8 pioa;
88 u8 piob;
89 u8 cmd;
90
91 pioa = speed - XFER_PIO_0;
92 piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]),
93 255, 4, NULL);
94 cmd = pioa < piob ? pioa : piob;
95
96 /* Write the speed of the current drive */
97 reg = (cs5535_pio_cmd_timings[cmd] << 16) |
98 cs5535_pio_dta_timings[pioa];
99 wrmsr(unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, reg, 0);
100
101 /* And if nessesary - change the speed of the other drive */
102 rdmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, dummy);
103
104 if (((reg >> 16) & cs5535_pio_cmd_timings[cmd]) !=
105 cs5535_pio_cmd_timings[cmd]) {
106 reg &= 0x0000FFFF;
107 reg |= cs5535_pio_cmd_timings[cmd] << 16;
108 wrmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, 0);
109 }
110
111 /* Set bit 31 of the DMA register for PIO format 1 timings */
112 rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
113 wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA,
114 reg | 0x80000000UL, 0);
115 } else {
116 rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
117
118 reg &= 0x80000000UL; /* Preserve the PIO format bit */
119
120 if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7)
121 reg |= cs5535_udma_timings[speed - XFER_UDMA_0];
122 else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
123 reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0];
124 else
125 return;
126
127 wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, 0);
128 }
129}
130
131static u8 cs5535_ratemask(ide_drive_t *drive)
132{
133 /* eighty93 will return 1 if it's 80core and capable of
134 exceeding udma2, 0 otherwise. we need ratemask to set
135 the max speed and if we can > udma2 then we return 2
136 which selects speed_max as udma4 which is the 5535's max
137 speed, and 1 selects udma2 which is the max for 40c */
138 if (!eighty_ninty_three(drive))
139 return 1;
140
141 return 2;
142}
143
144
145/****
146 * cs5535_set_drive - Configure the drive to the new speed
147 * @drive: Drive to set up
148 * @speed: desired speed
149 *
150 * cs5535_set_drive() configures the drive and the chipset to a
151 * new speed. It also can be called by upper layers.
152 */
153static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
154{
155 speed = ide_rate_filter(cs5535_ratemask(drive), speed);
156 ide_config_drive_speed(drive, speed);
157 cs5535_set_speed(drive, speed);
158
159 return 0;
160}
161
162/****
163 * cs5535_tuneproc - PIO setup
164 * @drive: drive to set up
165 * @pio: mode to use (255 for 'best possible')
166 *
167 * A callback from the upper layers for PIO-only tuning.
168 */
169static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed)
170{
171 u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3,
172 XFER_PIO_4 };
173
174 /* cs5535 max pio is pio 4, best_pio will check the blacklist.
175 i think we don't need to rate_filter the incoming xferspeed
176 since we know we're only going to choose pio */
177 xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4, NULL);
178 ide_config_drive_speed(drive, modes[xferspeed]);
179 cs5535_set_speed(drive, xferspeed);
180}
181
182static int cs5535_config_drive_for_dma(ide_drive_t *drive)
183{
184 u8 speed;
185
186 speed = ide_dma_speed(drive, cs5535_ratemask(drive));
187
188 /* If no DMA speed was available then let dma_check hit pio */
189 if (!speed) {
190 return 0;
191 }
192
193 cs5535_set_drive(drive, speed);
194 return ide_dma_enable(drive);
195}
196
197static int cs5535_dma_check(ide_drive_t *drive)
198{
199 ide_hwif_t *hwif = drive->hwif;
200 struct hd_driveid *id = drive->id;
201 u8 speed;
202
203 drive->init_speed = 0;
204
205 if ((id->capability & 1) && drive->autodma) {
206 if (ide_use_dma(drive)) {
207 if (cs5535_config_drive_for_dma(drive))
208 return hwif->ide_dma_on(drive);
209 }
210
211 goto fast_ata_pio;
212
213 } else if ((id->capability & 8) || (id->field_valid & 2)) {
214fast_ata_pio:
215 speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
216 cs5535_set_drive(drive, speed);
217 return hwif->ide_dma_off_quietly(drive);
218 }
219 /* IORDY not supported */
220 return 0;
221}
222
223static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
224{
225 u8 bit;
226
227 /* if a 80 wire cable was detected */
228 pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit);
229 return (bit & 1);
230}
231
232/****
233 * init_hwif_cs5535 - Initialize one ide cannel
234 * @hwif: Channel descriptor
235 *
236 * This gets invoked by the IDE driver once for each channel. It
237 * performs channel-specific pre-initialization before drive probing.
238 *
239 */
240static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
241{
242 int i;
243
244 hwif->autodma = 0;
245
246 hwif->tuneproc = &cs5535_tuneproc;
247 hwif->speedproc = &cs5535_set_drive;
248 hwif->ide_dma_check = &cs5535_dma_check;
249
250 hwif->atapi_dma = 1;
251 hwif->ultra_mask = 0x1F;
252 hwif->mwdma_mask = 0x07;
253
254
255 hwif->udma_four = cs5535_cable_detect(hwif->pci_dev);
256
257 if (!noautodma)
258 hwif->autodma = 1;
259
260 /* just setting autotune and not worrying about bios timings */
261 for (i = 0; i < 2; i++) {
262 hwif->drives[i].autotune = 1;
263 hwif->drives[i].autodma = hwif->autodma;
264 }
265}
266
267static ide_pci_device_t cs5535_chipset __devinitdata = {
268 .name = "CS5535",
269 .init_hwif = init_hwif_cs5535,
270 .channels = 1,
271 .autodma = AUTODMA,
272 .bootable = ON_BOARD,
273};
274
275static int __devinit cs5535_init_one(struct pci_dev *dev,
276 const struct pci_device_id *id)
277{
278 return ide_setup_pci_device(dev, &cs5535_chipset);
279}
280
281static struct pci_device_id cs5535_pci_tbl[] =
282{
283 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_IDE, PCI_ANY_ID,
284 PCI_ANY_ID, 0, 0, 0},
285 { 0, },
286};
287
288MODULE_DEVICE_TABLE(pci, cs5535_pci_tbl);
289
290static struct pci_driver driver = {
291 .name = "CS5535_IDE",
292 .id_table = cs5535_pci_tbl,
293 .probe = cs5535_init_one,
294};
295
296static int __init cs5535_ide_init(void)
297{
298 return ide_pci_register_driver(&driver);
299}
300
301module_init(cs5535_ide_init);
302
303MODULE_AUTHOR("AMD");
304MODULE_DESCRIPTION("PCI driver module for AMD/NS CS5535 IDE");
305MODULE_LICENSE("GPL");
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 5a33513f3dd1..9f41ecd56338 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -469,7 +469,7 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
469 469
470static __devinitdata ide_hwif_t *primary; 470static __devinitdata ide_hwif_t *primary;
471 471
472void __devinit init_iops_cy82c693(ide_hwif_t *hwif) 472static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
473{ 473{
474 if (PCI_FUNC(hwif->pci_dev->devfn) == 1) 474 if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
475 primary = hwif; 475 primary = hwif;
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 2b9961b88135..022d244f2eb0 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -701,6 +701,7 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
701 unsigned long barsize = pci_resource_len(dev, 5); 701 unsigned long barsize = pci_resource_len(dev, 5);
702 u8 tmpbyte = 0; 702 u8 tmpbyte = 0;
703 void __iomem *ioaddr; 703 void __iomem *ioaddr;
704 u32 tmp, irq_mask;
704 705
705 /* 706 /*
706 * Drop back to PIO if we can't map the mmio. Some 707 * Drop back to PIO if we can't map the mmio. Some
@@ -726,6 +727,14 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
726 pci_set_drvdata(dev, (void *) ioaddr); 727 pci_set_drvdata(dev, (void *) ioaddr);
727 728
728 if (pdev_is_sata(dev)) { 729 if (pdev_is_sata(dev)) {
730 /* make sure IDE0/1 interrupts are not masked */
731 irq_mask = (1 << 22) | (1 << 23);
732 tmp = readl(ioaddr + 0x48);
733 if (tmp & irq_mask) {
734 tmp &= ~irq_mask;
735 writel(tmp, ioaddr + 0x48);
736 readl(ioaddr + 0x48); /* flush */
737 }
729 writel(0, ioaddr + 0x148); 738 writel(0, ioaddr + 0x148);
730 writel(0, ioaddr + 0x1C8); 739 writel(0, ioaddr + 0x1C8);
731 } 740 }
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 2687e34aa5bc..321a3a10e69b 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -32,7 +32,6 @@
32 * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $ 32 * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $
33 */ 33 */
34 34
35#include <linux/version.h>
36#include <linux/module.h> 35#include <linux/module.h>
37#include <linux/init.h> 36#include <linux/init.h>
38#include <linux/slab.h> 37#include <linux/slab.h>
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 0879915b14d5..c8ae2bb054e0 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -669,7 +669,7 @@ static int input_dev_hotplug(struct class_device *cdev, char **envp,
669 INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name); 669 INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name);
670 if (dev->phys) 670 if (dev->phys)
671 INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys); 671 INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys);
672 if (dev->phys) 672 if (dev->uniq)
673 INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq); 673 INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq);
674 674
675 INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX); 675 INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX);
diff --git a/drivers/isdn/divert/divert_init.c b/drivers/isdn/divert/divert_init.c
index 434e684f5dbb..2f7c9fc2e898 100644
--- a/drivers/isdn/divert/divert_init.c
+++ b/drivers/isdn/divert/divert_init.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/version.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16 15
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 0b0ea26023e5..1b37d86d5ee1 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -11,7 +11,6 @@
11 11
12#include <linux/config.h> 12#include <linux/config.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/poll.h> 14#include <linux/poll.h>
16#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
17#ifdef CONFIG_PROC_FS 16#ifdef CONFIG_PROC_FS
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 0bfd698726a6..f1a1f9a9b88e 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -9,7 +9,6 @@
9 * 9 *
10 */ 10 */
11 11
12#include <linux/version.h>
13#include <linux/proc_fs.h> 12#include <linux/proc_fs.h>
14 13
15#include "isdn_divert.h" 14#include "isdn_divert.h"
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index b4d795d40154..dc7ef957e897 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -23,7 +23,6 @@
23 * o tx_skb at PH_DEACTIVATE time 23 * o tx_skb at PH_DEACTIVATE time
24 */ 24 */
25 25
26#include <linux/version.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/init.h> 27#include <linux/init.h>
29#include <linux/pci.h> 28#include <linux/pci.h>
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 2cf5d1a6df6c..8e192a3a3490 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -25,7 +25,6 @@
25 */ 25 */
26 26
27#include <linux/config.h> 27#include <linux/config.h>
28#include <linux/version.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/init.h> 29#include <linux/init.h>
31#include <linux/usb.h> 30#include <linux/usb.h>
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
index 1fd3d4e5f284..acc1d3cceebb 100644
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/signal.h> 14#include <linux/signal.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/skbuff.h> 16#include <linux/skbuff.h>
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c
index 12c8137b5161..cb791f8e793a 100644
--- a/drivers/isdn/hysdn/hysdn_init.c
+++ b/drivers/isdn/hysdn/hysdn_init.c
@@ -13,7 +13,6 @@
13#include <linux/config.h> 13#include <linux/config.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/version.h>
17#include <linux/poll.h> 16#include <linux/poll.h>
18#include <linux/vmalloc.h> 17#include <linux/vmalloc.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c
index babec8157ae6..aa01628d74c6 100644
--- a/drivers/isdn/hysdn/hysdn_net.c
+++ b/drivers/isdn/hysdn/hysdn_net.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/version.h>
18#include <linux/signal.h> 17#include <linux/signal.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/netdevice.h> 19#include <linux/netdevice.h>
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 87f59a0e2a95..40e56143c768 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/version.h>
16#include <linux/poll.h> 15#include <linux/poll.h>
17#include <linux/proc_fs.h> 16#include <linux/proc_fs.h>
18#include <linux/pci.h> 17#include <linux/pci.h>
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 4d57011c5737..6c26f1efabd5 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/poll.h> 14#include <linux/poll.h>
16#include <linux/proc_fs.h> 15#include <linux/proc_fs.h>
17#include <linux/pci.h> 16#include <linux/pci.h>
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 8a7d54a5c97d..4643df097bfe 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -14,7 +14,6 @@
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/version.h>
18#include <linux/poll.h> 17#include <linux/poll.h>
19#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
20#include <linux/isdn.h> 19#include <linux/isdn.h>
diff --git a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h
index 9028cc3b5071..7d7245fb0b32 100644
--- a/drivers/isdn/icn/icn.h
+++ b/drivers/isdn/icn/icn.h
@@ -35,7 +35,6 @@ typedef struct icn_cdef {
35#ifdef __KERNEL__ 35#ifdef __KERNEL__
36/* Kernel includes */ 36/* Kernel includes */
37 37
38#include <linux/version.h>
39#include <linux/errno.h> 38#include <linux/errno.h>
40#include <linux/fs.h> 39#include <linux/fs.h>
41#include <linux/major.h> 40#include <linux/major.h>
diff --git a/drivers/isdn/isdnloop/isdnloop.h b/drivers/isdn/isdnloop/isdnloop.h
index 8fb7bc1bfe0f..d699fe53e1c3 100644
--- a/drivers/isdn/isdnloop/isdnloop.h
+++ b/drivers/isdn/isdnloop/isdnloop.h
@@ -33,7 +33,6 @@ typedef struct isdnloop_sdef {
33#ifdef __KERNEL__ 33#ifdef __KERNEL__
34/* Kernel includes */ 34/* Kernel includes */
35 35
36#include <linux/version.h>
37#include <linux/errno.h> 36#include <linux/errno.h>
38#include <linux/fs.h> 37#include <linux/fs.h>
39#include <linux/major.h> 38#include <linux/major.h>
diff --git a/drivers/isdn/sc/includes.h b/drivers/isdn/sc/includes.h
index 4611da6e9231..5286e0c810a9 100644
--- a/drivers/isdn/sc/includes.h
+++ b/drivers/isdn/sc/includes.h
@@ -4,7 +4,6 @@
4 * 4 *
5 */ 5 */
6 6
7#include <linux/version.h>
8#include <linux/errno.h> 7#include <linux/errno.h>
9#include <asm/io.h> 8#include <asm/io.h>
10#include <linux/delay.h> 9#include <linux/delay.h>
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 01654fcabc52..51315302a85e 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -21,7 +21,6 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/version.h>
25#include <linux/errno.h> 24#include <linux/errno.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <linux/init.h> 26#include <linux/init.h>
@@ -272,7 +271,8 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
272 return ERR_PTR(-ENOMEM); 271 return ERR_PTR(-ENOMEM);
273 272
274 ITERATE_RDEV(mddev, rdev, tmp) { 273 ITERATE_RDEV(mddev, rdev, tmp) {
275 if (! rdev->in_sync || rdev->faulty) 274 if (! test_bit(In_sync, &rdev->flags)
275 || test_bit(Faulty, &rdev->flags))
276 continue; 276 continue;
277 277
278 target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512); 278 target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512);
@@ -292,7 +292,8 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai
292 struct list_head *tmp; 292 struct list_head *tmp;
293 293
294 ITERATE_RDEV(mddev, rdev, tmp) 294 ITERATE_RDEV(mddev, rdev, tmp)
295 if (rdev->in_sync && !rdev->faulty) 295 if (test_bit(In_sync, &rdev->flags)
296 && !test_bit(Faulty, &rdev->flags))
296 md_super_write(mddev, rdev, 297 md_super_write(mddev, rdev,
297 (rdev->sb_offset<<1) + offset 298 (rdev->sb_offset<<1) + offset
298 + page->index * (PAGE_SIZE/512), 299 + page->index * (PAGE_SIZE/512),
@@ -300,7 +301,7 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai
300 page); 301 page);
301 302
302 if (wait) 303 if (wait)
303 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 304 md_super_wait(mddev);
304 return 0; 305 return 0;
305} 306}
306 307
@@ -481,7 +482,8 @@ static int bitmap_read_sb(struct bitmap *bitmap)
481 /* verify that the bitmap-specific fields are valid */ 482 /* verify that the bitmap-specific fields are valid */
482 if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) 483 if (sb->magic != cpu_to_le32(BITMAP_MAGIC))
483 reason = "bad magic"; 484 reason = "bad magic";
484 else if (sb->version != cpu_to_le32(BITMAP_MAJOR)) 485 else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
486 le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
485 reason = "unrecognized superblock version"; 487 reason = "unrecognized superblock version";
486 else if (chunksize < 512 || chunksize > (1024 * 1024 * 4)) 488 else if (chunksize < 512 || chunksize > (1024 * 1024 * 4))
487 reason = "bitmap chunksize out of range (512B - 4MB)"; 489 reason = "bitmap chunksize out of range (512B - 4MB)";
@@ -526,6 +528,8 @@ success:
526 bitmap->daemon_lastrun = jiffies; 528 bitmap->daemon_lastrun = jiffies;
527 bitmap->max_write_behind = write_behind; 529 bitmap->max_write_behind = write_behind;
528 bitmap->flags |= sb->state; 530 bitmap->flags |= sb->state;
531 if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
532 bitmap->flags |= BITMAP_HOSTENDIAN;
529 bitmap->events_cleared = le64_to_cpu(sb->events_cleared); 533 bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
530 if (sb->state & BITMAP_STALE) 534 if (sb->state & BITMAP_STALE)
531 bitmap->events_cleared = bitmap->mddev->events; 535 bitmap->events_cleared = bitmap->mddev->events;
@@ -763,7 +767,10 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
763 767
764 /* set the bit */ 768 /* set the bit */
765 kaddr = kmap_atomic(page, KM_USER0); 769 kaddr = kmap_atomic(page, KM_USER0);
766 set_bit(bit, kaddr); 770 if (bitmap->flags & BITMAP_HOSTENDIAN)
771 set_bit(bit, kaddr);
772 else
773 ext2_set_bit(bit, kaddr);
767 kunmap_atomic(kaddr, KM_USER0); 774 kunmap_atomic(kaddr, KM_USER0);
768 PRINTK("set file bit %lu page %lu\n", bit, page->index); 775 PRINTK("set file bit %lu page %lu\n", bit, page->index);
769 776
@@ -821,8 +828,7 @@ int bitmap_unplug(struct bitmap *bitmap)
821 wake_up_process(bitmap->writeback_daemon->tsk)); 828 wake_up_process(bitmap->writeback_daemon->tsk));
822 spin_unlock_irq(&bitmap->write_lock); 829 spin_unlock_irq(&bitmap->write_lock);
823 } else 830 } else
824 wait_event(bitmap->mddev->sb_wait, 831 md_super_wait(bitmap->mddev);
825 atomic_read(&bitmap->mddev->pending_writes)==0);
826 } 832 }
827 return 0; 833 return 0;
828} 834}
@@ -890,6 +896,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
890 oldindex = ~0L; 896 oldindex = ~0L;
891 897
892 for (i = 0; i < chunks; i++) { 898 for (i = 0; i < chunks; i++) {
899 int b;
893 index = file_page_index(i); 900 index = file_page_index(i);
894 bit = file_page_offset(i); 901 bit = file_page_offset(i);
895 if (index != oldindex) { /* this is a new page, read it in */ 902 if (index != oldindex) { /* this is a new page, read it in */
@@ -938,7 +945,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
938 945
939 bitmap->filemap[bitmap->file_pages++] = page; 946 bitmap->filemap[bitmap->file_pages++] = page;
940 } 947 }
941 if (test_bit(bit, page_address(page))) { 948 if (bitmap->flags & BITMAP_HOSTENDIAN)
949 b = test_bit(bit, page_address(page));
950 else
951 b = ext2_test_bit(bit, page_address(page));
952 if (b) {
942 /* if the disk bit is set, set the memory bit */ 953 /* if the disk bit is set, set the memory bit */
943 bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap), 954 bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap),
944 ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start) 955 ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start)
@@ -1096,7 +1107,10 @@ int bitmap_daemon_work(struct bitmap *bitmap)
1096 -1); 1107 -1);
1097 1108
1098 /* clear the bit */ 1109 /* clear the bit */
1099 clear_bit(file_page_offset(j), page_address(page)); 1110 if (bitmap->flags & BITMAP_HOSTENDIAN)
1111 clear_bit(file_page_offset(j), page_address(page));
1112 else
1113 ext2_clear_bit(file_page_offset(j), page_address(page));
1100 } 1114 }
1101 } 1115 }
1102 spin_unlock_irqrestore(&bitmap->lock, flags); 1116 spin_unlock_irqrestore(&bitmap->lock, flags);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9ecf51ee596f..adf960d8a7c9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -131,6 +131,8 @@ static ctl_table raid_root_table[] = {
131 131
132static struct block_device_operations md_fops; 132static struct block_device_operations md_fops;
133 133
134static int start_readonly;
135
134/* 136/*
135 * Enables to iterate over all existing md arrays 137 * Enables to iterate over all existing md arrays
136 * all_mddevs_lock protects this list. 138 * all_mddevs_lock protects this list.
@@ -181,7 +183,7 @@ static void mddev_put(mddev_t *mddev)
181 if (!mddev->raid_disks && list_empty(&mddev->disks)) { 183 if (!mddev->raid_disks && list_empty(&mddev->disks)) {
182 list_del(&mddev->all_mddevs); 184 list_del(&mddev->all_mddevs);
183 blk_put_queue(mddev->queue); 185 blk_put_queue(mddev->queue);
184 kfree(mddev); 186 kobject_unregister(&mddev->kobj);
185 } 187 }
186 spin_unlock(&all_mddevs_lock); 188 spin_unlock(&all_mddevs_lock);
187} 189}
@@ -330,18 +332,46 @@ static void free_disk_sb(mdk_rdev_t * rdev)
330static int super_written(struct bio *bio, unsigned int bytes_done, int error) 332static int super_written(struct bio *bio, unsigned int bytes_done, int error)
331{ 333{
332 mdk_rdev_t *rdev = bio->bi_private; 334 mdk_rdev_t *rdev = bio->bi_private;
335 mddev_t *mddev = rdev->mddev;
333 if (bio->bi_size) 336 if (bio->bi_size)
334 return 1; 337 return 1;
335 338
336 if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) 339 if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags))
337 md_error(rdev->mddev, rdev); 340 md_error(mddev, rdev);
338 341
339 if (atomic_dec_and_test(&rdev->mddev->pending_writes)) 342 if (atomic_dec_and_test(&mddev->pending_writes))
340 wake_up(&rdev->mddev->sb_wait); 343 wake_up(&mddev->sb_wait);
341 bio_put(bio); 344 bio_put(bio);
342 return 0; 345 return 0;
343} 346}
344 347
348static int super_written_barrier(struct bio *bio, unsigned int bytes_done, int error)
349{
350 struct bio *bio2 = bio->bi_private;
351 mdk_rdev_t *rdev = bio2->bi_private;
352 mddev_t *mddev = rdev->mddev;
353 if (bio->bi_size)
354 return 1;
355
356 if (!test_bit(BIO_UPTODATE, &bio->bi_flags) &&
357 error == -EOPNOTSUPP) {
358 unsigned long flags;
359 /* barriers don't appear to be supported :-( */
360 set_bit(BarriersNotsupp, &rdev->flags);
361 mddev->barriers_work = 0;
362 spin_lock_irqsave(&mddev->write_lock, flags);
363 bio2->bi_next = mddev->biolist;
364 mddev->biolist = bio2;
365 spin_unlock_irqrestore(&mddev->write_lock, flags);
366 wake_up(&mddev->sb_wait);
367 bio_put(bio);
368 return 0;
369 }
370 bio_put(bio2);
371 bio->bi_private = rdev;
372 return super_written(bio, bytes_done, error);
373}
374
345void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, 375void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
346 sector_t sector, int size, struct page *page) 376 sector_t sector, int size, struct page *page)
347{ 377{
@@ -350,16 +380,54 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
350 * and decrement it on completion, waking up sb_wait 380 * and decrement it on completion, waking up sb_wait
351 * if zero is reached. 381 * if zero is reached.
352 * If an error occurred, call md_error 382 * If an error occurred, call md_error
383 *
384 * As we might need to resubmit the request if BIO_RW_BARRIER
385 * causes ENOTSUPP, we allocate a spare bio...
353 */ 386 */
354 struct bio *bio = bio_alloc(GFP_NOIO, 1); 387 struct bio *bio = bio_alloc(GFP_NOIO, 1);
388 int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNC);
355 389
356 bio->bi_bdev = rdev->bdev; 390 bio->bi_bdev = rdev->bdev;
357 bio->bi_sector = sector; 391 bio->bi_sector = sector;
358 bio_add_page(bio, page, size, 0); 392 bio_add_page(bio, page, size, 0);
359 bio->bi_private = rdev; 393 bio->bi_private = rdev;
360 bio->bi_end_io = super_written; 394 bio->bi_end_io = super_written;
395 bio->bi_rw = rw;
396
361 atomic_inc(&mddev->pending_writes); 397 atomic_inc(&mddev->pending_writes);
362 submit_bio((1<<BIO_RW)|(1<<BIO_RW_SYNC), bio); 398 if (!test_bit(BarriersNotsupp, &rdev->flags)) {
399 struct bio *rbio;
400 rw |= (1<<BIO_RW_BARRIER);
401 rbio = bio_clone(bio, GFP_NOIO);
402 rbio->bi_private = bio;
403 rbio->bi_end_io = super_written_barrier;
404 submit_bio(rw, rbio);
405 } else
406 submit_bio(rw, bio);
407}
408
409void md_super_wait(mddev_t *mddev)
410{
411 /* wait for all superblock writes that were scheduled to complete.
412 * if any had to be retried (due to BARRIER problems), retry them
413 */
414 DEFINE_WAIT(wq);
415 for(;;) {
416 prepare_to_wait(&mddev->sb_wait, &wq, TASK_UNINTERRUPTIBLE);
417 if (atomic_read(&mddev->pending_writes)==0)
418 break;
419 while (mddev->biolist) {
420 struct bio *bio;
421 spin_lock_irq(&mddev->write_lock);
422 bio = mddev->biolist;
423 mddev->biolist = bio->bi_next ;
424 bio->bi_next = NULL;
425 spin_unlock_irq(&mddev->write_lock);
426 submit_bio(bio->bi_rw, bio);
427 }
428 schedule();
429 }
430 finish_wait(&mddev->sb_wait, &wq);
363} 431}
364 432
365static int bi_complete(struct bio *bio, unsigned int bytes_done, int error) 433static int bi_complete(struct bio *bio, unsigned int bytes_done, int error)
@@ -610,7 +678,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
610 mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page); 678 mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page);
611 679
612 rdev->raid_disk = -1; 680 rdev->raid_disk = -1;
613 rdev->in_sync = 0; 681 rdev->flags = 0;
614 if (mddev->raid_disks == 0) { 682 if (mddev->raid_disks == 0) {
615 mddev->major_version = 0; 683 mddev->major_version = 0;
616 mddev->minor_version = sb->minor_version; 684 mddev->minor_version = sb->minor_version;
@@ -671,21 +739,19 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
671 return 0; 739 return 0;
672 740
673 if (mddev->level != LEVEL_MULTIPATH) { 741 if (mddev->level != LEVEL_MULTIPATH) {
674 rdev->faulty = 0;
675 rdev->flags = 0;
676 desc = sb->disks + rdev->desc_nr; 742 desc = sb->disks + rdev->desc_nr;
677 743
678 if (desc->state & (1<<MD_DISK_FAULTY)) 744 if (desc->state & (1<<MD_DISK_FAULTY))
679 rdev->faulty = 1; 745 set_bit(Faulty, &rdev->flags);
680 else if (desc->state & (1<<MD_DISK_SYNC) && 746 else if (desc->state & (1<<MD_DISK_SYNC) &&
681 desc->raid_disk < mddev->raid_disks) { 747 desc->raid_disk < mddev->raid_disks) {
682 rdev->in_sync = 1; 748 set_bit(In_sync, &rdev->flags);
683 rdev->raid_disk = desc->raid_disk; 749 rdev->raid_disk = desc->raid_disk;
684 } 750 }
685 if (desc->state & (1<<MD_DISK_WRITEMOSTLY)) 751 if (desc->state & (1<<MD_DISK_WRITEMOSTLY))
686 set_bit(WriteMostly, &rdev->flags); 752 set_bit(WriteMostly, &rdev->flags);
687 } else /* MULTIPATH are always insync */ 753 } else /* MULTIPATH are always insync */
688 rdev->in_sync = 1; 754 set_bit(In_sync, &rdev->flags);
689 return 0; 755 return 0;
690} 756}
691 757
@@ -699,6 +765,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
699 mdk_rdev_t *rdev2; 765 mdk_rdev_t *rdev2;
700 int next_spare = mddev->raid_disks; 766 int next_spare = mddev->raid_disks;
701 767
768
702 /* make rdev->sb match mddev data.. 769 /* make rdev->sb match mddev data..
703 * 770 *
704 * 1/ zero out disks 771 * 1/ zero out disks
@@ -758,23 +825,27 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
758 sb->disks[0].state = (1<<MD_DISK_REMOVED); 825 sb->disks[0].state = (1<<MD_DISK_REMOVED);
759 ITERATE_RDEV(mddev,rdev2,tmp) { 826 ITERATE_RDEV(mddev,rdev2,tmp) {
760 mdp_disk_t *d; 827 mdp_disk_t *d;
761 if (rdev2->raid_disk >= 0 && rdev2->in_sync && !rdev2->faulty) 828 int desc_nr;
762 rdev2->desc_nr = rdev2->raid_disk; 829 if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
830 && !test_bit(Faulty, &rdev2->flags))
831 desc_nr = rdev2->raid_disk;
763 else 832 else
764 rdev2->desc_nr = next_spare++; 833 desc_nr = next_spare++;
834 rdev2->desc_nr = desc_nr;
765 d = &sb->disks[rdev2->desc_nr]; 835 d = &sb->disks[rdev2->desc_nr];
766 nr_disks++; 836 nr_disks++;
767 d->number = rdev2->desc_nr; 837 d->number = rdev2->desc_nr;
768 d->major = MAJOR(rdev2->bdev->bd_dev); 838 d->major = MAJOR(rdev2->bdev->bd_dev);
769 d->minor = MINOR(rdev2->bdev->bd_dev); 839 d->minor = MINOR(rdev2->bdev->bd_dev);
770 if (rdev2->raid_disk >= 0 && rdev->in_sync && !rdev2->faulty) 840 if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
841 && !test_bit(Faulty, &rdev2->flags))
771 d->raid_disk = rdev2->raid_disk; 842 d->raid_disk = rdev2->raid_disk;
772 else 843 else
773 d->raid_disk = rdev2->desc_nr; /* compatibility */ 844 d->raid_disk = rdev2->desc_nr; /* compatibility */
774 if (rdev2->faulty) { 845 if (test_bit(Faulty, &rdev2->flags)) {
775 d->state = (1<<MD_DISK_FAULTY); 846 d->state = (1<<MD_DISK_FAULTY);
776 failed++; 847 failed++;
777 } else if (rdev2->in_sync) { 848 } else if (test_bit(In_sync, &rdev2->flags)) {
778 d->state = (1<<MD_DISK_ACTIVE); 849 d->state = (1<<MD_DISK_ACTIVE);
779 d->state |= (1<<MD_DISK_SYNC); 850 d->state |= (1<<MD_DISK_SYNC);
780 active++; 851 active++;
@@ -787,7 +858,6 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
787 if (test_bit(WriteMostly, &rdev2->flags)) 858 if (test_bit(WriteMostly, &rdev2->flags))
788 d->state |= (1<<MD_DISK_WRITEMOSTLY); 859 d->state |= (1<<MD_DISK_WRITEMOSTLY);
789 } 860 }
790
791 /* now set the "removed" and "faulty" bits on any missing devices */ 861 /* now set the "removed" and "faulty" bits on any missing devices */
792 for (i=0 ; i < mddev->raid_disks ; i++) { 862 for (i=0 ; i < mddev->raid_disks ; i++) {
793 mdp_disk_t *d = &sb->disks[i]; 863 mdp_disk_t *d = &sb->disks[i];
@@ -944,7 +1014,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
944 struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page); 1014 struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page);
945 1015
946 rdev->raid_disk = -1; 1016 rdev->raid_disk = -1;
947 rdev->in_sync = 0; 1017 rdev->flags = 0;
948 if (mddev->raid_disks == 0) { 1018 if (mddev->raid_disks == 0) {
949 mddev->major_version = 1; 1019 mddev->major_version = 1;
950 mddev->patch_version = 0; 1020 mddev->patch_version = 0;
@@ -996,22 +1066,19 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
996 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); 1066 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]);
997 switch(role) { 1067 switch(role) {
998 case 0xffff: /* spare */ 1068 case 0xffff: /* spare */
999 rdev->faulty = 0;
1000 break; 1069 break;
1001 case 0xfffe: /* faulty */ 1070 case 0xfffe: /* faulty */
1002 rdev->faulty = 1; 1071 set_bit(Faulty, &rdev->flags);
1003 break; 1072 break;
1004 default: 1073 default:
1005 rdev->in_sync = 1; 1074 set_bit(In_sync, &rdev->flags);
1006 rdev->faulty = 0;
1007 rdev->raid_disk = role; 1075 rdev->raid_disk = role;
1008 break; 1076 break;
1009 } 1077 }
1010 rdev->flags = 0;
1011 if (sb->devflags & WriteMostly1) 1078 if (sb->devflags & WriteMostly1)
1012 set_bit(WriteMostly, &rdev->flags); 1079 set_bit(WriteMostly, &rdev->flags);
1013 } else /* MULTIPATH are always insync */ 1080 } else /* MULTIPATH are always insync */
1014 rdev->in_sync = 1; 1081 set_bit(In_sync, &rdev->flags);
1015 1082
1016 return 0; 1083 return 0;
1017} 1084}
@@ -1055,9 +1122,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
1055 1122
1056 ITERATE_RDEV(mddev,rdev2,tmp) { 1123 ITERATE_RDEV(mddev,rdev2,tmp) {
1057 i = rdev2->desc_nr; 1124 i = rdev2->desc_nr;
1058 if (rdev2->faulty) 1125 if (test_bit(Faulty, &rdev2->flags))
1059 sb->dev_roles[i] = cpu_to_le16(0xfffe); 1126 sb->dev_roles[i] = cpu_to_le16(0xfffe);
1060 else if (rdev2->in_sync) 1127 else if (test_bit(In_sync, &rdev2->flags))
1061 sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk); 1128 sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk);
1062 else 1129 else
1063 sb->dev_roles[i] = cpu_to_le16(0xffff); 1130 sb->dev_roles[i] = cpu_to_le16(0xffff);
@@ -1115,6 +1182,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1115{ 1182{
1116 mdk_rdev_t *same_pdev; 1183 mdk_rdev_t *same_pdev;
1117 char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; 1184 char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
1185 struct kobject *ko;
1118 1186
1119 if (rdev->mddev) { 1187 if (rdev->mddev) {
1120 MD_BUG(); 1188 MD_BUG();
@@ -1143,10 +1211,22 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1143 if (find_rdev_nr(mddev, rdev->desc_nr)) 1211 if (find_rdev_nr(mddev, rdev->desc_nr))
1144 return -EBUSY; 1212 return -EBUSY;
1145 } 1213 }
1214 bdevname(rdev->bdev,b);
1215 if (kobject_set_name(&rdev->kobj, "dev-%s", b) < 0)
1216 return -ENOMEM;
1146 1217
1147 list_add(&rdev->same_set, &mddev->disks); 1218 list_add(&rdev->same_set, &mddev->disks);
1148 rdev->mddev = mddev; 1219 rdev->mddev = mddev;
1149 printk(KERN_INFO "md: bind<%s>\n", bdevname(rdev->bdev,b)); 1220 printk(KERN_INFO "md: bind<%s>\n", b);
1221
1222 rdev->kobj.parent = &mddev->kobj;
1223 kobject_add(&rdev->kobj);
1224
1225 if (rdev->bdev->bd_part)
1226 ko = &rdev->bdev->bd_part->kobj;
1227 else
1228 ko = &rdev->bdev->bd_disk->kobj;
1229 sysfs_create_link(&rdev->kobj, ko, "block");
1150 return 0; 1230 return 0;
1151} 1231}
1152 1232
@@ -1160,6 +1240,8 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
1160 list_del_init(&rdev->same_set); 1240 list_del_init(&rdev->same_set);
1161 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); 1241 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
1162 rdev->mddev = NULL; 1242 rdev->mddev = NULL;
1243 sysfs_remove_link(&rdev->kobj, "block");
1244 kobject_del(&rdev->kobj);
1163} 1245}
1164 1246
1165/* 1247/*
@@ -1215,7 +1297,7 @@ static void export_rdev(mdk_rdev_t * rdev)
1215 md_autodetect_dev(rdev->bdev->bd_dev); 1297 md_autodetect_dev(rdev->bdev->bd_dev);
1216#endif 1298#endif
1217 unlock_rdev(rdev); 1299 unlock_rdev(rdev);
1218 kfree(rdev); 1300 kobject_put(&rdev->kobj);
1219} 1301}
1220 1302
1221static void kick_rdev_from_array(mdk_rdev_t * rdev) 1303static void kick_rdev_from_array(mdk_rdev_t * rdev)
@@ -1287,7 +1369,8 @@ static void print_rdev(mdk_rdev_t *rdev)
1287 char b[BDEVNAME_SIZE]; 1369 char b[BDEVNAME_SIZE];
1288 printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n", 1370 printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n",
1289 bdevname(rdev->bdev,b), (unsigned long long)rdev->size, 1371 bdevname(rdev->bdev,b), (unsigned long long)rdev->size,
1290 rdev->faulty, rdev->in_sync, rdev->desc_nr); 1372 test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags),
1373 rdev->desc_nr);
1291 if (rdev->sb_loaded) { 1374 if (rdev->sb_loaded) {
1292 printk(KERN_INFO "md: rdev superblock:\n"); 1375 printk(KERN_INFO "md: rdev superblock:\n");
1293 print_sb((mdp_super_t*)page_address(rdev->sb_page)); 1376 print_sb((mdp_super_t*)page_address(rdev->sb_page));
@@ -1344,7 +1427,7 @@ static void md_update_sb(mddev_t * mddev)
1344 int sync_req; 1427 int sync_req;
1345 1428
1346repeat: 1429repeat:
1347 spin_lock(&mddev->write_lock); 1430 spin_lock_irq(&mddev->write_lock);
1348 sync_req = mddev->in_sync; 1431 sync_req = mddev->in_sync;
1349 mddev->utime = get_seconds(); 1432 mddev->utime = get_seconds();
1350 mddev->events ++; 1433 mddev->events ++;
@@ -1367,11 +1450,11 @@ repeat:
1367 */ 1450 */
1368 if (!mddev->persistent) { 1451 if (!mddev->persistent) {
1369 mddev->sb_dirty = 0; 1452 mddev->sb_dirty = 0;
1370 spin_unlock(&mddev->write_lock); 1453 spin_unlock_irq(&mddev->write_lock);
1371 wake_up(&mddev->sb_wait); 1454 wake_up(&mddev->sb_wait);
1372 return; 1455 return;
1373 } 1456 }
1374 spin_unlock(&mddev->write_lock); 1457 spin_unlock_irq(&mddev->write_lock);
1375 1458
1376 dprintk(KERN_INFO 1459 dprintk(KERN_INFO
1377 "md: updating %s RAID superblock on device (in sync %d)\n", 1460 "md: updating %s RAID superblock on device (in sync %d)\n",
@@ -1381,11 +1464,11 @@ repeat:
1381 ITERATE_RDEV(mddev,rdev,tmp) { 1464 ITERATE_RDEV(mddev,rdev,tmp) {
1382 char b[BDEVNAME_SIZE]; 1465 char b[BDEVNAME_SIZE];
1383 dprintk(KERN_INFO "md: "); 1466 dprintk(KERN_INFO "md: ");
1384 if (rdev->faulty) 1467 if (test_bit(Faulty, &rdev->flags))
1385 dprintk("(skipping faulty "); 1468 dprintk("(skipping faulty ");
1386 1469
1387 dprintk("%s ", bdevname(rdev->bdev,b)); 1470 dprintk("%s ", bdevname(rdev->bdev,b));
1388 if (!rdev->faulty) { 1471 if (!test_bit(Faulty, &rdev->flags)) {
1389 md_super_write(mddev,rdev, 1472 md_super_write(mddev,rdev,
1390 rdev->sb_offset<<1, rdev->sb_size, 1473 rdev->sb_offset<<1, rdev->sb_size,
1391 rdev->sb_page); 1474 rdev->sb_page);
@@ -1399,21 +1482,106 @@ repeat:
1399 /* only need to write one superblock... */ 1482 /* only need to write one superblock... */
1400 break; 1483 break;
1401 } 1484 }
1402 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 1485 md_super_wait(mddev);
1403 /* if there was a failure, sb_dirty was set to 1, and we re-write super */ 1486 /* if there was a failure, sb_dirty was set to 1, and we re-write super */
1404 1487
1405 spin_lock(&mddev->write_lock); 1488 spin_lock_irq(&mddev->write_lock);
1406 if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) { 1489 if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) {
1407 /* have to write it out again */ 1490 /* have to write it out again */
1408 spin_unlock(&mddev->write_lock); 1491 spin_unlock_irq(&mddev->write_lock);
1409 goto repeat; 1492 goto repeat;
1410 } 1493 }
1411 mddev->sb_dirty = 0; 1494 mddev->sb_dirty = 0;
1412 spin_unlock(&mddev->write_lock); 1495 spin_unlock_irq(&mddev->write_lock);
1413 wake_up(&mddev->sb_wait); 1496 wake_up(&mddev->sb_wait);
1414 1497
1415} 1498}
1416 1499
1500struct rdev_sysfs_entry {
1501 struct attribute attr;
1502 ssize_t (*show)(mdk_rdev_t *, char *);
1503 ssize_t (*store)(mdk_rdev_t *, const char *, size_t);
1504};
1505
1506static ssize_t
1507state_show(mdk_rdev_t *rdev, char *page)
1508{
1509 char *sep = "";
1510 int len=0;
1511
1512 if (test_bit(Faulty, &rdev->flags)) {
1513 len+= sprintf(page+len, "%sfaulty",sep);
1514 sep = ",";
1515 }
1516 if (test_bit(In_sync, &rdev->flags)) {
1517 len += sprintf(page+len, "%sin_sync",sep);
1518 sep = ",";
1519 }
1520 if (!test_bit(Faulty, &rdev->flags) &&
1521 !test_bit(In_sync, &rdev->flags)) {
1522 len += sprintf(page+len, "%sspare", sep);
1523 sep = ",";
1524 }
1525 return len+sprintf(page+len, "\n");
1526}
1527
1528static struct rdev_sysfs_entry
1529rdev_state = __ATTR_RO(state);
1530
1531static ssize_t
1532super_show(mdk_rdev_t *rdev, char *page)
1533{
1534 if (rdev->sb_loaded && rdev->sb_size) {
1535 memcpy(page, page_address(rdev->sb_page), rdev->sb_size);
1536 return rdev->sb_size;
1537 } else
1538 return 0;
1539}
1540static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super);
1541
1542static struct attribute *rdev_default_attrs[] = {
1543 &rdev_state.attr,
1544 &rdev_super.attr,
1545 NULL,
1546};
1547static ssize_t
1548rdev_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
1549{
1550 struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
1551 mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
1552
1553 if (!entry->show)
1554 return -EIO;
1555 return entry->show(rdev, page);
1556}
1557
1558static ssize_t
1559rdev_attr_store(struct kobject *kobj, struct attribute *attr,
1560 const char *page, size_t length)
1561{
1562 struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
1563 mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
1564
1565 if (!entry->store)
1566 return -EIO;
1567 return entry->store(rdev, page, length);
1568}
1569
1570static void rdev_free(struct kobject *ko)
1571{
1572 mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj);
1573 kfree(rdev);
1574}
1575static struct sysfs_ops rdev_sysfs_ops = {
1576 .show = rdev_attr_show,
1577 .store = rdev_attr_store,
1578};
1579static struct kobj_type rdev_ktype = {
1580 .release = rdev_free,
1581 .sysfs_ops = &rdev_sysfs_ops,
1582 .default_attrs = rdev_default_attrs,
1583};
1584
1417/* 1585/*
1418 * Import a device. If 'super_format' >= 0, then sanity check the superblock 1586 * Import a device. If 'super_format' >= 0, then sanity check the superblock
1419 * 1587 *
@@ -1445,11 +1613,15 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
1445 if (err) 1613 if (err)
1446 goto abort_free; 1614 goto abort_free;
1447 1615
1616 rdev->kobj.parent = NULL;
1617 rdev->kobj.ktype = &rdev_ktype;
1618 kobject_init(&rdev->kobj);
1619
1448 rdev->desc_nr = -1; 1620 rdev->desc_nr = -1;
1449 rdev->faulty = 0; 1621 rdev->flags = 0;
1450 rdev->in_sync = 0;
1451 rdev->data_offset = 0; 1622 rdev->data_offset = 0;
1452 atomic_set(&rdev->nr_pending, 0); 1623 atomic_set(&rdev->nr_pending, 0);
1624 atomic_set(&rdev->read_errors, 0);
1453 1625
1454 size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; 1626 size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
1455 if (!size) { 1627 if (!size) {
@@ -1537,7 +1709,7 @@ static void analyze_sbs(mddev_t * mddev)
1537 if (mddev->level == LEVEL_MULTIPATH) { 1709 if (mddev->level == LEVEL_MULTIPATH) {
1538 rdev->desc_nr = i++; 1710 rdev->desc_nr = i++;
1539 rdev->raid_disk = rdev->desc_nr; 1711 rdev->raid_disk = rdev->desc_nr;
1540 rdev->in_sync = 1; 1712 set_bit(In_sync, &rdev->flags);
1541 } 1713 }
1542 } 1714 }
1543 1715
@@ -1551,6 +1723,162 @@ static void analyze_sbs(mddev_t * mddev)
1551 1723
1552} 1724}
1553 1725
1726static ssize_t
1727level_show(mddev_t *mddev, char *page)
1728{
1729 mdk_personality_t *p = mddev->pers;
1730 if (p == NULL && mddev->raid_disks == 0)
1731 return 0;
1732 if (mddev->level >= 0)
1733 return sprintf(page, "RAID-%d\n", mddev->level);
1734 else
1735 return sprintf(page, "%s\n", p->name);
1736}
1737
1738static struct md_sysfs_entry md_level = __ATTR_RO(level);
1739
1740static ssize_t
1741raid_disks_show(mddev_t *mddev, char *page)
1742{
1743 if (mddev->raid_disks == 0)
1744 return 0;
1745 return sprintf(page, "%d\n", mddev->raid_disks);
1746}
1747
1748static struct md_sysfs_entry md_raid_disks = __ATTR_RO(raid_disks);
1749
1750static ssize_t
1751action_show(mddev_t *mddev, char *page)
1752{
1753 char *type = "idle";
1754 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
1755 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) {
1756 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
1757 if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
1758 type = "resync";
1759 else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
1760 type = "check";
1761 else
1762 type = "repair";
1763 } else
1764 type = "recover";
1765 }
1766 return sprintf(page, "%s\n", type);
1767}
1768
1769static ssize_t
1770action_store(mddev_t *mddev, const char *page, size_t len)
1771{
1772 if (!mddev->pers || !mddev->pers->sync_request)
1773 return -EINVAL;
1774
1775 if (strcmp(page, "idle")==0 || strcmp(page, "idle\n")==0) {
1776 if (mddev->sync_thread) {
1777 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
1778 md_unregister_thread(mddev->sync_thread);
1779 mddev->sync_thread = NULL;
1780 mddev->recovery = 0;
1781 }
1782 return len;
1783 }
1784
1785 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
1786 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
1787 return -EBUSY;
1788 if (strcmp(page, "resync")==0 || strcmp(page, "resync\n")==0 ||
1789 strcmp(page, "recover")==0 || strcmp(page, "recover\n")==0)
1790 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1791 else {
1792 if (strcmp(page, "check")==0 || strcmp(page, "check\n")==0)
1793 set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
1794 else if (strcmp(page, "repair")!=0 && strcmp(page, "repair\n")!=0)
1795 return -EINVAL;
1796 set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
1797 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
1798 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1799 }
1800 md_wakeup_thread(mddev->thread);
1801 return len;
1802}
1803
1804static ssize_t
1805mismatch_cnt_show(mddev_t *mddev, char *page)
1806{
1807 return sprintf(page, "%llu\n",
1808 (unsigned long long) mddev->resync_mismatches);
1809}
1810
1811static struct md_sysfs_entry
1812md_scan_mode = __ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
1813
1814
1815static struct md_sysfs_entry
1816md_mismatches = __ATTR_RO(mismatch_cnt);
1817
1818static struct attribute *md_default_attrs[] = {
1819 &md_level.attr,
1820 &md_raid_disks.attr,
1821 NULL,
1822};
1823
1824static struct attribute *md_redundancy_attrs[] = {
1825 &md_scan_mode.attr,
1826 &md_mismatches.attr,
1827 NULL,
1828};
1829static struct attribute_group md_redundancy_group = {
1830 .name = NULL,
1831 .attrs = md_redundancy_attrs,
1832};
1833
1834
1835static ssize_t
1836md_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
1837{
1838 struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
1839 mddev_t *mddev = container_of(kobj, struct mddev_s, kobj);
1840 ssize_t rv;
1841
1842 if (!entry->show)
1843 return -EIO;
1844 mddev_lock(mddev);
1845 rv = entry->show(mddev, page);
1846 mddev_unlock(mddev);
1847 return rv;
1848}
1849
1850static ssize_t
1851md_attr_store(struct kobject *kobj, struct attribute *attr,
1852 const char *page, size_t length)
1853{
1854 struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
1855 mddev_t *mddev = container_of(kobj, struct mddev_s, kobj);
1856 ssize_t rv;
1857
1858 if (!entry->store)
1859 return -EIO;
1860 mddev_lock(mddev);
1861 rv = entry->store(mddev, page, length);
1862 mddev_unlock(mddev);
1863 return rv;
1864}
1865
1866static void md_free(struct kobject *ko)
1867{
1868 mddev_t *mddev = container_of(ko, mddev_t, kobj);
1869 kfree(mddev);
1870}
1871
1872static struct sysfs_ops md_sysfs_ops = {
1873 .show = md_attr_show,
1874 .store = md_attr_store,
1875};
1876static struct kobj_type md_ktype = {
1877 .release = md_free,
1878 .sysfs_ops = &md_sysfs_ops,
1879 .default_attrs = md_default_attrs,
1880};
1881
1554int mdp_major = 0; 1882int mdp_major = 0;
1555 1883
1556static struct kobject *md_probe(dev_t dev, int *part, void *data) 1884static struct kobject *md_probe(dev_t dev, int *part, void *data)
@@ -1592,6 +1920,11 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
1592 add_disk(disk); 1920 add_disk(disk);
1593 mddev->gendisk = disk; 1921 mddev->gendisk = disk;
1594 up(&disks_sem); 1922 up(&disks_sem);
1923 mddev->kobj.parent = &disk->kobj;
1924 mddev->kobj.k_name = NULL;
1925 snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md");
1926 mddev->kobj.ktype = &md_ktype;
1927 kobject_register(&mddev->kobj);
1595 return NULL; 1928 return NULL;
1596} 1929}
1597 1930
@@ -1663,7 +1996,7 @@ static int do_md_run(mddev_t * mddev)
1663 1996
1664 /* devices must have minimum size of one chunk */ 1997 /* devices must have minimum size of one chunk */
1665 ITERATE_RDEV(mddev,rdev,tmp) { 1998 ITERATE_RDEV(mddev,rdev,tmp) {
1666 if (rdev->faulty) 1999 if (test_bit(Faulty, &rdev->flags))
1667 continue; 2000 continue;
1668 if (rdev->size < chunk_size / 1024) { 2001 if (rdev->size < chunk_size / 1024) {
1669 printk(KERN_WARNING 2002 printk(KERN_WARNING
@@ -1691,7 +2024,7 @@ static int do_md_run(mddev_t * mddev)
1691 * Also find largest hardsector size 2024 * Also find largest hardsector size
1692 */ 2025 */
1693 ITERATE_RDEV(mddev,rdev,tmp) { 2026 ITERATE_RDEV(mddev,rdev,tmp) {
1694 if (rdev->faulty) 2027 if (test_bit(Faulty, &rdev->flags))
1695 continue; 2028 continue;
1696 sync_blockdev(rdev->bdev); 2029 sync_blockdev(rdev->bdev);
1697 invalidate_bdev(rdev->bdev, 0); 2030 invalidate_bdev(rdev->bdev, 0);
@@ -1715,6 +2048,10 @@ static int do_md_run(mddev_t * mddev)
1715 2048
1716 mddev->recovery = 0; 2049 mddev->recovery = 0;
1717 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ 2050 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
2051 mddev->barriers_work = 1;
2052
2053 if (start_readonly)
2054 mddev->ro = 2; /* read-only, but switch on first write */
1718 2055
1719 /* before we start the array running, initialise the bitmap */ 2056 /* before we start the array running, initialise the bitmap */
1720 err = bitmap_create(mddev); 2057 err = bitmap_create(mddev);
@@ -1730,12 +2067,24 @@ static int do_md_run(mddev_t * mddev)
1730 bitmap_destroy(mddev); 2067 bitmap_destroy(mddev);
1731 return err; 2068 return err;
1732 } 2069 }
2070 if (mddev->pers->sync_request)
2071 sysfs_create_group(&mddev->kobj, &md_redundancy_group);
2072 else if (mddev->ro == 2) /* auto-readonly not meaningful */
2073 mddev->ro = 0;
2074
1733 atomic_set(&mddev->writes_pending,0); 2075 atomic_set(&mddev->writes_pending,0);
1734 mddev->safemode = 0; 2076 mddev->safemode = 0;
1735 mddev->safemode_timer.function = md_safemode_timeout; 2077 mddev->safemode_timer.function = md_safemode_timeout;
1736 mddev->safemode_timer.data = (unsigned long) mddev; 2078 mddev->safemode_timer.data = (unsigned long) mddev;
1737 mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */ 2079 mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */
1738 mddev->in_sync = 1; 2080 mddev->in_sync = 1;
2081
2082 ITERATE_RDEV(mddev,rdev,tmp)
2083 if (rdev->raid_disk >= 0) {
2084 char nm[20];
2085 sprintf(nm, "rd%d", rdev->raid_disk);
2086 sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
2087 }
1739 2088
1740 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 2089 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1741 md_wakeup_thread(mddev->thread); 2090 md_wakeup_thread(mddev->thread);
@@ -1821,16 +2170,19 @@ static int do_md_stop(mddev_t * mddev, int ro)
1821 2170
1822 if (ro) { 2171 if (ro) {
1823 err = -ENXIO; 2172 err = -ENXIO;
1824 if (mddev->ro) 2173 if (mddev->ro==1)
1825 goto out; 2174 goto out;
1826 mddev->ro = 1; 2175 mddev->ro = 1;
1827 } else { 2176 } else {
1828 bitmap_flush(mddev); 2177 bitmap_flush(mddev);
1829 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 2178 md_super_wait(mddev);
1830 if (mddev->ro) 2179 if (mddev->ro)
1831 set_disk_ro(disk, 0); 2180 set_disk_ro(disk, 0);
1832 blk_queue_make_request(mddev->queue, md_fail_request); 2181 blk_queue_make_request(mddev->queue, md_fail_request);
1833 mddev->pers->stop(mddev); 2182 mddev->pers->stop(mddev);
2183 if (mddev->pers->sync_request)
2184 sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
2185
1834 module_put(mddev->pers->owner); 2186 module_put(mddev->pers->owner);
1835 mddev->pers = NULL; 2187 mddev->pers = NULL;
1836 if (mddev->ro) 2188 if (mddev->ro)
@@ -1857,9 +2209,18 @@ static int do_md_stop(mddev_t * mddev, int ro)
1857 * Free resources if final stop 2209 * Free resources if final stop
1858 */ 2210 */
1859 if (!ro) { 2211 if (!ro) {
2212 mdk_rdev_t *rdev;
2213 struct list_head *tmp;
1860 struct gendisk *disk; 2214 struct gendisk *disk;
1861 printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); 2215 printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
1862 2216
2217 ITERATE_RDEV(mddev,rdev,tmp)
2218 if (rdev->raid_disk >= 0) {
2219 char nm[20];
2220 sprintf(nm, "rd%d", rdev->raid_disk);
2221 sysfs_remove_link(&mddev->kobj, nm);
2222 }
2223
1863 export_array(mddev); 2224 export_array(mddev);
1864 2225
1865 mddev->array_size = 0; 2226 mddev->array_size = 0;
@@ -2012,7 +2373,7 @@ static int autostart_array(dev_t startdev)
2012 return err; 2373 return err;
2013 } 2374 }
2014 2375
2015 if (start_rdev->faulty) { 2376 if (test_bit(Faulty, &start_rdev->flags)) {
2016 printk(KERN_WARNING 2377 printk(KERN_WARNING
2017 "md: can not autostart based on faulty %s!\n", 2378 "md: can not autostart based on faulty %s!\n",
2018 bdevname(start_rdev->bdev,b)); 2379 bdevname(start_rdev->bdev,b));
@@ -2071,11 +2432,11 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
2071 nr=working=active=failed=spare=0; 2432 nr=working=active=failed=spare=0;
2072 ITERATE_RDEV(mddev,rdev,tmp) { 2433 ITERATE_RDEV(mddev,rdev,tmp) {
2073 nr++; 2434 nr++;
2074 if (rdev->faulty) 2435 if (test_bit(Faulty, &rdev->flags))
2075 failed++; 2436 failed++;
2076 else { 2437 else {
2077 working++; 2438 working++;
2078 if (rdev->in_sync) 2439 if (test_bit(In_sync, &rdev->flags))
2079 active++; 2440 active++;
2080 else 2441 else
2081 spare++; 2442 spare++;
@@ -2166,9 +2527,9 @@ static int get_disk_info(mddev_t * mddev, void __user * arg)
2166 info.minor = MINOR(rdev->bdev->bd_dev); 2527 info.minor = MINOR(rdev->bdev->bd_dev);
2167 info.raid_disk = rdev->raid_disk; 2528 info.raid_disk = rdev->raid_disk;
2168 info.state = 0; 2529 info.state = 0;
2169 if (rdev->faulty) 2530 if (test_bit(Faulty, &rdev->flags))
2170 info.state |= (1<<MD_DISK_FAULTY); 2531 info.state |= (1<<MD_DISK_FAULTY);
2171 else if (rdev->in_sync) { 2532 else if (test_bit(In_sync, &rdev->flags)) {
2172 info.state |= (1<<MD_DISK_ACTIVE); 2533 info.state |= (1<<MD_DISK_ACTIVE);
2173 info.state |= (1<<MD_DISK_SYNC); 2534 info.state |= (1<<MD_DISK_SYNC);
2174 } 2535 }
@@ -2261,7 +2622,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
2261 validate_super(mddev, rdev); 2622 validate_super(mddev, rdev);
2262 rdev->saved_raid_disk = rdev->raid_disk; 2623 rdev->saved_raid_disk = rdev->raid_disk;
2263 2624
2264 rdev->in_sync = 0; /* just to be sure */ 2625 clear_bit(In_sync, &rdev->flags); /* just to be sure */
2265 if (info->state & (1<<MD_DISK_WRITEMOSTLY)) 2626 if (info->state & (1<<MD_DISK_WRITEMOSTLY))
2266 set_bit(WriteMostly, &rdev->flags); 2627 set_bit(WriteMostly, &rdev->flags);
2267 2628
@@ -2299,11 +2660,11 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
2299 else 2660 else
2300 rdev->raid_disk = -1; 2661 rdev->raid_disk = -1;
2301 2662
2302 rdev->faulty = 0; 2663 rdev->flags = 0;
2664
2303 if (rdev->raid_disk < mddev->raid_disks) 2665 if (rdev->raid_disk < mddev->raid_disks)
2304 rdev->in_sync = (info->state & (1<<MD_DISK_SYNC)); 2666 if (info->state & (1<<MD_DISK_SYNC))
2305 else 2667 set_bit(In_sync, &rdev->flags);
2306 rdev->in_sync = 0;
2307 2668
2308 if (info->state & (1<<MD_DISK_WRITEMOSTLY)) 2669 if (info->state & (1<<MD_DISK_WRITEMOSTLY))
2309 set_bit(WriteMostly, &rdev->flags); 2670 set_bit(WriteMostly, &rdev->flags);
@@ -2402,14 +2763,14 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
2402 goto abort_export; 2763 goto abort_export;
2403 } 2764 }
2404 2765
2405 if (rdev->faulty) { 2766 if (test_bit(Faulty, &rdev->flags)) {
2406 printk(KERN_WARNING 2767 printk(KERN_WARNING
2407 "md: can not hot-add faulty %s disk to %s!\n", 2768 "md: can not hot-add faulty %s disk to %s!\n",
2408 bdevname(rdev->bdev,b), mdname(mddev)); 2769 bdevname(rdev->bdev,b), mdname(mddev));
2409 err = -EINVAL; 2770 err = -EINVAL;
2410 goto abort_export; 2771 goto abort_export;
2411 } 2772 }
2412 rdev->in_sync = 0; 2773 clear_bit(In_sync, &rdev->flags);
2413 rdev->desc_nr = -1; 2774 rdev->desc_nr = -1;
2414 bind_rdev_to_array(rdev, mddev); 2775 bind_rdev_to_array(rdev, mddev);
2415 2776
@@ -2929,12 +3290,22 @@ static int md_ioctl(struct inode *inode, struct file *file,
2929 3290
2930 /* 3291 /*
2931 * The remaining ioctls are changing the state of the 3292 * The remaining ioctls are changing the state of the
2932 * superblock, so we do not allow read-only arrays 3293 * superblock, so we do not allow them on read-only arrays.
2933 * here: 3294 * However non-MD ioctls (e.g. get-size) will still come through
3295 * here and hit the 'default' below, so only disallow
3296 * 'md' ioctls, and switch to rw mode if started auto-readonly.
2934 */ 3297 */
2935 if (mddev->ro) { 3298 if (_IOC_TYPE(cmd) == MD_MAJOR &&
2936 err = -EROFS; 3299 mddev->ro && mddev->pers) {
2937 goto abort_unlock; 3300 if (mddev->ro == 2) {
3301 mddev->ro = 0;
3302 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3303 md_wakeup_thread(mddev->thread);
3304
3305 } else {
3306 err = -EROFS;
3307 goto abort_unlock;
3308 }
2938 } 3309 }
2939 3310
2940 switch (cmd) 3311 switch (cmd)
@@ -3064,21 +3435,17 @@ static int md_thread(void * arg)
3064 */ 3435 */
3065 3436
3066 allow_signal(SIGKILL); 3437 allow_signal(SIGKILL);
3067 complete(thread->event);
3068 while (!kthread_should_stop()) { 3438 while (!kthread_should_stop()) {
3069 void (*run)(mddev_t *);
3070 3439
3071 wait_event_interruptible_timeout(thread->wqueue, 3440 wait_event_timeout(thread->wqueue,
3072 test_bit(THREAD_WAKEUP, &thread->flags) 3441 test_bit(THREAD_WAKEUP, &thread->flags)
3073 || kthread_should_stop(), 3442 || kthread_should_stop(),
3074 thread->timeout); 3443 thread->timeout);
3075 try_to_freeze(); 3444 try_to_freeze();
3076 3445
3077 clear_bit(THREAD_WAKEUP, &thread->flags); 3446 clear_bit(THREAD_WAKEUP, &thread->flags);
3078 3447
3079 run = thread->run; 3448 thread->run(thread->mddev);
3080 if (run)
3081 run(thread->mddev);
3082 } 3449 }
3083 3450
3084 return 0; 3451 return 0;
@@ -3097,7 +3464,6 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
3097 const char *name) 3464 const char *name)
3098{ 3465{
3099 mdk_thread_t *thread; 3466 mdk_thread_t *thread;
3100 struct completion event;
3101 3467
3102 thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL); 3468 thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL);
3103 if (!thread) 3469 if (!thread)
@@ -3106,18 +3472,14 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
3106 memset(thread, 0, sizeof(mdk_thread_t)); 3472 memset(thread, 0, sizeof(mdk_thread_t));
3107 init_waitqueue_head(&thread->wqueue); 3473 init_waitqueue_head(&thread->wqueue);
3108 3474
3109 init_completion(&event);
3110 thread->event = &event;
3111 thread->run = run; 3475 thread->run = run;
3112 thread->mddev = mddev; 3476 thread->mddev = mddev;
3113 thread->name = name;
3114 thread->timeout = MAX_SCHEDULE_TIMEOUT; 3477 thread->timeout = MAX_SCHEDULE_TIMEOUT;
3115 thread->tsk = kthread_run(md_thread, thread, name, mdname(thread->mddev)); 3478 thread->tsk = kthread_run(md_thread, thread, name, mdname(thread->mddev));
3116 if (IS_ERR(thread->tsk)) { 3479 if (IS_ERR(thread->tsk)) {
3117 kfree(thread); 3480 kfree(thread);
3118 return NULL; 3481 return NULL;
3119 } 3482 }
3120 wait_for_completion(&event);
3121 return thread; 3483 return thread;
3122} 3484}
3123 3485
@@ -3136,7 +3498,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
3136 return; 3498 return;
3137 } 3499 }
3138 3500
3139 if (!rdev || rdev->faulty) 3501 if (!rdev || test_bit(Faulty, &rdev->flags))
3140 return; 3502 return;
3141/* 3503/*
3142 dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n", 3504 dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",
@@ -3322,8 +3684,10 @@ static int md_seq_show(struct seq_file *seq, void *v)
3322 seq_printf(seq, "%s : %sactive", mdname(mddev), 3684 seq_printf(seq, "%s : %sactive", mdname(mddev),
3323 mddev->pers ? "" : "in"); 3685 mddev->pers ? "" : "in");
3324 if (mddev->pers) { 3686 if (mddev->pers) {
3325 if (mddev->ro) 3687 if (mddev->ro==1)
3326 seq_printf(seq, " (read-only)"); 3688 seq_printf(seq, " (read-only)");
3689 if (mddev->ro==2)
3690 seq_printf(seq, "(auto-read-only)");
3327 seq_printf(seq, " %s", mddev->pers->name); 3691 seq_printf(seq, " %s", mddev->pers->name);
3328 } 3692 }
3329 3693
@@ -3334,7 +3698,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
3334 bdevname(rdev->bdev,b), rdev->desc_nr); 3698 bdevname(rdev->bdev,b), rdev->desc_nr);
3335 if (test_bit(WriteMostly, &rdev->flags)) 3699 if (test_bit(WriteMostly, &rdev->flags))
3336 seq_printf(seq, "(W)"); 3700 seq_printf(seq, "(W)");
3337 if (rdev->faulty) { 3701 if (test_bit(Faulty, &rdev->flags)) {
3338 seq_printf(seq, "(F)"); 3702 seq_printf(seq, "(F)");
3339 continue; 3703 continue;
3340 } else if (rdev->raid_disk < 0) 3704 } else if (rdev->raid_disk < 0)
@@ -3363,11 +3727,15 @@ static int md_seq_show(struct seq_file *seq, void *v)
3363 if (mddev->pers) { 3727 if (mddev->pers) {
3364 mddev->pers->status (seq, mddev); 3728 mddev->pers->status (seq, mddev);
3365 seq_printf(seq, "\n "); 3729 seq_printf(seq, "\n ");
3366 if (mddev->curr_resync > 2) { 3730 if (mddev->pers->sync_request) {
3367 status_resync (seq, mddev); 3731 if (mddev->curr_resync > 2) {
3368 seq_printf(seq, "\n "); 3732 status_resync (seq, mddev);
3369 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) 3733 seq_printf(seq, "\n ");
3370 seq_printf(seq, " resync=DELAYED\n "); 3734 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
3735 seq_printf(seq, "\tresync=DELAYED\n ");
3736 else if (mddev->recovery_cp < MaxSector)
3737 seq_printf(seq, "\tresync=PENDING\n ");
3738 }
3371 } else 3739 } else
3372 seq_printf(seq, "\n "); 3740 seq_printf(seq, "\n ");
3373 3741
@@ -3504,15 +3872,22 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
3504 if (bio_data_dir(bi) != WRITE) 3872 if (bio_data_dir(bi) != WRITE)
3505 return; 3873 return;
3506 3874
3875 BUG_ON(mddev->ro == 1);
3876 if (mddev->ro == 2) {
3877 /* need to switch to read/write */
3878 mddev->ro = 0;
3879 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3880 md_wakeup_thread(mddev->thread);
3881 }
3507 atomic_inc(&mddev->writes_pending); 3882 atomic_inc(&mddev->writes_pending);
3508 if (mddev->in_sync) { 3883 if (mddev->in_sync) {
3509 spin_lock(&mddev->write_lock); 3884 spin_lock_irq(&mddev->write_lock);
3510 if (mddev->in_sync) { 3885 if (mddev->in_sync) {
3511 mddev->in_sync = 0; 3886 mddev->in_sync = 0;
3512 mddev->sb_dirty = 1; 3887 mddev->sb_dirty = 1;
3513 md_wakeup_thread(mddev->thread); 3888 md_wakeup_thread(mddev->thread);
3514 } 3889 }
3515 spin_unlock(&mddev->write_lock); 3890 spin_unlock_irq(&mddev->write_lock);
3516 } 3891 }
3517 wait_event(mddev->sb_wait, mddev->sb_dirty==0); 3892 wait_event(mddev->sb_wait, mddev->sb_dirty==0);
3518} 3893}
@@ -3568,9 +3943,7 @@ static void md_do_sync(mddev_t *mddev)
3568 mddev->curr_resync = 2; 3943 mddev->curr_resync = 2;
3569 3944
3570 try_again: 3945 try_again:
3571 if (signal_pending(current) || 3946 if (kthread_should_stop()) {
3572 kthread_should_stop()) {
3573 flush_signals(current);
3574 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 3947 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
3575 goto skip; 3948 goto skip;
3576 } 3949 }
@@ -3590,9 +3963,8 @@ static void md_do_sync(mddev_t *mddev)
3590 * time 'round when curr_resync == 2 3963 * time 'round when curr_resync == 2
3591 */ 3964 */
3592 continue; 3965 continue;
3593 prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE); 3966 prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE);
3594 if (!signal_pending(current) && 3967 if (!kthread_should_stop() &&
3595 !kthread_should_stop() &&
3596 mddev2->curr_resync >= mddev->curr_resync) { 3968 mddev2->curr_resync >= mddev->curr_resync) {
3597 printk(KERN_INFO "md: delaying resync of %s" 3969 printk(KERN_INFO "md: delaying resync of %s"
3598 " until %s has finished resync (they" 3970 " until %s has finished resync (they"
@@ -3608,12 +3980,13 @@ static void md_do_sync(mddev_t *mddev)
3608 } 3980 }
3609 } while (mddev->curr_resync < 2); 3981 } while (mddev->curr_resync < 2);
3610 3982
3611 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) 3983 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
3612 /* resync follows the size requested by the personality, 3984 /* resync follows the size requested by the personality,
3613 * which defaults to physical size, but can be virtual size 3985 * which defaults to physical size, but can be virtual size
3614 */ 3986 */
3615 max_sectors = mddev->resync_max_sectors; 3987 max_sectors = mddev->resync_max_sectors;
3616 else 3988 mddev->resync_mismatches = 0;
3989 } else
3617 /* recovery follows the physical size of devices */ 3990 /* recovery follows the physical size of devices */
3618 max_sectors = mddev->size << 1; 3991 max_sectors = mddev->size << 1;
3619 3992
@@ -3626,7 +3999,8 @@ static void md_do_sync(mddev_t *mddev)
3626 3999
3627 is_mddev_idle(mddev); /* this also initializes IO event counters */ 4000 is_mddev_idle(mddev); /* this also initializes IO event counters */
3628 /* we don't use the checkpoint if there's a bitmap */ 4001 /* we don't use the checkpoint if there's a bitmap */
3629 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap) 4002 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap
4003 && ! test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
3630 j = mddev->recovery_cp; 4004 j = mddev->recovery_cp;
3631 else 4005 else
3632 j = 0; 4006 j = 0;
@@ -3699,13 +4073,12 @@ static void md_do_sync(mddev_t *mddev)
3699 } 4073 }
3700 4074
3701 4075
3702 if (signal_pending(current) || kthread_should_stop()) { 4076 if (kthread_should_stop()) {
3703 /* 4077 /*
3704 * got a signal, exit. 4078 * got a signal, exit.
3705 */ 4079 */
3706 printk(KERN_INFO 4080 printk(KERN_INFO
3707 "md: md_do_sync() got signal ... exiting\n"); 4081 "md: md_do_sync() got signal ... exiting\n");
3708 flush_signals(current);
3709 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 4082 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
3710 goto out; 4083 goto out;
3711 } 4084 }
@@ -3727,7 +4100,7 @@ static void md_do_sync(mddev_t *mddev)
3727 if (currspeed > sysctl_speed_limit_min) { 4100 if (currspeed > sysctl_speed_limit_min) {
3728 if ((currspeed > sysctl_speed_limit_max) || 4101 if ((currspeed > sysctl_speed_limit_max) ||
3729 !is_mddev_idle(mddev)) { 4102 !is_mddev_idle(mddev)) {
3730 msleep_interruptible(250); 4103 msleep(250);
3731 goto repeat; 4104 goto repeat;
3732 } 4105 }
3733 } 4106 }
@@ -3820,7 +4193,7 @@ void md_check_recovery(mddev_t *mddev)
3820 if (mddev_trylock(mddev)==0) { 4193 if (mddev_trylock(mddev)==0) {
3821 int spares =0; 4194 int spares =0;
3822 4195
3823 spin_lock(&mddev->write_lock); 4196 spin_lock_irq(&mddev->write_lock);
3824 if (mddev->safemode && !atomic_read(&mddev->writes_pending) && 4197 if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
3825 !mddev->in_sync && mddev->recovery_cp == MaxSector) { 4198 !mddev->in_sync && mddev->recovery_cp == MaxSector) {
3826 mddev->in_sync = 1; 4199 mddev->in_sync = 1;
@@ -3828,7 +4201,7 @@ void md_check_recovery(mddev_t *mddev)
3828 } 4201 }
3829 if (mddev->safemode == 1) 4202 if (mddev->safemode == 1)
3830 mddev->safemode = 0; 4203 mddev->safemode = 0;
3831 spin_unlock(&mddev->write_lock); 4204 spin_unlock_irq(&mddev->write_lock);
3832 4205
3833 if (mddev->sb_dirty) 4206 if (mddev->sb_dirty)
3834 md_update_sb(mddev); 4207 md_update_sb(mddev);
@@ -3864,9 +4237,13 @@ void md_check_recovery(mddev_t *mddev)
3864 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 4237 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3865 goto unlock; 4238 goto unlock;
3866 } 4239 }
3867 if (mddev->recovery) 4240 /* Clear some bits that don't mean anything, but
3868 /* probably just the RECOVERY_NEEDED flag */ 4241 * might be left set
3869 mddev->recovery = 0; 4242 */
4243 clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
4244 clear_bit(MD_RECOVERY_ERR, &mddev->recovery);
4245 clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
4246 clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
3870 4247
3871 /* no recovery is running. 4248 /* no recovery is running.
3872 * remove any failed drives, then 4249 * remove any failed drives, then
@@ -3876,31 +4253,41 @@ void md_check_recovery(mddev_t *mddev)
3876 */ 4253 */
3877 ITERATE_RDEV(mddev,rdev,rtmp) 4254 ITERATE_RDEV(mddev,rdev,rtmp)
3878 if (rdev->raid_disk >= 0 && 4255 if (rdev->raid_disk >= 0 &&
3879 (rdev->faulty || ! rdev->in_sync) && 4256 (test_bit(Faulty, &rdev->flags) || ! test_bit(In_sync, &rdev->flags)) &&
3880 atomic_read(&rdev->nr_pending)==0) { 4257 atomic_read(&rdev->nr_pending)==0) {
3881 if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0) 4258 if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0) {
4259 char nm[20];
4260 sprintf(nm,"rd%d", rdev->raid_disk);
4261 sysfs_remove_link(&mddev->kobj, nm);
3882 rdev->raid_disk = -1; 4262 rdev->raid_disk = -1;
4263 }
3883 } 4264 }
3884 4265
3885 if (mddev->degraded) { 4266 if (mddev->degraded) {
3886 ITERATE_RDEV(mddev,rdev,rtmp) 4267 ITERATE_RDEV(mddev,rdev,rtmp)
3887 if (rdev->raid_disk < 0 4268 if (rdev->raid_disk < 0
3888 && !rdev->faulty) { 4269 && !test_bit(Faulty, &rdev->flags)) {
3889 if (mddev->pers->hot_add_disk(mddev,rdev)) 4270 if (mddev->pers->hot_add_disk(mddev,rdev)) {
4271 char nm[20];
4272 sprintf(nm, "rd%d", rdev->raid_disk);
4273 sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
3890 spares++; 4274 spares++;
3891 else 4275 } else
3892 break; 4276 break;
3893 } 4277 }
3894 } 4278 }
3895 4279
3896 if (!spares && (mddev->recovery_cp == MaxSector )) { 4280 if (spares) {
3897 /* nothing we can do ... */ 4281 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
4282 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
4283 } else if (mddev->recovery_cp < MaxSector) {
4284 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
4285 } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
4286 /* nothing to be done ... */
3898 goto unlock; 4287 goto unlock;
3899 } 4288
3900 if (mddev->pers->sync_request) { 4289 if (mddev->pers->sync_request) {
3901 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); 4290 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
3902 if (!spares)
3903 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
3904 if (spares && mddev->bitmap && ! mddev->bitmap->file) { 4291 if (spares && mddev->bitmap && ! mddev->bitmap->file) {
3905 /* We are adding a device or devices to an array 4292 /* We are adding a device or devices to an array
3906 * which has the bitmap stored on all devices. 4293 * which has the bitmap stored on all devices.
@@ -3975,7 +4362,7 @@ static int __init md_init(void)
3975 " MD_SB_DISKS=%d\n", 4362 " MD_SB_DISKS=%d\n",
3976 MD_MAJOR_VERSION, MD_MINOR_VERSION, 4363 MD_MAJOR_VERSION, MD_MINOR_VERSION,
3977 MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS); 4364 MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);
3978 printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR, 4365 printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR_HI,
3979 BITMAP_MINOR); 4366 BITMAP_MINOR);
3980 4367
3981 if (register_blkdev(MAJOR_NR, "md")) 4368 if (register_blkdev(MAJOR_NR, "md"))
@@ -4039,7 +4426,7 @@ static void autostart_arrays(int part)
4039 if (IS_ERR(rdev)) 4426 if (IS_ERR(rdev))
4040 continue; 4427 continue;
4041 4428
4042 if (rdev->faulty) { 4429 if (test_bit(Faulty, &rdev->flags)) {
4043 MD_BUG(); 4430 MD_BUG();
4044 continue; 4431 continue;
4045 } 4432 }
@@ -4086,6 +4473,23 @@ static __exit void md_exit(void)
4086module_init(md_init) 4473module_init(md_init)
4087module_exit(md_exit) 4474module_exit(md_exit)
4088 4475
4476static int get_ro(char *buffer, struct kernel_param *kp)
4477{
4478 return sprintf(buffer, "%d", start_readonly);
4479}
4480static int set_ro(const char *val, struct kernel_param *kp)
4481{
4482 char *e;
4483 int num = simple_strtoul(val, &e, 10);
4484 if (*val && (*e == '\0' || *e == '\n')) {
4485 start_readonly = num;
4486 return 0;;
4487 }
4488 return -EINVAL;
4489}
4490
4491module_param_call(start_ro, set_ro, get_ro, NULL, 0600);
4492
4089EXPORT_SYMBOL(register_md_personality); 4493EXPORT_SYMBOL(register_md_personality);
4090EXPORT_SYMBOL(unregister_md_personality); 4494EXPORT_SYMBOL(unregister_md_personality);
4091EXPORT_SYMBOL(md_error); 4495EXPORT_SYMBOL(md_error);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index c06f4474192b..145cdc5ad008 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -63,8 +63,8 @@ static int multipath_map (multipath_conf_t *conf)
63 63
64 rcu_read_lock(); 64 rcu_read_lock();
65 for (i = 0; i < disks; i++) { 65 for (i = 0; i < disks; i++) {
66 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 66 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
67 if (rdev && rdev->in_sync) { 67 if (rdev && test_bit(In_sync, &rdev->flags)) {
68 atomic_inc(&rdev->nr_pending); 68 atomic_inc(&rdev->nr_pending);
69 rcu_read_unlock(); 69 rcu_read_unlock();
70 return i; 70 return i;
@@ -139,8 +139,9 @@ static void unplug_slaves(mddev_t *mddev)
139 139
140 rcu_read_lock(); 140 rcu_read_lock();
141 for (i=0; i<mddev->raid_disks; i++) { 141 for (i=0; i<mddev->raid_disks; i++) {
142 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 142 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
143 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 143 if (rdev && !test_bit(Faulty, &rdev->flags)
144 && atomic_read(&rdev->nr_pending)) {
144 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 145 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
145 146
146 atomic_inc(&rdev->nr_pending); 147 atomic_inc(&rdev->nr_pending);
@@ -211,7 +212,7 @@ static void multipath_status (struct seq_file *seq, mddev_t *mddev)
211 for (i = 0; i < conf->raid_disks; i++) 212 for (i = 0; i < conf->raid_disks; i++)
212 seq_printf (seq, "%s", 213 seq_printf (seq, "%s",
213 conf->multipaths[i].rdev && 214 conf->multipaths[i].rdev &&
214 conf->multipaths[i].rdev->in_sync ? "U" : "_"); 215 test_bit(In_sync, &conf->multipaths[i].rdev->flags) ? "U" : "_");
215 seq_printf (seq, "]"); 216 seq_printf (seq, "]");
216} 217}
217 218
@@ -224,8 +225,8 @@ static int multipath_issue_flush(request_queue_t *q, struct gendisk *disk,
224 225
225 rcu_read_lock(); 226 rcu_read_lock();
226 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 227 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
227 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 228 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
228 if (rdev && !rdev->faulty) { 229 if (rdev && !test_bit(Faulty, &rdev->flags)) {
229 struct block_device *bdev = rdev->bdev; 230 struct block_device *bdev = rdev->bdev;
230 request_queue_t *r_queue = bdev_get_queue(bdev); 231 request_queue_t *r_queue = bdev_get_queue(bdev);
231 232
@@ -265,10 +266,10 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
265 /* 266 /*
266 * Mark disk as unusable 267 * Mark disk as unusable
267 */ 268 */
268 if (!rdev->faulty) { 269 if (!test_bit(Faulty, &rdev->flags)) {
269 char b[BDEVNAME_SIZE]; 270 char b[BDEVNAME_SIZE];
270 rdev->in_sync = 0; 271 clear_bit(In_sync, &rdev->flags);
271 rdev->faulty = 1; 272 set_bit(Faulty, &rdev->flags);
272 mddev->sb_dirty = 1; 273 mddev->sb_dirty = 1;
273 conf->working_disks--; 274 conf->working_disks--;
274 printk(KERN_ALERT "multipath: IO failure on %s," 275 printk(KERN_ALERT "multipath: IO failure on %s,"
@@ -298,7 +299,7 @@ static void print_multipath_conf (multipath_conf_t *conf)
298 tmp = conf->multipaths + i; 299 tmp = conf->multipaths + i;
299 if (tmp->rdev) 300 if (tmp->rdev)
300 printk(" disk%d, o:%d, dev:%s\n", 301 printk(" disk%d, o:%d, dev:%s\n",
301 i,!tmp->rdev->faulty, 302 i,!test_bit(Faulty, &tmp->rdev->flags),
302 bdevname(tmp->rdev->bdev,b)); 303 bdevname(tmp->rdev->bdev,b));
303 } 304 }
304} 305}
@@ -330,8 +331,8 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
330 331
331 conf->working_disks++; 332 conf->working_disks++;
332 rdev->raid_disk = path; 333 rdev->raid_disk = path;
333 rdev->in_sync = 1; 334 set_bit(In_sync, &rdev->flags);
334 p->rdev = rdev; 335 rcu_assign_pointer(p->rdev, rdev);
335 found = 1; 336 found = 1;
336 } 337 }
337 338
@@ -350,7 +351,7 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
350 351
351 rdev = p->rdev; 352 rdev = p->rdev;
352 if (rdev) { 353 if (rdev) {
353 if (rdev->in_sync || 354 if (test_bit(In_sync, &rdev->flags) ||
354 atomic_read(&rdev->nr_pending)) { 355 atomic_read(&rdev->nr_pending)) {
355 printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number); 356 printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number);
356 err = -EBUSY; 357 err = -EBUSY;
@@ -482,7 +483,7 @@ static int multipath_run (mddev_t *mddev)
482 mddev->queue->max_sectors > (PAGE_SIZE>>9)) 483 mddev->queue->max_sectors > (PAGE_SIZE>>9))
483 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); 484 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
484 485
485 if (!rdev->faulty) 486 if (!test_bit(Faulty, &rdev->flags))
486 conf->working_disks++; 487 conf->working_disks++;
487 } 488 }
488 489
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index e16f473bcf46..2da9d3ba902d 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -301,7 +301,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
301{ 301{
302 int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); 302 int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
303 r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); 303 r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
304 int mirror, behind; 304 int mirror, behind = test_bit(R1BIO_BehindIO, &r1_bio->state);
305 conf_t *conf = mddev_to_conf(r1_bio->mddev); 305 conf_t *conf = mddev_to_conf(r1_bio->mddev);
306 306
307 if (bio->bi_size) 307 if (bio->bi_size)
@@ -311,47 +311,54 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
311 if (r1_bio->bios[mirror] == bio) 311 if (r1_bio->bios[mirror] == bio)
312 break; 312 break;
313 313
314 /* 314 if (error == -ENOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) {
315 * this branch is our 'one mirror IO has finished' event handler: 315 set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags);
316 */ 316 set_bit(R1BIO_BarrierRetry, &r1_bio->state);
317 if (!uptodate) { 317 r1_bio->mddev->barriers_work = 0;
318 md_error(r1_bio->mddev, conf->mirrors[mirror].rdev); 318 } else {
319 /* an I/O failed, we can't clear the bitmap */
320 set_bit(R1BIO_Degraded, &r1_bio->state);
321 } else
322 /* 319 /*
323 * Set R1BIO_Uptodate in our master bio, so that 320 * this branch is our 'one mirror IO has finished' event handler:
324 * we will return a good error code for to the higher
325 * levels even if IO on some other mirrored buffer fails.
326 *
327 * The 'master' represents the composite IO operation to
328 * user-side. So if something waits for IO, then it will
329 * wait for the 'master' bio.
330 */ 321 */
331 set_bit(R1BIO_Uptodate, &r1_bio->state); 322 r1_bio->bios[mirror] = NULL;
332 323 bio_put(bio);
333 update_head_pos(mirror, r1_bio); 324 if (!uptodate) {
334 325 md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
335 behind = test_bit(R1BIO_BehindIO, &r1_bio->state); 326 /* an I/O failed, we can't clear the bitmap */
336 if (behind) { 327 set_bit(R1BIO_Degraded, &r1_bio->state);
337 if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags)) 328 } else
338 atomic_dec(&r1_bio->behind_remaining); 329 /*
339 330 * Set R1BIO_Uptodate in our master bio, so that
340 /* In behind mode, we ACK the master bio once the I/O has safely 331 * we will return a good error code for to the higher
341 * reached all non-writemostly disks. Setting the Returned bit 332 * levels even if IO on some other mirrored buffer fails.
342 * ensures that this gets done only once -- we don't ever want to 333 *
343 * return -EIO here, instead we'll wait */ 334 * The 'master' represents the composite IO operation to
344 335 * user-side. So if something waits for IO, then it will
345 if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) && 336 * wait for the 'master' bio.
346 test_bit(R1BIO_Uptodate, &r1_bio->state)) { 337 */
347 /* Maybe we can return now */ 338 set_bit(R1BIO_Uptodate, &r1_bio->state);
348 if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) { 339
349 struct bio *mbio = r1_bio->master_bio; 340 update_head_pos(mirror, r1_bio);
350 PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n", 341
351 (unsigned long long) mbio->bi_sector, 342 if (behind) {
352 (unsigned long long) mbio->bi_sector + 343 if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags))
353 (mbio->bi_size >> 9) - 1); 344 atomic_dec(&r1_bio->behind_remaining);
354 bio_endio(mbio, mbio->bi_size, 0); 345
346 /* In behind mode, we ACK the master bio once the I/O has safely
347 * reached all non-writemostly disks. Setting the Returned bit
348 * ensures that this gets done only once -- we don't ever want to
349 * return -EIO here, instead we'll wait */
350
351 if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) &&
352 test_bit(R1BIO_Uptodate, &r1_bio->state)) {
353 /* Maybe we can return now */
354 if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
355 struct bio *mbio = r1_bio->master_bio;
356 PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n",
357 (unsigned long long) mbio->bi_sector,
358 (unsigned long long) mbio->bi_sector +
359 (mbio->bi_size >> 9) - 1);
360 bio_endio(mbio, mbio->bi_size, 0);
361 }
355 } 362 }
356 } 363 }
357 } 364 }
@@ -361,8 +368,16 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
361 * already. 368 * already.
362 */ 369 */
363 if (atomic_dec_and_test(&r1_bio->remaining)) { 370 if (atomic_dec_and_test(&r1_bio->remaining)) {
371 if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
372 reschedule_retry(r1_bio);
373 /* Don't dec_pending yet, we want to hold
374 * the reference over the retry
375 */
376 return 0;
377 }
364 if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { 378 if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
365 /* free extra copy of the data pages */ 379 /* free extra copy of the data pages */
380/* FIXME bio has been freed!!! */
366 int i = bio->bi_vcnt; 381 int i = bio->bi_vcnt;
367 while (i--) 382 while (i--)
368 __free_page(bio->bi_io_vec[i].bv_page); 383 __free_page(bio->bi_io_vec[i].bv_page);
@@ -416,12 +431,12 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
416 /* Choose the first operation device, for consistancy */ 431 /* Choose the first operation device, for consistancy */
417 new_disk = 0; 432 new_disk = 0;
418 433
419 for (rdev = conf->mirrors[new_disk].rdev; 434 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
420 !rdev || !rdev->in_sync 435 !rdev || !test_bit(In_sync, &rdev->flags)
421 || test_bit(WriteMostly, &rdev->flags); 436 || test_bit(WriteMostly, &rdev->flags);
422 rdev = conf->mirrors[++new_disk].rdev) { 437 rdev = rcu_dereference(conf->mirrors[++new_disk].rdev)) {
423 438
424 if (rdev && rdev->in_sync) 439 if (rdev && test_bit(In_sync, &rdev->flags))
425 wonly_disk = new_disk; 440 wonly_disk = new_disk;
426 441
427 if (new_disk == conf->raid_disks - 1) { 442 if (new_disk == conf->raid_disks - 1) {
@@ -434,12 +449,12 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
434 449
435 450
436 /* make sure the disk is operational */ 451 /* make sure the disk is operational */
437 for (rdev = conf->mirrors[new_disk].rdev; 452 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
438 !rdev || !rdev->in_sync || 453 !rdev || !test_bit(In_sync, &rdev->flags) ||
439 test_bit(WriteMostly, &rdev->flags); 454 test_bit(WriteMostly, &rdev->flags);
440 rdev = conf->mirrors[new_disk].rdev) { 455 rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) {
441 456
442 if (rdev && rdev->in_sync) 457 if (rdev && test_bit(In_sync, &rdev->flags))
443 wonly_disk = new_disk; 458 wonly_disk = new_disk;
444 459
445 if (new_disk <= 0) 460 if (new_disk <= 0)
@@ -474,10 +489,10 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
474 disk = conf->raid_disks; 489 disk = conf->raid_disks;
475 disk--; 490 disk--;
476 491
477 rdev = conf->mirrors[disk].rdev; 492 rdev = rcu_dereference(conf->mirrors[disk].rdev);
478 493
479 if (!rdev || 494 if (!rdev ||
480 !rdev->in_sync || 495 !test_bit(In_sync, &rdev->flags) ||
481 test_bit(WriteMostly, &rdev->flags)) 496 test_bit(WriteMostly, &rdev->flags))
482 continue; 497 continue;
483 498
@@ -496,11 +511,11 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
496 511
497 512
498 if (new_disk >= 0) { 513 if (new_disk >= 0) {
499 rdev = conf->mirrors[new_disk].rdev; 514 rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
500 if (!rdev) 515 if (!rdev)
501 goto retry; 516 goto retry;
502 atomic_inc(&rdev->nr_pending); 517 atomic_inc(&rdev->nr_pending);
503 if (!rdev->in_sync) { 518 if (!test_bit(In_sync, &rdev->flags)) {
504 /* cannot risk returning a device that failed 519 /* cannot risk returning a device that failed
505 * before we inc'ed nr_pending 520 * before we inc'ed nr_pending
506 */ 521 */
@@ -522,8 +537,8 @@ static void unplug_slaves(mddev_t *mddev)
522 537
523 rcu_read_lock(); 538 rcu_read_lock();
524 for (i=0; i<mddev->raid_disks; i++) { 539 for (i=0; i<mddev->raid_disks; i++) {
525 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 540 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
526 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 541 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
527 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 542 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
528 543
529 atomic_inc(&rdev->nr_pending); 544 atomic_inc(&rdev->nr_pending);
@@ -556,8 +571,8 @@ static int raid1_issue_flush(request_queue_t *q, struct gendisk *disk,
556 571
557 rcu_read_lock(); 572 rcu_read_lock();
558 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 573 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
559 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 574 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
560 if (rdev && !rdev->faulty) { 575 if (rdev && !test_bit(Faulty, &rdev->flags)) {
561 struct block_device *bdev = rdev->bdev; 576 struct block_device *bdev = rdev->bdev;
562 request_queue_t *r_queue = bdev_get_queue(bdev); 577 request_queue_t *r_queue = bdev_get_queue(bdev);
563 578
@@ -648,8 +663,9 @@ static int make_request(request_queue_t *q, struct bio * bio)
648 struct bio_list bl; 663 struct bio_list bl;
649 struct page **behind_pages = NULL; 664 struct page **behind_pages = NULL;
650 const int rw = bio_data_dir(bio); 665 const int rw = bio_data_dir(bio);
666 int do_barriers;
651 667
652 if (unlikely(bio_barrier(bio))) { 668 if (unlikely(!mddev->barriers_work && bio_barrier(bio))) {
653 bio_endio(bio, bio->bi_size, -EOPNOTSUPP); 669 bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
654 return 0; 670 return 0;
655 } 671 }
@@ -728,10 +744,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
728#endif 744#endif
729 rcu_read_lock(); 745 rcu_read_lock();
730 for (i = 0; i < disks; i++) { 746 for (i = 0; i < disks; i++) {
731 if ((rdev=conf->mirrors[i].rdev) != NULL && 747 if ((rdev=rcu_dereference(conf->mirrors[i].rdev)) != NULL &&
732 !rdev->faulty) { 748 !test_bit(Faulty, &rdev->flags)) {
733 atomic_inc(&rdev->nr_pending); 749 atomic_inc(&rdev->nr_pending);
734 if (rdev->faulty) { 750 if (test_bit(Faulty, &rdev->flags)) {
735 atomic_dec(&rdev->nr_pending); 751 atomic_dec(&rdev->nr_pending);
736 r1_bio->bios[i] = NULL; 752 r1_bio->bios[i] = NULL;
737 } else 753 } else
@@ -759,6 +775,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
759 atomic_set(&r1_bio->remaining, 0); 775 atomic_set(&r1_bio->remaining, 0);
760 atomic_set(&r1_bio->behind_remaining, 0); 776 atomic_set(&r1_bio->behind_remaining, 0);
761 777
778 do_barriers = bio->bi_rw & BIO_RW_BARRIER;
779 if (do_barriers)
780 set_bit(R1BIO_Barrier, &r1_bio->state);
781
762 bio_list_init(&bl); 782 bio_list_init(&bl);
763 for (i = 0; i < disks; i++) { 783 for (i = 0; i < disks; i++) {
764 struct bio *mbio; 784 struct bio *mbio;
@@ -771,7 +791,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
771 mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; 791 mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset;
772 mbio->bi_bdev = conf->mirrors[i].rdev->bdev; 792 mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
773 mbio->bi_end_io = raid1_end_write_request; 793 mbio->bi_end_io = raid1_end_write_request;
774 mbio->bi_rw = WRITE; 794 mbio->bi_rw = WRITE | do_barriers;
775 mbio->bi_private = r1_bio; 795 mbio->bi_private = r1_bio;
776 796
777 if (behind_pages) { 797 if (behind_pages) {
@@ -824,7 +844,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
824 for (i = 0; i < conf->raid_disks; i++) 844 for (i = 0; i < conf->raid_disks; i++)
825 seq_printf(seq, "%s", 845 seq_printf(seq, "%s",
826 conf->mirrors[i].rdev && 846 conf->mirrors[i].rdev &&
827 conf->mirrors[i].rdev->in_sync ? "U" : "_"); 847 test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_");
828 seq_printf(seq, "]"); 848 seq_printf(seq, "]");
829} 849}
830 850
@@ -840,14 +860,14 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
840 * next level up know. 860 * next level up know.
841 * else mark the drive as failed 861 * else mark the drive as failed
842 */ 862 */
843 if (rdev->in_sync 863 if (test_bit(In_sync, &rdev->flags)
844 && conf->working_disks == 1) 864 && conf->working_disks == 1)
845 /* 865 /*
846 * Don't fail the drive, act as though we were just a 866 * Don't fail the drive, act as though we were just a
847 * normal single drive 867 * normal single drive
848 */ 868 */
849 return; 869 return;
850 if (rdev->in_sync) { 870 if (test_bit(In_sync, &rdev->flags)) {
851 mddev->degraded++; 871 mddev->degraded++;
852 conf->working_disks--; 872 conf->working_disks--;
853 /* 873 /*
@@ -855,8 +875,8 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
855 */ 875 */
856 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 876 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
857 } 877 }
858 rdev->in_sync = 0; 878 clear_bit(In_sync, &rdev->flags);
859 rdev->faulty = 1; 879 set_bit(Faulty, &rdev->flags);
860 mddev->sb_dirty = 1; 880 mddev->sb_dirty = 1;
861 printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n" 881 printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
862 " Operation continuing on %d devices\n", 882 " Operation continuing on %d devices\n",
@@ -881,7 +901,7 @@ static void print_conf(conf_t *conf)
881 tmp = conf->mirrors + i; 901 tmp = conf->mirrors + i;
882 if (tmp->rdev) 902 if (tmp->rdev)
883 printk(" disk %d, wo:%d, o:%d, dev:%s\n", 903 printk(" disk %d, wo:%d, o:%d, dev:%s\n",
884 i, !tmp->rdev->in_sync, !tmp->rdev->faulty, 904 i, !test_bit(In_sync, &tmp->rdev->flags), !test_bit(Faulty, &tmp->rdev->flags),
885 bdevname(tmp->rdev->bdev,b)); 905 bdevname(tmp->rdev->bdev,b));
886 } 906 }
887} 907}
@@ -913,11 +933,11 @@ static int raid1_spare_active(mddev_t *mddev)
913 for (i = 0; i < conf->raid_disks; i++) { 933 for (i = 0; i < conf->raid_disks; i++) {
914 tmp = conf->mirrors + i; 934 tmp = conf->mirrors + i;
915 if (tmp->rdev 935 if (tmp->rdev
916 && !tmp->rdev->faulty 936 && !test_bit(Faulty, &tmp->rdev->flags)
917 && !tmp->rdev->in_sync) { 937 && !test_bit(In_sync, &tmp->rdev->flags)) {
918 conf->working_disks++; 938 conf->working_disks++;
919 mddev->degraded--; 939 mddev->degraded--;
920 tmp->rdev->in_sync = 1; 940 set_bit(In_sync, &tmp->rdev->flags);
921 } 941 }
922 } 942 }
923 943
@@ -954,7 +974,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
954 found = 1; 974 found = 1;
955 if (rdev->saved_raid_disk != mirror) 975 if (rdev->saved_raid_disk != mirror)
956 conf->fullsync = 1; 976 conf->fullsync = 1;
957 p->rdev = rdev; 977 rcu_assign_pointer(p->rdev, rdev);
958 break; 978 break;
959 } 979 }
960 980
@@ -972,7 +992,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
972 print_conf(conf); 992 print_conf(conf);
973 rdev = p->rdev; 993 rdev = p->rdev;
974 if (rdev) { 994 if (rdev) {
975 if (rdev->in_sync || 995 if (test_bit(In_sync, &rdev->flags) ||
976 atomic_read(&rdev->nr_pending)) { 996 atomic_read(&rdev->nr_pending)) {
977 err = -EBUSY; 997 err = -EBUSY;
978 goto abort; 998 goto abort;
@@ -1153,6 +1173,36 @@ static void raid1d(mddev_t *mddev)
1153 if (test_bit(R1BIO_IsSync, &r1_bio->state)) { 1173 if (test_bit(R1BIO_IsSync, &r1_bio->state)) {
1154 sync_request_write(mddev, r1_bio); 1174 sync_request_write(mddev, r1_bio);
1155 unplug = 1; 1175 unplug = 1;
1176 } else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
1177 /* some requests in the r1bio were BIO_RW_BARRIER
1178 * requests which failed with -ENOTSUPP. Hohumm..
1179 * Better resubmit without the barrier.
1180 * We know which devices to resubmit for, because
1181 * all others have had their bios[] entry cleared.
1182 */
1183 int i;
1184 clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
1185 clear_bit(R1BIO_Barrier, &r1_bio->state);
1186 for (i=0; i < conf->raid_disks; i++)
1187 if (r1_bio->bios[i]) {
1188 struct bio_vec *bvec;
1189 int j;
1190
1191 bio = bio_clone(r1_bio->master_bio, GFP_NOIO);
1192 /* copy pages from the failed bio, as
1193 * this might be a write-behind device */
1194 __bio_for_each_segment(bvec, bio, j, 0)
1195 bvec->bv_page = bio_iovec_idx(r1_bio->bios[i], j)->bv_page;
1196 bio_put(r1_bio->bios[i]);
1197 bio->bi_sector = r1_bio->sector +
1198 conf->mirrors[i].rdev->data_offset;
1199 bio->bi_bdev = conf->mirrors[i].rdev->bdev;
1200 bio->bi_end_io = raid1_end_write_request;
1201 bio->bi_rw = WRITE;
1202 bio->bi_private = r1_bio;
1203 r1_bio->bios[i] = bio;
1204 generic_make_request(bio);
1205 }
1156 } else { 1206 } else {
1157 int disk; 1207 int disk;
1158 bio = r1_bio->bios[r1_bio->read_disk]; 1208 bio = r1_bio->bios[r1_bio->read_disk];
@@ -1260,7 +1310,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1260 * This call the bitmap_start_sync doesn't actually record anything 1310 * This call the bitmap_start_sync doesn't actually record anything
1261 */ 1311 */
1262 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && 1312 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
1263 !conf->fullsync) { 1313 !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
1264 /* We can skip this block, and probably several more */ 1314 /* We can skip this block, and probably several more */
1265 *skipped = 1; 1315 *skipped = 1;
1266 return sync_blocks; 1316 return sync_blocks;
@@ -1282,11 +1332,11 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1282 /* make sure disk is operational */ 1332 /* make sure disk is operational */
1283 wonly = disk; 1333 wonly = disk;
1284 while (conf->mirrors[disk].rdev == NULL || 1334 while (conf->mirrors[disk].rdev == NULL ||
1285 !conf->mirrors[disk].rdev->in_sync || 1335 !test_bit(In_sync, &conf->mirrors[disk].rdev->flags) ||
1286 test_bit(WriteMostly, &conf->mirrors[disk].rdev->flags) 1336 test_bit(WriteMostly, &conf->mirrors[disk].rdev->flags)
1287 ) { 1337 ) {
1288 if (conf->mirrors[disk].rdev && 1338 if (conf->mirrors[disk].rdev &&
1289 conf->mirrors[disk].rdev->in_sync) 1339 test_bit(In_sync, &conf->mirrors[disk].rdev->flags))
1290 wonly = disk; 1340 wonly = disk;
1291 if (disk <= 0) 1341 if (disk <= 0)
1292 disk = conf->raid_disks; 1342 disk = conf->raid_disks;
@@ -1333,11 +1383,12 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1333 bio->bi_rw = READ; 1383 bio->bi_rw = READ;
1334 bio->bi_end_io = end_sync_read; 1384 bio->bi_end_io = end_sync_read;
1335 } else if (conf->mirrors[i].rdev == NULL || 1385 } else if (conf->mirrors[i].rdev == NULL ||
1336 conf->mirrors[i].rdev->faulty) { 1386 test_bit(Faulty, &conf->mirrors[i].rdev->flags)) {
1337 still_degraded = 1; 1387 still_degraded = 1;
1338 continue; 1388 continue;
1339 } else if (!conf->mirrors[i].rdev->in_sync || 1389 } else if (!test_bit(In_sync, &conf->mirrors[i].rdev->flags) ||
1340 sector_nr + RESYNC_SECTORS > mddev->recovery_cp) { 1390 sector_nr + RESYNC_SECTORS > mddev->recovery_cp ||
1391 test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
1341 bio->bi_rw = WRITE; 1392 bio->bi_rw = WRITE;
1342 bio->bi_end_io = end_sync_write; 1393 bio->bi_end_io = end_sync_write;
1343 write_targets ++; 1394 write_targets ++;
@@ -1371,8 +1422,9 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1371 break; 1422 break;
1372 if (sync_blocks == 0) { 1423 if (sync_blocks == 0) {
1373 if (!bitmap_start_sync(mddev->bitmap, sector_nr, 1424 if (!bitmap_start_sync(mddev->bitmap, sector_nr,
1374 &sync_blocks, still_degraded) && 1425 &sync_blocks, still_degraded) &&
1375 !conf->fullsync) 1426 !conf->fullsync &&
1427 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
1376 break; 1428 break;
1377 if (sync_blocks < (PAGE_SIZE>>9)) 1429 if (sync_blocks < (PAGE_SIZE>>9))
1378 BUG(); 1430 BUG();
@@ -1478,7 +1530,7 @@ static int run(mddev_t *mddev)
1478 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); 1530 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
1479 1531
1480 disk->head_position = 0; 1532 disk->head_position = 0;
1481 if (!rdev->faulty && rdev->in_sync) 1533 if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
1482 conf->working_disks++; 1534 conf->working_disks++;
1483 } 1535 }
1484 conf->raid_disks = mddev->raid_disks; 1536 conf->raid_disks = mddev->raid_disks;
@@ -1518,7 +1570,7 @@ static int run(mddev_t *mddev)
1518 */ 1570 */
1519 for (j = 0; j < conf->raid_disks && 1571 for (j = 0; j < conf->raid_disks &&
1520 (!conf->mirrors[j].rdev || 1572 (!conf->mirrors[j].rdev ||
1521 !conf->mirrors[j].rdev->in_sync) ; j++) 1573 !test_bit(In_sync, &conf->mirrors[j].rdev->flags)) ; j++)
1522 /* nothing */; 1574 /* nothing */;
1523 conf->last_used = j; 1575 conf->last_used = j;
1524 1576
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index bbe40e9cf923..867f06ae33d9 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -496,6 +496,7 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
496 int disk, slot, nslot; 496 int disk, slot, nslot;
497 const int sectors = r10_bio->sectors; 497 const int sectors = r10_bio->sectors;
498 sector_t new_distance, current_distance; 498 sector_t new_distance, current_distance;
499 mdk_rdev_t *rdev;
499 500
500 raid10_find_phys(conf, r10_bio); 501 raid10_find_phys(conf, r10_bio);
501 rcu_read_lock(); 502 rcu_read_lock();
@@ -510,8 +511,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
510 slot = 0; 511 slot = 0;
511 disk = r10_bio->devs[slot].devnum; 512 disk = r10_bio->devs[slot].devnum;
512 513
513 while (!conf->mirrors[disk].rdev || 514 while ((rdev = rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
514 !conf->mirrors[disk].rdev->in_sync) { 515 !test_bit(In_sync, &rdev->flags)) {
515 slot++; 516 slot++;
516 if (slot == conf->copies) { 517 if (slot == conf->copies) {
517 slot = 0; 518 slot = 0;
@@ -527,8 +528,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
527 /* make sure the disk is operational */ 528 /* make sure the disk is operational */
528 slot = 0; 529 slot = 0;
529 disk = r10_bio->devs[slot].devnum; 530 disk = r10_bio->devs[slot].devnum;
530 while (!conf->mirrors[disk].rdev || 531 while ((rdev=rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
531 !conf->mirrors[disk].rdev->in_sync) { 532 !test_bit(In_sync, &rdev->flags)) {
532 slot ++; 533 slot ++;
533 if (slot == conf->copies) { 534 if (slot == conf->copies) {
534 disk = -1; 535 disk = -1;
@@ -547,11 +548,11 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
547 int ndisk = r10_bio->devs[nslot].devnum; 548 int ndisk = r10_bio->devs[nslot].devnum;
548 549
549 550
550 if (!conf->mirrors[ndisk].rdev || 551 if ((rdev=rcu_dereference(conf->mirrors[ndisk].rdev)) == NULL ||
551 !conf->mirrors[ndisk].rdev->in_sync) 552 !test_bit(In_sync, &rdev->flags))
552 continue; 553 continue;
553 554
554 if (!atomic_read(&conf->mirrors[ndisk].rdev->nr_pending)) { 555 if (!atomic_read(&rdev->nr_pending)) {
555 disk = ndisk; 556 disk = ndisk;
556 slot = nslot; 557 slot = nslot;
557 break; 558 break;
@@ -569,7 +570,7 @@ rb_out:
569 r10_bio->read_slot = slot; 570 r10_bio->read_slot = slot;
570/* conf->next_seq_sect = this_sector + sectors;*/ 571/* conf->next_seq_sect = this_sector + sectors;*/
571 572
572 if (disk >= 0 && conf->mirrors[disk].rdev) 573 if (disk >= 0 && (rdev=rcu_dereference(conf->mirrors[disk].rdev))!= NULL)
573 atomic_inc(&conf->mirrors[disk].rdev->nr_pending); 574 atomic_inc(&conf->mirrors[disk].rdev->nr_pending);
574 rcu_read_unlock(); 575 rcu_read_unlock();
575 576
@@ -583,8 +584,8 @@ static void unplug_slaves(mddev_t *mddev)
583 584
584 rcu_read_lock(); 585 rcu_read_lock();
585 for (i=0; i<mddev->raid_disks; i++) { 586 for (i=0; i<mddev->raid_disks; i++) {
586 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 587 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
587 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 588 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
588 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 589 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
589 590
590 atomic_inc(&rdev->nr_pending); 591 atomic_inc(&rdev->nr_pending);
@@ -614,8 +615,8 @@ static int raid10_issue_flush(request_queue_t *q, struct gendisk *disk,
614 615
615 rcu_read_lock(); 616 rcu_read_lock();
616 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 617 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
617 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 618 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
618 if (rdev && !rdev->faulty) { 619 if (rdev && !test_bit(Faulty, &rdev->flags)) {
619 struct block_device *bdev = rdev->bdev; 620 struct block_device *bdev = rdev->bdev;
620 request_queue_t *r_queue = bdev_get_queue(bdev); 621 request_queue_t *r_queue = bdev_get_queue(bdev);
621 622
@@ -768,9 +769,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
768 rcu_read_lock(); 769 rcu_read_lock();
769 for (i = 0; i < conf->copies; i++) { 770 for (i = 0; i < conf->copies; i++) {
770 int d = r10_bio->devs[i].devnum; 771 int d = r10_bio->devs[i].devnum;
771 if (conf->mirrors[d].rdev && 772 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[d].rdev);
772 !conf->mirrors[d].rdev->faulty) { 773 if (rdev &&
773 atomic_inc(&conf->mirrors[d].rdev->nr_pending); 774 !test_bit(Faulty, &rdev->flags)) {
775 atomic_inc(&rdev->nr_pending);
774 r10_bio->devs[i].bio = bio; 776 r10_bio->devs[i].bio = bio;
775 } else 777 } else
776 r10_bio->devs[i].bio = NULL; 778 r10_bio->devs[i].bio = NULL;
@@ -824,7 +826,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
824 for (i = 0; i < conf->raid_disks; i++) 826 for (i = 0; i < conf->raid_disks; i++)
825 seq_printf(seq, "%s", 827 seq_printf(seq, "%s",
826 conf->mirrors[i].rdev && 828 conf->mirrors[i].rdev &&
827 conf->mirrors[i].rdev->in_sync ? "U" : "_"); 829 test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_");
828 seq_printf(seq, "]"); 830 seq_printf(seq, "]");
829} 831}
830 832
@@ -839,7 +841,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
839 * next level up know. 841 * next level up know.
840 * else mark the drive as failed 842 * else mark the drive as failed
841 */ 843 */
842 if (rdev->in_sync 844 if (test_bit(In_sync, &rdev->flags)
843 && conf->working_disks == 1) 845 && conf->working_disks == 1)
844 /* 846 /*
845 * Don't fail the drive, just return an IO error. 847 * Don't fail the drive, just return an IO error.
@@ -849,7 +851,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
849 * really dead" tests... 851 * really dead" tests...
850 */ 852 */
851 return; 853 return;
852 if (rdev->in_sync) { 854 if (test_bit(In_sync, &rdev->flags)) {
853 mddev->degraded++; 855 mddev->degraded++;
854 conf->working_disks--; 856 conf->working_disks--;
855 /* 857 /*
@@ -857,8 +859,8 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
857 */ 859 */
858 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 860 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
859 } 861 }
860 rdev->in_sync = 0; 862 clear_bit(In_sync, &rdev->flags);
861 rdev->faulty = 1; 863 set_bit(Faulty, &rdev->flags);
862 mddev->sb_dirty = 1; 864 mddev->sb_dirty = 1;
863 printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n" 865 printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n"
864 " Operation continuing on %d devices\n", 866 " Operation continuing on %d devices\n",
@@ -883,7 +885,8 @@ static void print_conf(conf_t *conf)
883 tmp = conf->mirrors + i; 885 tmp = conf->mirrors + i;
884 if (tmp->rdev) 886 if (tmp->rdev)
885 printk(" disk %d, wo:%d, o:%d, dev:%s\n", 887 printk(" disk %d, wo:%d, o:%d, dev:%s\n",
886 i, !tmp->rdev->in_sync, !tmp->rdev->faulty, 888 i, !test_bit(In_sync, &tmp->rdev->flags),
889 !test_bit(Faulty, &tmp->rdev->flags),
887 bdevname(tmp->rdev->bdev,b)); 890 bdevname(tmp->rdev->bdev,b));
888 } 891 }
889} 892}
@@ -936,11 +939,11 @@ static int raid10_spare_active(mddev_t *mddev)
936 for (i = 0; i < conf->raid_disks; i++) { 939 for (i = 0; i < conf->raid_disks; i++) {
937 tmp = conf->mirrors + i; 940 tmp = conf->mirrors + i;
938 if (tmp->rdev 941 if (tmp->rdev
939 && !tmp->rdev->faulty 942 && !test_bit(Faulty, &tmp->rdev->flags)
940 && !tmp->rdev->in_sync) { 943 && !test_bit(In_sync, &tmp->rdev->flags)) {
941 conf->working_disks++; 944 conf->working_disks++;
942 mddev->degraded--; 945 mddev->degraded--;
943 tmp->rdev->in_sync = 1; 946 set_bit(In_sync, &tmp->rdev->flags);
944 } 947 }
945 } 948 }
946 949
@@ -980,7 +983,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
980 p->head_position = 0; 983 p->head_position = 0;
981 rdev->raid_disk = mirror; 984 rdev->raid_disk = mirror;
982 found = 1; 985 found = 1;
983 p->rdev = rdev; 986 rcu_assign_pointer(p->rdev, rdev);
984 break; 987 break;
985 } 988 }
986 989
@@ -998,7 +1001,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
998 print_conf(conf); 1001 print_conf(conf);
999 rdev = p->rdev; 1002 rdev = p->rdev;
1000 if (rdev) { 1003 if (rdev) {
1001 if (rdev->in_sync || 1004 if (test_bit(In_sync, &rdev->flags) ||
1002 atomic_read(&rdev->nr_pending)) { 1005 atomic_read(&rdev->nr_pending)) {
1003 err = -EBUSY; 1006 err = -EBUSY;
1004 goto abort; 1007 goto abort;
@@ -1414,7 +1417,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1414 1417
1415 for (i=0 ; i<conf->raid_disks; i++) 1418 for (i=0 ; i<conf->raid_disks; i++)
1416 if (conf->mirrors[i].rdev && 1419 if (conf->mirrors[i].rdev &&
1417 !conf->mirrors[i].rdev->in_sync) { 1420 !test_bit(In_sync, &conf->mirrors[i].rdev->flags)) {
1418 /* want to reconstruct this device */ 1421 /* want to reconstruct this device */
1419 r10bio_t *rb2 = r10_bio; 1422 r10bio_t *rb2 = r10_bio;
1420 1423
@@ -1435,7 +1438,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1435 for (j=0; j<conf->copies;j++) { 1438 for (j=0; j<conf->copies;j++) {
1436 int d = r10_bio->devs[j].devnum; 1439 int d = r10_bio->devs[j].devnum;
1437 if (conf->mirrors[d].rdev && 1440 if (conf->mirrors[d].rdev &&
1438 conf->mirrors[d].rdev->in_sync) { 1441 test_bit(In_sync, &conf->mirrors[d].rdev->flags)) {
1439 /* This is where we read from */ 1442 /* This is where we read from */
1440 bio = r10_bio->devs[0].bio; 1443 bio = r10_bio->devs[0].bio;
1441 bio->bi_next = biolist; 1444 bio->bi_next = biolist;
@@ -1511,7 +1514,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1511 bio = r10_bio->devs[i].bio; 1514 bio = r10_bio->devs[i].bio;
1512 bio->bi_end_io = NULL; 1515 bio->bi_end_io = NULL;
1513 if (conf->mirrors[d].rdev == NULL || 1516 if (conf->mirrors[d].rdev == NULL ||
1514 conf->mirrors[d].rdev->faulty) 1517 test_bit(Faulty, &conf->mirrors[d].rdev->flags))
1515 continue; 1518 continue;
1516 atomic_inc(&conf->mirrors[d].rdev->nr_pending); 1519 atomic_inc(&conf->mirrors[d].rdev->nr_pending);
1517 atomic_inc(&r10_bio->remaining); 1520 atomic_inc(&r10_bio->remaining);
@@ -1697,7 +1700,7 @@ static int run(mddev_t *mddev)
1697 mddev->queue->max_sectors = (PAGE_SIZE>>9); 1700 mddev->queue->max_sectors = (PAGE_SIZE>>9);
1698 1701
1699 disk->head_position = 0; 1702 disk->head_position = 0;
1700 if (!rdev->faulty && rdev->in_sync) 1703 if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
1701 conf->working_disks++; 1704 conf->working_disks++;
1702 } 1705 }
1703 conf->raid_disks = mddev->raid_disks; 1706 conf->raid_disks = mddev->raid_disks;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 1223e98ecd70..e2a40283e323 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -293,9 +293,31 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
293 return sh; 293 return sh;
294} 294}
295 295
296static int grow_stripes(raid5_conf_t *conf, int num) 296static int grow_one_stripe(raid5_conf_t *conf)
297{ 297{
298 struct stripe_head *sh; 298 struct stripe_head *sh;
299 sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL);
300 if (!sh)
301 return 0;
302 memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev));
303 sh->raid_conf = conf;
304 spin_lock_init(&sh->lock);
305
306 if (grow_buffers(sh, conf->raid_disks)) {
307 shrink_buffers(sh, conf->raid_disks);
308 kmem_cache_free(conf->slab_cache, sh);
309 return 0;
310 }
311 /* we just created an active stripe so... */
312 atomic_set(&sh->count, 1);
313 atomic_inc(&conf->active_stripes);
314 INIT_LIST_HEAD(&sh->lru);
315 release_stripe(sh);
316 return 1;
317}
318
319static int grow_stripes(raid5_conf_t *conf, int num)
320{
299 kmem_cache_t *sc; 321 kmem_cache_t *sc;
300 int devs = conf->raid_disks; 322 int devs = conf->raid_disks;
301 323
@@ -308,48 +330,39 @@ static int grow_stripes(raid5_conf_t *conf, int num)
308 return 1; 330 return 1;
309 conf->slab_cache = sc; 331 conf->slab_cache = sc;
310 while (num--) { 332 while (num--) {
311 sh = kmem_cache_alloc(sc, GFP_KERNEL); 333 if (!grow_one_stripe(conf))
312 if (!sh)
313 return 1;
314 memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev));
315 sh->raid_conf = conf;
316 spin_lock_init(&sh->lock);
317
318 if (grow_buffers(sh, conf->raid_disks)) {
319 shrink_buffers(sh, conf->raid_disks);
320 kmem_cache_free(sc, sh);
321 return 1; 334 return 1;
322 }
323 /* we just created an active stripe so... */
324 atomic_set(&sh->count, 1);
325 atomic_inc(&conf->active_stripes);
326 INIT_LIST_HEAD(&sh->lru);
327 release_stripe(sh);
328 } 335 }
329 return 0; 336 return 0;
330} 337}
331 338
332static void shrink_stripes(raid5_conf_t *conf) 339static int drop_one_stripe(raid5_conf_t *conf)
333{ 340{
334 struct stripe_head *sh; 341 struct stripe_head *sh;
335 342
336 while (1) { 343 spin_lock_irq(&conf->device_lock);
337 spin_lock_irq(&conf->device_lock); 344 sh = get_free_stripe(conf);
338 sh = get_free_stripe(conf); 345 spin_unlock_irq(&conf->device_lock);
339 spin_unlock_irq(&conf->device_lock); 346 if (!sh)
340 if (!sh) 347 return 0;
341 break; 348 if (atomic_read(&sh->count))
342 if (atomic_read(&sh->count)) 349 BUG();
343 BUG(); 350 shrink_buffers(sh, conf->raid_disks);
344 shrink_buffers(sh, conf->raid_disks); 351 kmem_cache_free(conf->slab_cache, sh);
345 kmem_cache_free(conf->slab_cache, sh); 352 atomic_dec(&conf->active_stripes);
346 atomic_dec(&conf->active_stripes); 353 return 1;
347 } 354}
355
356static void shrink_stripes(raid5_conf_t *conf)
357{
358 while (drop_one_stripe(conf))
359 ;
360
348 kmem_cache_destroy(conf->slab_cache); 361 kmem_cache_destroy(conf->slab_cache);
349 conf->slab_cache = NULL; 362 conf->slab_cache = NULL;
350} 363}
351 364
352static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done, 365static int raid5_end_read_request(struct bio * bi, unsigned int bytes_done,
353 int error) 366 int error)
354{ 367{
355 struct stripe_head *sh = bi->bi_private; 368 struct stripe_head *sh = bi->bi_private;
@@ -401,10 +414,35 @@ static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done,
401 } 414 }
402#else 415#else
403 set_bit(R5_UPTODATE, &sh->dev[i].flags); 416 set_bit(R5_UPTODATE, &sh->dev[i].flags);
404#endif 417#endif
418 if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
419 printk("R5: read error corrected!!\n");
420 clear_bit(R5_ReadError, &sh->dev[i].flags);
421 clear_bit(R5_ReWrite, &sh->dev[i].flags);
422 }
423 if (atomic_read(&conf->disks[i].rdev->read_errors))
424 atomic_set(&conf->disks[i].rdev->read_errors, 0);
405 } else { 425 } else {
406 md_error(conf->mddev, conf->disks[i].rdev); 426 int retry = 0;
407 clear_bit(R5_UPTODATE, &sh->dev[i].flags); 427 clear_bit(R5_UPTODATE, &sh->dev[i].flags);
428 atomic_inc(&conf->disks[i].rdev->read_errors);
429 if (conf->mddev->degraded)
430 printk("R5: read error not correctable.\n");
431 else if (test_bit(R5_ReWrite, &sh->dev[i].flags))
432 /* Oh, no!!! */
433 printk("R5: read error NOT corrected!!\n");
434 else if (atomic_read(&conf->disks[i].rdev->read_errors)
435 > conf->max_nr_stripes)
436 printk("raid5: Too many read errors, failing device.\n");
437 else
438 retry = 1;
439 if (retry)
440 set_bit(R5_ReadError, &sh->dev[i].flags);
441 else {
442 clear_bit(R5_ReadError, &sh->dev[i].flags);
443 clear_bit(R5_ReWrite, &sh->dev[i].flags);
444 md_error(conf->mddev, conf->disks[i].rdev);
445 }
408 } 446 }
409 rdev_dec_pending(conf->disks[i].rdev, conf->mddev); 447 rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
410#if 0 448#if 0
@@ -487,19 +525,19 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
487 raid5_conf_t *conf = (raid5_conf_t *) mddev->private; 525 raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
488 PRINTK("raid5: error called\n"); 526 PRINTK("raid5: error called\n");
489 527
490 if (!rdev->faulty) { 528 if (!test_bit(Faulty, &rdev->flags)) {
491 mddev->sb_dirty = 1; 529 mddev->sb_dirty = 1;
492 if (rdev->in_sync) { 530 if (test_bit(In_sync, &rdev->flags)) {
493 conf->working_disks--; 531 conf->working_disks--;
494 mddev->degraded++; 532 mddev->degraded++;
495 conf->failed_disks++; 533 conf->failed_disks++;
496 rdev->in_sync = 0; 534 clear_bit(In_sync, &rdev->flags);
497 /* 535 /*
498 * if recovery was running, make sure it aborts. 536 * if recovery was running, make sure it aborts.
499 */ 537 */
500 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 538 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
501 } 539 }
502 rdev->faulty = 1; 540 set_bit(Faulty, &rdev->flags);
503 printk (KERN_ALERT 541 printk (KERN_ALERT
504 "raid5: Disk failure on %s, disabling device." 542 "raid5: Disk failure on %s, disabling device."
505 " Operation continuing on %d devices\n", 543 " Operation continuing on %d devices\n",
@@ -965,7 +1003,13 @@ static void handle_stripe(struct stripe_head *sh)
965 } 1003 }
966 if (dev->written) written++; 1004 if (dev->written) written++;
967 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */ 1005 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
968 if (!rdev || !rdev->in_sync) { 1006 if (!rdev || !test_bit(In_sync, &rdev->flags)) {
1007 /* The ReadError flag wil just be confusing now */
1008 clear_bit(R5_ReadError, &dev->flags);
1009 clear_bit(R5_ReWrite, &dev->flags);
1010 }
1011 if (!rdev || !test_bit(In_sync, &rdev->flags)
1012 || test_bit(R5_ReadError, &dev->flags)) {
969 failed++; 1013 failed++;
970 failed_num = i; 1014 failed_num = i;
971 } else 1015 } else
@@ -980,6 +1024,14 @@ static void handle_stripe(struct stripe_head *sh)
980 if (failed > 1 && to_read+to_write+written) { 1024 if (failed > 1 && to_read+to_write+written) {
981 for (i=disks; i--; ) { 1025 for (i=disks; i--; ) {
982 int bitmap_end = 0; 1026 int bitmap_end = 0;
1027
1028 if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
1029 mdk_rdev_t *rdev = conf->disks[i].rdev;
1030 if (rdev && test_bit(In_sync, &rdev->flags))
1031 /* multiple read failures in one stripe */
1032 md_error(conf->mddev, rdev);
1033 }
1034
983 spin_lock_irq(&conf->device_lock); 1035 spin_lock_irq(&conf->device_lock);
984 /* fail all writes first */ 1036 /* fail all writes first */
985 bi = sh->dev[i].towrite; 1037 bi = sh->dev[i].towrite;
@@ -1015,7 +1067,8 @@ static void handle_stripe(struct stripe_head *sh)
1015 } 1067 }
1016 1068
1017 /* fail any reads if this device is non-operational */ 1069 /* fail any reads if this device is non-operational */
1018 if (!test_bit(R5_Insync, &sh->dev[i].flags)) { 1070 if (!test_bit(R5_Insync, &sh->dev[i].flags) ||
1071 test_bit(R5_ReadError, &sh->dev[i].flags)) {
1019 bi = sh->dev[i].toread; 1072 bi = sh->dev[i].toread;
1020 sh->dev[i].toread = NULL; 1073 sh->dev[i].toread = NULL;
1021 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) 1074 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
@@ -1247,6 +1300,11 @@ static void handle_stripe(struct stripe_head *sh)
1247 !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) { 1300 !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) {
1248 /* parity is correct (on disc, not in buffer any more) */ 1301 /* parity is correct (on disc, not in buffer any more) */
1249 set_bit(STRIPE_INSYNC, &sh->state); 1302 set_bit(STRIPE_INSYNC, &sh->state);
1303 } else {
1304 conf->mddev->resync_mismatches += STRIPE_SECTORS;
1305 if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
1306 /* don't try to repair!! */
1307 set_bit(STRIPE_INSYNC, &sh->state);
1250 } 1308 }
1251 } 1309 }
1252 if (!test_bit(STRIPE_INSYNC, &sh->state)) { 1310 if (!test_bit(STRIPE_INSYNC, &sh->state)) {
@@ -1274,7 +1332,27 @@ static void handle_stripe(struct stripe_head *sh)
1274 md_done_sync(conf->mddev, STRIPE_SECTORS,1); 1332 md_done_sync(conf->mddev, STRIPE_SECTORS,1);
1275 clear_bit(STRIPE_SYNCING, &sh->state); 1333 clear_bit(STRIPE_SYNCING, &sh->state);
1276 } 1334 }
1277 1335
1336 /* If the failed drive is just a ReadError, then we might need to progress
1337 * the repair/check process
1338 */
1339 if (failed == 1 && ! conf->mddev->ro &&
1340 test_bit(R5_ReadError, &sh->dev[failed_num].flags)
1341 && !test_bit(R5_LOCKED, &sh->dev[failed_num].flags)
1342 && test_bit(R5_UPTODATE, &sh->dev[failed_num].flags)
1343 ) {
1344 dev = &sh->dev[failed_num];
1345 if (!test_bit(R5_ReWrite, &dev->flags)) {
1346 set_bit(R5_Wantwrite, &dev->flags);
1347 set_bit(R5_ReWrite, &dev->flags);
1348 set_bit(R5_LOCKED, &dev->flags);
1349 } else {
1350 /* let's read it back */
1351 set_bit(R5_Wantread, &dev->flags);
1352 set_bit(R5_LOCKED, &dev->flags);
1353 }
1354 }
1355
1278 spin_unlock(&sh->lock); 1356 spin_unlock(&sh->lock);
1279 1357
1280 while ((bi=return_bi)) { 1358 while ((bi=return_bi)) {
@@ -1305,8 +1383,8 @@ static void handle_stripe(struct stripe_head *sh)
1305 bi->bi_end_io = raid5_end_read_request; 1383 bi->bi_end_io = raid5_end_read_request;
1306 1384
1307 rcu_read_lock(); 1385 rcu_read_lock();
1308 rdev = conf->disks[i].rdev; 1386 rdev = rcu_dereference(conf->disks[i].rdev);
1309 if (rdev && rdev->faulty) 1387 if (rdev && test_bit(Faulty, &rdev->flags))
1310 rdev = NULL; 1388 rdev = NULL;
1311 if (rdev) 1389 if (rdev)
1312 atomic_inc(&rdev->nr_pending); 1390 atomic_inc(&rdev->nr_pending);
@@ -1379,8 +1457,8 @@ static void unplug_slaves(mddev_t *mddev)
1379 1457
1380 rcu_read_lock(); 1458 rcu_read_lock();
1381 for (i=0; i<mddev->raid_disks; i++) { 1459 for (i=0; i<mddev->raid_disks; i++) {
1382 mdk_rdev_t *rdev = conf->disks[i].rdev; 1460 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1383 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 1461 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
1384 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 1462 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
1385 1463
1386 atomic_inc(&rdev->nr_pending); 1464 atomic_inc(&rdev->nr_pending);
@@ -1424,8 +1502,8 @@ static int raid5_issue_flush(request_queue_t *q, struct gendisk *disk,
1424 1502
1425 rcu_read_lock(); 1503 rcu_read_lock();
1426 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 1504 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
1427 mdk_rdev_t *rdev = conf->disks[i].rdev; 1505 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1428 if (rdev && !rdev->faulty) { 1506 if (rdev && !test_bit(Faulty, &rdev->flags)) {
1429 struct block_device *bdev = rdev->bdev; 1507 struct block_device *bdev = rdev->bdev;
1430 request_queue_t *r_queue = bdev_get_queue(bdev); 1508 request_queue_t *r_queue = bdev_get_queue(bdev);
1431 1509
@@ -1567,6 +1645,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1567 return rv; 1645 return rv;
1568 } 1646 }
1569 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && 1647 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
1648 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
1570 !conf->fullsync && sync_blocks >= STRIPE_SECTORS) { 1649 !conf->fullsync && sync_blocks >= STRIPE_SECTORS) {
1571 /* we can skip this block, and probably more */ 1650 /* we can skip this block, and probably more */
1572 sync_blocks /= STRIPE_SECTORS; 1651 sync_blocks /= STRIPE_SECTORS;
@@ -1663,6 +1742,74 @@ static void raid5d (mddev_t *mddev)
1663 PRINTK("--- raid5d inactive\n"); 1742 PRINTK("--- raid5d inactive\n");
1664} 1743}
1665 1744
1745static ssize_t
1746raid5_show_stripe_cache_size(mddev_t *mddev, char *page)
1747{
1748 raid5_conf_t *conf = mddev_to_conf(mddev);
1749 if (conf)
1750 return sprintf(page, "%d\n", conf->max_nr_stripes);
1751 else
1752 return 0;
1753}
1754
1755static ssize_t
1756raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len)
1757{
1758 raid5_conf_t *conf = mddev_to_conf(mddev);
1759 char *end;
1760 int new;
1761 if (len >= PAGE_SIZE)
1762 return -EINVAL;
1763 if (!conf)
1764 return -ENODEV;
1765
1766 new = simple_strtoul(page, &end, 10);
1767 if (!*page || (*end && *end != '\n') )
1768 return -EINVAL;
1769 if (new <= 16 || new > 32768)
1770 return -EINVAL;
1771 while (new < conf->max_nr_stripes) {
1772 if (drop_one_stripe(conf))
1773 conf->max_nr_stripes--;
1774 else
1775 break;
1776 }
1777 while (new > conf->max_nr_stripes) {
1778 if (grow_one_stripe(conf))
1779 conf->max_nr_stripes++;
1780 else break;
1781 }
1782 return len;
1783}
1784
1785static struct md_sysfs_entry
1786raid5_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR,
1787 raid5_show_stripe_cache_size,
1788 raid5_store_stripe_cache_size);
1789
1790static ssize_t
1791stripe_cache_active_show(mddev_t *mddev, char *page)
1792{
1793 raid5_conf_t *conf = mddev_to_conf(mddev);
1794 if (conf)
1795 return sprintf(page, "%d\n", atomic_read(&conf->active_stripes));
1796 else
1797 return 0;
1798}
1799
1800static struct md_sysfs_entry
1801raid5_stripecache_active = __ATTR_RO(stripe_cache_active);
1802
1803static struct attribute *raid5_attrs[] = {
1804 &raid5_stripecache_size.attr,
1805 &raid5_stripecache_active.attr,
1806 NULL,
1807};
1808static struct attribute_group raid5_attrs_group = {
1809 .name = NULL,
1810 .attrs = raid5_attrs,
1811};
1812
1666static int run(mddev_t *mddev) 1813static int run(mddev_t *mddev)
1667{ 1814{
1668 raid5_conf_t *conf; 1815 raid5_conf_t *conf;
@@ -1709,7 +1856,7 @@ static int run(mddev_t *mddev)
1709 1856
1710 disk->rdev = rdev; 1857 disk->rdev = rdev;
1711 1858
1712 if (rdev->in_sync) { 1859 if (test_bit(In_sync, &rdev->flags)) {
1713 char b[BDEVNAME_SIZE]; 1860 char b[BDEVNAME_SIZE];
1714 printk(KERN_INFO "raid5: device %s operational as raid" 1861 printk(KERN_INFO "raid5: device %s operational as raid"
1715 " disk %d\n", bdevname(rdev->bdev,b), 1862 " disk %d\n", bdevname(rdev->bdev,b),
@@ -1804,6 +1951,7 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
1804 } 1951 }
1805 1952
1806 /* Ok, everything is just fine now */ 1953 /* Ok, everything is just fine now */
1954 sysfs_create_group(&mddev->kobj, &raid5_attrs_group);
1807 1955
1808 if (mddev->bitmap) 1956 if (mddev->bitmap)
1809 mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ; 1957 mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
@@ -1828,7 +1976,7 @@ abort:
1828 1976
1829 1977
1830 1978
1831static int stop (mddev_t *mddev) 1979static int stop(mddev_t *mddev)
1832{ 1980{
1833 raid5_conf_t *conf = (raid5_conf_t *) mddev->private; 1981 raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
1834 1982
@@ -1837,6 +1985,7 @@ static int stop (mddev_t *mddev)
1837 shrink_stripes(conf); 1985 shrink_stripes(conf);
1838 free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER); 1986 free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
1839 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 1987 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
1988 sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
1840 kfree(conf); 1989 kfree(conf);
1841 mddev->private = NULL; 1990 mddev->private = NULL;
1842 return 0; 1991 return 0;
@@ -1887,7 +2036,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
1887 for (i = 0; i < conf->raid_disks; i++) 2036 for (i = 0; i < conf->raid_disks; i++)
1888 seq_printf (seq, "%s", 2037 seq_printf (seq, "%s",
1889 conf->disks[i].rdev && 2038 conf->disks[i].rdev &&
1890 conf->disks[i].rdev->in_sync ? "U" : "_"); 2039 test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_");
1891 seq_printf (seq, "]"); 2040 seq_printf (seq, "]");
1892#if RAID5_DEBUG 2041#if RAID5_DEBUG
1893#define D(x) \ 2042#define D(x) \
@@ -1914,7 +2063,7 @@ static void print_raid5_conf (raid5_conf_t *conf)
1914 tmp = conf->disks + i; 2063 tmp = conf->disks + i;
1915 if (tmp->rdev) 2064 if (tmp->rdev)
1916 printk(" disk %d, o:%d, dev:%s\n", 2065 printk(" disk %d, o:%d, dev:%s\n",
1917 i, !tmp->rdev->faulty, 2066 i, !test_bit(Faulty, &tmp->rdev->flags),
1918 bdevname(tmp->rdev->bdev,b)); 2067 bdevname(tmp->rdev->bdev,b));
1919 } 2068 }
1920} 2069}
@@ -1928,12 +2077,12 @@ static int raid5_spare_active(mddev_t *mddev)
1928 for (i = 0; i < conf->raid_disks; i++) { 2077 for (i = 0; i < conf->raid_disks; i++) {
1929 tmp = conf->disks + i; 2078 tmp = conf->disks + i;
1930 if (tmp->rdev 2079 if (tmp->rdev
1931 && !tmp->rdev->faulty 2080 && !test_bit(Faulty, &tmp->rdev->flags)
1932 && !tmp->rdev->in_sync) { 2081 && !test_bit(In_sync, &tmp->rdev->flags)) {
1933 mddev->degraded--; 2082 mddev->degraded--;
1934 conf->failed_disks--; 2083 conf->failed_disks--;
1935 conf->working_disks++; 2084 conf->working_disks++;
1936 tmp->rdev->in_sync = 1; 2085 set_bit(In_sync, &tmp->rdev->flags);
1937 } 2086 }
1938 } 2087 }
1939 print_raid5_conf(conf); 2088 print_raid5_conf(conf);
@@ -1950,7 +2099,7 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
1950 print_raid5_conf(conf); 2099 print_raid5_conf(conf);
1951 rdev = p->rdev; 2100 rdev = p->rdev;
1952 if (rdev) { 2101 if (rdev) {
1953 if (rdev->in_sync || 2102 if (test_bit(In_sync, &rdev->flags) ||
1954 atomic_read(&rdev->nr_pending)) { 2103 atomic_read(&rdev->nr_pending)) {
1955 err = -EBUSY; 2104 err = -EBUSY;
1956 goto abort; 2105 goto abort;
@@ -1985,12 +2134,12 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
1985 */ 2134 */
1986 for (disk=0; disk < mddev->raid_disks; disk++) 2135 for (disk=0; disk < mddev->raid_disks; disk++)
1987 if ((p=conf->disks + disk)->rdev == NULL) { 2136 if ((p=conf->disks + disk)->rdev == NULL) {
1988 rdev->in_sync = 0; 2137 clear_bit(In_sync, &rdev->flags);
1989 rdev->raid_disk = disk; 2138 rdev->raid_disk = disk;
1990 found = 1; 2139 found = 1;
1991 if (rdev->saved_raid_disk != disk) 2140 if (rdev->saved_raid_disk != disk)
1992 conf->fullsync = 1; 2141 conf->fullsync = 1;
1993 p->rdev = rdev; 2142 rcu_assign_pointer(p->rdev, rdev);
1994 break; 2143 break;
1995 } 2144 }
1996 print_raid5_conf(conf); 2145 print_raid5_conf(conf);
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 775786947701..eae5a35629c5 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -507,19 +507,19 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
507 raid6_conf_t *conf = (raid6_conf_t *) mddev->private; 507 raid6_conf_t *conf = (raid6_conf_t *) mddev->private;
508 PRINTK("raid6: error called\n"); 508 PRINTK("raid6: error called\n");
509 509
510 if (!rdev->faulty) { 510 if (!test_bit(Faulty, &rdev->flags)) {
511 mddev->sb_dirty = 1; 511 mddev->sb_dirty = 1;
512 if (rdev->in_sync) { 512 if (test_bit(In_sync, &rdev->flags)) {
513 conf->working_disks--; 513 conf->working_disks--;
514 mddev->degraded++; 514 mddev->degraded++;
515 conf->failed_disks++; 515 conf->failed_disks++;
516 rdev->in_sync = 0; 516 clear_bit(In_sync, &rdev->flags);
517 /* 517 /*
518 * if recovery was running, make sure it aborts. 518 * if recovery was running, make sure it aborts.
519 */ 519 */
520 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 520 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
521 } 521 }
522 rdev->faulty = 1; 522 set_bit(Faulty, &rdev->flags);
523 printk (KERN_ALERT 523 printk (KERN_ALERT
524 "raid6: Disk failure on %s, disabling device." 524 "raid6: Disk failure on %s, disabling device."
525 " Operation continuing on %d devices\n", 525 " Operation continuing on %d devices\n",
@@ -1071,7 +1071,7 @@ static void handle_stripe(struct stripe_head *sh)
1071 } 1071 }
1072 if (dev->written) written++; 1072 if (dev->written) written++;
1073 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */ 1073 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
1074 if (!rdev || !rdev->in_sync) { 1074 if (!rdev || !test_bit(In_sync, &rdev->flags)) {
1075 if ( failed < 2 ) 1075 if ( failed < 2 )
1076 failed_num[failed] = i; 1076 failed_num[failed] = i;
1077 failed++; 1077 failed++;
@@ -1464,8 +1464,8 @@ static void handle_stripe(struct stripe_head *sh)
1464 bi->bi_end_io = raid6_end_read_request; 1464 bi->bi_end_io = raid6_end_read_request;
1465 1465
1466 rcu_read_lock(); 1466 rcu_read_lock();
1467 rdev = conf->disks[i].rdev; 1467 rdev = rcu_dereference(conf->disks[i].rdev);
1468 if (rdev && rdev->faulty) 1468 if (rdev && test_bit(Faulty, &rdev->flags))
1469 rdev = NULL; 1469 rdev = NULL;
1470 if (rdev) 1470 if (rdev)
1471 atomic_inc(&rdev->nr_pending); 1471 atomic_inc(&rdev->nr_pending);
@@ -1538,8 +1538,8 @@ static void unplug_slaves(mddev_t *mddev)
1538 1538
1539 rcu_read_lock(); 1539 rcu_read_lock();
1540 for (i=0; i<mddev->raid_disks; i++) { 1540 for (i=0; i<mddev->raid_disks; i++) {
1541 mdk_rdev_t *rdev = conf->disks[i].rdev; 1541 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1542 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 1542 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
1543 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 1543 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
1544 1544
1545 atomic_inc(&rdev->nr_pending); 1545 atomic_inc(&rdev->nr_pending);
@@ -1583,8 +1583,8 @@ static int raid6_issue_flush(request_queue_t *q, struct gendisk *disk,
1583 1583
1584 rcu_read_lock(); 1584 rcu_read_lock();
1585 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 1585 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
1586 mdk_rdev_t *rdev = conf->disks[i].rdev; 1586 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1587 if (rdev && !rdev->faulty) { 1587 if (rdev && !test_bit(Faulty, &rdev->flags)) {
1588 struct block_device *bdev = rdev->bdev; 1588 struct block_device *bdev = rdev->bdev;
1589 request_queue_t *r_queue = bdev_get_queue(bdev); 1589 request_queue_t *r_queue = bdev_get_queue(bdev);
1590 1590
@@ -1868,7 +1868,7 @@ static int run(mddev_t *mddev)
1868 1868
1869 disk->rdev = rdev; 1869 disk->rdev = rdev;
1870 1870
1871 if (rdev->in_sync) { 1871 if (test_bit(In_sync, &rdev->flags)) {
1872 char b[BDEVNAME_SIZE]; 1872 char b[BDEVNAME_SIZE];
1873 printk(KERN_INFO "raid6: device %s operational as raid" 1873 printk(KERN_INFO "raid6: device %s operational as raid"
1874 " disk %d\n", bdevname(rdev->bdev,b), 1874 " disk %d\n", bdevname(rdev->bdev,b),
@@ -2052,7 +2052,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
2052 for (i = 0; i < conf->raid_disks; i++) 2052 for (i = 0; i < conf->raid_disks; i++)
2053 seq_printf (seq, "%s", 2053 seq_printf (seq, "%s",
2054 conf->disks[i].rdev && 2054 conf->disks[i].rdev &&
2055 conf->disks[i].rdev->in_sync ? "U" : "_"); 2055 test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_");
2056 seq_printf (seq, "]"); 2056 seq_printf (seq, "]");
2057#if RAID6_DUMPSTATE 2057#if RAID6_DUMPSTATE
2058 seq_printf (seq, "\n"); 2058 seq_printf (seq, "\n");
@@ -2078,7 +2078,7 @@ static void print_raid6_conf (raid6_conf_t *conf)
2078 tmp = conf->disks + i; 2078 tmp = conf->disks + i;
2079 if (tmp->rdev) 2079 if (tmp->rdev)
2080 printk(" disk %d, o:%d, dev:%s\n", 2080 printk(" disk %d, o:%d, dev:%s\n",
2081 i, !tmp->rdev->faulty, 2081 i, !test_bit(Faulty, &tmp->rdev->flags),
2082 bdevname(tmp->rdev->bdev,b)); 2082 bdevname(tmp->rdev->bdev,b));
2083 } 2083 }
2084} 2084}
@@ -2092,12 +2092,12 @@ static int raid6_spare_active(mddev_t *mddev)
2092 for (i = 0; i < conf->raid_disks; i++) { 2092 for (i = 0; i < conf->raid_disks; i++) {
2093 tmp = conf->disks + i; 2093 tmp = conf->disks + i;
2094 if (tmp->rdev 2094 if (tmp->rdev
2095 && !tmp->rdev->faulty 2095 && !test_bit(Faulty, &tmp->rdev->flags)
2096 && !tmp->rdev->in_sync) { 2096 && !test_bit(In_sync, &tmp->rdev->flags)) {
2097 mddev->degraded--; 2097 mddev->degraded--;
2098 conf->failed_disks--; 2098 conf->failed_disks--;
2099 conf->working_disks++; 2099 conf->working_disks++;
2100 tmp->rdev->in_sync = 1; 2100 set_bit(In_sync, &tmp->rdev->flags);
2101 } 2101 }
2102 } 2102 }
2103 print_raid6_conf(conf); 2103 print_raid6_conf(conf);
@@ -2114,7 +2114,7 @@ static int raid6_remove_disk(mddev_t *mddev, int number)
2114 print_raid6_conf(conf); 2114 print_raid6_conf(conf);
2115 rdev = p->rdev; 2115 rdev = p->rdev;
2116 if (rdev) { 2116 if (rdev) {
2117 if (rdev->in_sync || 2117 if (test_bit(In_sync, &rdev->flags) ||
2118 atomic_read(&rdev->nr_pending)) { 2118 atomic_read(&rdev->nr_pending)) {
2119 err = -EBUSY; 2119 err = -EBUSY;
2120 goto abort; 2120 goto abort;
@@ -2149,12 +2149,12 @@ static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
2149 */ 2149 */
2150 for (disk=0; disk < mddev->raid_disks; disk++) 2150 for (disk=0; disk < mddev->raid_disks; disk++)
2151 if ((p=conf->disks + disk)->rdev == NULL) { 2151 if ((p=conf->disks + disk)->rdev == NULL) {
2152 rdev->in_sync = 0; 2152 clear_bit(In_sync, &rdev->flags);
2153 rdev->raid_disk = disk; 2153 rdev->raid_disk = disk;
2154 found = 1; 2154 found = 1;
2155 if (rdev->saved_raid_disk != disk) 2155 if (rdev->saved_raid_disk != disk)
2156 conf->fullsync = 1; 2156 conf->fullsync = 1;
2157 p->rdev = rdev; 2157 rcu_assign_pointer(p->rdev, rdev);
2158 break; 2158 break;
2159 } 2159 }
2160 print_raid6_conf(conf); 2160 print_raid6_conf(conf);
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 31fccb4f05d6..4b71fd6f7aed 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -116,7 +116,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
116 [ 46 ] = KEY_BLUE, 116 [ 46 ] = KEY_BLUE,
117 [ 24 ] = KEY_KPPLUS, /* fine tune + */ 117 [ 24 ] = KEY_KPPLUS, /* fine tune + */
118 [ 25 ] = KEY_KPMINUS, /* fine tune - */ 118 [ 25 ] = KEY_KPMINUS, /* fine tune - */
119 [ 33 ] = KEY_KPDOT, 119 [ 33 ] = KEY_KPDOT,
120 [ 19 ] = KEY_KPENTER, 120 [ 19 ] = KEY_KPENTER,
121 [ 34 ] = KEY_BACK, 121 [ 34 ] = KEY_BACK,
122 [ 35 ] = KEY_PLAYPAUSE, 122 [ 35 ] = KEY_PLAYPAUSE,
@@ -239,7 +239,7 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
239 dprintk(1,"%s: key event code=%d down=%d\n", 239 dprintk(1,"%s: key event code=%d down=%d\n",
240 dev->name,ir->keycode,ir->keypressed); 240 dev->name,ir->keycode,ir->keypressed);
241 input_report_key(dev,ir->keycode,ir->keypressed); 241 input_report_key(dev,ir->keycode,ir->keypressed);
242 input_sync(dev); 242 input_sync(dev);
243} 243}
244 244
245/* -------------------------------------------------------------------------- */ 245/* -------------------------------------------------------------------------- */
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 47e28b0ee951..a35330315f65 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -13,6 +13,8 @@
13#include "bcm3510.h" 13#include "bcm3510.h"
14#include "stv0297.h" 14#include "stv0297.h"
15#include "mt312.h" 15#include "mt312.h"
16#include "lgdt330x.h"
17#include "dvb-pll.h"
16 18
17/* lnb control */ 19/* lnb control */
18 20
@@ -234,7 +236,6 @@ static struct stv0299_config samsung_tbmu24112_config = {
234 .inittab = samsung_tbmu24112_inittab, 236 .inittab = samsung_tbmu24112_inittab,
235 .mclk = 88000000UL, 237 .mclk = 88000000UL,
236 .invert = 0, 238 .invert = 0,
237 .enhanced_tuning = 0,
238 .skip_reinit = 0, 239 .skip_reinit = 0,
239 .lock_output = STV0229_LOCKOUTPUT_LK, 240 .lock_output = STV0229_LOCKOUTPUT_LK,
240 .volt13_op0_op1 = STV0299_VOLT13_OP1, 241 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -296,6 +297,52 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir
296 return request_firmware(fw, name, fc->dev); 297 return request_firmware(fw, name, fc->dev);
297} 298}
298 299
300static int lgdt3303_pll_set(struct dvb_frontend* fe,
301 struct dvb_frontend_parameters* params)
302{
303 struct flexcop_device *fc = fe->dvb->priv;
304 u8 buf[4];
305 struct i2c_msg msg =
306 { .addr = 0x61, .flags = 0, .buf = buf, .len = 4 };
307 int err;
308
309 dvb_pll_configure(&dvb_pll_tdvs_tua6034,buf, params->frequency, 0);
310 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
311 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
312 if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
313 printk(KERN_WARNING "lgdt3303: %s error "
314 "(addr %02x <- %02x, err = %i)\n",
315 __FUNCTION__, buf[0], buf[1], err);
316 if (err < 0)
317 return err;
318 else
319 return -EREMOTEIO;
320 }
321
322 buf[0] = 0x86 | 0x18;
323 buf[1] = 0x50;
324 msg.len = 2;
325 if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
326 printk(KERN_WARNING "lgdt3303: %s error "
327 "(addr %02x <- %02x, err = %i)\n",
328 __FUNCTION__, buf[0], buf[1], err);
329 if (err < 0)
330 return err;
331 else
332 return -EREMOTEIO;
333 }
334
335 return 0;
336}
337
338static struct lgdt330x_config air2pc_atsc_hd5000_config = {
339 .demod_address = 0x59,
340 .demod_chip = LGDT3303,
341 .serial_mpeg = 0x04,
342 .pll_set = lgdt3303_pll_set,
343 .clock_polarity_flip = 1,
344};
345
299static struct nxt2002_config samsung_tbmv_config = { 346static struct nxt2002_config samsung_tbmv_config = {
300 .demod_address = 0x0a, 347 .demod_address = 0x0a,
301 .request_firmware = flexcop_fe_request_firmware, 348 .request_firmware = flexcop_fe_request_firmware,
@@ -458,6 +505,11 @@ int flexcop_frontend_init(struct flexcop_device *fc)
458 fc->dev_type = FC_AIR_ATSC2; 505 fc->dev_type = FC_AIR_ATSC2;
459 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); 506 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
460 } else 507 } else
508 /* try the air atsc 3nd generation (lgdt3303) */
509 if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
510 fc->dev_type = FC_AIR_ATSC3;
511 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
512 } else
461 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ 513 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
462 if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) { 514 if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
463 fc->dev_type = FC_AIR_ATSC1; 515 fc->dev_type = FC_AIR_ATSC1;
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 3a08d38b318a..62282d8dbfa8 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -51,6 +51,7 @@ const char *flexcop_device_names[] = {
51 "Sky2PC/SkyStar 2 DVB-S", 51 "Sky2PC/SkyStar 2 DVB-S",
52 "Sky2PC/SkyStar 2 DVB-S (old version)", 52 "Sky2PC/SkyStar 2 DVB-S (old version)",
53 "Cable2PC/CableStar 2 DVB-C", 53 "Cable2PC/CableStar 2 DVB-C",
54 "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
54}; 55};
55 56
56const char *flexcop_bus_names[] = { 57const char *flexcop_bus_names[] = {
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 4ae1eb5bfe98..23cc6431e2b8 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -26,6 +26,7 @@ typedef enum {
26 FC_SKY, 26 FC_SKY,
27 FC_SKY_OLD, 27 FC_SKY_OLD,
28 FC_CABLE, 28 FC_CABLE,
29 FC_AIR_ATSC3,
29} flexcop_device_type_t; 30} flexcop_device_type_t;
30 31
31typedef enum { 32typedef enum {
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 12873d435406..123ed96f6faa 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -193,6 +193,7 @@ static void flexcop_reset(struct flexcop_device *fc)
193 v204 = fc->read_ibi_reg(fc,misc_204); 193 v204 = fc->read_ibi_reg(fc,misc_204);
194 v204.misc_204.Per_reset_sig = 0; 194 v204.misc_204.Per_reset_sig = 0;
195 fc->write_ibi_reg(fc,misc_204,v204); 195 fc->write_ibi_reg(fc,misc_204,v204);
196 msleep(1);
196 v204.misc_204.Per_reset_sig = 1; 197 v204.misc_204.Per_reset_sig = 1;
197 fc->write_ibi_reg(fc,misc_204,v204); 198 fc->write_ibi_reg(fc,misc_204,v204);
198} 199}
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 1e85d16491b0..2337b41714e0 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -6,10 +6,12 @@ config DVB_BT8XX
6 select DVB_NXT6000 6 select DVB_NXT6000
7 select DVB_CX24110 7 select DVB_CX24110
8 select DVB_OR51211 8 select DVB_OR51211
9 select DVB_LGDT330X
9 help 10 help
10 Support for PCI cards based on the Bt8xx PCI bridge. Examples are 11 Support for PCI cards based on the Bt8xx PCI bridge. Examples are
11 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, 12 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
12 the pcHDTV HD2000 cards, and certain AVerMedia cards. 13 the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and
14 some AVerMedia cards.
13 15
14 Since these cards have no MPEG decoder onboard, they transmit 16 Since these cards have no MPEG decoder onboard, they transmit
15 only compressed MPEG data over the PCI bus, so you need 17 only compressed MPEG data over the PCI bus, so you need
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index b3c9d7327ac1..8977c7a313df 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -690,8 +690,8 @@ struct dst_types dst_tlist[] = {
690 .device_id = "DTT-CI", 690 .device_id = "DTT-CI",
691 .offset = 1, 691 .offset = 1,
692 .dst_type = DST_TYPE_IS_TERR, 692 .dst_type = DST_TYPE_IS_TERR,
693 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, 693 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE,
694 .dst_feature = 0 694 .dst_feature = DST_TYPE_HAS_CA
695 }, 695 },
696 696
697 { 697 {
@@ -796,6 +796,56 @@ static int dst_get_vendor(struct dst_state *state)
796 return 0; 796 return 0;
797} 797}
798 798
799static int dst_get_tuner_info(struct dst_state *state)
800{
801 u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
802 u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
803
804 get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
805 get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
806 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
807 if (dst_command(state, get_tuner_2, 8) < 0) {
808 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
809 return -1;
810 }
811 } else {
812 if (dst_command(state, get_tuner_1, 8) < 0) {
813 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
814 return -1;
815 }
816 }
817 memset(&state->board_info, '\0', 8);
818 memcpy(&state->board_info, &state->rxbuffer, 8);
819 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
820 if (state->board_info[1] == 0x0b) {
821 if (state->type_flags & DST_TYPE_HAS_TS204)
822 state->type_flags &= ~DST_TYPE_HAS_TS204;
823 state->type_flags |= DST_TYPE_HAS_NEWTUNE;
824 dprintk(verbose, DST_INFO, 1, "DST type has TS=188");
825 } else {
826 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
827 state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
828 state->type_flags |= DST_TYPE_HAS_TS204;
829 dprintk(verbose, DST_INFO, 1, "DST type has TS=204");
830 }
831 } else {
832 if (state->board_info[0] == 0xbc) {
833 if (state->type_flags & DST_TYPE_HAS_TS204)
834 state->type_flags &= ~DST_TYPE_HAS_TS204;
835 state->type_flags |= DST_TYPE_HAS_NEWTUNE;
836 dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]);
837
838 } else if (state->board_info[0] == 0xcc) {
839 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
840 state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
841 state->type_flags |= DST_TYPE_HAS_TS204;
842 dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]);
843 }
844 }
845
846 return 0;
847}
848
799static int dst_get_device_id(struct dst_state *state) 849static int dst_get_device_id(struct dst_state *state)
800{ 850{
801 u8 reply; 851 u8 reply;
@@ -855,15 +905,12 @@ static int dst_get_device_id(struct dst_state *state)
855 state->dst_type = use_dst_type; 905 state->dst_type = use_dst_type;
856 dst_type_flags_print(state->type_flags); 906 dst_type_flags_print(state->type_flags);
857 907
858 if (state->type_flags & DST_TYPE_HAS_TS204) {
859 dst_packsize(state, 204);
860 }
861
862 return 0; 908 return 0;
863} 909}
864 910
865static int dst_probe(struct dst_state *state) 911static int dst_probe(struct dst_state *state)
866{ 912{
913 sema_init(&state->dst_mutex, 1);
867 if ((rdc_8820_reset(state)) < 0) { 914 if ((rdc_8820_reset(state)) < 0) {
868 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); 915 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
869 return -1; 916 return -1;
@@ -886,6 +933,13 @@ static int dst_probe(struct dst_state *state)
886 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); 933 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
887 return 0; 934 return 0;
888 } 935 }
936 if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
937 if (dst_get_tuner_info(state) < 0)
938 dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command");
939 }
940 if (state->type_flags & DST_TYPE_HAS_TS204) {
941 dst_packsize(state, 204);
942 }
889 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { 943 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
890 if (dst_fw_ver(state) < 0) { 944 if (dst_fw_ver(state) < 0) {
891 dprintk(verbose, DST_INFO, 1, "FW: Unsupported command"); 945 dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
@@ -907,21 +961,23 @@ static int dst_probe(struct dst_state *state)
907int dst_command(struct dst_state *state, u8 *data, u8 len) 961int dst_command(struct dst_state *state, u8 *data, u8 len)
908{ 962{
909 u8 reply; 963 u8 reply;
964
965 down(&state->dst_mutex);
910 if ((dst_comm_init(state)) < 0) { 966 if ((dst_comm_init(state)) < 0) {
911 dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); 967 dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
912 return -1; 968 goto error;
913 } 969 }
914 if (write_dst(state, data, len)) { 970 if (write_dst(state, data, len)) {
915 dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); 971 dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
916 if ((dst_error_recovery(state)) < 0) { 972 if ((dst_error_recovery(state)) < 0) {
917 dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); 973 dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
918 return -1; 974 goto error;
919 } 975 }
920 return -1; 976 goto error;
921 } 977 }
922 if ((dst_pio_disable(state)) < 0) { 978 if ((dst_pio_disable(state)) < 0) {
923 dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); 979 dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
924 return -1; 980 goto error;
925 } 981 }
926 if (state->type_flags & DST_TYPE_HAS_FW_1) 982 if (state->type_flags & DST_TYPE_HAS_FW_1)
927 udelay(3000); 983 udelay(3000);
@@ -929,36 +985,41 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
929 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); 985 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
930 if ((dst_error_recovery(state)) < 0) { 986 if ((dst_error_recovery(state)) < 0) {
931 dprintk(verbose, DST_INFO, 1, "Recovery Failed."); 987 dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
932 return -1; 988 goto error;
933 } 989 }
934 return -1; 990 goto error;
935 } 991 }
936 if (reply != ACK) { 992 if (reply != ACK) {
937 dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); 993 dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
938 return -1; 994 goto error;
939 } 995 }
940 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 996 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
941 return 0; 997 goto error;
942 if (state->type_flags & DST_TYPE_HAS_FW_1) 998 if (state->type_flags & DST_TYPE_HAS_FW_1)
943 udelay(3000); 999 udelay(3000);
944 else 1000 else
945 udelay(2000); 1001 udelay(2000);
946 if (!dst_wait_dst_ready(state, NO_DELAY)) 1002 if (!dst_wait_dst_ready(state, NO_DELAY))
947 return -1; 1003 goto error;
948 if (read_dst(state, state->rxbuffer, FIXED_COMM)) { 1004 if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
949 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); 1005 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
950 if ((dst_error_recovery(state)) < 0) { 1006 if ((dst_error_recovery(state)) < 0) {
951 dprintk(verbose, DST_INFO, 1, "Recovery failed."); 1007 dprintk(verbose, DST_INFO, 1, "Recovery failed.");
952 return -1; 1008 goto error;
953 } 1009 }
954 return -1; 1010 goto error;
955 } 1011 }
956 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 1012 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
957 dprintk(verbose, DST_INFO, 1, "checksum failure"); 1013 dprintk(verbose, DST_INFO, 1, "checksum failure");
958 return -1; 1014 goto error;
959 } 1015 }
960 1016 up(&state->dst_mutex);
961 return 0; 1017 return 0;
1018
1019error:
1020 up(&state->dst_mutex);
1021 return -EIO;
1022
962} 1023}
963EXPORT_SYMBOL(dst_command); 1024EXPORT_SYMBOL(dst_command);
964 1025
@@ -1016,7 +1077,7 @@ static int dst_get_tuna(struct dst_state *state)
1016 return 0; 1077 return 0;
1017 state->diseq_flags &= ~(HAS_LOCK); 1078 state->diseq_flags &= ~(HAS_LOCK);
1018 if (!dst_wait_dst_ready(state, NO_DELAY)) 1079 if (!dst_wait_dst_ready(state, NO_DELAY))
1019 return 0; 1080 return -EIO;
1020 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) 1081 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
1021 /* how to get variable length reply ???? */ 1082 /* how to get variable length reply ???? */
1022 retval = read_dst(state, state->rx_tuna, 10); 1083 retval = read_dst(state, state->rx_tuna, 10);
@@ -1024,22 +1085,27 @@ static int dst_get_tuna(struct dst_state *state)
1024 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); 1085 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
1025 if (retval < 0) { 1086 if (retval < 0) {
1026 dprintk(verbose, DST_DEBUG, 1, "read not successful"); 1087 dprintk(verbose, DST_DEBUG, 1, "read not successful");
1027 return 0; 1088 return retval;
1028 } 1089 }
1029 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1090 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1030 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 1091 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1031 dprintk(verbose, DST_INFO, 1, "checksum failure ? "); 1092 dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
1032 return 0; 1093 return -EIO;
1033 } 1094 }
1034 } else { 1095 } else {
1035 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { 1096 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1036 dprintk(verbose, DST_INFO, 1, "checksum failure? "); 1097 dprintk(verbose, DST_INFO, 1, "checksum failure? ");
1037 return 0; 1098 return -EIO;
1038 } 1099 }
1039 } 1100 }
1040 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) 1101 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1041 return 0; 1102 return 0;
1042 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; 1103 if (state->dst_type == DST_TYPE_IS_SAT) {
1104 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1105 } else {
1106 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1107 }
1108 state->decode_freq = state->decode_freq * 1000;
1043 state->decode_lock = 1; 1109 state->decode_lock = 1;
1044 state->diseq_flags |= HAS_LOCK; 1110 state->diseq_flags |= HAS_LOCK;
1045 1111
@@ -1062,10 +1128,10 @@ static int dst_write_tuna(struct dvb_frontend *fe)
1062 dst_set_voltage(fe, SEC_VOLTAGE_13); 1128 dst_set_voltage(fe, SEC_VOLTAGE_13);
1063 } 1129 }
1064 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); 1130 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1065 1131 down(&state->dst_mutex);
1066 if ((dst_comm_init(state)) < 0) { 1132 if ((dst_comm_init(state)) < 0) {
1067 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); 1133 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
1068 return -1; 1134 goto error;
1069 } 1135 }
1070 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1136 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1071 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); 1137 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
@@ -1077,23 +1143,29 @@ static int dst_write_tuna(struct dvb_frontend *fe)
1077 if (retval < 0) { 1143 if (retval < 0) {
1078 dst_pio_disable(state); 1144 dst_pio_disable(state);
1079 dprintk(verbose, DST_DEBUG, 1, "write not successful"); 1145 dprintk(verbose, DST_DEBUG, 1, "write not successful");
1080 return retval; 1146 goto werr;
1081 } 1147 }
1082 if ((dst_pio_disable(state)) < 0) { 1148 if ((dst_pio_disable(state)) < 0) {
1083 dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); 1149 dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
1084 return -1; 1150 goto error;
1085 } 1151 }
1086 if ((read_dst(state, &reply, GET_ACK) < 0)) { 1152 if ((read_dst(state, &reply, GET_ACK) < 0)) {
1087 dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); 1153 dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
1088 return -1; 1154 goto error;
1089 } 1155 }
1090 if (reply != ACK) { 1156 if (reply != ACK) {
1091 dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); 1157 dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
1092 return 0; 1158 goto error;
1093 } 1159 }
1094 state->diseq_flags |= ATTEMPT_TUNE; 1160 state->diseq_flags |= ATTEMPT_TUNE;
1095 1161 retval = dst_get_tuna(state);
1096 return dst_get_tuna(state); 1162werr:
1163 up(&state->dst_mutex);
1164 return retval;
1165
1166error:
1167 up(&state->dst_mutex);
1168 return -EIO;
1097} 1169}
1098 1170
1099/* 1171/*
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 6776a592045f..e6541aff3996 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -69,62 +69,53 @@ static int ca_set_pid(void)
69} 69}
70 70
71 71
72static int put_checksum(u8 *check_string, int length) 72static void put_checksum(u8 *check_string, int length)
73{ 73{
74 u8 i = 0, checksum = 0; 74 dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum.");
75 75 dprintk(verbose, DST_CA_DEBUG, 1, " -> string length : 0x%02x", length);
76 dprintk(verbose, DST_CA_DEBUG, 1, " ========================= Checksum calculation ==========================="); 76 check_string[length] = dst_check_sum (check_string, length);
77 dprintk(verbose, DST_CA_DEBUG, 1, " String Length=[0x%02x]", length); 77 dprintk(verbose, DST_CA_DEBUG, 1, " -> checksum : 0x%02x", check_string[length]);
78 dprintk(verbose, DST_CA_DEBUG, 1, " String=[");
79
80 while (i < length) {
81 dprintk(verbose, DST_CA_DEBUG, 0, " %02x", check_string[i]);
82 checksum += check_string[i];
83 i++;
84 }
85 dprintk(verbose, DST_CA_DEBUG, 0, " ]\n");
86 dprintk(verbose, DST_CA_DEBUG, 1, "Sum=[%02x]\n", checksum);
87 check_string[length] = ~checksum + 1;
88 dprintk(verbose, DST_CA_DEBUG, 1, " Checksum=[%02x]", check_string[length]);
89 dprintk(verbose, DST_CA_DEBUG, 1, " ==========================================================================");
90
91 return 0;
92} 78}
93 79
94static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) 80static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
95{ 81{
96 u8 reply; 82 u8 reply;
97 83
84 down(&state->dst_mutex);
98 dst_comm_init(state); 85 dst_comm_init(state);
99 msleep(65); 86 msleep(65);
100 87
101 if (write_dst(state, data, len)) { 88 if (write_dst(state, data, len)) {
102 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); 89 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
103 dst_error_recovery(state); 90 dst_error_recovery(state);
104 return -1; 91 goto error;
105 } 92 }
106 if ((dst_pio_disable(state)) < 0) { 93 if ((dst_pio_disable(state)) < 0) {
107 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); 94 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
108 return -1; 95 goto error;
109 } 96 }
110 if (read_dst(state, &reply, GET_ACK) < 0) { 97 if (read_dst(state, &reply, GET_ACK) < 0) {
111 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); 98 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
112 dst_error_recovery(state); 99 dst_error_recovery(state);
113 return -1; 100 goto error;
114 } 101 }
115 if (read) { 102 if (read) {
116 if (! dst_wait_dst_ready(state, LONG_DELAY)) { 103 if (! dst_wait_dst_ready(state, LONG_DELAY)) {
117 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); 104 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
118 return -1; 105 goto error;
119 } 106 }
120 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ 107 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
121 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); 108 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
122 dst_error_recovery(state); 109 dst_error_recovery(state);
123 return -1; 110 goto error;
124 } 111 }
125 } 112 }
126 113 up(&state->dst_mutex);
127 return 0; 114 return 0;
115
116error:
117 up(&state->dst_mutex);
118 return -EIO;
128} 119}
129 120
130 121
@@ -166,7 +157,7 @@ static int ca_get_app_info(struct dst_state *state)
166 return 0; 157 return 0;
167} 158}
168 159
169static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg) 160static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg)
170{ 161{
171 int i; 162 int i;
172 u8 slot_cap[256]; 163 u8 slot_cap[256];
@@ -192,25 +183,25 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps,
192 p_ca_caps->descr_num = slot_cap[7]; 183 p_ca_caps->descr_num = slot_cap[7];
193 p_ca_caps->descr_type = 1; 184 p_ca_caps->descr_type = 1;
194 185
195 if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) 186 if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps)))
196 return -EFAULT; 187 return -EFAULT;
197 188
198 return 0; 189 return 0;
199} 190}
200 191
201/* Need some more work */ 192/* Need some more work */
202static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 193static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
203{ 194{
204 return -EOPNOTSUPP; 195 return -EOPNOTSUPP;
205} 196}
206 197
207 198
208static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg) 199static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg)
209{ 200{
210 int i; 201 int i;
211 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; 202 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
212 203
213 u8 *slot_info = state->rxbuffer; 204 u8 *slot_info = state->messages;
214 205
215 put_checksum(&slot_command[0], 7); 206 put_checksum(&slot_command[0], 7);
216 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { 207 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
@@ -238,19 +229,19 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s
238 } else 229 } else
239 p_ca_slot_info->flags = 0; 230 p_ca_slot_info->flags = 0;
240 231
241 if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) 232 if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
242 return -EFAULT; 233 return -EFAULT;
243 234
244 return 0; 235 return 0;
245} 236}
246 237
247 238
248static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 239static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
249{ 240{
250 u8 i = 0; 241 u8 i = 0;
251 u32 command = 0; 242 u32 command = 0;
252 243
253 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 244 if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg)))
254 return -EFAULT; 245 return -EFAULT;
255 246
256 if (p_ca_message->msg) { 247 if (p_ca_message->msg) {
@@ -266,7 +257,7 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
266 switch (command) { 257 switch (command) {
267 case CA_APP_INFO: 258 case CA_APP_INFO:
268 memcpy(p_ca_message->msg, state->messages, 128); 259 memcpy(p_ca_message->msg, state->messages, 128);
269 if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) ) 260 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
270 return -EFAULT; 261 return -EFAULT;
271 break; 262 break;
272 } 263 }
@@ -315,7 +306,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l
315 return 0; 306 return 0;
316} 307}
317 308
318u32 asn_1_decode(u8 *asn_1_array) 309static u32 asn_1_decode(u8 *asn_1_array)
319{ 310{
320 u8 length_field = 0, word_count = 0, count = 0; 311 u8 length_field = 0, word_count = 0, count = 0;
321 u32 length = 0; 312 u32 length = 0;
@@ -328,7 +319,8 @@ u32 asn_1_decode(u8 *asn_1_array)
328 } else { 319 } else {
329 word_count = length_field & 0x7f; 320 word_count = length_field & 0x7f;
330 for (count = 0; count < word_count; count++) { 321 for (count = 0; count < word_count; count++) {
331 length = (length | asn_1_array[count + 1]) << 8; 322 length = length << 8;
323 length += asn_1_array[count + 1];
332 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length); 324 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
333 } 325 }
334 } 326 }
@@ -399,13 +391,14 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
399 return 0; 391 return 0;
400} 392}
401 393
402static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 394static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
403{ 395{
404 int i = 0; 396 int i = 0;
405 unsigned int ca_message_header_len; 397 unsigned int ca_message_header_len;
406 398
407 u32 command = 0; 399 u32 command = 0;
408 struct ca_msg *hw_buffer; 400 struct ca_msg *hw_buffer;
401 int result = 0;
409 402
410 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 403 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
411 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 404 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -413,8 +406,11 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
413 } 406 }
414 dprintk(verbose, DST_CA_DEBUG, 1, " "); 407 dprintk(verbose, DST_CA_DEBUG, 1, " ");
415 408
416 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 409 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) {
417 return -EFAULT; 410 result = -EFAULT;
411 goto free_mem_and_exit;
412 }
413
418 414
419 if (p_ca_message->msg) { 415 if (p_ca_message->msg) {
420 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ 416 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */
@@ -433,7 +429,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
433 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); 429 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
434 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started 430 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
435 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); 431 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
436 return -1; 432 result = -1;
433 goto free_mem_and_exit;
437 } 434 }
438 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); 435 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
439 break; 436 break;
@@ -442,7 +439,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
442 /* Have to handle the 2 basic types of cards here */ 439 /* Have to handle the 2 basic types of cards here */
443 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { 440 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
444 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); 441 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
445 return -1; 442 result = -1;
443 goto free_mem_and_exit;
446 } 444 }
447 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); 445 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
448 break; 446 break;
@@ -451,22 +449,28 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
451 449
452 if ((ca_get_app_info(state)) < 0) { 450 if ((ca_get_app_info(state)) < 0) {
453 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); 451 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
454 return -1; 452 result = -1;
453 goto free_mem_and_exit;
455 } 454 }
456 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); 455 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
457 break; 456 break;
458 } 457 }
459 } 458 }
460 return 0; 459free_mem_and_exit:
460 kfree (hw_buffer);
461
462 return result;
461} 463}
462 464
463static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) 465static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg)
464{ 466{
465 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; 467 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
466 struct dst_state* state = (struct dst_state*) dvbdev->priv; 468 struct dst_state* state = (struct dst_state*) dvbdev->priv;
467 struct ca_slot_info *p_ca_slot_info; 469 struct ca_slot_info *p_ca_slot_info;
468 struct ca_caps *p_ca_caps; 470 struct ca_caps *p_ca_caps;
469 struct ca_msg *p_ca_message; 471 struct ca_msg *p_ca_message;
472 void __user *arg = (void __user *)ioctl_arg;
473 int result = 0;
470 474
471 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 475 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
472 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 476 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -486,14 +490,16 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
486 dprintk(verbose, DST_CA_INFO, 1, " Sending message"); 490 dprintk(verbose, DST_CA_INFO, 1, " Sending message");
487 if ((ca_send_message(state, p_ca_message, arg)) < 0) { 491 if ((ca_send_message(state, p_ca_message, arg)) < 0) {
488 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); 492 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
489 return -1; 493 result = -1;
494 goto free_mem_and_exit;
490 } 495 }
491 break; 496 break;
492 case CA_GET_MSG: 497 case CA_GET_MSG:
493 dprintk(verbose, DST_CA_INFO, 1, " Getting message"); 498 dprintk(verbose, DST_CA_INFO, 1, " Getting message");
494 if ((ca_get_message(state, p_ca_message, arg)) < 0) { 499 if ((ca_get_message(state, p_ca_message, arg)) < 0) {
495 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); 500 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
496 return -1; 501 result = -1;
502 goto free_mem_and_exit;
497 } 503 }
498 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); 504 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
499 break; 505 break;
@@ -506,7 +512,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
506 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); 512 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
507 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { 513 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
508 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); 514 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
509 return -1; 515 result = -1;
516 goto free_mem_and_exit;
510 } 517 }
511 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !"); 518 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
512 break; 519 break;
@@ -514,7 +521,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
514 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); 521 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
515 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { 522 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
516 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); 523 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
517 return -1; 524 result = -1;
525 goto free_mem_and_exit;
518 } 526 }
519 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); 527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
520 break; 528 break;
@@ -522,7 +530,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
522 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); 530 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
523 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { 531 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
524 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); 532 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
525 return -1; 533 result = -1;
534 goto free_mem_and_exit;
526 } 535 }
527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); 536 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
528 break; 537 break;
@@ -530,7 +539,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
530 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); 539 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
531 if ((ca_set_slot_descr()) < 0) { 540 if ((ca_set_slot_descr()) < 0) {
532 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); 541 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
533 return -1; 542 result = -1;
543 goto free_mem_and_exit;
534 } 544 }
535 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); 545 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
536 break; 546 break;
@@ -538,14 +548,19 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
538 dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); 548 dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
539 if ((ca_set_pid()) < 0) { 549 if ((ca_set_pid()) < 0) {
540 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); 550 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
541 return -1; 551 result = -1;
552 goto free_mem_and_exit;
542 } 553 }
543 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); 554 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
544 default: 555 default:
545 return -EOPNOTSUPP; 556 result = -EOPNOTSUPP;
546 }; 557 };
558 free_mem_and_exit:
559 kfree (p_ca_message);
560 kfree (p_ca_slot_info);
561 kfree (p_ca_caps);
547 562
548 return 0; 563 return result;
549} 564}
550 565
551static int dst_ca_open(struct inode *inode, struct file *file) 566static int dst_ca_open(struct inode *inode, struct file *file)
@@ -582,7 +597,7 @@ static int dst_ca_write(struct file *file, const char __user *buffer, size_t len
582 597
583static struct file_operations dst_ca_fops = { 598static struct file_operations dst_ca_fops = {
584 .owner = THIS_MODULE, 599 .owner = THIS_MODULE,
585 .ioctl = (void *)dst_ca_ioctl, 600 .ioctl = dst_ca_ioctl,
586 .open = dst_ca_open, 601 .open = dst_ca_open,
587 .release = dst_ca_release, 602 .release = dst_ca_release,
588 .read = dst_ca_read, 603 .read = dst_ca_read,
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 3281a6ca3685..81557f38fe38 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -22,6 +22,7 @@
22#ifndef DST_COMMON_H 22#ifndef DST_COMMON_H
23#define DST_COMMON_H 23#define DST_COMMON_H
24 24
25#include <linux/smp_lock.h>
25#include <linux/dvb/frontend.h> 26#include <linux/dvb/frontend.h>
26#include <linux/device.h> 27#include <linux/device.h>
27#include "bt878.h" 28#include "bt878.h"
@@ -49,6 +50,7 @@
49#define DST_TYPE_HAS_FW_BUILD 64 50#define DST_TYPE_HAS_FW_BUILD 64
50#define DST_TYPE_HAS_OBS_REGS 128 51#define DST_TYPE_HAS_OBS_REGS 128
51#define DST_TYPE_HAS_INC_COUNT 256 52#define DST_TYPE_HAS_INC_COUNT 256
53#define DST_TYPE_HAS_MULTI_FE 512
52 54
53/* Card capability list */ 55/* Card capability list */
54 56
@@ -117,6 +119,9 @@ struct dst_state {
117 u8 fw_version[8]; 119 u8 fw_version[8];
118 u8 card_info[8]; 120 u8 card_info[8];
119 u8 vendor[8]; 121 u8 vendor[8];
122 u8 board_info[8];
123
124 struct semaphore dst_mutex;
120}; 125};
121 126
122struct dst_types { 127struct dst_types {
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index c5c7672cd538..2e398090cf63 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -34,6 +34,7 @@
34#include "dvb_frontend.h" 34#include "dvb_frontend.h"
35#include "dvb-bt8xx.h" 35#include "dvb-bt8xx.h"
36#include "bt878.h" 36#include "bt878.h"
37#include "dvb-pll.h"
37 38
38static int debug; 39static int debug;
39 40
@@ -279,7 +280,7 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front
279 data[0] = (div >> 8) & 0x7f; 280 data[0] = (div >> 8) & 0x7f;
280 data[1] = div & 0xff; 281 data[1] = div & 0xff;
281 data[2] = ((div >> 10) & 0x60) | cfg; 282 data[2] = ((div >> 10) & 0x60) | cfg;
282 data[3] = cpump | band_select; 283 data[3] = (cpump << 6) | band_select;
283 284
284 i2c_transfer(card->i2c_adapter, &msg, 1); 285 i2c_transfer(card->i2c_adapter, &msg, 1);
285 return (div * 166666 - 36000000); 286 return (div * 166666 - 36000000);
@@ -522,9 +523,7 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
522 /* 523 /*
523 * Reset the frontend, must be called before trying 524 * Reset the frontend, must be called before trying
524 * to initialise the MT352 or mt352_attach 525 * to initialise the MT352 or mt352_attach
525 * will fail. 526 * will fail. Same goes for the nxt6000 frontend.
526 *
527 * Presumably not required for the NXT6000 frontend.
528 * 527 *
529 */ 528 */
530 529
@@ -546,14 +545,63 @@ static struct mt352_config digitv_alps_tded4_config = {
546 .pll_set = digitv_alps_tded4_pll_set, 545 .pll_set = digitv_alps_tded4_pll_set,
547}; 546};
548 547
548static int tdvs_tua6034_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
549{
550 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
551 u8 buf[4];
552 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
553 int err;
554
555 dvb_pll_configure(&dvb_pll_tdvs_tua6034, buf, params->frequency, 0);
556 dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
557 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
558 if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) {
559 printk(KERN_WARNING "dvb-bt8xx: %s error "
560 "(addr %02x <- %02x, err = %i)\n",
561 __FUNCTION__, buf[0], buf[1], err);
562 if (err < 0)
563 return err;
564 else
565 return -EREMOTEIO;
566 }
567
568 /* Set the Auxiliary Byte. */
569 buf[2] &= ~0x20;
570 buf[2] |= 0x18;
571 buf[3] = 0x50;
572 i2c_transfer(card->i2c_adapter, &msg, 1);
573
574 return 0;
575}
576
577static struct lgdt330x_config tdvs_tua6034_config = {
578 .demod_address = 0x0e,
579 .demod_chip = LGDT3303,
580 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
581 .pll_set = tdvs_tua6034_pll_set,
582};
583
584static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
585{
586 /* Set pin 27 of the lgdt3303 chip high to reset the frontend */
587
588 /* Pulse the reset line */
589 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
590 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */
591 msleep(100);
592
593 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
594 msleep(100);
595}
596
549static void frontend_init(struct dvb_bt8xx_card *card, u32 type) 597static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
550{ 598{
551 int ret; 599 int ret;
552 struct dst_state* state = NULL; 600 struct dst_state* state = NULL;
553 601
554 switch(type) { 602 switch(type) {
555#ifdef BTTV_DVICO_DVBT_LITE 603#ifdef BTTV_BOARD_DVICO_DVBT_LITE
556 case BTTV_DVICO_DVBT_LITE: 604 case BTTV_BOARD_DVICO_DVBT_LITE:
557 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); 605 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter);
558 if (card->fe != NULL) { 606 if (card->fe != NULL) {
559 card->fe->ops->info.frequency_min = 174000000; 607 card->fe->ops->info.frequency_min = 174000000;
@@ -562,10 +610,19 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
562 break; 610 break;
563#endif 611#endif
564 612
565#ifdef BTTV_TWINHAN_VP3021 613#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
566 case BTTV_TWINHAN_VP3021: 614 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
615 lgdt330x_reset(card);
616 card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter);
617 if (card->fe != NULL)
618 dprintk ("dvb_bt8xx: lgdt330x detected\n");
619 break;
620#endif
621
622#ifdef BTTV_BOARD_TWINHAN_VP3021
623 case BTTV_BOARD_TWINHAN_VP3021:
567#else 624#else
568 case BTTV_NEBULA_DIGITV: 625 case BTTV_BOARD_NEBULA_DIGITV:
569#endif 626#endif
570 /* 627 /*
571 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); 628 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
@@ -573,6 +630,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
573 */ 630 */
574 631
575 /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ 632 /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
633 digitv_alps_tded4_reset(card);
576 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); 634 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
577 if (card->fe != NULL) { 635 if (card->fe != NULL) {
578 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); 636 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
@@ -587,11 +645,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
587 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); 645 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
588 break; 646 break;
589 647
590 case BTTV_AVDVBT_761: 648 case BTTV_BOARD_AVDVBT_761:
591 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter); 649 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
592 break; 650 break;
593 651
594 case BTTV_AVDVBT_771: 652 case BTTV_BOARD_AVDVBT_771:
595 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); 653 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
596 if (card->fe != NULL) { 654 if (card->fe != NULL) {
597 card->fe->ops->info.frequency_min = 174000000; 655 card->fe->ops->info.frequency_min = 174000000;
@@ -599,7 +657,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
599 } 657 }
600 break; 658 break;
601 659
602 case BTTV_TWINHAN_DST: 660 case BTTV_BOARD_TWINHAN_DST:
603 /* DST is not a frontend driver !!! */ 661 /* DST is not a frontend driver !!! */
604 state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); 662 state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL);
605 /* Setup the Card */ 663 /* Setup the Card */
@@ -620,11 +678,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
620 ret = dst_ca_attach(state, &card->dvb_adapter); 678 ret = dst_ca_attach(state, &card->dvb_adapter);
621 break; 679 break;
622 680
623 case BTTV_PINNACLESAT: 681 case BTTV_BOARD_PINNACLESAT:
624 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); 682 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
625 break; 683 break;
626 684
627 case BTTV_PC_HDTV: 685 case BTTV_BOARD_PC_HDTV:
628 card->fe = or51211_attach(&or51211_config, card->i2c_adapter); 686 card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
629 break; 687 break;
630 } 688 }
@@ -746,7 +804,7 @@ static int dvb_bt8xx_probe(struct device *dev)
746 card->i2c_adapter = &sub->core->i2c_adap; 804 card->i2c_adapter = &sub->core->i2c_adap;
747 805
748 switch(sub->core->type) { 806 switch(sub->core->type) {
749 case BTTV_PINNACLESAT: 807 case BTTV_BOARD_PINNACLESAT:
750 card->gpio_mode = 0x0400c060; 808 card->gpio_mode = 0x0400c060;
751 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, 809 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
752 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ 810 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
@@ -754,8 +812,8 @@ static int dvb_bt8xx_probe(struct device *dev)
754 card->irq_err_ignore = 0; 812 card->irq_err_ignore = 0;
755 break; 813 break;
756 814
757#ifdef BTTV_DVICO_DVBT_LITE 815#ifdef BTTV_BOARD_DVICO_DVBT_LITE
758 case BTTV_DVICO_DVBT_LITE: 816 case BTTV_BOARD_DVICO_DVBT_LITE:
759#endif 817#endif
760 card->gpio_mode = 0x0400C060; 818 card->gpio_mode = 0x0400C060;
761 card->op_sync_orin = 0; 819 card->op_sync_orin = 0;
@@ -765,26 +823,34 @@ static int dvb_bt8xx_probe(struct device *dev)
765 * DA_APP(parallel) */ 823 * DA_APP(parallel) */
766 break; 824 break;
767 825
768#ifdef BTTV_TWINHAN_VP3021 826#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
769 case BTTV_TWINHAN_VP3021: 827 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
828#endif
829 card->gpio_mode = 0x0400c060;
830 card->op_sync_orin = BT878_RISC_SYNC_MASK;
831 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
832 break;
833
834#ifdef BTTV_BOARD_TWINHAN_VP3021
835 case BTTV_BOARD_TWINHAN_VP3021:
770#else 836#else
771 case BTTV_NEBULA_DIGITV: 837 case BTTV_BOARD_NEBULA_DIGITV:
772#endif 838#endif
773 case BTTV_AVDVBT_761: 839 case BTTV_BOARD_AVDVBT_761:
774 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); 840 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
775 card->op_sync_orin = 0; 841 card->op_sync_orin = 0;
776 card->irq_err_ignore = 0; 842 card->irq_err_ignore = 0;
777 /* A_PWRDN DA_SBR DA_APP (high speed serial) */ 843 /* A_PWRDN DA_SBR DA_APP (high speed serial) */
778 break; 844 break;
779 845
780 case BTTV_AVDVBT_771: //case 0x07711461: 846 case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
781 card->gpio_mode = 0x0400402B; 847 card->gpio_mode = 0x0400402B;
782 card->op_sync_orin = BT878_RISC_SYNC_MASK; 848 card->op_sync_orin = BT878_RISC_SYNC_MASK;
783 card->irq_err_ignore = 0; 849 card->irq_err_ignore = 0;
784 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ 850 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
785 break; 851 break;
786 852
787 case BTTV_TWINHAN_DST: 853 case BTTV_BOARD_TWINHAN_DST:
788 card->gpio_mode = 0x2204f2c; 854 card->gpio_mode = 0x2204f2c;
789 card->op_sync_orin = BT878_RISC_SYNC_MASK; 855 card->op_sync_orin = BT878_RISC_SYNC_MASK;
790 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | 856 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
@@ -802,7 +868,7 @@ static int dvb_bt8xx_probe(struct device *dev)
802 * RISC+FIFO ENABLE */ 868 * RISC+FIFO ENABLE */
803 break; 869 break;
804 870
805 case BTTV_PC_HDTV: 871 case BTTV_BOARD_PC_HDTV:
806 card->gpio_mode = 0x0100EC7B; 872 card->gpio_mode = 0x0100EC7B;
807 card->op_sync_orin = 0; 873 card->op_sync_orin = 0;
808 card->irq_err_ignore = 0; 874 card->irq_err_ignore = 0;
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index 9ec8e5bd6c1f..cf035a80361c 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -35,6 +35,7 @@
35#include "nxt6000.h" 35#include "nxt6000.h"
36#include "cx24110.h" 36#include "cx24110.h"
37#include "or51211.h" 37#include "or51211.h"
38#include "lgdt330x.h"
38 39
39struct dvb_bt8xx_card { 40struct dvb_bt8xx_card {
40 struct semaphore lock; 41 struct semaphore lock;
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index 9719a3b30f78..7d7b0067f228 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -48,8 +48,11 @@
48 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter. 48 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
49 */ 49 */
50 50
51#ifndef DMX_MAX_SECTION_SIZE
52#define DMX_MAX_SECTION_SIZE 4096
53#endif
51#ifndef DMX_MAX_SECFEED_SIZE 54#ifndef DMX_MAX_SECFEED_SIZE
52#define DMX_MAX_SECFEED_SIZE 4096 55#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
53#endif 56#endif
54 57
55 58
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index dc476dda2b71..b4c899b15959 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -246,7 +246,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
246 246
247 for (n = 0; sec->secbufp + 2 < limit; n++) { 247 for (n = 0; sec->secbufp + 2 < limit; n++) {
248 seclen = section_length(sec->secbuf); 248 seclen = section_length(sec->secbuf);
249 if (seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE 249 if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
250 || seclen + sec->secbufp > limit) 250 || seclen + sec->secbufp > limit)
251 return 0; 251 return 0;
252 sec->seclen = seclen; 252 sec->seclen = seclen;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index a8bc84240b50..6ffa6b216363 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -42,8 +42,6 @@
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
47static int dvb_frontend_debug; 45static int dvb_frontend_debug;
48static int dvb_shutdown_timeout = 5; 46static int dvb_shutdown_timeout = 5;
49static int dvb_force_auto_inversion; 47static int dvb_force_auto_inversion;
@@ -438,25 +436,6 @@ static int dvb_frontend_thread(void *data)
438 if (s & FE_HAS_LOCK) 436 if (s & FE_HAS_LOCK)
439 continue; 437 continue;
440 else { /* if we _WERE_ tuned, but now don't have a lock */ 438 else { /* if we _WERE_ tuned, but now don't have a lock */
441#ifdef DEBUG_LOCKLOSS
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 */
460 fepriv->state = FESTATE_ZIGZAG_FAST; 439 fepriv->state = FESTATE_ZIGZAG_FAST;
461 fepriv->started_auto_step = fepriv->auto_step; 440 fepriv->started_auto_step = fepriv->auto_step;
462 check_wrapped = 0; 441 check_wrapped = 0;
@@ -577,6 +556,49 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
577 fepriv->thread_pid); 556 fepriv->thread_pid);
578} 557}
579 558
559s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
560{
561 return ((curtime.tv_usec < lasttime.tv_usec) ?
562 1000000 - lasttime.tv_usec + curtime.tv_usec :
563 curtime.tv_usec - lasttime.tv_usec);
564}
565EXPORT_SYMBOL(timeval_usec_diff);
566
567static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec)
568{
569 curtime->tv_usec += add_usec;
570 if (curtime->tv_usec >= 1000000) {
571 curtime->tv_usec -= 1000000;
572 curtime->tv_sec++;
573 }
574}
575
576/*
577 * Sleep until gettimeofday() > waketime + add_usec
578 * This needs to be as precise as possible, but as the delay is
579 * usually between 2ms and 32ms, it is done using a scheduled msleep
580 * followed by usleep (normally a busy-wait loop) for the remainder
581 */
582void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec)
583{
584 struct timeval lasttime;
585 s32 delta, newdelta;
586
587 timeval_usec_add(waketime, add_usec);
588
589 do_gettimeofday(&lasttime);
590 delta = timeval_usec_diff(lasttime, *waketime);
591 if (delta > 2500) {
592 msleep((delta - 1500) / 1000);
593 do_gettimeofday(&lasttime);
594 newdelta = timeval_usec_diff(lasttime, *waketime);
595 delta = (newdelta > delta) ? 0 : newdelta;
596 }
597 if (delta > 0)
598 udelay(delta);
599}
600EXPORT_SYMBOL(dvb_frontend_sleep_until);
601
580static int dvb_frontend_start(struct dvb_frontend *fe) 602static int dvb_frontend_start(struct dvb_frontend *fe)
581{ 603{
582 int ret; 604 int ret;
@@ -728,6 +750,60 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
728 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); 750 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg);
729 fepriv->state = FESTATE_DISEQC; 751 fepriv->state = FESTATE_DISEQC;
730 fepriv->status = 0; 752 fepriv->status = 0;
753 } else if (fe->ops->set_voltage) {
754 /*
755 * NOTE: This is a fallback condition. Some frontends
756 * (stv0299 for instance) take longer than 8msec to
757 * respond to a set_voltage command. Those switches
758 * need custom routines to switch properly. For all
759 * other frontends, the following shoule work ok.
760 * Dish network legacy switches (as used by Dish500)
761 * are controlled by sending 9-bit command words
762 * spaced 8msec apart.
763 * the actual command word is switch/port dependant
764 * so it is up to the userspace application to send
765 * the right command.
766 * The command must always start with a '0' after
767 * initialization, so parg is 8 bits and does not
768 * include the initialization or start bit
769 */
770 unsigned int cmd = ((unsigned int) parg) << 1;
771 struct timeval nexttime;
772 struct timeval tv[10];
773 int i;
774 u8 last = 1;
775 if (dvb_frontend_debug)
776 printk("%s switch command: 0x%04x\n", __FUNCTION__, cmd);
777 do_gettimeofday(&nexttime);
778 if (dvb_frontend_debug)
779 memcpy(&tv[0], &nexttime, sizeof(struct timeval));
780 /* before sending a command, initialize by sending
781 * a 32ms 18V to the switch
782 */
783 fe->ops->set_voltage(fe, SEC_VOLTAGE_18);
784 dvb_frontend_sleep_until(&nexttime, 32000);
785
786 for (i = 0; i < 9; i++) {
787 if (dvb_frontend_debug)
788 do_gettimeofday(&tv[i + 1]);
789 if ((cmd & 0x01) != last) {
790 /* set voltage to (last ? 13V : 18V) */
791 fe->ops->set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
792 last = (last) ? 0 : 1;
793 }
794 cmd = cmd >> 1;
795 if (i != 8)
796 dvb_frontend_sleep_until(&nexttime, 8000);
797 }
798 if (dvb_frontend_debug) {
799 printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
800 __FUNCTION__, fe->dvb->num);
801 for (i = 1; i < 10; i++)
802 printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
803 }
804 err = 0;
805 fepriv->state = FESTATE_DISEQC;
806 fepriv->status = 0;
731 } 807 }
732 break; 808 break;
733 809
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 9c2c1d1136bd..348c9b0b988a 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -101,4 +101,7 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb,
101 101
102extern int dvb_unregister_frontend(struct dvb_frontend* fe); 102extern int dvb_unregister_frontend(struct dvb_frontend* fe);
103 103
104extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
105extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
106
104#endif 107#endif
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index e55322ef76b3..49f541d9a042 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -43,11 +43,9 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
43 { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */ 43 { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */
44 { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */ 44 { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */
45 { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */ 45 { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */
46 { 0x02, 0x03, KEY_CHANNELUP }, /* CH UP */
47 { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */ 46 { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */
48 { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */ 47 { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */
49 { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */ 48 { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */
50 { 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
51 { 0x02, 0x14, KEY_MUTE }, /* MUTE */ 49 { 0x02, 0x14, KEY_MUTE }, /* MUTE */
52 { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */ 50 { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */
53 { 0x02, 0x19, KEY_RECORD }, /* RECORD */ 51 { 0x02, 0x19, KEY_RECORD }, /* RECORD */
@@ -57,8 +55,6 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
57 { 0x02, 0x1d, KEY_BACK }, /* << / RED */ 55 { 0x02, 0x1d, KEY_BACK }, /* << / RED */
58 { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */ 56 { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */
59 { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */ 57 { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */
60 { 0x02, 0x01, KEY_FIRST }, /* |<< / GREEN */
61 { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */
62 { 0x02, 0x04, KEY_EPG }, /* EPG */ 58 { 0x02, 0x04, KEY_EPG }, /* EPG */
63 { 0x02, 0x15, KEY_MENU }, /* MENU */ 59 { 0x02, 0x15, KEY_MENU }, /* MENU */
64 60
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 0058505634a0..aa271a2496d5 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -82,13 +82,15 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
82static struct dvb_usb_properties dibusb1_1_properties; 82static struct dvb_usb_properties dibusb1_1_properties;
83static struct dvb_usb_properties dibusb1_1_an2235_properties; 83static struct dvb_usb_properties dibusb1_1_an2235_properties;
84static struct dvb_usb_properties dibusb2_0b_properties; 84static struct dvb_usb_properties dibusb2_0b_properties;
85static struct dvb_usb_properties artec_t1_usb2_properties;
85 86
86static int dibusb_probe(struct usb_interface *intf, 87static int dibusb_probe(struct usb_interface *intf,
87 const struct usb_device_id *id) 88 const struct usb_device_id *id)
88{ 89{
89 if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 || 90 if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 ||
90 dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 || 91 dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 ||
91 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0) 92 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0 ||
93 dvb_usb_device_init(intf,&artec_t1_usb2_properties,THIS_MODULE,NULL) == 0)
92 return 0; 94 return 0;
93 95
94 return -EINVAL; 96 return -EINVAL;
@@ -128,10 +130,13 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
128 130
129/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, 131/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
130 132
133/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
134/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
135
131// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 136// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
132 137
133#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 138#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
134/* 28 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, 139/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
135#endif 140#endif
136 { } /* Terminating entry */ 141 { } /* Terminating entry */
137}; 142};
@@ -264,7 +269,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
264 }, 269 },
265#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 270#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
266 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", 271 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
267 { &dibusb_dib3000mb_table[28], NULL }, 272 { &dibusb_dib3000mb_table[30], NULL },
268 { NULL }, 273 { NULL },
269 }, 274 },
270#endif 275#endif
@@ -273,7 +278,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
273 278
274static struct dvb_usb_properties dibusb2_0b_properties = { 279static struct dvb_usb_properties dibusb2_0b_properties = {
275 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, 280 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
276 .pid_filter_count = 32, 281 .pid_filter_count = 16,
277 282
278 .usb_ctrl = CYPRESS_FX2, 283 .usb_ctrl = CYPRESS_FX2,
279 284
@@ -321,6 +326,52 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
321 } 326 }
322}; 327};
323 328
329static struct dvb_usb_properties artec_t1_usb2_properties = {
330 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
331 .pid_filter_count = 16,
332
333 .usb_ctrl = CYPRESS_FX2,
334
335 .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
336
337 .size_of_priv = sizeof(struct dibusb_state),
338
339 .streaming_ctrl = dibusb2_0_streaming_ctrl,
340 .pid_filter = dibusb_pid_filter,
341 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
342 .power_ctrl = dibusb2_0_power_ctrl,
343 .frontend_attach = dibusb_dib3000mb_frontend_attach,
344 .tuner_attach = dibusb_tuner_probe_and_attach,
345
346 .rc_interval = DEFAULT_RC_INTERVAL,
347 .rc_key_map = dibusb_rc_keys,
348 .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
349 .rc_query = dibusb_rc_query,
350
351 .i2c_algo = &dibusb_i2c_algo,
352
353 .generic_bulk_ctrl_endpoint = 0x01,
354 /* parameter for the MPEG2-data transfer */
355 .urb = {
356 .type = DVB_USB_BULK,
357 .count = 7,
358 .endpoint = 0x06,
359 .u = {
360 .bulk = {
361 .buffersize = 4096,
362 }
363 }
364 },
365
366 .num_device_descs = 1,
367 .devices = {
368 { "Artec T1 USB2.0",
369 { &dibusb_dib3000mb_table[28], NULL },
370 { &dibusb_dib3000mb_table[29], NULL },
371 },
372 }
373};
374
324static struct usb_driver dibusb_driver = { 375static struct usb_driver dibusb_driver = {
325 .owner = THIS_MODULE, 376 .owner = THIS_MODULE,
326 .name = "dvb_usb_dibusb_mb", 377 .name = "dvb_usb_dibusb_mb",
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
index 6611f62977c0..2d99d05c7eab 100644
--- a/drivers/media/dvb/dvb-usb/dibusb.h
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -11,7 +11,9 @@
11#ifndef _DVB_USB_DIBUSB_H_ 11#ifndef _DVB_USB_DIBUSB_H_
12#define _DVB_USB_DIBUSB_H_ 12#define _DVB_USB_DIBUSB_H_
13 13
14#define DVB_USB_LOG_PREFIX "dibusb" 14#ifndef DVB_USB_LOG_PREFIX
15 #define DVB_USB_LOG_PREFIX "dibusb"
16#endif
15#include "dvb-usb.h" 17#include "dvb-usb.h"
16 18
17#include "dib3000.h" 19#include "dib3000.h"
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 0818996bf150..6be99e537e12 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -43,10 +43,14 @@
43#define USB_PID_COMPRO_DVBU2000_WARM 0xd001 43#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
44#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c 44#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
45#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d 45#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
46#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
47#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
46#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 48#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
47#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9 49#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
48#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6 50#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
49#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 51#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
52#define USB_PID_DIBCOM_STK7700 0x1e14
53#define USB_PID_DIBCOM_STK7700_REENUM 0x1e15
50#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 54#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
51#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 55#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
52#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 56#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
@@ -68,6 +72,7 @@
68#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108 72#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
69#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235 73#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
70#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109 74#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
75#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a
71#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 76#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
72#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 77#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
73#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e 78#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
index f5799a4c228e..36b7048c02d2 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -196,7 +196,9 @@ static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, un
196 dvb_usb_free_stream_buffers(d); 196 dvb_usb_free_stream_buffers(d);
197 return -ENOMEM; 197 return -ENOMEM;
198 } 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]); 199 deb_mem("buffer %d: %p (dma: %llu)\n",
200 d->buf_num, d->buf_list[d->buf_num],
201 (unsigned long long)d->dma_addr[d->buf_num]);
200 memset(d->buf_list[d->buf_num],0,size); 202 memset(d->buf_list[d->buf_num],0,size);
201 } 203 }
202 deb_mem("allocation successful\n"); 204 deb_mem("allocation successful\n");
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index a50a41f6f79d..8e269e1c1f9d 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -164,6 +164,14 @@ config DVB_NXT2002
164 help 164 help
165 An ATSC 8VSB tuner module. Say Y when you want to support this frontend. 165 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
166 166
167config DVB_NXT200X
168 tristate "Nextwave NXT2002/NXT2004 based"
169 depends on DVB_CORE
170 select FW_LOADER
171 help
172 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
173 to support this frontend.
174
167config DVB_OR51211 175config DVB_OR51211
168 tristate "or51211 based (pcHDTV HD2000 card)" 176 tristate "or51211 based (pcHDTV HD2000 card)"
169 depends on DVB_CORE 177 depends on DVB_CORE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index ad8658ffd60a..a98760fe08a1 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
26obj-$(CONFIG_DVB_TDA10021) += tda10021.o 26obj-$(CONFIG_DVB_TDA10021) += tda10021.o
27obj-$(CONFIG_DVB_STV0297) += stv0297.o 27obj-$(CONFIG_DVB_STV0297) += stv0297.o
28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o 28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
29obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
29obj-$(CONFIG_DVB_OR51211) += or51211.o 30obj-$(CONFIG_DVB_OR51211) += or51211.o
30obj-$(CONFIG_DVB_OR51132) += or51132.o 31obj-$(CONFIG_DVB_OR51132) += or51132.o
31obj-$(CONFIG_DVB_BCM3510) += bcm3510.o 32obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 536c35d969b7..f857b869616c 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -226,7 +226,7 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
226EXPORT_SYMBOL(dvb_pll_tua6034); 226EXPORT_SYMBOL(dvb_pll_tua6034);
227 227
228/* Infineon TUA6034 228/* Infineon TUA6034
229 * used in LG Innotek TDVS-H062F 229 * used in LG TDVS H061F and LG TDVS H062F
230 */ 230 */
231struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { 231struct dvb_pll_desc dvb_pll_tdvs_tua6034 = {
232 .name = "LG/Infineon TUA6034", 232 .name = "LG/Infineon TUA6034",
@@ -292,6 +292,58 @@ struct dvb_pll_desc dvb_pll_tded4 = {
292}; 292};
293EXPORT_SYMBOL(dvb_pll_tded4); 293EXPORT_SYMBOL(dvb_pll_tded4);
294 294
295/* ALPS TDHU2
296 * used in AverTVHD MCE A180
297 */
298struct dvb_pll_desc dvb_pll_tdhu2 = {
299 .name = "ALPS TDHU2",
300 .min = 54000000,
301 .max = 864000000,
302 .count = 4,
303 .entries = {
304 { 162000000, 44000000, 62500, 0x85, 0x01 },
305 { 426000000, 44000000, 62500, 0x85, 0x02 },
306 { 782000000, 44000000, 62500, 0x85, 0x08 },
307 { 999999999, 44000000, 62500, 0x85, 0x88 },
308 }
309};
310EXPORT_SYMBOL(dvb_pll_tdhu2);
311
312/* Philips TUV1236D
313 * used in ATI HDTV Wonder
314 */
315struct dvb_pll_desc dvb_pll_tuv1236d = {
316 .name = "Philips TUV1236D",
317 .min = 54000000,
318 .max = 864000000,
319 .count = 3,
320 .entries = {
321 { 157250000, 44000000, 62500, 0xc6, 0x41 },
322 { 454000000, 44000000, 62500, 0xc6, 0x42 },
323 { 999999999, 44000000, 62500, 0xc6, 0x44 },
324 },
325};
326EXPORT_SYMBOL(dvb_pll_tuv1236d);
327
328/* Samsung TBMV30111IN
329 * used in Air2PC ATSC - 2nd generation (nxt2002)
330 */
331struct dvb_pll_desc dvb_pll_tbmv30111in = {
332 .name = "Samsung TBMV30111IN",
333 .min = 54000000,
334 .max = 860000000,
335 .count = 4,
336 .entries = {
337 { 172000000, 44000000, 166666, 0xb4, 0x01 },
338 { 214000000, 44000000, 166666, 0xb4, 0x02 },
339 { 467000000, 44000000, 166666, 0xbc, 0x02 },
340 { 721000000, 44000000, 166666, 0xbc, 0x08 },
341 { 841000000, 44000000, 166666, 0xf4, 0x08 },
342 { 999999999, 44000000, 166666, 0xfc, 0x02 },
343 }
344};
345EXPORT_SYMBOL(dvb_pll_tbmv30111in);
346
295/* ----------------------------------------------------------- */ 347/* ----------------------------------------------------------- */
296/* code */ 348/* code */
297 349
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 205b2d1a8852..497d31dcf41e 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -36,6 +36,10 @@ extern struct dvb_pll_desc dvb_pll_tda665x;
36extern struct dvb_pll_desc dvb_pll_fmd1216me; 36extern struct dvb_pll_desc dvb_pll_fmd1216me;
37extern struct dvb_pll_desc dvb_pll_tded4; 37extern struct dvb_pll_desc dvb_pll_tded4;
38 38
39extern struct dvb_pll_desc dvb_pll_tuv1236d;
40extern struct dvb_pll_desc dvb_pll_tdhu2;
41extern struct dvb_pll_desc dvb_pll_tbmv30111in;
42
39int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, 43int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
40 u32 freq, int bandwidth); 44 u32 freq, int bandwidth);
41 45
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index 7852b83b82d4..6a33f5a19a8d 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -26,6 +26,8 @@
26 * DViCO FusionHDTV 3 Gold-Q 26 * DViCO FusionHDTV 3 Gold-Q
27 * DViCO FusionHDTV 3 Gold-T 27 * DViCO FusionHDTV 3 Gold-T
28 * DViCO FusionHDTV 5 Gold 28 * DViCO FusionHDTV 5 Gold
29 * DViCO FusionHDTV 5 Lite
30 * Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
29 * 31 *
30 * TODO: 32 * TODO:
31 * signal strength always returns 0. 33 * signal strength always returns 0.
@@ -222,6 +224,11 @@ static int lgdt330x_init(struct dvb_frontend* fe)
222 0x4c, 0x14 224 0x4c, 0x14
223 }; 225 };
224 226
227 static u8 flip_lgdt3303_init_data[] = {
228 0x4c, 0x14,
229 0x87, 0xf3
230 };
231
225 struct lgdt330x_state* state = fe->demodulator_priv; 232 struct lgdt330x_state* state = fe->demodulator_priv;
226 char *chip_name; 233 char *chip_name;
227 int err; 234 int err;
@@ -234,8 +241,13 @@ static int lgdt330x_init(struct dvb_frontend* fe)
234 break; 241 break;
235 case LGDT3303: 242 case LGDT3303:
236 chip_name = "LGDT3303"; 243 chip_name = "LGDT3303";
237 err = i2c_write_demod_bytes(state, lgdt3303_init_data, 244 if (state->config->clock_polarity_flip) {
238 sizeof(lgdt3303_init_data)); 245 err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data,
246 sizeof(flip_lgdt3303_init_data));
247 } else {
248 err = i2c_write_demod_bytes(state, lgdt3303_init_data,
249 sizeof(lgdt3303_init_data));
250 }
239 break; 251 break;
240 default: 252 default:
241 chip_name = "undefined"; 253 chip_name = "undefined";
@@ -743,9 +755,8 @@ static struct dvb_frontend_ops lgdt3302_ops = {
743 .frequency_min= 54000000, 755 .frequency_min= 54000000,
744 .frequency_max= 858000000, 756 .frequency_max= 858000000,
745 .frequency_stepsize= 62500, 757 .frequency_stepsize= 62500,
746 /* Symbol rate is for all VSB modes need to check QAM */ 758 .symbol_rate_min = 5056941, /* QAM 64 */
747 .symbol_rate_min = 10762000, 759 .symbol_rate_max = 10762000, /* VSB 8 */
748 .symbol_rate_max = 10762000,
749 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB 760 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
750 }, 761 },
751 .init = lgdt330x_init, 762 .init = lgdt330x_init,
@@ -767,9 +778,8 @@ static struct dvb_frontend_ops lgdt3303_ops = {
767 .frequency_min= 54000000, 778 .frequency_min= 54000000,
768 .frequency_max= 858000000, 779 .frequency_max= 858000000,
769 .frequency_stepsize= 62500, 780 .frequency_stepsize= 62500,
770 /* Symbol rate is for all VSB modes need to check QAM */ 781 .symbol_rate_min = 5056941, /* QAM 64 */
771 .symbol_rate_min = 10762000, 782 .symbol_rate_max = 10762000, /* VSB 8 */
772 .symbol_rate_max = 10762000,
773 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB 783 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
774 }, 784 },
775 .init = lgdt330x_init, 785 .init = lgdt330x_init,
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
index e209ba1e47c5..2a6529cccf1a 100644
--- a/drivers/media/dvb/frontends/lgdt330x.h
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -47,6 +47,10 @@ struct lgdt330x_config
47 47
48 /* Need to set device param for start_dma */ 48 /* Need to set device param for start_dma */
49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
50
51 /* Flip the polarity of the mpeg data transfer clock using alternate init data
52 * This option applies ONLY to LGDT3303 - 0:disabled (default) 1:enabled */
53 int clock_polarity_flip;
50}; 54};
51 55
52extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, 56extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
new file mode 100644
index 000000000000..bad0933eb714
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -0,0 +1,1205 @@
1/*
2 * Support for NXT2002 and NXT2004 - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
5 * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
6 * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 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/*
25 * NOTES ABOUT THIS DRIVER
26 *
27 * This Linux driver supports:
28 * B2C2/BBTI Technisat Air2PC - ATSC (NXT2002)
29 * AverTVHD MCE A180 (NXT2004)
30 * ATI HDTV Wonder (NXT2004)
31 *
32 * This driver needs external firmware. Please use the command
33 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or
34 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
35 * download/extract the appropriate firmware, and then copy it to
36 * /usr/lib/hotplug/firmware/ or /lib/firmware/
37 * (depending on configuration of firmware hotplug).
38 */
39#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
40#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
41#define CRC_CCIT_MASK 0x1021
42
43#include <linux/kernel.h>
44#include <linux/init.h>
45#include <linux/module.h>
46#include <linux/moduleparam.h>
47
48#include "dvb_frontend.h"
49#include "dvb-pll.h"
50#include "nxt200x.h"
51
52struct nxt200x_state {
53
54 struct i2c_adapter* i2c;
55 struct dvb_frontend_ops ops;
56 const struct nxt200x_config* config;
57 struct dvb_frontend frontend;
58
59 /* demodulator private data */
60 nxt_chip_type demod_chip;
61 u8 initialised:1;
62};
63
64static int debug;
65#define dprintk(args...) \
66 do { \
67 if (debug) printk(KERN_DEBUG "nxt200x: " args); \
68 } while (0)
69
70static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
71{
72 int err;
73 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
74
75 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
76 printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
77 __FUNCTION__, addr, err);
78 return -EREMOTEIO;
79 }
80 return 0;
81}
82
83static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len)
84{
85 int err;
86 struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
87
88 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
89 printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
90 __FUNCTION__, addr, err);
91 return -EREMOTEIO;
92 }
93 return 0;
94}
95
96static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, u8 *buf, u8 len)
97{
98 u8 buf2 [len+1];
99 int err;
100 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
101
102 buf2[0] = reg;
103 memcpy(&buf2[1], buf, len);
104
105 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
106 printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
107 __FUNCTION__, state->config->demod_address, err);
108 return -EREMOTEIO;
109 }
110 return 0;
111}
112
113static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 len)
114{
115 u8 reg2 [] = { reg };
116
117 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
118 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
119
120 int err;
121
122 if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
123 printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
124 __FUNCTION__, state->config->demod_address, err);
125 return -EREMOTEIO;
126 }
127 return 0;
128}
129
130static u16 nxt200x_crc(u16 crc, u8 c)
131{
132 u8 i;
133 u16 input = (u16) c & 0xFF;
134
135 input<<=8;
136 for(i=0; i<8; i++) {
137 if((crc^input) & 0x8000)
138 crc=(crc<<1)^CRC_CCIT_MASK;
139 else
140 crc<<=1;
141 input<<=1;
142 }
143 return crc;
144}
145
146static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
147{
148 u8 attr, len2, buf;
149 dprintk("%s\n", __FUNCTION__);
150
151 /* set mutli register register */
152 nxt200x_writebytes(state, 0x35, &reg, 1);
153
154 /* send the actual data */
155 nxt200x_writebytes(state, 0x36, data, len);
156
157 switch (state->demod_chip) {
158 case NXT2002:
159 len2 = len;
160 buf = 0x02;
161 break;
162 case NXT2004:
163 /* probably not right, but gives correct values */
164 attr = 0x02;
165 if (reg & 0x80) {
166 attr = attr << 1;
167 if (reg & 0x04)
168 attr = attr >> 1;
169 }
170 /* set write bit */
171 len2 = ((attr << 4) | 0x10) | len;
172 buf = 0x80;
173 break;
174 default:
175 return -EINVAL;
176 break;
177 }
178
179 /* set multi register length */
180 nxt200x_writebytes(state, 0x34, &len2, 1);
181
182 /* toggle the multireg write bit */
183 nxt200x_writebytes(state, 0x21, &buf, 1);
184
185 nxt200x_readbytes(state, 0x21, &buf, 1);
186
187 switch (state->demod_chip) {
188 case NXT2002:
189 if ((buf & 0x02) == 0)
190 return 0;
191 break;
192 case NXT2004:
193 if (buf == 0)
194 return 0;
195 break;
196 default:
197 return -EINVAL;
198 break;
199 }
200
201 printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg);
202
203 return 0;
204}
205
206static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
207{
208 int i;
209 u8 buf, len2, attr;
210 dprintk("%s\n", __FUNCTION__);
211
212 /* set mutli register register */
213 nxt200x_writebytes(state, 0x35, &reg, 1);
214
215 switch (state->demod_chip) {
216 case NXT2002:
217 /* set multi register length */
218 len2 = len & 0x80;
219 nxt200x_writebytes(state, 0x34, &len2, 1);
220
221 /* read the actual data */
222 nxt200x_readbytes(state, reg, data, len);
223 return 0;
224 break;
225 case NXT2004:
226 /* probably not right, but gives correct values */
227 attr = 0x02;
228 if (reg & 0x80) {
229 attr = attr << 1;
230 if (reg & 0x04)
231 attr = attr >> 1;
232 }
233
234 /* set multi register length */
235 len2 = (attr << 4) | len;
236 nxt200x_writebytes(state, 0x34, &len2, 1);
237
238 /* toggle the multireg bit*/
239 buf = 0x80;
240 nxt200x_writebytes(state, 0x21, &buf, 1);
241
242 /* read the actual data */
243 for(i = 0; i < len; i++) {
244 nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
245 }
246 return 0;
247 break;
248 default:
249 return -EINVAL;
250 break;
251 }
252}
253
254static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
255{
256 u8 buf, stopval, counter = 0;
257 dprintk("%s\n", __FUNCTION__);
258
259 /* set correct stop value */
260 switch (state->demod_chip) {
261 case NXT2002:
262 stopval = 0x40;
263 break;
264 case NXT2004:
265 stopval = 0x10;
266 break;
267 default:
268 stopval = 0;
269 break;
270 }
271
272 buf = 0x80;
273 nxt200x_writebytes(state, 0x22, &buf, 1);
274
275 while (counter < 20) {
276 nxt200x_readbytes(state, 0x31, &buf, 1);
277 if (buf & stopval)
278 return;
279 msleep(10);
280 counter++;
281 }
282
283 printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n");
284 return;
285}
286
287static void nxt200x_microcontroller_start (struct nxt200x_state* state)
288{
289 u8 buf;
290 dprintk("%s\n", __FUNCTION__);
291
292 buf = 0x00;
293 nxt200x_writebytes(state, 0x22, &buf, 1);
294}
295
296static void nxt2004_microcontroller_init (struct nxt200x_state* state)
297{
298 u8 buf[9];
299 u8 counter = 0;
300 dprintk("%s\n", __FUNCTION__);
301
302 buf[0] = 0x00;
303 nxt200x_writebytes(state, 0x2b, buf, 1);
304 buf[0] = 0x70;
305 nxt200x_writebytes(state, 0x34, buf, 1);
306 buf[0] = 0x04;
307 nxt200x_writebytes(state, 0x35, buf, 1);
308 buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89;
309 buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0;
310 nxt200x_writebytes(state, 0x36, buf, 9);
311 buf[0] = 0x80;
312 nxt200x_writebytes(state, 0x21, buf, 1);
313
314 while (counter < 20) {
315 nxt200x_readbytes(state, 0x21, buf, 1);
316 if (buf[0] == 0)
317 return;
318 msleep(10);
319 counter++;
320 }
321
322 printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n");
323
324 return;
325}
326
327static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
328{
329 u8 buf, count = 0;
330
331 dprintk("%s\n", __FUNCTION__);
332
333 dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]);
334
335 /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
336 * direct write is required for Philips TUV1236D and ALPS TDHU2 */
337 switch (state->demod_chip) {
338 case NXT2004:
339 if (i2c_writebytes(state, state->config->pll_address, data, 4))
340 printk(KERN_WARNING "nxt200x: error writing to tuner\n");
341 /* wait until we have a lock */
342 while (count < 20) {
343 i2c_readbytes(state, state->config->pll_address, &buf, 1);
344 if (buf & 0x40)
345 return 0;
346 msleep(100);
347 count++;
348 }
349 printk("nxt2004: timeout waiting for tuner lock\n");
350 break;
351 case NXT2002:
352 /* set the i2c transfer speed to the tuner */
353 buf = 0x03;
354 nxt200x_writebytes(state, 0x20, &buf, 1);
355
356 /* setup to transfer 4 bytes via i2c */
357 buf = 0x04;
358 nxt200x_writebytes(state, 0x34, &buf, 1);
359
360 /* write actual tuner bytes */
361 nxt200x_writebytes(state, 0x36, data, 4);
362
363 /* set tuner i2c address */
364 buf = state->config->pll_address;
365 nxt200x_writebytes(state, 0x35, &buf, 1);
366
367 /* write UC Opmode to begin transfer */
368 buf = 0x80;
369 nxt200x_writebytes(state, 0x21, &buf, 1);
370
371 while (count < 20) {
372 nxt200x_readbytes(state, 0x21, &buf, 1);
373 if ((buf & 0x80)== 0x00)
374 return 0;
375 msleep(100);
376 count++;
377 }
378 printk("nxt2002: timeout error writing tuner\n");
379 break;
380 default:
381 return -EINVAL;
382 break;
383 }
384 return 0;
385}
386
387static void nxt200x_agc_reset(struct nxt200x_state* state)
388{
389 u8 buf;
390 dprintk("%s\n", __FUNCTION__);
391
392 switch (state->demod_chip) {
393 case NXT2002:
394 buf = 0x08;
395 nxt200x_writebytes(state, 0x08, &buf, 1);
396 buf = 0x00;
397 nxt200x_writebytes(state, 0x08, &buf, 1);
398 break;
399 case NXT2004:
400 nxt200x_readreg_multibyte(state, 0x08, &buf, 1);
401 buf = 0x08;
402 nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
403 buf = 0x00;
404 nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
405 break;
406 default:
407 break;
408 }
409 return;
410}
411
412static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
413{
414
415 struct nxt200x_state* state = fe->demodulator_priv;
416 u8 buf[3], written = 0, chunkpos = 0;
417 u16 rambase, position, crc = 0;
418
419 dprintk("%s\n", __FUNCTION__);
420 dprintk("Firmware is %zu bytes\n", fw->size);
421
422 /* Get the RAM base for this nxt2002 */
423 nxt200x_readbytes(state, 0x10, buf, 1);
424
425 if (buf[0] & 0x10)
426 rambase = 0x1000;
427 else
428 rambase = 0x0000;
429
430 dprintk("rambase on this nxt2002 is %04X\n", rambase);
431
432 /* Hold the micro in reset while loading firmware */
433 buf[0] = 0x80;
434 nxt200x_writebytes(state, 0x2B, buf, 1);
435
436 for (position = 0; position < fw->size; position++) {
437 if (written == 0) {
438 crc = 0;
439 chunkpos = 0x28;
440 buf[0] = ((rambase + position) >> 8);
441 buf[1] = (rambase + position) & 0xFF;
442 buf[2] = 0x81;
443 /* write starting address */
444 nxt200x_writebytes(state, 0x29, buf, 3);
445 }
446 written++;
447 chunkpos++;
448
449 if ((written % 4) == 0)
450 nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4);
451
452 crc = nxt200x_crc(crc, fw->data[position]);
453
454 if ((written == 255) || (position+1 == fw->size)) {
455 /* write remaining bytes of firmware */
456 nxt200x_writebytes(state, chunkpos+4-(written %4),
457 &fw->data[position-(written %4) + 1],
458 written %4);
459 buf[0] = crc << 8;
460 buf[1] = crc & 0xFF;
461
462 /* write crc */
463 nxt200x_writebytes(state, 0x2C, buf, 2);
464
465 /* do a read to stop things */
466 nxt200x_readbytes(state, 0x2A, buf, 1);
467
468 /* set transfer mode to complete */
469 buf[0] = 0x80;
470 nxt200x_writebytes(state, 0x2B, buf, 1);
471
472 written = 0;
473 }
474 }
475
476 return 0;
477};
478
479static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
480{
481
482 struct nxt200x_state* state = fe->demodulator_priv;
483 u8 buf[3];
484 u16 rambase, position, crc=0;
485
486 dprintk("%s\n", __FUNCTION__);
487 dprintk("Firmware is %zu bytes\n", fw->size);
488
489 /* set rambase */
490 rambase = 0x1000;
491
492 /* hold the micro in reset while loading firmware */
493 buf[0] = 0x80;
494 nxt200x_writebytes(state, 0x2B, buf,1);
495
496 /* calculate firmware CRC */
497 for (position = 0; position < fw->size; position++) {
498 crc = nxt200x_crc(crc, fw->data[position]);
499 }
500
501 buf[0] = rambase >> 8;
502 buf[1] = rambase & 0xFF;
503 buf[2] = 0x81;
504 /* write starting address */
505 nxt200x_writebytes(state,0x29,buf,3);
506
507 for (position = 0; position < fw->size;) {
508 nxt200x_writebytes(state, 0x2C, &fw->data[position],
509 fw->size-position > 255 ? 255 : fw->size-position);
510 position += (fw->size-position > 255 ? 255 : fw->size-position);
511 }
512 buf[0] = crc >> 8;
513 buf[1] = crc & 0xFF;
514
515 dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]);
516
517 /* write crc */
518 nxt200x_writebytes(state, 0x2C, buf,2);
519
520 /* do a read to stop things */
521 nxt200x_readbytes(state, 0x2C, buf, 1);
522
523 /* set transfer mode to complete */
524 buf[0] = 0x80;
525 nxt200x_writebytes(state, 0x2B, buf,1);
526
527 return 0;
528};
529
530static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
531 struct dvb_frontend_parameters *p)
532{
533 struct nxt200x_state* state = fe->demodulator_priv;
534 u8 buf[4];
535
536 /* stop the micro first */
537 nxt200x_microcontroller_stop(state);
538
539 if (state->demod_chip == NXT2004) {
540 /* make sure demod is set to digital */
541 buf[0] = 0x04;
542 nxt200x_writebytes(state, 0x14, buf, 1);
543 buf[0] = 0x00;
544 nxt200x_writebytes(state, 0x17, buf, 1);
545 }
546
547 /* get tuning information */
548 dvb_pll_configure(state->config->pll_desc, buf, p->frequency, 0);
549
550 /* set additional params */
551 switch (p->u.vsb.modulation) {
552 case QAM_64:
553 case QAM_256:
554 /* Set punctured clock for QAM */
555 /* This is just a guess since I am unable to test it */
556 if (state->config->set_ts_params)
557 state->config->set_ts_params(fe, 1);
558
559 /* set input */
560 if (state->config->set_pll_input)
561 state->config->set_pll_input(buf, 1);
562 break;
563 case VSB_8:
564 /* Set non-punctured clock for VSB */
565 if (state->config->set_ts_params)
566 state->config->set_ts_params(fe, 0);
567
568 /* set input */
569 if (state->config->set_pll_input)
570 state->config->set_pll_input(buf, 0);
571 break;
572 default:
573 return -EINVAL;
574 break;
575 }
576
577 /* write frequency information */
578 nxt200x_writetuner(state, buf);
579
580 /* reset the agc now that tuning has been completed */
581 nxt200x_agc_reset(state);
582
583 /* set target power level */
584 switch (p->u.vsb.modulation) {
585 case QAM_64:
586 case QAM_256:
587 buf[0] = 0x74;
588 break;
589 case VSB_8:
590 buf[0] = 0x70;
591 break;
592 default:
593 return -EINVAL;
594 break;
595 }
596 nxt200x_writebytes(state, 0x42, buf, 1);
597
598 /* configure sdm */
599 switch (state->demod_chip) {
600 case NXT2002:
601 buf[0] = 0x87;
602 break;
603 case NXT2004:
604 buf[0] = 0x07;
605 break;
606 default:
607 return -EINVAL;
608 break;
609 }
610 nxt200x_writebytes(state, 0x57, buf, 1);
611
612 /* write sdm1 input */
613 buf[0] = 0x10;
614 buf[1] = 0x00;
615 nxt200x_writebytes(state, 0x58, buf, 2);
616
617 /* write sdmx input */
618 switch (p->u.vsb.modulation) {
619 case QAM_64:
620 buf[0] = 0x68;
621 break;
622 case QAM_256:
623 buf[0] = 0x64;
624 break;
625 case VSB_8:
626 buf[0] = 0x60;
627 break;
628 default:
629 return -EINVAL;
630 break;
631 }
632 buf[1] = 0x00;
633 nxt200x_writebytes(state, 0x5C, buf, 2);
634
635 /* write adc power lpf fc */
636 buf[0] = 0x05;
637 nxt200x_writebytes(state, 0x43, buf, 1);
638
639 if (state->demod_chip == NXT2004) {
640 /* write ??? */
641 buf[0] = 0x00;
642 buf[1] = 0x00;
643 nxt200x_writebytes(state, 0x46, buf, 2);
644 }
645
646 /* write accumulator2 input */
647 buf[0] = 0x80;
648 buf[1] = 0x00;
649 nxt200x_writebytes(state, 0x4B, buf, 2);
650
651 /* write kg1 */
652 buf[0] = 0x00;
653 nxt200x_writebytes(state, 0x4D, buf, 1);
654
655 /* write sdm12 lpf fc */
656 buf[0] = 0x44;
657 nxt200x_writebytes(state, 0x55, buf, 1);
658
659 /* write agc control reg */
660 buf[0] = 0x04;
661 nxt200x_writebytes(state, 0x41, buf, 1);
662
663 if (state->demod_chip == NXT2004) {
664 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
665 buf[0] = 0x24;
666 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
667
668 /* soft reset? */
669 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
670 buf[0] = 0x10;
671 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
672 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
673 buf[0] = 0x00;
674 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
675
676 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
677 buf[0] = 0x04;
678 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
679 buf[0] = 0x00;
680 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
681 buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
682 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
683 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
684 buf[0] = 0x11;
685 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
686 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
687 buf[0] = 0x44;
688 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
689 }
690
691 /* write agc ucgp0 */
692 switch (p->u.vsb.modulation) {
693 case QAM_64:
694 buf[0] = 0x02;
695 break;
696 case QAM_256:
697 buf[0] = 0x03;
698 break;
699 case VSB_8:
700 buf[0] = 0x00;
701 break;
702 default:
703 return -EINVAL;
704 break;
705 }
706 nxt200x_writebytes(state, 0x30, buf, 1);
707
708 /* write agc control reg */
709 buf[0] = 0x00;
710 nxt200x_writebytes(state, 0x41, buf, 1);
711
712 /* write accumulator2 input */
713 buf[0] = 0x80;
714 buf[1] = 0x00;
715 nxt200x_writebytes(state, 0x49, buf,2);
716 nxt200x_writebytes(state, 0x4B, buf,2);
717
718 /* write agc control reg */
719 buf[0] = 0x04;
720 nxt200x_writebytes(state, 0x41, buf, 1);
721
722 nxt200x_microcontroller_start(state);
723
724 if (state->demod_chip == NXT2004) {
725 nxt2004_microcontroller_init(state);
726
727 /* ???? */
728 buf[0] = 0xF0;
729 buf[1] = 0x00;
730 nxt200x_writebytes(state, 0x5C, buf, 2);
731 }
732
733 /* adjacent channel detection should be done here, but I don't
734 have any stations with this need so I cannot test it */
735
736 return 0;
737}
738
739static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status)
740{
741 struct nxt200x_state* state = fe->demodulator_priv;
742 u8 lock;
743 nxt200x_readbytes(state, 0x31, &lock, 1);
744
745 *status = 0;
746 if (lock & 0x20) {
747 *status |= FE_HAS_SIGNAL;
748 *status |= FE_HAS_CARRIER;
749 *status |= FE_HAS_VITERBI;
750 *status |= FE_HAS_SYNC;
751 *status |= FE_HAS_LOCK;
752 }
753 return 0;
754}
755
756static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber)
757{
758 struct nxt200x_state* state = fe->demodulator_priv;
759 u8 b[3];
760
761 nxt200x_readreg_multibyte(state, 0xE6, b, 3);
762
763 *ber = ((b[0] << 8) + b[1]) * 8;
764
765 return 0;
766}
767
768static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
769{
770 struct nxt200x_state* state = fe->demodulator_priv;
771 u8 b[2];
772 u16 temp = 0;
773
774 /* setup to read cluster variance */
775 b[0] = 0x00;
776 nxt200x_writebytes(state, 0xA1, b, 1);
777
778 /* get multreg val */
779 nxt200x_readreg_multibyte(state, 0xA6, b, 2);
780
781 temp = (b[0] << 8) | b[1];
782 *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
783
784 return 0;
785}
786
787static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr)
788{
789
790 struct nxt200x_state* state = fe->demodulator_priv;
791 u8 b[2];
792 u16 temp = 0, temp2;
793 u32 snrdb = 0;
794
795 /* setup to read cluster variance */
796 b[0] = 0x00;
797 nxt200x_writebytes(state, 0xA1, b, 1);
798
799 /* get multreg val from 0xA6 */
800 nxt200x_readreg_multibyte(state, 0xA6, b, 2);
801
802 temp = (b[0] << 8) | b[1];
803 temp2 = 0x7FFF - temp;
804
805 /* snr will be in db */
806 if (temp2 > 0x7F00)
807 snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
808 else if (temp2 > 0x7EC0)
809 snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
810 else if (temp2 > 0x7C00)
811 snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
812 else
813 snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
814
815 /* the value reported back from the frontend will be FFFF=32db 0000=0db */
816 *snr = snrdb * (0xFFFF/32000);
817
818 return 0;
819}
820
821static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
822{
823 struct nxt200x_state* state = fe->demodulator_priv;
824 u8 b[3];
825
826 nxt200x_readreg_multibyte(state, 0xE6, b, 3);
827 *ucblocks = b[2];
828
829 return 0;
830}
831
832static int nxt200x_sleep(struct dvb_frontend* fe)
833{
834 return 0;
835}
836
837static int nxt2002_init(struct dvb_frontend* fe)
838{
839 struct nxt200x_state* state = fe->demodulator_priv;
840 const struct firmware *fw;
841 int ret;
842 u8 buf[2];
843
844 /* request the firmware, this will block until someone uploads it */
845 printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
846 ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev);
847 printk("nxt2002: Waiting for firmware upload(2)...\n");
848 if (ret) {
849 printk("nxt2002: No firmware uploaded (timeout or file not found?)\n");
850 return ret;
851 }
852
853 ret = nxt2002_load_firmware(fe, fw);
854 if (ret) {
855 printk("nxt2002: Writing firmware to device failed\n");
856 release_firmware(fw);
857 return ret;
858 }
859 printk("nxt2002: Firmware upload complete\n");
860
861 /* Put the micro into reset */
862 nxt200x_microcontroller_stop(state);
863
864 /* ensure transfer is complete */
865 buf[0]=0x00;
866 nxt200x_writebytes(state, 0x2B, buf, 1);
867
868 /* Put the micro into reset for real this time */
869 nxt200x_microcontroller_stop(state);
870
871 /* soft reset everything (agc,frontend,eq,fec)*/
872 buf[0] = 0x0F;
873 nxt200x_writebytes(state, 0x08, buf, 1);
874 buf[0] = 0x00;
875 nxt200x_writebytes(state, 0x08, buf, 1);
876
877 /* write agc sdm configure */
878 buf[0] = 0xF1;
879 nxt200x_writebytes(state, 0x57, buf, 1);
880
881 /* write mod output format */
882 buf[0] = 0x20;
883 nxt200x_writebytes(state, 0x09, buf, 1);
884
885 /* write fec mpeg mode */
886 buf[0] = 0x7E;
887 buf[1] = 0x00;
888 nxt200x_writebytes(state, 0xE9, buf, 2);
889
890 /* write mux selection */
891 buf[0] = 0x00;
892 nxt200x_writebytes(state, 0xCC, buf, 1);
893
894 return 0;
895}
896
897static int nxt2004_init(struct dvb_frontend* fe)
898{
899 struct nxt200x_state* state = fe->demodulator_priv;
900 const struct firmware *fw;
901 int ret;
902 u8 buf[3];
903
904 /* ??? */
905 buf[0]=0x00;
906 nxt200x_writebytes(state, 0x1E, buf, 1);
907
908 /* request the firmware, this will block until someone uploads it */
909 printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE);
910 ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev);
911 printk("nxt2004: Waiting for firmware upload(2)...\n");
912 if (ret) {
913 printk("nxt2004: No firmware uploaded (timeout or file not found?)\n");
914 return ret;
915 }
916
917 ret = nxt2004_load_firmware(fe, fw);
918 if (ret) {
919 printk("nxt2004: Writing firmware to device failed\n");
920 release_firmware(fw);
921 return ret;
922 }
923 printk("nxt2004: Firmware upload complete\n");
924
925 /* ensure transfer is complete */
926 buf[0] = 0x01;
927 nxt200x_writebytes(state, 0x19, buf, 1);
928
929 nxt2004_microcontroller_init(state);
930 nxt200x_microcontroller_stop(state);
931 nxt200x_microcontroller_stop(state);
932 nxt2004_microcontroller_init(state);
933 nxt200x_microcontroller_stop(state);
934
935 /* soft reset everything (agc,frontend,eq,fec)*/
936 buf[0] = 0xFF;
937 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
938 buf[0] = 0x00;
939 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
940
941 /* write agc sdm configure */
942 buf[0] = 0xD7;
943 nxt200x_writebytes(state, 0x57, buf, 1);
944
945 /* ???*/
946 buf[0] = 0x07;
947 buf[1] = 0xfe;
948 nxt200x_writebytes(state, 0x35, buf, 2);
949 buf[0] = 0x12;
950 nxt200x_writebytes(state, 0x34, buf, 1);
951 buf[0] = 0x80;
952 nxt200x_writebytes(state, 0x21, buf, 1);
953
954 /* ???*/
955 buf[0] = 0x21;
956 nxt200x_writebytes(state, 0x0A, buf, 1);
957
958 /* ???*/
959 buf[0] = 0x01;
960 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
961
962 /* write fec mpeg mode */
963 buf[0] = 0x7E;
964 buf[1] = 0x00;
965 nxt200x_writebytes(state, 0xE9, buf, 2);
966
967 /* write mux selection */
968 buf[0] = 0x00;
969 nxt200x_writebytes(state, 0xCC, buf, 1);
970
971 /* ???*/
972 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
973 buf[0] = 0x00;
974 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
975
976 /* soft reset? */
977 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
978 buf[0] = 0x10;
979 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
980 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
981 buf[0] = 0x00;
982 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
983
984 /* ???*/
985 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
986 buf[0] = 0x01;
987 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
988 buf[0] = 0x70;
989 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
990 buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;
991 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
992
993 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
994 buf[0] = 0x11;
995 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
996 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
997 buf[0] = 0x40;
998 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
999
1000 nxt200x_readbytes(state, 0x10, buf, 1);
1001 buf[0] = 0x10;
1002 nxt200x_writebytes(state, 0x10, buf, 1);
1003 nxt200x_readbytes(state, 0x0A, buf, 1);
1004 buf[0] = 0x21;
1005 nxt200x_writebytes(state, 0x0A, buf, 1);
1006
1007 nxt2004_microcontroller_init(state);
1008
1009 buf[0] = 0x21;
1010 nxt200x_writebytes(state, 0x0A, buf, 1);
1011 buf[0] = 0x7E;
1012 nxt200x_writebytes(state, 0xE9, buf, 1);
1013 buf[0] = 0x00;
1014 nxt200x_writebytes(state, 0xEA, buf, 1);
1015
1016 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1017 buf[0] = 0x00;
1018 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1019 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1020 buf[0] = 0x00;
1021 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1022
1023 /* soft reset? */
1024 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1025 buf[0] = 0x10;
1026 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1027 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1028 buf[0] = 0x00;
1029 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1030
1031 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1032 buf[0] = 0x04;
1033 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1034 buf[0] = 0x00;
1035 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
1036 buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
1037 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
1038
1039 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
1040 buf[0] = 0x11;
1041 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
1042
1043 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1044 buf[0] = 0x44;
1045 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1046
1047 /* initialize tuner */
1048 nxt200x_readbytes(state, 0x10, buf, 1);
1049 buf[0] = 0x12;
1050 nxt200x_writebytes(state, 0x10, buf, 1);
1051 buf[0] = 0x04;
1052 nxt200x_writebytes(state, 0x13, buf, 1);
1053 buf[0] = 0x00;
1054 nxt200x_writebytes(state, 0x16, buf, 1);
1055 buf[0] = 0x04;
1056 nxt200x_writebytes(state, 0x14, buf, 1);
1057 buf[0] = 0x00;
1058 nxt200x_writebytes(state, 0x14, buf, 1);
1059 nxt200x_writebytes(state, 0x17, buf, 1);
1060 nxt200x_writebytes(state, 0x14, buf, 1);
1061 nxt200x_writebytes(state, 0x17, buf, 1);
1062
1063 return 0;
1064}
1065
1066static int nxt200x_init(struct dvb_frontend* fe)
1067{
1068 struct nxt200x_state* state = fe->demodulator_priv;
1069 int ret = 0;
1070
1071 if (!state->initialised) {
1072 switch (state->demod_chip) {
1073 case NXT2002:
1074 ret = nxt2002_init(fe);
1075 break;
1076 case NXT2004:
1077 ret = nxt2004_init(fe);
1078 break;
1079 default:
1080 return -EINVAL;
1081 break;
1082 }
1083 state->initialised = 1;
1084 }
1085 return ret;
1086}
1087
1088static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1089{
1090 fesettings->min_delay_ms = 500;
1091 fesettings->step_size = 0;
1092 fesettings->max_drift = 0;
1093 return 0;
1094}
1095
1096static void nxt200x_release(struct dvb_frontend* fe)
1097{
1098 struct nxt200x_state* state = fe->demodulator_priv;
1099 kfree(state);
1100}
1101
1102static struct dvb_frontend_ops nxt200x_ops;
1103
1104struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
1105 struct i2c_adapter* i2c)
1106{
1107 struct nxt200x_state* state = NULL;
1108 u8 buf [] = {0,0,0,0,0};
1109
1110 /* allocate memory for the internal state */
1111 state = (struct nxt200x_state*) kmalloc(sizeof(struct nxt200x_state), GFP_KERNEL);
1112 if (state == NULL)
1113 goto error;
1114 memset(state,0,sizeof(*state));
1115
1116 /* setup the state */
1117 state->config = config;
1118 state->i2c = i2c;
1119 memcpy(&state->ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
1120 state->initialised = 0;
1121
1122 /* read card id */
1123 nxt200x_readbytes(state, 0x00, buf, 5);
1124 dprintk("NXT info: %02X %02X %02X %02X %02X\n",
1125 buf[0], buf[1], buf[2], buf[3], buf[4]);
1126
1127 /* set demod chip */
1128 switch (buf[0]) {
1129 case 0x04:
1130 state->demod_chip = NXT2002;
1131 printk("nxt200x: NXT2002 Detected\n");
1132 break;
1133 case 0x05:
1134 state->demod_chip = NXT2004;
1135 printk("nxt200x: NXT2004 Detected\n");
1136 break;
1137 default:
1138 goto error;
1139 }
1140
1141 /* make sure demod chip is supported */
1142 switch (state->demod_chip) {
1143 case NXT2002:
1144 if (buf[0] != 0x04) goto error; /* device id */
1145 if (buf[1] != 0x02) goto error; /* fab id */
1146 if (buf[2] != 0x11) goto error; /* month */
1147 if (buf[3] != 0x20) goto error; /* year msb */
1148 if (buf[4] != 0x00) goto error; /* year lsb */
1149 break;
1150 case NXT2004:
1151 if (buf[0] != 0x05) goto error; /* device id */
1152 break;
1153 default:
1154 goto error;
1155 }
1156
1157 /* create dvb_frontend */
1158 state->frontend.ops = &state->ops;
1159 state->frontend.demodulator_priv = state;
1160 return &state->frontend;
1161
1162error:
1163 kfree(state);
1164 printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n",
1165 buf[0], buf[1], buf[2], buf[3], buf[4]);
1166 return NULL;
1167}
1168
1169static struct dvb_frontend_ops nxt200x_ops = {
1170
1171 .info = {
1172 .name = "Nextwave NXT200X VSB/QAM frontend",
1173 .type = FE_ATSC,
1174 .frequency_min = 54000000,
1175 .frequency_max = 860000000,
1176 .frequency_stepsize = 166666, /* stepsize is just a guess */
1177 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1178 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1179 FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
1180 },
1181
1182 .release = nxt200x_release,
1183
1184 .init = nxt200x_init,
1185 .sleep = nxt200x_sleep,
1186
1187 .set_frontend = nxt200x_setup_frontend_parameters,
1188 .get_tune_settings = nxt200x_get_tune_settings,
1189
1190 .read_status = nxt200x_read_status,
1191 .read_ber = nxt200x_read_ber,
1192 .read_signal_strength = nxt200x_read_signal_strength,
1193 .read_snr = nxt200x_read_snr,
1194 .read_ucblocks = nxt200x_read_ucblocks,
1195};
1196
1197module_param(debug, int, 0644);
1198MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1199
1200MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
1201MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob");
1202MODULE_LICENSE("GPL");
1203
1204EXPORT_SYMBOL(nxt200x_attach);
1205
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h
new file mode 100644
index 000000000000..1d9d70bc37ef
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.h
@@ -0,0 +1,61 @@
1/*
2 * Support for NXT2002 and NXT2004 - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
5 * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
6 * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 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 NXT200X_H
25#define NXT200X_H
26
27#include <linux/dvb/frontend.h>
28#include <linux/firmware.h>
29
30typedef enum nxt_chip_t {
31 NXTUNDEFINED,
32 NXT2002,
33 NXT2004
34}nxt_chip_type;
35
36struct nxt200x_config
37{
38 /* the demodulator's i2c address */
39 u8 demod_address;
40
41 /* tuner information */
42 u8 pll_address;
43 struct dvb_pll_desc *pll_desc;
44
45 /* used to set pll input */
46 int (*set_pll_input)(u8* buf, int input);
47
48 /* need to set device param for start_dma */
49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
50};
51
52extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
53 struct i2c_adapter* i2c);
54
55#endif /* NXT200X_H */
56
57/*
58 * Local variables:
59 * c-basic-offset: 8
60 * End:
61 */
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index fc74c40d6477..78bded861d02 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -468,6 +468,7 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
468 unsigned char snd_buf[2]; 468 unsigned char snd_buf[2];
469 u8 rcvr_stat; 469 u8 rcvr_stat;
470 u16 snr_equ; 470 u16 snr_equ;
471 u32 signal_strength;
471 int usK; 472 int usK;
472 473
473 snd_buf[0]=0x04; 474 snd_buf[0]=0x04;
@@ -503,7 +504,11 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
503 usK = (rcvr_stat & 0x10) ? 3 : 0; 504 usK = (rcvr_stat & 0x10) ? 3 : 0;
504 505
505 /* The value reported back from the frontend will be FFFF=100% 0000=0% */ 506 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
506 *strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000; 507 signal_strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000;
508 if (signal_strength > 0xffff)
509 *strength = 0xffff;
510 else
511 *strength = signal_strength;
507 dprintk("read_signal_strength %i\n",*strength); 512 dprintk("read_signal_strength %i\n",*strength);
508 513
509 return 0; 514 return 0;
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index 8a9db23dd1b7..531f76246e5f 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -339,6 +339,7 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
339 u8 rec_buf[2]; 339 u8 rec_buf[2];
340 u8 snd_buf[4]; 340 u8 snd_buf[4];
341 u8 snr_equ; 341 u8 snr_equ;
342 u32 signal_strength;
342 343
343 /* SNR after Equalizer */ 344 /* SNR after Equalizer */
344 snd_buf[0] = 0x04; 345 snd_buf[0] = 0x04;
@@ -358,8 +359,11 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
358 snr_equ = rec_buf[0] & 0xff; 359 snr_equ = rec_buf[0] & 0xff;
359 360
360 /* The value reported back from the frontend will be FFFF=100% 0000=0% */ 361 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
361 *strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000; 362 signal_strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000;
362 363 if (signal_strength > 0xffff)
364 *strength = 0xffff;
365 else
366 *strength = signal_strength;
363 dprintk("read_signal_strength %i\n",*strength); 367 dprintk("read_signal_strength %i\n",*strength);
364 368
365 return 0; 369 return 0;
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 889d9257215d..29c48665e130 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -64,8 +64,12 @@ struct stv0299_state {
64 u32 tuner_frequency; 64 u32 tuner_frequency;
65 u32 symbol_rate; 65 u32 symbol_rate;
66 fe_code_rate_t fec_inner; 66 fe_code_rate_t fec_inner;
67 int errmode;
67}; 68};
68 69
70#define STATUS_BER 0
71#define STATUS_UCBLOCKS 1
72
69static int debug; 73static int debug;
70static int debug_legacy_dish_switch; 74static int debug_legacy_dish_switch;
71#define dprintk(args...) \ 75#define dprintk(args...) \
@@ -383,36 +387,6 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
383 }; 387 };
384} 388}
385 389
386static inline s32 stv0299_calc_usec_delay (struct timeval lasttime, struct timeval curtime)
387{
388 return ((curtime.tv_usec < lasttime.tv_usec) ?
389 1000000 - lasttime.tv_usec + curtime.tv_usec :
390 curtime.tv_usec - lasttime.tv_usec);
391}
392
393static void stv0299_sleep_until (struct timeval *waketime, u32 add_usec)
394{
395 struct timeval lasttime;
396 s32 delta, newdelta;
397
398 waketime->tv_usec += add_usec;
399 if (waketime->tv_usec >= 1000000) {
400 waketime->tv_usec -= 1000000;
401 waketime->tv_sec++;
402 }
403
404 do_gettimeofday (&lasttime);
405 delta = stv0299_calc_usec_delay (lasttime, *waketime);
406 if (delta > 2500) {
407 msleep ((delta - 1500) / 1000);
408 do_gettimeofday (&lasttime);
409 newdelta = stv0299_calc_usec_delay (lasttime, *waketime);
410 delta = (newdelta > delta) ? 0 : newdelta;
411 }
412 if (delta > 0)
413 udelay (delta);
414}
415
416static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) 390static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
417{ 391{
418 struct stv0299_state* state = fe->demodulator_priv; 392 struct stv0299_state* state = fe->demodulator_priv;
@@ -440,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
440 memcpy (&tv[0], &nexttime, sizeof (struct timeval)); 414 memcpy (&tv[0], &nexttime, sizeof (struct timeval));
441 stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */ 415 stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
442 416
443 stv0299_sleep_until (&nexttime, 32000); 417 dvb_frontend_sleep_until(&nexttime, 32000);
444 418
445 for (i=0; i<9; i++) { 419 for (i=0; i<9; i++) {
446 if (debug_legacy_dish_switch) 420 if (debug_legacy_dish_switch)
@@ -454,13 +428,13 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
454 cmd = cmd >> 1; 428 cmd = cmd >> 1;
455 429
456 if (i != 8) 430 if (i != 8)
457 stv0299_sleep_until (&nexttime, 8000); 431 dvb_frontend_sleep_until(&nexttime, 8000);
458 } 432 }
459 if (debug_legacy_dish_switch) { 433 if (debug_legacy_dish_switch) {
460 printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", 434 printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
461 __FUNCTION__, fe->dvb->num); 435 __FUNCTION__, fe->dvb->num);
462 for (i=1; i < 10; i++) 436 for (i = 1; i < 10; i++)
463 printk ("%d: %d\n", i, stv0299_calc_usec_delay (tv[i-1] , tv[i])); 437 printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
464 } 438 }
465 439
466 return 0; 440 return 0;
@@ -517,8 +491,7 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
517{ 491{
518 struct stv0299_state* state = fe->demodulator_priv; 492 struct stv0299_state* state = fe->demodulator_priv;
519 493
520 stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x10); 494 if (state->errmode != STATUS_BER) return 0;
521 msleep(100);
522 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); 495 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
523 496
524 return 0; 497 return 0;
@@ -557,9 +530,8 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
557{ 530{
558 struct stv0299_state* state = fe->demodulator_priv; 531 struct stv0299_state* state = fe->demodulator_priv;
559 532
560 stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x30); 533 if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
561 msleep(100); 534 else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
562 *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
563 535
564 return 0; 536 return 0;
565} 537}
@@ -581,49 +553,14 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
581 if (state->config->invert) invval = (~invval) & 1; 553 if (state->config->invert) invval = (~invval) & 1;
582 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); 554 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
583 555
584 if (state->config->enhanced_tuning) { 556 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
585 /* check if we should do a finetune */ 557 state->config->pll_set(fe, state->i2c, p);
586 int frequency_delta = p->frequency - state->tuner_frequency; 558 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
587 int minmax = p->u.qpsk.symbol_rate / 2000;
588 if (minmax < 5000) minmax = 5000;
589
590 if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) &&
591 (state->fec_inner == p->u.qpsk.fec_inner) &&
592 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
593 int Drot_freq = (frequency_delta << 16) / (state->config->mclk / 1000);
594
595 // zap the derotator registers first
596 stv0299_writeregI(state, 0x22, 0x00);
597 stv0299_writeregI(state, 0x23, 0x00);
598
599 // now set them as we want
600 stv0299_writeregI(state, 0x22, Drot_freq >> 8);
601 stv0299_writeregI(state, 0x23, Drot_freq);
602 } else {
603 /* A "normal" tune is requested */
604 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
605 state->config->pll_set(fe, state->i2c, p);
606 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
607
608 stv0299_writeregI(state, 0x32, 0x80);
609 stv0299_writeregI(state, 0x22, 0x00);
610 stv0299_writeregI(state, 0x23, 0x00);
611 stv0299_writeregI(state, 0x32, 0x19);
612 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
613 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
614 }
615 } else {
616 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
617 state->config->pll_set(fe, state->i2c, p);
618 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
619 559
620 stv0299_set_FEC (state, p->u.qpsk.fec_inner); 560 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
621 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); 561 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
622 stv0299_writeregI(state, 0x22, 0x00); 562 stv0299_writeregI(state, 0x22, 0x00);
623 stv0299_writeregI(state, 0x23, 0x00); 563 stv0299_writeregI(state, 0x23, 0x00);
624 stv0299_readreg (state, 0x23);
625 stv0299_writeregI(state, 0x12, 0xb9);
626 }
627 564
628 state->tuner_frequency = p->frequency; 565 state->tuner_frequency = p->frequency;
629 state->fec_inner = p->u.qpsk.fec_inner; 566 state->fec_inner = p->u.qpsk.fec_inner;
@@ -708,6 +645,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
708 state->tuner_frequency = 0; 645 state->tuner_frequency = 0;
709 state->symbol_rate = 0; 646 state->symbol_rate = 0;
710 state->fec_inner = 0; 647 state->fec_inner = 0;
648 state->errmode = STATUS_BER;
711 649
712 /* check if the demod is there */ 650 /* check if the demod is there */
713 stv0299_writeregI(state, 0x02, 0x34); /* standby off */ 651 stv0299_writeregI(state, 0x02, 0x34); /* standby off */
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index d0c4484861e1..9af3d71c89db 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -73,9 +73,6 @@ struct stv0299_config
73 /* does the inversion require inversion? */ 73 /* does the inversion require inversion? */
74 u8 invert:1; 74 u8 invert:1;
75 75
76 /* Should the enhanced tuning code be used? */
77 u8 enhanced_tuning:1;
78
79 /* Skip reinitialisation? */ 76 /* Skip reinitialisation? */
80 u8 skip_reinit:1; 77 u8 skip_reinit:1;
81 78
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 3529c618f828..7968743826fc 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -420,7 +420,7 @@ static void tda10046_init_plls(struct dvb_frontend* fe)
420 struct tda1004x_state* state = fe->demodulator_priv; 420 struct tda1004x_state* state = fe->demodulator_priv;
421 421
422 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); 422 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
423 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10 423 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10
424 if (state->config->xtal_freq == TDA10046_XTAL_4M ) { 424 if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
425 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); 425 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
426 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 426 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
@@ -597,7 +597,10 @@ static int tda10046_init(struct dvb_frontend* fe)
597 // Init the tuner PLL 597 // Init the tuner PLL
598 if (state->config->pll_init) { 598 if (state->config->pll_init) {
599 tda1004x_enable_tuner_i2c(state); 599 tda1004x_enable_tuner_i2c(state);
600 state->config->pll_init(fe); 600 if (state->config->pll_init(fe)) {
601 printk(KERN_ERR "tda1004x: pll init failed\n");
602 return -EIO;
603 }
601 tda1004x_disable_tuner_i2c(state); 604 tda1004x_disable_tuner_i2c(state);
602 } 605 }
603 606
@@ -667,7 +670,10 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
667 670
668 // set frequency 671 // set frequency
669 tda1004x_enable_tuner_i2c(state); 672 tda1004x_enable_tuner_i2c(state);
670 state->config->pll_set(fe, fe_params); 673 if (state->config->pll_set(fe, fe_params)) {
674 printk(KERN_ERR "tda1004x: pll set failed\n");
675 return -EIO;
676 }
671 tda1004x_disable_tuner_i2c(state); 677 tda1004x_disable_tuner_i2c(state);
672 678
673 // Hardcoded to use auto as much as possible on the TDA10045 as it 679 // Hardcoded to use auto as much as possible on the TDA10045 as it
@@ -832,6 +838,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
832 838
833 case TDA1004X_DEMOD_TDA10046: 839 case TDA1004X_DEMOD_TDA10046:
834 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); 840 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
841 msleep(1);
842 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1);
835 break; 843 break;
836 } 844 }
837 845
@@ -1129,7 +1137,12 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1129 if (state->config->pll_sleep != NULL) { 1137 if (state->config->pll_sleep != NULL) {
1130 tda1004x_enable_tuner_i2c(state); 1138 tda1004x_enable_tuner_i2c(state);
1131 state->config->pll_sleep(fe); 1139 state->config->pll_sleep(fe);
1132 tda1004x_disable_tuner_i2c(state); 1140 if (state->config->if_freq != TDA10046_FREQ_052) {
1141 /* special hack for Philips EUROPA Based boards:
1142 * keep the I2c bridge open for tuner access in analog mode
1143 */
1144 tda1004x_disable_tuner_i2c(state);
1145 }
1133 } 1146 }
1134 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1147 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1135 break; 1148 break;
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 85b437bbddcd..bbebd1c4caca 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -286,15 +286,10 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
286 * although one packet has been transfered. 286 * although one packet has been transfered.
287 */ 287 */
288 if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { 288 if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
289 unsigned int i = 0, valid; 289 unsigned int i = 0;
290 while (pluto->dma_buf[i] == 0x47) 290 while (pluto->dma_buf[i] == 0x47)
291 i += 188; 291 i += 188;
292 valid = i / 188; 292 nbpackets = 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 } 293 }
299 294
300 dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets); 295 dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 22b203f8ff27..87ea52757a21 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1566,7 +1566,7 @@ static u8 alps_bsru6_inittab[] = {
1566 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1566 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1567 0x10, 0x3f, // AGC2 0x3d 1567 0x10, 0x3f, // AGC2 0x3d
1568 0x11, 0x84, 1568 0x11, 0x84,
1569 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1569 0x12, 0xb9,
1570 0x15, 0xc9, // lock detector threshold 1570 0x15, 0xc9, // lock detector threshold
1571 0x16, 0x00, 1571 0x16, 0x00,
1572 0x17, 0x00, 1572 0x17, 0x00,
@@ -1644,7 +1644,6 @@ static struct stv0299_config alps_bsru6_config = {
1644 .inittab = alps_bsru6_inittab, 1644 .inittab = alps_bsru6_inittab,
1645 .mclk = 88000000UL, 1645 .mclk = 88000000UL,
1646 .invert = 1, 1646 .invert = 1,
1647 .enhanced_tuning = 0,
1648 .skip_reinit = 0, 1647 .skip_reinit = 0,
1649 .lock_output = STV0229_LOCKOUTPUT_1, 1648 .lock_output = STV0229_LOCKOUTPUT_1,
1650 .volt13_op0_op1 = STV0299_VOLT13_OP1, 1649 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -1669,7 +1668,7 @@ static u8 alps_bsbe1_inittab[] = {
1669 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1668 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1670 0x10, 0x3f, // AGC2 0x3d 1669 0x10, 0x3f, // AGC2 0x3d
1671 0x11, 0x84, 1670 0x11, 0x84,
1672 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1671 0x12, 0xb9,
1673 0x15, 0xc9, // lock detector threshold 1672 0x15, 0xc9, // lock detector threshold
1674 0x16, 0x00, 1673 0x16, 0x00,
1675 0x17, 0x00, 1674 0x17, 0x00,
@@ -1721,7 +1720,6 @@ static struct stv0299_config alps_bsbe1_config = {
1721 .inittab = alps_bsbe1_inittab, 1720 .inittab = alps_bsbe1_inittab,
1722 .mclk = 88000000UL, 1721 .mclk = 88000000UL,
1723 .invert = 1, 1722 .invert = 1,
1724 .enhanced_tuning = 0,
1725 .skip_reinit = 0, 1723 .skip_reinit = 0,
1726 .min_delay_ms = 100, 1724 .min_delay_ms = 100,
1727 .set_symbol_rate = alps_bsru6_set_symbol_rate, 1725 .set_symbol_rate = alps_bsru6_set_symbol_rate,
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 7692cd23f839..aa75dc03a0b3 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -499,7 +499,7 @@ static u8 typhoon_cinergy1200s_inittab[] = {
499 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 499 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
500 0x10, 0x3f, // AGC2 0x3d 500 0x10, 0x3f, // AGC2 0x3d
501 0x11, 0x84, 501 0x11, 0x84,
502 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 502 0x12, 0xb9,
503 0x15, 0xc9, // lock detector threshold 503 0x15, 0xc9, // lock detector threshold
504 0x16, 0x00, 504 0x16, 0x00,
505 0x17, 0x00, 505 0x17, 0x00,
@@ -531,7 +531,6 @@ static struct stv0299_config typhoon_config = {
531 .inittab = typhoon_cinergy1200s_inittab, 531 .inittab = typhoon_cinergy1200s_inittab,
532 .mclk = 88000000UL, 532 .mclk = 88000000UL,
533 .invert = 0, 533 .invert = 0,
534 .enhanced_tuning = 0,
535 .skip_reinit = 0, 534 .skip_reinit = 0,
536 .lock_output = STV0229_LOCKOUTPUT_1, 535 .lock_output = STV0229_LOCKOUTPUT_1,
537 .volt13_op0_op1 = STV0299_VOLT13_OP0, 536 .volt13_op0_op1 = STV0299_VOLT13_OP0,
@@ -546,7 +545,6 @@ static struct stv0299_config cinergy_1200s_config = {
546 .inittab = typhoon_cinergy1200s_inittab, 545 .inittab = typhoon_cinergy1200s_inittab,
547 .mclk = 88000000UL, 546 .mclk = 88000000UL,
548 .invert = 0, 547 .invert = 0,
549 .enhanced_tuning = 0,
550 .skip_reinit = 0, 548 .skip_reinit = 0,
551 .lock_output = STV0229_LOCKOUTPUT_0, 549 .lock_output = STV0229_LOCKOUTPUT_0,
552 .volt13_op0_op1 = STV0299_VOLT13_OP0, 550 .volt13_op0_op1 = STV0299_VOLT13_OP0,
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 51c30ba68140..75fb92d60998 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -490,7 +490,7 @@ static u8 alps_bsru6_inittab[] = {
490 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 490 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
491 0x10, 0x3f, // AGC2 0x3d 491 0x10, 0x3f, // AGC2 0x3d
492 0x11, 0x84, 492 0x11, 0x84,
493 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 493 0x12, 0xb9,
494 0x15, 0xc9, // lock detector threshold 494 0x15, 0xc9, // lock detector threshold
495 0x16, 0x00, 495 0x16, 0x00,
496 0x17, 0x00, 496 0x17, 0x00,
@@ -580,7 +580,6 @@ static struct stv0299_config alps_bsru6_config = {
580 .inittab = alps_bsru6_inittab, 580 .inittab = alps_bsru6_inittab,
581 .mclk = 88000000UL, 581 .mclk = 88000000UL,
582 .invert = 1, 582 .invert = 1,
583 .enhanced_tuning = 0,
584 .skip_reinit = 0, 583 .skip_reinit = 0,
585 .lock_output = STV0229_LOCKOUTPUT_1, 584 .lock_output = STV0229_LOCKOUTPUT_1,
586 .volt13_op0_op1 = STV0299_VOLT13_OP1, 585 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -710,7 +709,6 @@ static struct stv0299_config philips_su1278_tt_config = {
710 .inittab = philips_su1278_tt_inittab, 709 .inittab = philips_su1278_tt_inittab,
711 .mclk = 64000000UL, 710 .mclk = 64000000UL,
712 .invert = 0, 711 .invert = 0,
713 .enhanced_tuning = 1,
714 .skip_reinit = 1, 712 .skip_reinit = 1,
715 .lock_output = STV0229_LOCKOUTPUT_1, 713 .lock_output = STV0229_LOCKOUTPUT_1,
716 .volt13_op0_op1 = STV0299_VOLT13_OP1, 714 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index b1f21ef0e3b3..755df81cbc49 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -305,7 +305,7 @@ static u8 alps_bsru6_inittab[] = {
305 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 305 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
306 0x10, 0x3f, // AGC2 0x3d 306 0x10, 0x3f, // AGC2 0x3d
307 0x11, 0x84, 307 0x11, 0x84,
308 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 308 0x12, 0xb9,
309 0x15, 0xc9, // lock detector threshold 309 0x15, 0xc9, // lock detector threshold
310 0x16, 0x00, 310 0x16, 0x00,
311 0x17, 0x00, 311 0x17, 0x00,
@@ -379,7 +379,6 @@ static struct stv0299_config alps_bsru6_config = {
379 .inittab = alps_bsru6_inittab, 379 .inittab = alps_bsru6_inittab,
380 .mclk = 88000000UL, 380 .mclk = 88000000UL,
381 .invert = 1, 381 .invert = 1,
382 .enhanced_tuning = 0,
383 .skip_reinit = 0, 382 .skip_reinit = 0,
384 .lock_output = STV0229_LOCKOUTPUT_1, 383 .lock_output = STV0229_LOCKOUTPUT_1,
385 .volt13_op0_op1 = STV0299_VOLT13_OP1, 384 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 43d6c8268642..4fd8bbc47037 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -226,12 +226,14 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg)
226 return 0; 226 return 0;
227} 227}
228 228
229static void lnbp21_init(struct budget* budget) 229static int lnbp21_init(struct budget* budget)
230{ 230{
231 u8 buf = 0x00; 231 u8 buf = 0x00;
232 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) }; 232 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) };
233 233
234 i2c_transfer (&budget->i2c_adap, &msg, 1); 234 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
235 return -EIO;
236 return 0;
235} 237}
236 238
237static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 239static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -273,7 +275,7 @@ static u8 alps_bsru6_inittab[] = {
273 0x01, 0x15, 275 0x01, 0x15,
274 0x02, 0x00, 276 0x02, 0x00,
275 0x03, 0x00, 277 0x03, 0x00,
276 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ 278 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
277 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ 279 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
278 0x06, 0x40, /* DAC not used, set to high impendance mode */ 280 0x06, 0x40, /* DAC not used, set to high impendance mode */
279 0x07, 0x00, /* DAC LSB */ 281 0x07, 0x00, /* DAC LSB */
@@ -284,7 +286,7 @@ static u8 alps_bsru6_inittab[] = {
284 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 286 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
285 0x10, 0x3f, // AGC2 0x3d 287 0x10, 0x3f, // AGC2 0x3d
286 0x11, 0x84, 288 0x11, 0x84,
287 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 289 0x12, 0xb9,
288 0x15, 0xc9, // lock detector threshold 290 0x15, 0xc9, // lock detector threshold
289 0x16, 0x00, 291 0x16, 0x00,
290 0x17, 0x00, 292 0x17, 0x00,
@@ -358,7 +360,6 @@ static struct stv0299_config alps_bsru6_config = {
358 .inittab = alps_bsru6_inittab, 360 .inittab = alps_bsru6_inittab,
359 .mclk = 88000000UL, 361 .mclk = 88000000UL,
360 .invert = 1, 362 .invert = 1,
361 .enhanced_tuning = 0,
362 .skip_reinit = 0, 363 .skip_reinit = 0,
363 .lock_output = STV0229_LOCKOUTPUT_1, 364 .lock_output = STV0229_LOCKOUTPUT_1,
364 .volt13_op0_op1 = STV0299_VOLT13_OP1, 365 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -367,6 +368,79 @@ static struct stv0299_config alps_bsru6_config = {
367 .pll_set = alps_bsru6_pll_set, 368 .pll_set = alps_bsru6_pll_set,
368}; 369};
369 370
371static u8 alps_bsbe1_inittab[] = {
372 0x01, 0x15,
373 0x02, 0x30,
374 0x03, 0x00,
375 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
376 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
377 0x06, 0x40, /* DAC not used, set to high impendance mode */
378 0x07, 0x00, /* DAC LSB */
379 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
380 0x09, 0x00, /* FIFO */
381 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
382 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
383 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
384 0x10, 0x3f, // AGC2 0x3d
385 0x11, 0x84,
386 0x12, 0xb9,
387 0x15, 0xc9, // lock detector threshold
388 0x16, 0x00,
389 0x17, 0x00,
390 0x18, 0x00,
391 0x19, 0x00,
392 0x1a, 0x00,
393 0x1f, 0x50,
394 0x20, 0x00,
395 0x21, 0x00,
396 0x22, 0x00,
397 0x23, 0x00,
398 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
399 0x29, 0x1e, // 1/2 threshold
400 0x2a, 0x14, // 2/3 threshold
401 0x2b, 0x0f, // 3/4 threshold
402 0x2c, 0x09, // 5/6 threshold
403 0x2d, 0x05, // 7/8 threshold
404 0x2e, 0x01,
405 0x31, 0x1f, // test all FECs
406 0x32, 0x19, // viterbi and synchro search
407 0x33, 0xfc, // rs control
408 0x34, 0x93, // error control
409 0x0f, 0x92, // 0x80 = inverse AGC
410 0xff, 0xff
411};
412
413static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
414{
415 int ret;
416 u8 data[4];
417 u32 div;
418 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
419
420 if ((params->frequency < 950000) || (params->frequency > 2150000))
421 return -EINVAL;
422
423 div = (params->frequency + (125 - 1)) / 125; // round correctly
424 data[0] = (div >> 8) & 0x7f;
425 data[1] = div & 0xff;
426 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
427 data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
428
429 ret = i2c_transfer(i2c, &msg, 1);
430 return (ret != 1) ? -EIO : 0;
431}
432
433static struct stv0299_config alps_bsbe1_config = {
434 .demod_address = 0x68,
435 .inittab = alps_bsbe1_inittab,
436 .mclk = 88000000UL,
437 .invert = 1,
438 .skip_reinit = 0,
439 .min_delay_ms = 100,
440 .set_symbol_rate = alps_bsru6_set_symbol_rate,
441 .pll_set = alps_bsbe1_pll_set,
442};
443
370static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 444static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
371{ 445{
372 struct budget* budget = (struct budget*) fe->dvb->priv; 446 struct budget* budget = (struct budget*) fe->dvb->priv;
@@ -500,6 +574,19 @@ static u8 read_pwm(struct budget* budget)
500static void frontend_init(struct budget *budget) 574static void frontend_init(struct budget *budget)
501{ 575{
502 switch(budget->dev->pci->subsystem_device) { 576 switch(budget->dev->pci->subsystem_device) {
577 case 0x1017:
578 // try the ALPS BSBE1 now
579 budget->dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget->i2c_adap);
580 if (budget->dvb_frontend) {
581 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
582 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
583 if (lnbp21_init(budget)) {
584 printk("%s: No LNBP21 found!\n", __FUNCTION__);
585 goto error_out;
586 }
587 }
588
589 break;
503 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) 590 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
504 case 0x1013: 591 case 0x1013:
505 // try the ALPS BSRV2 first of all 592 // try the ALPS BSRV2 first of all
@@ -554,7 +641,10 @@ static void frontend_init(struct budget *budget)
554 if (budget->dvb_frontend) { 641 if (budget->dvb_frontend) {
555 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; 642 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
556 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; 643 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
557 lnbp21_init(budget); 644 if (lnbp21_init(budget)) {
645 printk("%s: No LNBP21 found!\n", __FUNCTION__);
646 goto error_out;
647 }
558 break; 648 break;
559 } 649 }
560 } 650 }
@@ -566,13 +656,17 @@ static void frontend_init(struct budget *budget)
566 budget->dev->pci->subsystem_vendor, 656 budget->dev->pci->subsystem_vendor,
567 budget->dev->pci->subsystem_device); 657 budget->dev->pci->subsystem_device);
568 } else { 658 } else {
569 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { 659 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend))
570 printk("budget: Frontend registration failed!\n"); 660 goto error_out;
571 if (budget->dvb_frontend->ops->release)
572 budget->dvb_frontend->ops->release(budget->dvb_frontend);
573 budget->dvb_frontend = NULL;
574 }
575 } 661 }
662 return;
663
664error_out:
665 printk("budget: Frontend registration failed!\n");
666 if (budget->dvb_frontend->ops->release)
667 budget->dvb_frontend->ops->release(budget->dvb_frontend);
668 budget->dvb_frontend = NULL;
669 return;
576} 670}
577 671
578static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) 672static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
@@ -618,6 +712,7 @@ static int budget_detach (struct saa7146_dev* dev)
618 712
619static struct saa7146_extension budget_extension; 713static struct saa7146_extension budget_extension;
620 714
715MAKE_BUDGET_INFO(ttbs2, "TT-Budget/WinTV-NOVA-S PCI (rev AL/alps bsbe1 lnbp21 frontend)", BUDGET_TT);
621MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); 716MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT);
622MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); 717MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
623MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); 718MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
@@ -630,6 +725,7 @@ static struct pci_device_id pci_tbl[] = {
630 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), 725 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004),
631 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), 726 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
632 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), 727 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
728 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
633 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), 729 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016),
634 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), 730 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
635 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), 731 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index d200ab0ad9e7..fd53d6010502 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -1198,7 +1198,7 @@ static u8 alps_bsbe1_inittab[] = {
1198 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1198 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1199 0x10, 0x3f, // AGC2 0x3d 1199 0x10, 0x3f, // AGC2 0x3d
1200 0x11, 0x84, 1200 0x11, 0x84,
1201 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1201 0x12, 0xb9,
1202 0x15, 0xc9, // lock detector threshold 1202 0x15, 0xc9, // lock detector threshold
1203 0x16, 0x00, 1203 0x16, 0x00,
1204 0x17, 0x00, 1204 0x17, 0x00,
@@ -1240,7 +1240,7 @@ static u8 alps_bsru6_inittab[] = {
1240 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1240 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1241 0x10, 0x3f, // AGC2 0x3d 1241 0x10, 0x3f, // AGC2 0x3d
1242 0x11, 0x84, 1242 0x11, 0x84,
1243 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1243 0x12, 0xb9,
1244 0x15, 0xc9, // lock detector threshold 1244 0x15, 0xc9, // lock detector threshold
1245 0x16, 0x00, 1245 0x16, 0x00,
1246 0x17, 0x00, 1246 0x17, 0x00,
@@ -1335,7 +1335,6 @@ static struct stv0299_config alps_stv0299_config = {
1335 .inittab = alps_bsru6_inittab, 1335 .inittab = alps_bsru6_inittab,
1336 .mclk = 88000000UL, 1336 .mclk = 88000000UL,
1337 .invert = 1, 1337 .invert = 1,
1338 .enhanced_tuning = 0,
1339 .skip_reinit = 0, 1338 .skip_reinit = 0,
1340 .lock_output = STV0229_LOCKOUTPUT_1, 1339 .lock_output = STV0229_LOCKOUTPUT_1,
1341 .volt13_op0_op1 = STV0299_VOLT13_OP1, 1340 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index bbb989df4cf0..199b01188858 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -25,6 +25,16 @@ config VIDEO_BT848
25 To compile this driver as a module, choose M here: the 25 To compile this driver as a module, choose M here: the
26 module will be called bttv. 26 module will be called bttv.
27 27
28config VIDEO_BT848_DVB
29 tristate "DVB/ATSC Support for bt878 based TV cards"
30 depends on VIDEO_BT848 && DVB_CORE
31 select DVB_BT8XX
32 ---help---
33 This adds support for DVB/ATSC cards based on the BT878 chip.
34
35 To compile this driver as a module, choose M here: the
36 module will be called dvb-bt8xx.
37
28config VIDEO_SAA6588 38config VIDEO_SAA6588
29 tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards" 39 tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
30 depends on VIDEO_DEV && I2C && VIDEO_BT848 40 depends on VIDEO_DEV && I2C && VIDEO_BT848
@@ -243,29 +253,7 @@ config VIDEO_MEYE
243 To compile this driver as a module, choose M here: the 253 To compile this driver as a module, choose M here: the
244 module will be called meye. 254 module will be called meye.
245 255
246config VIDEO_SAA7134 256source "drivers/media/video/saa7134/Kconfig"
247 tristate "Philips SAA7134 support"
248 depends on VIDEO_DEV && PCI && I2C && SOUND
249 select VIDEO_BUF
250 select VIDEO_IR
251 select VIDEO_TUNER
252 select CRC32
253 ---help---
254 This is a video4linux driver for Philips SAA7130/7134 based
255 TV cards.
256
257 To compile this driver as a module, choose M here: the
258 module will be called saa7134.
259
260config VIDEO_SAA7134_DVB
261 tristate "DVB Support for saa7134 based TV cards"
262 depends on VIDEO_SAA7134 && DVB_CORE
263 select VIDEO_BUF_DVB
264 select DVB_MT352
265 select DVB_TDA1004X
266 ---help---
267 This adds support for DVB cards based on the
268 Philips saa7134 chip.
269 257
270config VIDEO_MXB 258config VIDEO_MXB
271 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" 259 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
@@ -316,34 +304,9 @@ config VIDEO_HEXIUM_GEMINI
316 To compile this driver as a module, choose M here: the 304 To compile this driver as a module, choose M here: the
317 module will be called hexium_gemini. 305 module will be called hexium_gemini.
318 306
319config VIDEO_CX88 307source "drivers/media/video/cx88/Kconfig"
320 tristate "Conexant 2388x (bt878 successor) support"
321 depends on VIDEO_DEV && PCI && I2C && EXPERIMENTAL
322 select I2C_ALGOBIT
323 select FW_LOADER
324 select VIDEO_BTCX
325 select VIDEO_BUF
326 select VIDEO_TUNER
327 select VIDEO_TVEEPROM
328 select VIDEO_IR
329 ---help---
330 This is a video4linux driver for Conexant 2388x based
331 TV cards.
332 308
333 To compile this driver as a module, choose M here: the 309source "drivers/media/video/em28xx/Kconfig"
334 module will be called cx8800
335
336config VIDEO_CX88_DVB
337 tristate "DVB Support for cx2388x based TV cards"
338 depends on VIDEO_CX88 && DVB_CORE
339 select VIDEO_BUF_DVB
340 select DVB_MT352
341 select DVB_OR51132
342 select DVB_CX22702
343 select DVB_LGDT330X
344 ---help---
345 This adds support for DVB/ATSC cards based on the
346 Connexant 2388x chip.
347 310
348config VIDEO_OVCAMCHIP 311config VIDEO_OVCAMCHIP
349 tristate "OmniVision Camera Chip support" 312 tristate "OmniVision Camera Chip support"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 046b82de9285..3ac465992400 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -5,7 +5,6 @@
5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ 5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o 6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o
7zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o 7zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
8rds-objs := saa6588.o
9zr36067-objs := zoran_procfs.o zoran_device.o \ 8zr36067-objs := zoran_procfs.o zoran_device.o \
10 zoran_driver.o zoran_card.o 9 zoran_driver.o zoran_card.o
11tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o 10tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
@@ -16,7 +15,7 @@ obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
16obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o 15obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
17 16
18obj-$(CONFIG_VIDEO_ZR36120) += zoran.o 17obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
19obj-$(CONFIG_VIDEO_SAA6588) += rds.o 18obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
20obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o 19obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
21obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o 20obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
22obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o 21obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
@@ -39,6 +38,8 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
39obj-$(CONFIG_VIDEO_MEYE) += meye.o 38obj-$(CONFIG_VIDEO_MEYE) += meye.o
40obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ 39obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
41obj-$(CONFIG_VIDEO_CX88) += cx88/ 40obj-$(CONFIG_VIDEO_CX88) += cx88/
41obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
42obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o
42obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ 43obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
43obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o 44obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
44obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o 45obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 0823ddaf7004..881cdcb1875d 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -22,7 +22,6 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/devfs_fs_kernel.h> 23#include <linux/devfs_fs_kernel.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/version.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/errno.h> 26#include <linux/errno.h>
28#include <linux/fs.h> 27#include <linux/fs.h>
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
index 76c1b63ebdf2..e4063950ae57 100644
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -32,7 +32,6 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33 33
34#include <media/audiochip.h> 34#include <media/audiochip.h>
35#include <media/id.h>
36#include "bttv.h" 35#include "bttv.h"
37#include "bt832.h" 36#include "bt832.h"
38 37
@@ -54,36 +53,36 @@ static struct i2c_driver driver;
54static struct i2c_client client_template; 53static struct i2c_client client_template;
55 54
56struct bt832 { 55struct bt832 {
57 struct i2c_client client; 56 struct i2c_client client;
58}; 57};
59 58
60int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf) 59int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf)
61{ 60{
62 int i,rc; 61 int i,rc;
63 buf[0]=0x80; // start at register 0 with auto-increment 62 buf[0]=0x80; // start at register 0 with auto-increment
64 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1))) 63 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
65 printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc); 64 printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc);
66 65
67 for(i=0;i<65;i++) 66 for(i=0;i<65;i++)
68 buf[i]=0; 67 buf[i]=0;
69 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65))) 68 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
70 printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc); 69 printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc);
71 70
72 // Note: On READ the first byte is the current index 71 // Note: On READ the first byte is the current index
73 // (e.g. 0x80, what we just wrote) 72 // (e.g. 0x80, what we just wrote)
74 73
75 if(1) { 74 if(1) {
76 int i; 75 int i;
77 printk("BT832 hexdump:\n"); 76 printk("BT832 hexdump:\n");
78 for(i=1;i<65;i++) { 77 for(i=1;i<65;i++) {
79 if(i!=1) { 78 if(i!=1) {
80 if(((i-1)%8)==0) printk(" "); 79 if(((i-1)%8)==0) printk(" ");
81 if(((i-1)%16)==0) printk("\n"); 80 if(((i-1)%16)==0) printk("\n");
82 } 81 }
83 printk(" %02x",buf[i]); 82 printk(" %02x",buf[i]);
84 } 83 }
85 printk("\n"); 84 printk("\n");
86 } 85 }
87 return 0; 86 return 0;
88} 87}
89 88
@@ -102,13 +101,13 @@ int bt832_init(struct i2c_client *i2c_client_s)
102 return 0; 101 return 0;
103 } 102 }
104 103
105 printk("Write 0 tp VPSTATUS\n"); 104 printk("Write 0 tp VPSTATUS\n");
106 buf[0]=BT832_VP_STATUS; // Reg.52 105 buf[0]=BT832_VP_STATUS; // Reg.52
107 buf[1]= 0x00; 106 buf[1]= 0x00;
108 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 107 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
109 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); 108 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
110 109
111 bt832_hexdump(i2c_client_s,buf); 110 bt832_hexdump(i2c_client_s,buf);
112 111
113 112
114 // Leave low power mode: 113 // Leave low power mode:
@@ -116,17 +115,17 @@ int bt832_init(struct i2c_client *i2c_client_s)
116 buf[0]=BT832_CAM_SETUP0; //0x39 57 115 buf[0]=BT832_CAM_SETUP0; //0x39 57
117 buf[1]=0x08; 116 buf[1]=0x08;
118 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 117 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
119 printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc); 118 printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
120 119
121 bt832_hexdump(i2c_client_s,buf); 120 bt832_hexdump(i2c_client_s,buf);
122 121
123 printk("Write 0 tp VPSTATUS\n"); 122 printk("Write 0 tp VPSTATUS\n");
124 buf[0]=BT832_VP_STATUS; // Reg.52 123 buf[0]=BT832_VP_STATUS; // Reg.52
125 buf[1]= 0x00; 124 buf[1]= 0x00;
126 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 125 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
127 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); 126 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
128 127
129 bt832_hexdump(i2c_client_s,buf); 128 bt832_hexdump(i2c_client_s,buf);
130 129
131 130
132 // Enable Output 131 // Enable Output
@@ -134,22 +133,22 @@ int bt832_init(struct i2c_client *i2c_client_s)
134 buf[0]=BT832_VP_CONTROL1; // Reg.40 133 buf[0]=BT832_VP_CONTROL1; // Reg.40
135 buf[1]= 0x27 & (~0x01); // Default | !skip 134 buf[1]= 0x27 & (~0x01); // Default | !skip
136 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 135 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
137 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc); 136 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);
138 137
139 bt832_hexdump(i2c_client_s,buf); 138 bt832_hexdump(i2c_client_s,buf);
140 139
141 140
142 // for testing (even works when no camera attached) 141 // for testing (even works when no camera attached)
143 printk("bt832: *** Generate NTSC M Bars *****\n"); 142 printk("bt832: *** Generate NTSC M Bars *****\n");
144 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42 143 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
145 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally 144 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
146 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 145 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
147 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc); 146 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
148 147
149 printk("Bt832: Camera Present: %s\n", 148 printk("Bt832: Camera Present: %s\n",
150 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no"); 149 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
151 150
152 bt832_hexdump(i2c_client_s,buf); 151 bt832_hexdump(i2c_client_s,buf);
153 kfree(buf); 152 kfree(buf);
154 return 1; 153 return 1;
155} 154}
@@ -162,17 +161,17 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
162 161
163 printk("bt832_attach\n"); 162 printk("bt832_attach\n");
164 163
165 client_template.adapter = adap; 164 client_template.adapter = adap;
166 client_template.addr = addr; 165 client_template.addr = addr;
167 166
168 printk("bt832: chip found @ 0x%x\n", addr<<1); 167 printk("bt832: chip found @ 0x%x\n", addr<<1);
169 168
170 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) 169 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
171 return -ENOMEM; 170 return -ENOMEM;
172 memset(t,0,sizeof(*t)); 171 memset(t,0,sizeof(*t));
173 t->client = client_template; 172 t->client = client_template;
174 i2c_set_clientdata(&t->client, t); 173 i2c_set_clientdata(&t->client, t);
175 i2c_attach_client(&t->client); 174 i2c_attach_client(&t->client);
176 175
177 if(! bt832_init(&t->client)) { 176 if(! bt832_init(&t->client)) {
178 bt832_detach(&t->client); 177 bt832_detach(&t->client);
@@ -211,7 +210,7 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
211 210
212 printk("bt832: command %x\n",cmd); 211 printk("bt832: command %x\n",cmd);
213 212
214 switch (cmd) { 213 switch (cmd) {
215 case BT832_HEXDUMP: { 214 case BT832_HEXDUMP: {
216 unsigned char *buf; 215 unsigned char *buf;
217 buf=kmalloc(65,GFP_KERNEL); 216 buf=kmalloc(65,GFP_KERNEL);
diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h
index 9b6a8d2c96b5..1ce8fa71f7db 100644
--- a/drivers/media/video/bt832.h
+++ b/drivers/media/video/bt832.h
@@ -233,8 +233,8 @@ SetInterlaceMode( spec.interlace );
233/* from web: 233/* from web:
234 Video Sampling 234 Video Sampling
235Digital video is a sampled form of analog video. The most common sampling schemes in use today are: 235Digital video is a sampled form of analog video. The most common sampling schemes in use today are:
236 Pixel Clock Horiz Horiz Vert 236 Pixel Clock Horiz Horiz Vert
237 Rate Total Active 237 Rate Total Active
238NTSC square pixel 12.27 MHz 780 640 525 238NTSC square pixel 12.27 MHz 780 640 525
239NTSC CCIR-601 13.5 MHz 858 720 525 239NTSC CCIR-601 13.5 MHz 858 720 525
240NTSC 4FSc 14.32 MHz 910 768 525 240NTSC 4FSc 14.32 MHz 910 768 525
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 0881a17d5226..3413bace443a 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -6,7 +6,7 @@
6 like the big tvcards array for the most part 6 like the big tvcards array for the most part
7 7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de) 9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> 10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11 11
12 This program is free software; you can redistribute it and/or modify 12 This program is free software; you can redistribute it and/or modify
@@ -145,162 +145,163 @@ static struct CARD {
145 int cardnr; 145 int cardnr;
146 char *name; 146 char *name;
147} cards[] __devinitdata = { 147} cards[] __devinitdata = {
148 { 0x13eb0070, BTTV_HAUPPAUGE878, "Hauppauge WinTV" }, 148 { 0x13eb0070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV" },
149 { 0x39000070, BTTV_HAUPPAUGE878, "Hauppauge WinTV-D" }, 149 { 0x39000070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV-D" },
150 { 0x45000070, BTTV_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" }, 150 { 0x45000070, BTTV_BOARD_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" },
151 { 0xff000070, BTTV_OSPREY1x0, "Osprey-100" }, 151 { 0xff000070, BTTV_BOARD_OSPREY1x0, "Osprey-100" },
152 { 0xff010070, BTTV_OSPREY2x0_SVID,"Osprey-200" }, 152 { 0xff010070, BTTV_BOARD_OSPREY2x0_SVID,"Osprey-200" },
153 { 0xff020070, BTTV_OSPREY500, "Osprey-500" }, 153 { 0xff020070, BTTV_BOARD_OSPREY500, "Osprey-500" },
154 { 0xff030070, BTTV_OSPREY2000, "Osprey-2000" }, 154 { 0xff030070, BTTV_BOARD_OSPREY2000, "Osprey-2000" },
155 { 0xff040070, BTTV_OSPREY540, "Osprey-540" }, 155 { 0xff040070, BTTV_BOARD_OSPREY540, "Osprey-540" },
156 156 { 0xff070070, BTTV_BOARD_OSPREY440, "Osprey-440" },
157 { 0x00011002, BTTV_ATI_TVWONDER, "ATI TV Wonder" }, 157
158 { 0x00031002, BTTV_ATI_TVWONDERVE,"ATI TV Wonder/VE" }, 158 { 0x00011002, BTTV_BOARD_ATI_TVWONDER, "ATI TV Wonder" },
159 159 { 0x00031002, BTTV_BOARD_ATI_TVWONDERVE,"ATI TV Wonder/VE" },
160 { 0x6606107d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 160
161 { 0x6607107d, BTTV_WINFASTVC100, "Leadtek WinFast VC 100" }, 161 { 0x6606107d, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
162 { 0x6609107d, BTTV_WINFAST2000, "Leadtek TV 2000 XP" }, 162 { 0x6607107d, BTTV_BOARD_WINFASTVC100, "Leadtek WinFast VC 100" },
163 { 0x263610b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, 163 { 0x6609107d, BTTV_BOARD_WINFAST2000, "Leadtek TV 2000 XP" },
164 { 0x264510b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, 164 { 0x263610b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
165 { 0x402010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" }, 165 { 0x264510b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
166 { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" }, 166 { 0x402010fc, BTTV_BOARD_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" },
167 { 0x407010fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, 167 { 0x405010fc, BTTV_BOARD_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" },
168 { 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, 168 { 0x407010fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
169 169 { 0xd01810fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
170 { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, 170
171 { 0x001211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
171 /* some cards ship with byteswapped IDs ... */ 172 /* some cards ship with byteswapped IDs ... */
172 { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, 173 { 0x1200bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
173 { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, 174 { 0xff00bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
174 /* this seems to happen as well ... */ 175 /* this seems to happen as well ... */
175 { 0xff1211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, 176 { 0xff1211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
176 177
177 { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, 178 { 0x3000121a, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
178 { 0x263710b4, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, 179 { 0x263710b4, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
179 { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" }, 180 { 0x3060121a, BTTV_BOARD_STB2, "3Dfx VoodooTV 100/ STB OEM" },
180 181
181 { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, 182 { 0x3000144f, BTTV_BOARD_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
182 { 0xa005144f, BTTV_MAGICTVIEW063, "CPH06X TView99-Card" }, 183 { 0xa005144f, BTTV_BOARD_MAGICTVIEW063, "CPH06X TView99-Card" },
183 { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" }, 184 { 0x3002144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
184 { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" }, 185 { 0x3005144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
185 { 0x5000144f, BTTV_MAGICTVIEW061, "Askey CPH050" }, 186 { 0x5000144f, BTTV_BOARD_MAGICTVIEW061, "Askey CPH050" },
186 { 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" }, 187 { 0x300014ff, BTTV_BOARD_MAGICTVIEW061, "TView 99 (CPH061)" },
187 { 0x300214ff, BTTV_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" }, 188 { 0x300214ff, BTTV_BOARD_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" },
188 189
189 { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, 190 { 0x00011461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
190 { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" }, 191 { 0x00021461, BTTV_BOARD_AVERMEDIA98, "AVermedia TVCapture 98" },
191 { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, 192 { 0x00031461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
192 { 0x00041461, BTTV_AVERMEDIA98, "AVerMedia TVCapture 98" }, 193 { 0x00041461, BTTV_BOARD_AVERMEDIA98, "AVerMedia TVCapture 98" },
193 { 0x03001461, BTTV_AVERMEDIA98, "VDOMATE TV TUNER CARD" }, 194 { 0x03001461, BTTV_BOARD_AVERMEDIA98, "VDOMATE TV TUNER CARD" },
194 195
195 { 0x1117153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" }, 196 { 0x1117153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" },
196 { 0x1118153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" }, 197 { 0x1118153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" },
197 { 0x1119153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL I)" }, 198 { 0x1119153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL I)" },
198 { 0x111a153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL I)" }, 199 { 0x111a153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL I)" },
199 200
200 { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" }, 201 { 0x1123153b, BTTV_BOARD_TERRATVRADIO, "Terratec TV Radio+" },
201 { 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" }, 202 { 0x1127153b, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.05)" },
202 /* clashes with FlyVideo 203 /* clashes with FlyVideo
203 *{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" }, */ 204 *{ 0x18521852, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.10)" }, */
204 { 0x1134153b, BTTV_TERRATVALUE, "Terratec TValue (LR102)" }, 205 { 0x1134153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (LR102)" },
205 { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */ 206 { 0x1135153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */
206 { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, /* ?? */ 207 { 0x5018153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue" }, /* ?? */
207 { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */ 208 { 0xff3b153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */
208 209
209 { 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, 210 { 0x400015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
210 { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, 211 { 0x400a15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
211 { 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 212 { 0x400d15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
212 { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 213 { 0x401015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
213 { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 214 { 0x401615b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
214 215
215 { 0x1430aa00, BTTV_PV143, "Provideo PV143A" }, 216 { 0x1430aa00, BTTV_BOARD_PV143, "Provideo PV143A" },
216 { 0x1431aa00, BTTV_PV143, "Provideo PV143B" }, 217 { 0x1431aa00, BTTV_BOARD_PV143, "Provideo PV143B" },
217 { 0x1432aa00, BTTV_PV143, "Provideo PV143C" }, 218 { 0x1432aa00, BTTV_BOARD_PV143, "Provideo PV143C" },
218 { 0x1433aa00, BTTV_PV143, "Provideo PV143D" }, 219 { 0x1433aa00, BTTV_BOARD_PV143, "Provideo PV143D" },
219 { 0x1433aa03, BTTV_PV143, "Security Eyes" }, 220 { 0x1433aa03, BTTV_BOARD_PV143, "Security Eyes" },
220 221
221 { 0x1460aa00, BTTV_PV150, "Provideo PV150A-1" }, 222 { 0x1460aa00, BTTV_BOARD_PV150, "Provideo PV150A-1" },
222 { 0x1461aa01, BTTV_PV150, "Provideo PV150A-2" }, 223 { 0x1461aa01, BTTV_BOARD_PV150, "Provideo PV150A-2" },
223 { 0x1462aa02, BTTV_PV150, "Provideo PV150A-3" }, 224 { 0x1462aa02, BTTV_BOARD_PV150, "Provideo PV150A-3" },
224 { 0x1463aa03, BTTV_PV150, "Provideo PV150A-4" }, 225 { 0x1463aa03, BTTV_BOARD_PV150, "Provideo PV150A-4" },
225 226
226 { 0x1464aa04, BTTV_PV150, "Provideo PV150B-1" }, 227 { 0x1464aa04, BTTV_BOARD_PV150, "Provideo PV150B-1" },
227 { 0x1465aa05, BTTV_PV150, "Provideo PV150B-2" }, 228 { 0x1465aa05, BTTV_BOARD_PV150, "Provideo PV150B-2" },
228 { 0x1466aa06, BTTV_PV150, "Provideo PV150B-3" }, 229 { 0x1466aa06, BTTV_BOARD_PV150, "Provideo PV150B-3" },
229 { 0x1467aa07, BTTV_PV150, "Provideo PV150B-4" }, 230 { 0x1467aa07, BTTV_BOARD_PV150, "Provideo PV150B-4" },
230 231
231 { 0xa132ff00, BTTV_IVC100, "IVC-100" }, 232 { 0xa132ff00, BTTV_BOARD_IVC100, "IVC-100" },
232 { 0xa1550000, BTTV_IVC200, "IVC-200" }, 233 { 0xa1550000, BTTV_BOARD_IVC200, "IVC-200" },
233 { 0xa1550001, BTTV_IVC200, "IVC-200" }, 234 { 0xa1550001, BTTV_BOARD_IVC200, "IVC-200" },
234 { 0xa1550002, BTTV_IVC200, "IVC-200" }, 235 { 0xa1550002, BTTV_BOARD_IVC200, "IVC-200" },
235 { 0xa1550003, BTTV_IVC200, "IVC-200" }, 236 { 0xa1550003, BTTV_BOARD_IVC200, "IVC-200" },
236 { 0xa1550100, BTTV_IVC200, "IVC-200G" }, 237 { 0xa1550100, BTTV_BOARD_IVC200, "IVC-200G" },
237 { 0xa1550101, BTTV_IVC200, "IVC-200G" }, 238 { 0xa1550101, BTTV_BOARD_IVC200, "IVC-200G" },
238 { 0xa1550102, BTTV_IVC200, "IVC-200G" }, 239 { 0xa1550102, BTTV_BOARD_IVC200, "IVC-200G" },
239 { 0xa1550103, BTTV_IVC200, "IVC-200G" }, 240 { 0xa1550103, BTTV_BOARD_IVC200, "IVC-200G" },
240 { 0xa182ff00, BTTV_IVC120, "IVC-120G" }, 241 { 0xa182ff00, BTTV_BOARD_IVC120, "IVC-120G" },
241 { 0xa182ff01, BTTV_IVC120, "IVC-120G" }, 242 { 0xa182ff01, BTTV_BOARD_IVC120, "IVC-120G" },
242 { 0xa182ff02, BTTV_IVC120, "IVC-120G" }, 243 { 0xa182ff02, BTTV_BOARD_IVC120, "IVC-120G" },
243 { 0xa182ff03, BTTV_IVC120, "IVC-120G" }, 244 { 0xa182ff03, BTTV_BOARD_IVC120, "IVC-120G" },
244 { 0xa182ff04, BTTV_IVC120, "IVC-120G" }, 245 { 0xa182ff04, BTTV_BOARD_IVC120, "IVC-120G" },
245 { 0xa182ff05, BTTV_IVC120, "IVC-120G" }, 246 { 0xa182ff05, BTTV_BOARD_IVC120, "IVC-120G" },
246 { 0xa182ff06, BTTV_IVC120, "IVC-120G" }, 247 { 0xa182ff06, BTTV_BOARD_IVC120, "IVC-120G" },
247 { 0xa182ff07, BTTV_IVC120, "IVC-120G" }, 248 { 0xa182ff07, BTTV_BOARD_IVC120, "IVC-120G" },
248 { 0xa182ff08, BTTV_IVC120, "IVC-120G" }, 249 { 0xa182ff08, BTTV_BOARD_IVC120, "IVC-120G" },
249 { 0xa182ff09, BTTV_IVC120, "IVC-120G" }, 250 { 0xa182ff09, BTTV_BOARD_IVC120, "IVC-120G" },
250 { 0xa182ff0a, BTTV_IVC120, "IVC-120G" }, 251 { 0xa182ff0a, BTTV_BOARD_IVC120, "IVC-120G" },
251 { 0xa182ff0b, BTTV_IVC120, "IVC-120G" }, 252 { 0xa182ff0b, BTTV_BOARD_IVC120, "IVC-120G" },
252 { 0xa182ff0c, BTTV_IVC120, "IVC-120G" }, 253 { 0xa182ff0c, BTTV_BOARD_IVC120, "IVC-120G" },
253 { 0xa182ff0d, BTTV_IVC120, "IVC-120G" }, 254 { 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" },
254 { 0xa182ff0e, BTTV_IVC120, "IVC-120G" }, 255 { 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" },
255 { 0xa182ff0f, BTTV_IVC120, "IVC-120G" }, 256 { 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" },
256 257
257 { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" }, 258 { 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" },
258 { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" }, 259 { 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" },
259 260
260 { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, 261 { 0x18501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
261 { 0xa0501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, 262 { 0xa0501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
262 { 0x18511851, BTTV_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" }, 263 { 0x18511851, BTTV_BOARD_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" },
263 { 0x18521852, BTTV_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" }, 264 { 0x18521852, BTTV_BOARD_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
264 { 0x41a0a051, BTTV_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, 265 { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" },
265 { 0x18501f7f, BTTV_FLYVIDEO_98, "Lifeview Flyvideo 98" }, 266 { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" },
266 267
267 { 0x010115cb, BTTV_GMV1, "AG GMV1" }, 268 { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" },
268 { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, 269 { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
269 270
270 { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" }, 271 { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" },
271 { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 272 { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
272 { 0xfff6f6ff, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 273 { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
273 { 0x03116000, BTTV_SENSORAY311, "Sensoray 311" }, 274 { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" },
274 { 0x00790e11, BTTV_WINDVR, "Canopus WinDVR PCI" }, 275 { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" },
275 { 0xa0fca1a0, BTTV_ZOLTRIX, "Face to Face Tvmax" }, 276 { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" },
276 { 0x20007063, BTTV_PC_HDTV, "pcHDTV HD-2000 TV"}, 277 { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"},
277 { 0x82b2aa6a, BTTV_SIMUS_GVC1100, "SIMUS GVC1100" }, 278 { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" },
278 { 0x146caa0c, BTTV_PV951, "ituner spectra8" }, 279 { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" },
279 { 0x200a1295, BTTV_PXC200, "ImageNation PXC200A" }, 280 { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" },
280 281
281 { 0x40111554, BTTV_PV_BT878P_9B, "Prolink Pixelview PV-BT" }, 282 { 0x40111554, BTTV_BOARD_PV_BT878P_9B, "Prolink Pixelview PV-BT" },
282 { 0x17de0a01, BTTV_KWORLD, "Mecer TV/FM/Video Tuner" }, 283 { 0x17de0a01, BTTV_BOARD_KWORLD, "Mecer TV/FM/Video Tuner" },
283 284
284 { 0x01051805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" }, 285 { 0x01051805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" },
285 { 0x01061805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" }, 286 { 0x01061805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" },
286 { 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" }, 287 { 0x01071805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
287 { 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" }, 288 { 0x01081805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
288 289
289 { 0x15409511, BTTV_ACORP_Y878F, "Acorp Y878F" }, 290 { 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" },
290 291
291 /* likely broken, vendor id doesn't match the other magic views ... 292 /* likely broken, vendor id doesn't match the other magic views ...
292 * { 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ 293 * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
293 294
294 /* DVB cards (using pci function .1 for mpeg data xfer) */ 295 /* DVB cards (using pci function .1 for mpeg data xfer) */
295 { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, 296 { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
296 { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, 297 { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
297 { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" }, 298 { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" },
298 { 0x002611bd, BTTV_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, 299 { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
299 { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB" }, 300 { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" },
300 { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, 301 { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
301 { 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, 302 { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
302 { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, 303 { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
303 { 0xd50018ac, BTTV_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, 304 { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
304 305
305 { 0, -1, NULL } 306 { 0, -1, NULL }
306}; 307};
@@ -309,2116 +310,2494 @@ static struct CARD {
309/* array with description for bt848 / bt878 tv/grabber cards */ 310/* array with description for bt848 / bt878 tv/grabber cards */
310 311
311struct tvcard bttv_tvcards[] = { 312struct tvcard bttv_tvcards[] = {
312{ 313 /* ---- card 0x00 ---------------------------------- */
313/* ---- card 0x00 ---------------------------------- */ 314 [BTTV_BOARD_UNKNOWN] = {
314 .name = " *** UNKNOWN/GENERIC *** ", 315 .name = " *** UNKNOWN/GENERIC *** ",
315 .video_inputs = 4, 316 .video_inputs = 4,
316 .audio_inputs = 1, 317 .audio_inputs = 1,
317 .tuner = 0, 318 .tuner = 0,
318 .svhs = 2, 319 .svhs = 2,
319 .muxsel = { 2, 3, 1, 0}, 320 .muxsel = { 2, 3, 1, 0},
320 .tuner_type = -1, 321 .tuner_type = -1,
321 .tuner_addr = ADDR_UNSET, 322 .tuner_addr = ADDR_UNSET,
322},{ 323 .radio_addr = ADDR_UNSET,
323 .name = "MIRO PCTV", 324 },
324 .video_inputs = 4, 325 [BTTV_BOARD_MIRO] = {
325 .audio_inputs = 1, 326 .name = "MIRO PCTV",
326 .tuner = 0, 327 .video_inputs = 4,
327 .svhs = 2, 328 .audio_inputs = 1,
328 .gpiomask = 15, 329 .tuner = 0,
329 .muxsel = { 2, 3, 1, 1}, 330 .svhs = 2,
330 .audiomux = { 2, 0, 0, 0, 10}, 331 .gpiomask = 15,
331 .needs_tvaudio = 1, 332 .muxsel = { 2, 3, 1, 1},
332 .tuner_type = -1, 333 .audiomux = { 2, 0, 0, 0, 10},
333 .tuner_addr = ADDR_UNSET, 334 .needs_tvaudio = 1,
334},{ 335 .tuner_type = -1,
335 .name = "Hauppauge (bt848)", 336 .tuner_addr = ADDR_UNSET,
336 .video_inputs = 4, 337 .radio_addr = ADDR_UNSET,
337 .audio_inputs = 1, 338 },
338 .tuner = 0, 339 [BTTV_BOARD_HAUPPAUGE] = {
339 .svhs = 2, 340 .name = "Hauppauge (bt848)",
340 .gpiomask = 7, 341 .video_inputs = 4,
341 .muxsel = { 2, 3, 1, 1}, 342 .audio_inputs = 1,
342 .audiomux = { 0, 1, 2, 3, 4}, 343 .tuner = 0,
343 .needs_tvaudio = 1, 344 .svhs = 2,
344 .tuner_type = -1, 345 .gpiomask = 7,
345 .tuner_addr = ADDR_UNSET, 346 .muxsel = { 2, 3, 1, 1},
346},{ 347 .audiomux = { 0, 1, 2, 3, 4},
347 .name = "STB, Gateway P/N 6000699 (bt848)", 348 .needs_tvaudio = 1,
348 .video_inputs = 3, 349 .tuner_type = -1,
349 .audio_inputs = 1, 350 .tuner_addr = ADDR_UNSET,
350 .tuner = 0, 351 .radio_addr = ADDR_UNSET,
351 .svhs = 2, 352 },
352 .gpiomask = 7, 353 [BTTV_BOARD_STB] = {
353 .muxsel = { 2, 3, 1, 1}, 354 .name = "STB, Gateway P/N 6000699 (bt848)",
354 .audiomux = { 4, 0, 2, 3, 1}, 355 .video_inputs = 3,
355 .no_msp34xx = 1, 356 .audio_inputs = 1,
356 .needs_tvaudio = 1, 357 .tuner = 0,
357 .tuner_type = TUNER_PHILIPS_NTSC, 358 .svhs = 2,
358 .tuner_addr = ADDR_UNSET, 359 .gpiomask = 7,
359 .pll = PLL_28, 360 .muxsel = { 2, 3, 1, 1},
360 .has_radio = 1, 361 .audiomux = { 4, 0, 2, 3, 1},
361},{ 362 .no_msp34xx = 1,
362 363 .needs_tvaudio = 1,
363/* ---- card 0x04 ---------------------------------- */ 364 .tuner_type = TUNER_PHILIPS_NTSC,
364 .name = "Intel Create and Share PCI/ Smart Video Recorder III", 365 .tuner_addr = ADDR_UNSET,
365 .video_inputs = 4, 366 .radio_addr = ADDR_UNSET,
366 .audio_inputs = 0, 367 .pll = PLL_28,
367 .tuner = -1, 368 .has_radio = 1,
368 .svhs = 2, 369 },
369 .gpiomask = 0, 370
370 .muxsel = { 2, 3, 1, 1}, 371 /* ---- card 0x04 ---------------------------------- */
371 .audiomux = { 0 }, 372 [BTTV_BOARD_INTEL] = {
372 .needs_tvaudio = 0, 373 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
373 .tuner_type = 4, 374 .video_inputs = 4,
374 .tuner_addr = ADDR_UNSET, 375 .audio_inputs = 0,
375},{ 376 .tuner = -1,
376 .name = "Diamond DTV2000", 377 .svhs = 2,
377 .video_inputs = 4, 378 .gpiomask = 0,
378 .audio_inputs = 1, 379 .muxsel = { 2, 3, 1, 1},
379 .tuner = 0, 380 .audiomux = { 0 },
380 .svhs = 2, 381 .needs_tvaudio = 0,
381 .gpiomask = 3, 382 .tuner_type = 4,
382 .muxsel = { 2, 3, 1, 0}, 383 .tuner_addr = ADDR_UNSET,
383 .audiomux = { 0, 1, 0, 1, 3}, 384 .radio_addr = ADDR_UNSET,
384 .needs_tvaudio = 1, 385 },
385 .tuner_type = -1, 386 [BTTV_BOARD_DIAMOND] = {
386 .tuner_addr = ADDR_UNSET, 387 .name = "Diamond DTV2000",
387},{ 388 .video_inputs = 4,
388 .name = "AVerMedia TVPhone", 389 .audio_inputs = 1,
389 .video_inputs = 3, 390 .tuner = 0,
390 .audio_inputs = 1, 391 .svhs = 2,
391 .tuner = 0, 392 .gpiomask = 3,
392 .svhs = 3, 393 .muxsel = { 2, 3, 1, 0},
393 .muxsel = { 2, 3, 1, 1}, 394 .audiomux = { 0, 1, 0, 1, 3},
394 .gpiomask = 0x0f, 395 .needs_tvaudio = 1,
395 .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0}, 396 .tuner_type = -1,
396 /* 0x04 for some cards ?? */ 397 .tuner_addr = ADDR_UNSET,
397 .needs_tvaudio = 1, 398 .radio_addr = ADDR_UNSET,
398 .tuner_type = -1, 399 },
399 .tuner_addr = ADDR_UNSET, 400 [BTTV_BOARD_AVERMEDIA] = {
400 .audio_hook = avermedia_tvphone_audio, 401 .name = "AVerMedia TVPhone",
401 .has_remote = 1, 402 .video_inputs = 3,
402},{ 403 .audio_inputs = 1,
403 .name = "MATRIX-Vision MV-Delta", 404 .tuner = 0,
404 .video_inputs = 5, 405 .svhs = 3,
405 .audio_inputs = 1, 406 .muxsel = { 2, 3, 1, 1},
406 .tuner = -1, 407 .gpiomask = 0x0f,
407 .svhs = 3, 408 .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0},
408 .gpiomask = 0, 409 /* 0x04 for some cards ?? */
409 .muxsel = { 2, 3, 1, 0, 0}, 410 .needs_tvaudio = 1,
410 .audiomux = {0 }, 411 .tuner_type = -1,
411 .needs_tvaudio = 1, 412 .tuner_addr = ADDR_UNSET,
412 .tuner_type = -1, 413 .radio_addr = ADDR_UNSET,
413 .tuner_addr = ADDR_UNSET, 414 .audio_hook = avermedia_tvphone_audio,
414},{ 415 .has_remote = 1,
415 416 },
416/* ---- card 0x08 ---------------------------------- */ 417 [BTTV_BOARD_MATRIX_VISION] = {
417 .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26", 418 .name = "MATRIX-Vision MV-Delta",
418 .video_inputs = 4, 419 .video_inputs = 5,
419 .audio_inputs = 1, 420 .audio_inputs = 1,
420 .tuner = 0, 421 .tuner = -1,
421 .svhs = 2, 422 .svhs = 3,
422 .gpiomask = 0xc00, 423 .gpiomask = 0,
423 .muxsel = { 2, 3, 1, 1}, 424 .muxsel = { 2, 3, 1, 0, 0},
424 .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0}, 425 .audiomux = {0 },
425 .needs_tvaudio = 1, 426 .needs_tvaudio = 1,
426 .pll = PLL_28, 427 .tuner_type = -1,
427 .tuner_type = -1, 428 .tuner_addr = ADDR_UNSET,
428 .tuner_addr = ADDR_UNSET, 429 .radio_addr = ADDR_UNSET,
429},{ 430 },
430 .name = "IMS/IXmicro TurboTV", 431
431 .video_inputs = 3, 432 /* ---- card 0x08 ---------------------------------- */
432 .audio_inputs = 1, 433 [BTTV_BOARD_FLYVIDEO] = {
433 .tuner = 0, 434 .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
434 .svhs = 2, 435 .video_inputs = 4,
435 .gpiomask = 3, 436 .audio_inputs = 1,
436 .muxsel = { 2, 3, 1, 1}, 437 .tuner = 0,
437 .audiomux = { 1, 1, 2, 3, 0}, 438 .svhs = 2,
438 .needs_tvaudio = 0, 439 .gpiomask = 0xc00,
439 .pll = PLL_28, 440 .muxsel = { 2, 3, 1, 1},
440 .tuner_type = TUNER_TEMIC_PAL, 441 .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0},
441 .tuner_addr = ADDR_UNSET, 442 .needs_tvaudio = 1,
442},{ 443 .pll = PLL_28,
443 .name = "Hauppauge (bt878)", 444 .tuner_type = -1,
444 .video_inputs = 4, 445 .tuner_addr = ADDR_UNSET,
445 .audio_inputs = 1, 446 .radio_addr = ADDR_UNSET,
446 .tuner = 0, 447 },
447 .svhs = 2, 448 [BTTV_BOARD_TURBOTV] = {
448 .gpiomask = 0x0f, /* old: 7 */ 449 .name = "IMS/IXmicro TurboTV",
449 .muxsel = { 2, 0, 1, 1}, 450 .video_inputs = 3,
450 .audiomux = { 0, 1, 2, 3, 4}, 451 .audio_inputs = 1,
451 .needs_tvaudio = 1, 452 .tuner = 0,
452 .pll = PLL_28, 453 .svhs = 2,
453 .tuner_type = -1, 454 .gpiomask = 3,
454 .tuner_addr = ADDR_UNSET, 455 .muxsel = { 2, 3, 1, 1},
455},{ 456 .audiomux = { 1, 1, 2, 3, 0},
456 .name = "MIRO PCTV pro", 457 .needs_tvaudio = 0,
457 .video_inputs = 3, 458 .pll = PLL_28,
458 .audio_inputs = 1, 459 .tuner_type = TUNER_TEMIC_PAL,
459 .tuner = 0, 460 .tuner_addr = ADDR_UNSET,
460 .svhs = 2, 461 .radio_addr = ADDR_UNSET,
461 .gpiomask = 0x3014f, 462 },
462 .muxsel = { 2, 3, 1, 1}, 463 [BTTV_BOARD_HAUPPAUGE878] = {
463 .audiomux = { 0x20001,0x10001, 0, 0,10}, 464 .name = "Hauppauge (bt878)",
464 .needs_tvaudio = 1, 465 .video_inputs = 4,
465 .tuner_type = -1, 466 .audio_inputs = 1,
466 .tuner_addr = ADDR_UNSET, 467 .tuner = 0,
467},{ 468 .svhs = 2,
468 469 .gpiomask = 0x0f, /* old: 7 */
469/* ---- card 0x0c ---------------------------------- */ 470 .muxsel = { 2, 0, 1, 1},
470 .name = "ADS Technologies Channel Surfer TV (bt848)", 471 .audiomux = { 0, 1, 2, 3, 4},
471 .video_inputs = 3, 472 .needs_tvaudio = 1,
472 .audio_inputs = 1, 473 .pll = PLL_28,
473 .tuner = 0, 474 .tuner_type = -1,
474 .svhs = 2, 475 .tuner_addr = ADDR_UNSET,
475 .gpiomask = 15, 476 .radio_addr = ADDR_UNSET,
476 .muxsel = { 2, 3, 1, 1}, 477 },
477 .audiomux = { 13, 14, 11, 7, 0, 0}, 478 [BTTV_BOARD_MIROPRO] = {
478 .needs_tvaudio = 1, 479 .name = "MIRO PCTV pro",
479 .tuner_type = -1, 480 .video_inputs = 3,
480 .tuner_addr = ADDR_UNSET, 481 .audio_inputs = 1,
481},{ 482 .tuner = 0,
482 .name = "AVerMedia TVCapture 98", 483 .svhs = 2,
483 .video_inputs = 3, 484 .gpiomask = 0x3014f,
484 .audio_inputs = 4, 485 .muxsel = { 2, 3, 1, 1},
485 .tuner = 0, 486 .audiomux = { 0x20001,0x10001, 0, 0,10},
486 .svhs = 2, 487 .needs_tvaudio = 1,
487 .gpiomask = 15, 488 .tuner_type = -1,
488 .muxsel = { 2, 3, 1, 1}, 489 .tuner_addr = ADDR_UNSET,
489 .audiomux = { 13, 14, 11, 7, 0, 0}, 490 .radio_addr = ADDR_UNSET,
490 .needs_tvaudio = 1, 491 },
491 .msp34xx_alt = 1, 492
492 .pll = PLL_28, 493 /* ---- card 0x0c ---------------------------------- */
493 .tuner_type = TUNER_PHILIPS_PAL, 494 [BTTV_BOARD_ADSTECH_TV] = {
494 .tuner_addr = ADDR_UNSET, 495 .name = "ADS Technologies Channel Surfer TV (bt848)",
495 .audio_hook = avermedia_tv_stereo_audio, 496 .video_inputs = 3,
496},{ 497 .audio_inputs = 1,
497 .name = "Aimslab Video Highway Xtreme (VHX)", 498 .tuner = 0,
498 .video_inputs = 3, 499 .svhs = 2,
499 .audio_inputs = 1, 500 .gpiomask = 15,
500 .tuner = 0, 501 .muxsel = { 2, 3, 1, 1},
501 .svhs = 2, 502 .audiomux = { 13, 14, 11, 7, 0, 0},
502 .gpiomask = 7, 503 .needs_tvaudio = 1,
503 .muxsel = { 2, 3, 1, 1}, 504 .tuner_type = -1,
504 .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */ 505 .tuner_addr = ADDR_UNSET,
505 .needs_tvaudio = 1, 506 .radio_addr = ADDR_UNSET,
506 .pll = PLL_28, 507 },
507 .tuner_type = -1, 508 [BTTV_BOARD_AVERMEDIA98] = {
508 .tuner_addr = ADDR_UNSET, 509 .name = "AVerMedia TVCapture 98",
509},{ 510 .video_inputs = 3,
510 .name = "Zoltrix TV-Max", 511 .audio_inputs = 4,
511 .video_inputs = 3, 512 .tuner = 0,
512 .audio_inputs = 1, 513 .svhs = 2,
513 .tuner = 0, 514 .gpiomask = 15,
514 .svhs = 2, 515 .muxsel = { 2, 3, 1, 1},
515 .gpiomask = 15, 516 .audiomux = { 13, 14, 11, 7, 0, 0},
516 .muxsel = { 2, 3, 1, 1}, 517 .needs_tvaudio = 1,
517 .audiomux = {0 , 0, 1 , 0, 10}, 518 .msp34xx_alt = 1,
518 .needs_tvaudio = 1, 519 .pll = PLL_28,
519 .tuner_type = -1, 520 .tuner_type = TUNER_PHILIPS_PAL,
520 .tuner_addr = ADDR_UNSET, 521 .tuner_addr = ADDR_UNSET,
521},{ 522 .radio_addr = ADDR_UNSET,
522 523 .audio_hook = avermedia_tv_stereo_audio,
523/* ---- card 0x10 ---------------------------------- */ 524 .no_gpioirq = 1,
524 .name = "Prolink Pixelview PlayTV (bt878)", 525 },
525 .video_inputs = 3, 526 [BTTV_BOARD_VHX] = {
526 .audio_inputs = 1, 527 .name = "Aimslab Video Highway Xtreme (VHX)",
527 .tuner = 0, 528 .video_inputs = 3,
528 .svhs = 2, 529 .audio_inputs = 1,
529 .gpiomask = 0x01fe00, 530 .tuner = 0,
530 .muxsel = { 2, 3, 1, 1}, 531 .svhs = 2,
531 /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */ 532 .gpiomask = 7,
532 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, 533 .muxsel = { 2, 3, 1, 1},
533 .needs_tvaudio = 1, 534 .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */
534 .pll = PLL_28, 535 .needs_tvaudio = 1,
535 .tuner_type = -1, 536 .pll = PLL_28,
536},{ 537 .tuner_type = -1,
537 .name = "Leadtek WinView 601", 538 .tuner_addr = ADDR_UNSET,
538 .video_inputs = 3, 539 .radio_addr = ADDR_UNSET,
539 .audio_inputs = 1, 540 },
540 .tuner = 0, 541 [BTTV_BOARD_ZOLTRIX] = {
541 .svhs = 2, 542 .name = "Zoltrix TV-Max",
542 .gpiomask = 0x8300f8, 543 .video_inputs = 3,
543 .muxsel = { 2, 3, 1, 1,0}, 544 .audio_inputs = 1,
544 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}, 545 .tuner = 0,
545 .needs_tvaudio = 1, 546 .svhs = 2,
546 .tuner_type = -1, 547 .gpiomask = 15,
547 .tuner_addr = ADDR_UNSET, 548 .muxsel = { 2, 3, 1, 1},
548 .audio_hook = winview_audio, 549 .audiomux = {0 , 0, 1 , 0, 10},
549 .has_radio = 1, 550 .needs_tvaudio = 1,
550},{ 551 .tuner_type = -1,
551 .name = "AVEC Intercapture", 552 .tuner_addr = ADDR_UNSET,
552 .video_inputs = 3, 553 .radio_addr = ADDR_UNSET,
553 .audio_inputs = 2, 554 },
554 .tuner = 0, 555
555 .svhs = 2, 556 /* ---- card 0x10 ---------------------------------- */
556 .gpiomask = 0, 557 [BTTV_BOARD_PIXVIEWPLAYTV] = {
557 .muxsel = {2, 3, 1, 1}, 558 .name = "Prolink Pixelview PlayTV (bt878)",
558 .audiomux = {1, 0, 0, 0, 0}, 559 .video_inputs = 3,
559 .needs_tvaudio = 1, 560 .audio_inputs = 1,
560 .tuner_type = -1, 561 .tuner = 0,
561 .tuner_addr = ADDR_UNSET, 562 .svhs = 2,
562},{ 563 .gpiomask = 0x01fe00,
563 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", 564 .muxsel = { 2, 3, 1, 1},
564 .video_inputs = 4, 565 #if 0
565 .audio_inputs = 1, 566 /* old */
566 .tuner = -1, 567 .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },
567 .svhs = -1, 568 #else
568 .gpiomask = 0x8dff00, 569 /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
569 .muxsel = { 2, 3, 1, 1}, 570 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
570 .audiomux = { 0 }, 571 #endif
571 .no_msp34xx = 1, 572 .needs_tvaudio = 1,
572 .tuner_type = -1, 573 .pll = PLL_28,
573 .tuner_addr = ADDR_UNSET, 574 .tuner_type = -1,
574},{ 575 },
575 576 [BTTV_BOARD_WINVIEW_601] = {
576/* ---- card 0x14 ---------------------------------- */ 577 .name = "Leadtek WinView 601",
577 .name = "CEI Raffles Card", 578 .video_inputs = 3,
578 .video_inputs = 3, 579 .audio_inputs = 1,
579 .audio_inputs = 3, 580 .tuner = 0,
580 .tuner = 0, 581 .svhs = 2,
581 .svhs = 2, 582 .gpiomask = 0x8300f8,
582 .muxsel = {2, 3, 1, 1}, 583 .muxsel = { 2, 3, 1, 1,0},
583 .tuner_type = -1, 584 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
584 .tuner_addr = ADDR_UNSET, 585 .needs_tvaudio = 1,
585},{ 586 .tuner_type = -1,
586 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", 587 .tuner_addr = ADDR_UNSET,
587 .video_inputs = 4, 588 .radio_addr = ADDR_UNSET,
588 .audio_inputs = 2, /* tuner, line in */ 589 .audio_hook = winview_audio,
589 .tuner = 0, 590 .has_radio = 1,
590 .svhs = 2, 591 },
591 .gpiomask = 0x1800, 592 [BTTV_BOARD_AVEC_INTERCAP] = {
592 .muxsel = { 2, 3, 1, 1}, 593 .name = "AVEC Intercapture",
593 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, 594 .video_inputs = 3,
594 .pll = PLL_28, 595 .audio_inputs = 2,
595 .tuner_type = TUNER_PHILIPS_PAL_I, 596 .tuner = 0,
596 .tuner_addr = ADDR_UNSET, 597 .svhs = 2,
597},{ 598 .gpiomask = 0,
598 .name = "Askey CPH050/ Phoebe Tv Master + FM", 599 .muxsel = {2, 3, 1, 1},
599 .video_inputs = 3, 600 .audiomux = {1, 0, 0, 0, 0},
600 .audio_inputs = 1, 601 .needs_tvaudio = 1,
601 .tuner = 0, 602 .tuner_type = -1,
602 .svhs = 2, 603 .tuner_addr = ADDR_UNSET,
603 .gpiomask = 0xc00, 604 .radio_addr = ADDR_UNSET,
604 .muxsel = { 2, 3, 1, 1}, 605 },
605 .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0}, 606 [BTTV_BOARD_LIFE_FLYKIT] = {
606 .needs_tvaudio = 1, 607 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
607 .pll = PLL_28, 608 .video_inputs = 4,
608 .tuner_type = -1, 609 .audio_inputs = 1,
609 .tuner_addr = ADDR_UNSET, 610 .tuner = -1,
610},{ 611 .svhs = -1,
611 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878", 612 .gpiomask = 0x8dff00,
612 .video_inputs = 3, 613 .muxsel = { 2, 3, 1, 1},
613 .audio_inputs = 1, 614 .audiomux = { 0 },
614 .tuner = 0, 615 .no_msp34xx = 1,
615 .svhs = -1, 616 .tuner_type = -1,
616 .gpiomask = 7, 617 .tuner_addr = ADDR_UNSET,
617 .muxsel = { 2, 3, -1 }, 618 .radio_addr = ADDR_UNSET,
618 .digital_mode = DIGITAL_MODE_CAMERA, 619 },
619 .audiomux = { 0, 0, 0, 0, 0 }, 620
620 .no_msp34xx = 1, 621 /* ---- card 0x14 ---------------------------------- */
621 .pll = PLL_28, 622 [BTTV_BOARD_CEI_RAFFLES] = {
622 .tuner_type = TUNER_ALPS_TSBB5_PAL_I, 623 .name = "CEI Raffles Card",
623 .tuner_addr = ADDR_UNSET, 624 .video_inputs = 3,
624},{ 625 .audio_inputs = 3,
625 626 .tuner = 0,
626/* ---- card 0x18 ---------------------------------- */ 627 .svhs = 2,
627 .name = "Askey CPH05X/06X (bt878) [many vendors]", 628 .muxsel = {2, 3, 1, 1},
628 .video_inputs = 3, 629 .tuner_type = -1,
629 .audio_inputs = 1, 630 .tuner_addr = ADDR_UNSET,
630 .tuner = 0, 631 .radio_addr = ADDR_UNSET,
631 .svhs = 2, 632 },
632 .gpiomask = 0xe00, 633 [BTTV_BOARD_CONFERENCETV] = {
633 .muxsel = { 2, 3, 1, 1}, 634 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
634 .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00}, 635 .video_inputs = 4,
635 .needs_tvaudio = 1, 636 .audio_inputs = 2, /* tuner, line in */
636 .pll = PLL_28, 637 .tuner = 0,
637 .tuner_type = -1, 638 .svhs = 2,
638 .tuner_addr = ADDR_UNSET, 639 .gpiomask = 0x1800,
639 .has_remote = 1, 640 .muxsel = { 2, 3, 1, 1},
640},{ 641 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
641 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", 642 .pll = PLL_28,
642 .video_inputs = 3, 643 .tuner_type = TUNER_PHILIPS_PAL_I,
643 .audio_inputs = 1, 644 .tuner_addr = ADDR_UNSET,
644 .tuner = 0, 645 .radio_addr = ADDR_UNSET,
645 .svhs = 2, 646 },
646 .gpiomask = 0x1f0fff, 647 [BTTV_BOARD_PHOEBE_TVMAS] = {
647 .muxsel = { 2, 3, 1, 1}, 648 .name = "Askey CPH050/ Phoebe Tv Master + FM",
648 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000}, 649 .video_inputs = 3,
649 .needs_tvaudio = 0, 650 .audio_inputs = 1,
650 .tuner_type = TUNER_PHILIPS_PAL, 651 .tuner = 0,
651 .tuner_addr = ADDR_UNSET, 652 .svhs = 2,
652 .audio_hook = terratv_audio, 653 .gpiomask = 0xc00,
653},{ 654 .muxsel = { 2, 3, 1, 1},
654 .name = "Hauppauge WinCam newer (bt878)", 655 .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0},
655 .video_inputs = 4, 656 .needs_tvaudio = 1,
656 .audio_inputs = 1, 657 .pll = PLL_28,
657 .tuner = 0, 658 .tuner_type = -1,
658 .svhs = 3, 659 .tuner_addr = ADDR_UNSET,
659 .gpiomask = 7, 660 .radio_addr = ADDR_UNSET,
660 .muxsel = { 2, 0, 1, 1}, 661 },
661 .audiomux = { 0, 1, 2, 3, 4}, 662 [BTTV_BOARD_MODTEC_205] = {
662 .needs_tvaudio = 1, 663 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
663 .tuner_type = -1, 664 .video_inputs = 3,
664 .tuner_addr = ADDR_UNSET, 665 .audio_inputs = 1,
665},{ 666 .tuner = 0,
666 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", 667 .svhs = -1,
667 .video_inputs = 4, 668 .gpiomask = 7,
668 .audio_inputs = 2, 669 .muxsel = { 2, 3, -1 },
669 .tuner = 0, 670 .digital_mode = DIGITAL_MODE_CAMERA,
670 .svhs = 2, 671 .audiomux = { 0, 0, 0, 0, 0 },
671 .gpiomask = 0x1800, 672 .no_msp34xx = 1,
672 .muxsel = { 2, 3, 1, 1}, 673 .pll = PLL_28,
673 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, 674 .tuner_type = TUNER_ALPS_TSBB5_PAL_I,
674 .pll = PLL_28, 675 .tuner_addr = ADDR_UNSET,
675 .tuner_type = TUNER_PHILIPS_SECAM, 676 .radio_addr = ADDR_UNSET,
676 .tuner_addr = ADDR_UNSET, 677 },
677},{ 678
678 679 /* ---- card 0x18 ---------------------------------- */
679/* ---- card 0x1c ---------------------------------- */ 680 [BTTV_BOARD_MAGICTVIEW061] = {
680 .name = "Terratec TerraTV+ Version 1.1 (bt878)", 681 .name = "Askey CPH05X/06X (bt878) [many vendors]",
681 .video_inputs = 3, 682 .video_inputs = 3,
682 .audio_inputs = 1, 683 .audio_inputs = 1,
683 .tuner = 0, 684 .tuner = 0,
684 .svhs = 2, 685 .svhs = 2,
685 .gpiomask = 0x1f0fff, 686 .gpiomask = 0xe00,
686 .muxsel = { 2, 3, 1, 1}, 687 .muxsel = { 2, 3, 1, 1},
687 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000}, 688 .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00},
688 .needs_tvaudio = 0, 689 .needs_tvaudio = 1,
689 .tuner_type = TUNER_PHILIPS_PAL, 690 .pll = PLL_28,
690 .tuner_addr = ADDR_UNSET, 691 .tuner_type = -1,
691 .audio_hook = terratv_audio, 692 .tuner_addr = ADDR_UNSET,
692 /* GPIO wiring: 693 .radio_addr = ADDR_UNSET,
693 External 20 pin connector (for Active Radio Upgrade board) 694 .has_remote = 1,
694 gpio00: i2c-sda 695 },
695 gpio01: i2c-scl 696 [BTTV_BOARD_VOBIS_BOOSTAR] = {
696 gpio02: om5610-data 697 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
697 gpio03: om5610-clk 698 .video_inputs = 3,
698 gpio04: om5610-wre 699 .audio_inputs = 1,
699 gpio05: om5610-stereo 700 .tuner = 0,
700 gpio06: rds6588-davn 701 .svhs = 2,
701 gpio07: Pin 7 n.c. 702 .gpiomask = 0x1f0fff,
702 gpio08: nIOW 703 .muxsel = { 2, 3, 1, 1},
703 gpio09+10: nIOR, nSEL ?? (bt878) 704 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000},
704 gpio09: nIOR (bt848) 705 .needs_tvaudio = 0,
705 gpio10: nSEL (bt848) 706 .tuner_type = TUNER_PHILIPS_PAL,
706 Sound Routing: 707 .tuner_addr = ADDR_UNSET,
707 gpio16: u2-A0 (1st 4052bt) 708 .radio_addr = ADDR_UNSET,
708 gpio17: u2-A1 709 .audio_hook = terratv_audio,
709 gpio18: u2-nEN 710 },
710 gpio19: u4-A0 (2nd 4052) 711 [BTTV_BOARD_HAUPPAUG_WCAM] = {
711 gpio20: u4-A1 712 .name = "Hauppauge WinCam newer (bt878)",
712 u4-nEN - GND 713 .video_inputs = 4,
713 Btspy: 714 .audio_inputs = 1,
714 00000 : Cdrom (internal audio input) 715 .tuner = 0,
715 10000 : ext. Video audio input 716 .svhs = 3,
716 20000 : TV Mono 717 .gpiomask = 7,
717 a0000 : TV Mono/2 718 .muxsel = { 2, 0, 1, 1},
718 1a0000 : TV Stereo 719 .audiomux = { 0, 1, 2, 3, 4},
719 30000 : Radio 720 .needs_tvaudio = 1,
720 40000 : Mute 721 .tuner_type = -1,
721*/ 722 .tuner_addr = ADDR_UNSET,
722 723 .radio_addr = ADDR_UNSET,
723},{ 724 },
724 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */ 725 [BTTV_BOARD_MAXI] = {
725 .name = "Imagenation PXC200", 726 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
726 .video_inputs = 5, 727 .video_inputs = 4,
727 .audio_inputs = 1, 728 .audio_inputs = 2,
728 .tuner = -1, 729 .tuner = 0,
729 .svhs = 1, /* was: 4 */ 730 .svhs = 2,
730 .gpiomask = 0, 731 .gpiomask = 0x1800,
731 .muxsel = { 2, 3, 1, 0, 0}, 732 .muxsel = { 2, 3, 1, 1},
732 .audiomux = { 0 }, 733 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
733 .needs_tvaudio = 1, 734 .pll = PLL_28,
734 .tuner_type = -1, 735 .tuner_type = TUNER_PHILIPS_SECAM,
735 .tuner_addr = ADDR_UNSET, 736 .tuner_addr = ADDR_UNSET,
736 .muxsel_hook = PXC200_muxsel, 737 .radio_addr = ADDR_UNSET,
737 738 },
738},{ 739
739 .name = "Lifeview FlyVideo 98 LR50", 740 /* ---- card 0x1c ---------------------------------- */
740 .video_inputs = 4, 741 [BTTV_BOARD_TERRATV] = {
741 .audio_inputs = 1, 742 .name = "Terratec TerraTV+ Version 1.1 (bt878)",
742 .tuner = 0, 743 .video_inputs = 3,
743 .svhs = 2, 744 .audio_inputs = 1,
744 .gpiomask = 0x1800, /* 0x8dfe00 */ 745 .tuner = 0,
745 .muxsel = { 2, 3, 1, 1}, 746 .svhs = 2,
746 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 }, 747 .gpiomask = 0x1f0fff,
747 .pll = PLL_28, 748 .muxsel = { 2, 3, 1, 1},
748 .tuner_type = -1, 749 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
749 .tuner_addr = ADDR_UNSET, 750 .needs_tvaudio = 0,
750},{ 751 .tuner_type = TUNER_PHILIPS_PAL,
751 .name = "Formac iProTV, Formac ProTV I (bt848)", 752 .tuner_addr = ADDR_UNSET,
752 .video_inputs = 4, 753 .radio_addr = ADDR_UNSET,
753 .audio_inputs = 1, 754 .audio_hook = terratv_audio,
754 .tuner = 0, 755 /* GPIO wiring:
755 .svhs = 3, 756 External 20 pin connector (for Active Radio Upgrade board)
756 .gpiomask = 1, 757 gpio00: i2c-sda
757 .muxsel = { 2, 3, 1, 1}, 758 gpio01: i2c-scl
758 .audiomux = { 1, 0, 0, 0, 0 }, 759 gpio02: om5610-data
759 .pll = PLL_28, 760 gpio03: om5610-clk
760 .tuner_type = TUNER_PHILIPS_PAL, 761 gpio04: om5610-wre
761 .tuner_addr = ADDR_UNSET, 762 gpio05: om5610-stereo
762},{ 763 gpio06: rds6588-davn
763 764 gpio07: Pin 7 n.c.
764/* ---- card 0x20 ---------------------------------- */ 765 gpio08: nIOW
765 .name = "Intel Create and Share PCI/ Smart Video Recorder III", 766 gpio09+10: nIOR, nSEL ?? (bt878)
766 .video_inputs = 4, 767 gpio09: nIOR (bt848)
767 .audio_inputs = 0, 768 gpio10: nSEL (bt848)
768 .tuner = -1, 769 Sound Routing:
769 .svhs = 2, 770 gpio16: u2-A0 (1st 4052bt)
770 .gpiomask = 0, 771 gpio17: u2-A1
771 .muxsel = { 2, 3, 1, 1}, 772 gpio18: u2-nEN
772 .audiomux = { 0 }, 773 gpio19: u4-A0 (2nd 4052)
773 .needs_tvaudio = 0, 774 gpio20: u4-A1
774 .tuner_type = 4, 775 u4-nEN - GND
775 .tuner_addr = ADDR_UNSET, 776 Btspy:
776},{ 777 00000 : Cdrom (internal audio input)
777 .name = "Terratec TerraTValue Version Bt878", 778 10000 : ext. Video audio input
778 .video_inputs = 3, 779 20000 : TV Mono
779 .audio_inputs = 1, 780 a0000 : TV Mono/2
780 .tuner = 0, 781 1a0000 : TV Stereo
781 .svhs = 2, 782 30000 : Radio
782 .gpiomask = 0xffff00, 783 40000 : Mute
783 .muxsel = { 2, 3, 1, 1},
784 .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
785 .needs_tvaudio = 1,
786 .pll = PLL_28,
787 .tuner_type = TUNER_PHILIPS_PAL,
788 .tuner_addr = ADDR_UNSET,
789},{
790 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
791 .video_inputs = 4,
792 .audio_inputs = 1,
793 .tuner = 0,
794 .svhs = 2,
795 .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
796 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
797 .gpiomask = 0xb33000,
798 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
799 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
800 gpio23 -- hef4052:nEnable (0x800000)
801 gpio12 -- hef4052:A1
802 gpio13 -- hef4052:A0
803 0x0000: external audio
804 0x1000: FM
805 0x2000: TV
806 0x3000: n.c.
807 Note: There exists another variant "Winfast 2000" with tv stereo !?
808 Note: eeprom only contains FF and pci subsystem id 107d:6606
809 */
810 .needs_tvaudio = 0,
811 .pll = PLL_28,
812 .has_radio = 1,
813 .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
814 .tuner_addr = ADDR_UNSET,
815 .audio_hook = winfast2000_audio,
816 .has_remote = 1,
817},{
818 .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
819 .video_inputs = 4,
820 .audio_inputs = 3,
821 .tuner = 0,
822 .svhs = 2,
823 .gpiomask = 0x1800,
824 .muxsel = { 2, 3, 1, 1},
825 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
826 .pll = PLL_28,
827 .tuner_type = -1,
828 .tuner_addr = ADDR_UNSET,
829},{
830
831/* ---- card 0x24 ---------------------------------- */
832 .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
833 .video_inputs = 4,
834 .audio_inputs = 3,
835 .tuner = 0,
836 .svhs = 2,
837 .gpiomask = 0x1800,
838 .muxsel = { 2, 3, 1, 1},
839 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
840 .pll = PLL_28,
841 .tuner_type = -1,
842 .tuner_addr = ADDR_UNSET,
843 .has_radio = 1,
844},{
845 .name = "Prolink PixelView PlayTV pro",
846 .video_inputs = 3,
847 .audio_inputs = 1,
848 .tuner = 0,
849 .svhs = 2,
850 .gpiomask = 0xff,
851 .muxsel = { 2, 3, 1, 1 },
852 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
853 .no_msp34xx = 1,
854 .pll = PLL_28,
855 .tuner_type = -1,
856 .tuner_addr = ADDR_UNSET,
857},{
858 .name = "Askey CPH06X TView99",
859 .video_inputs = 4,
860 .audio_inputs = 1,
861 .tuner = 0,
862 .svhs = 2,
863 .gpiomask = 0x551e00,
864 .muxsel = { 2, 3, 1, 0},
865 .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
866 .needs_tvaudio = 1,
867 .pll = PLL_28,
868 .tuner_type = 1,
869 .tuner_addr = ADDR_UNSET,
870 .has_remote = 1,
871},{
872 .name = "Pinnacle PCTV Studio/Rave",
873 .video_inputs = 3,
874 .audio_inputs = 1,
875 .tuner = 0,
876 .svhs = 2,
877 .gpiomask = 0x03000F,
878 .muxsel = { 2, 3, 1, 1},
879 .audiomux = { 2, 0xd0001, 0, 0, 1},
880 .needs_tvaudio = 0,
881 .pll = PLL_28,
882 .tuner_type = -1,
883 .tuner_addr = ADDR_UNSET,
884},{
885
886/* ---- card 0x28 ---------------------------------- */
887 .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
888 .video_inputs = 3,
889 .audio_inputs = 1,
890 .tuner = 0,
891 .svhs = 2,
892 .gpiomask = 7,
893 .muxsel = { 2, 3, 1, 1},
894 .audiomux = { 4, 0, 2, 3, 1},
895 .no_msp34xx = 1,
896 .needs_tvaudio = 1,
897 .tuner_type = TUNER_PHILIPS_NTSC,
898 .tuner_addr = ADDR_UNSET,
899 .pll = PLL_28,
900 .has_radio = 1,
901},{
902 .name = "AVerMedia TVPhone 98",
903 .video_inputs = 3,
904 .audio_inputs = 4,
905 .tuner = 0,
906 .svhs = 2,
907 .gpiomask = 15,
908 .muxsel = { 2, 3, 1, 1},
909 .audiomux = { 13, 4, 11, 7, 0, 0},
910 .needs_tvaudio = 1,
911 .pll = PLL_28,
912 .tuner_type = -1,
913 .tuner_addr = ADDR_UNSET,
914 .has_radio = 1,
915 .audio_hook = avermedia_tvphone_audio,
916},{
917 .name = "ProVideo PV951", /* pic16c54 */
918 .video_inputs = 3,
919 .audio_inputs = 1,
920 .tuner = 0,
921 .svhs = 2,
922 .gpiomask = 0,
923 .muxsel = { 2, 3, 1, 1},
924 .audiomux = { 0, 0, 0, 0, 0},
925 .needs_tvaudio = 1,
926 .no_msp34xx = 1,
927 .pll = PLL_28,
928 .tuner_type = 1,
929 .tuner_addr = ADDR_UNSET,
930},{
931 .name = "Little OnAir TV",
932 .video_inputs = 3,
933 .audio_inputs = 1,
934 .tuner = 0,
935 .svhs = 2,
936 .gpiomask = 0xe00b,
937 .muxsel = {2, 3, 1, 1},
938 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
939 .no_msp34xx = 1,
940 .tuner_type = -1,
941 .tuner_addr = ADDR_UNSET,
942},{
943
944/* ---- card 0x2c ---------------------------------- */
945 .name = "Sigma TVII-FM",
946 .video_inputs = 2,
947 .audio_inputs = 1,
948 .tuner = 0,
949 .svhs = -1,
950 .gpiomask = 3,
951 .muxsel = {2, 3, 1, 1},
952 .audiomux = {1, 1, 0, 2, 3},
953 .no_msp34xx = 1,
954 .pll = PLL_NONE,
955 .tuner_type = -1,
956 .tuner_addr = ADDR_UNSET,
957},{
958 .name = "MATRIX-Vision MV-Delta 2",
959 .video_inputs = 5,
960 .audio_inputs = 1,
961 .tuner = -1,
962 .svhs = 3,
963 .gpiomask = 0,
964 .muxsel = { 2, 3, 1, 0, 0},
965 .audiomux = {0 },
966 .no_msp34xx = 1,
967 .pll = PLL_28,
968 .tuner_type = -1,
969 .tuner_addr = ADDR_UNSET,
970},{
971 .name = "Zoltrix Genie TV/FM",
972 .video_inputs = 3,
973 .audio_inputs = 1,
974 .tuner = 0,
975 .svhs = 2,
976 .gpiomask = 0xbcf03f,
977 .muxsel = { 2, 3, 1, 1},
978 .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
979 .no_msp34xx = 1,
980 .pll = PLL_28,
981 .tuner_type = 21,
982 .tuner_addr = ADDR_UNSET,
983},{
984 .name = "Terratec TV/Radio+",
985 .video_inputs = 3,
986 .audio_inputs = 1,
987 .tuner = 0,
988 .svhs = 2,
989 .gpiomask = 0x70000,
990 .muxsel = { 2, 3, 1, 1},
991 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
992 .needs_tvaudio = 1,
993 .no_msp34xx = 1,
994 .pll = PLL_35,
995 .tuner_type = 1,
996 .tuner_addr = ADDR_UNSET,
997 .has_radio = 1,
998},{
999
1000/* ---- card 0x30 ---------------------------------- */
1001 .name = "Askey CPH03x/ Dynalink Magic TView",
1002 .video_inputs = 3,
1003 .audio_inputs = 1,
1004 .tuner = 0,
1005 .svhs = 2,
1006 .gpiomask = 15,
1007 .muxsel = { 2, 3, 1, 1},
1008 .audiomux = {2,0,0,0,1},
1009 .needs_tvaudio = 1,
1010 .pll = PLL_28,
1011 .tuner_type = -1,
1012 .tuner_addr = ADDR_UNSET,
1013},{
1014 .name = "IODATA GV-BCTV3/PCI",
1015 .video_inputs = 3,
1016 .audio_inputs = 1,
1017 .tuner = 0,
1018 .svhs = 2,
1019 .gpiomask = 0x010f00,
1020 .muxsel = {2, 3, 0, 0},
1021 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1022 .no_msp34xx = 1,
1023 .pll = PLL_28,
1024 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
1025 .tuner_addr = ADDR_UNSET,
1026 .audio_hook = gvbctv3pci_audio,
1027},{
1028 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
1029 .video_inputs = 5,
1030 .audio_inputs = 1,
1031 .tuner = 0,
1032 .svhs = 3,
1033 .gpiomask = 0xAA0000,
1034 .muxsel = { 2,3,1,1,-1 },
1035 .digital_mode = DIGITAL_MODE_CAMERA,
1036 .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
1037 .no_msp34xx = 1,
1038 .pll = PLL_28,
1039 .tuner_type = TUNER_PHILIPS_PAL_I,
1040 .tuner_addr = ADDR_UNSET,
1041 .has_remote = 1,
1042 /* GPIO wiring: (different from Rev.4C !)
1043 GPIO17: U4.A0 (first hef4052bt)
1044 GPIO19: U4.A1
1045 GPIO20: U5.A1 (second hef4052bt)
1046 GPIO21: U4.nEN
1047 GPIO22: BT832 Reset Line
1048 GPIO23: A5,A0, U5,nEN
1049 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
1050 */
1051},{
1052 .name = "Eagle Wireless Capricorn2 (bt878A)",
1053 .video_inputs = 4,
1054 .audio_inputs = 1,
1055 .tuner = 0,
1056 .svhs = 2,
1057 .gpiomask = 7,
1058 .muxsel = { 2, 0, 1, 1},
1059 .audiomux = { 0, 1, 2, 3, 4},
1060 .pll = PLL_28,
1061 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1062 .tuner_addr = ADDR_UNSET,
1063},{
1064
1065/* ---- card 0x34 ---------------------------------- */
1066 /* David Härdeman <david@2gen.com> */
1067 .name = "Pinnacle PCTV Studio Pro",
1068 .video_inputs = 4,
1069 .audio_inputs = 1,
1070 .tuner = 0,
1071 .svhs = 3,
1072 .gpiomask = 0x03000F,
1073 .muxsel = { 2, 3, 1, 1},
1074 .audiomux = { 1, 0xd0001, 0, 0, 10},
1075 /* sound path (5 sources):
1076 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1077 0= ext. Audio IN
1078 1= from MUX2
1079 2= Mono TV sound from Tuner
1080 3= not connected
1081 MUX2 (mask 0x30000):
1082 0,2,3= from MSP34xx
1083 1= FM stereo Radio from Tuner */
1084 .needs_tvaudio = 0,
1085 .pll = PLL_28,
1086 .tuner_type = -1,
1087 .tuner_addr = ADDR_UNSET,
1088},{
1089 /* Claas Langbehn <claas@bigfoot.com>,
1090 Sven Grothklags <sven@upb.de> */
1091 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1092 .video_inputs = 4,
1093 .audio_inputs = 3,
1094 .tuner = 0,
1095 .svhs = 2,
1096 .gpiomask = 0x1c,
1097 .muxsel = { 2, 3, 1, 1},
1098 .audiomux = { 0, 0, 0x10, 8, 4 },
1099 .needs_tvaudio = 1,
1100 .pll = PLL_28,
1101 .tuner_type = TUNER_PHILIPS_PAL,
1102 .tuner_addr = ADDR_UNSET,
1103 .has_radio = 1,
1104},{
1105 /* Tim Röstermundt <rosterm@uni-muenster.de>
1106 in de.comp.os.unix.linux.hardware:
1107 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1108 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1109 options tuner type=5 */
1110 .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
1111 .video_inputs = 4,
1112 .audio_inputs = 1,
1113 .tuner = 0,
1114 .svhs = 2,
1115 .gpiomask = 0x18e0,
1116 .muxsel = { 2, 3, 1, 1},
1117 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
1118 /* For cards with tda9820/tda9821:
1119 0x0000: Tuner normal stereo
1120 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1121 0x0880: Tuner A2 stereo */
1122 .pll = PLL_28,
1123 .tuner_type = -1,
1124 .tuner_addr = ADDR_UNSET,
1125},{
1126 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1127 old Easy TV BT848 version (model CPH031) */
1128 .name = "Askey CPH031/ BESTBUY Easy TV",
1129 .video_inputs = 4,
1130 .audio_inputs = 1,
1131 .tuner = 0,
1132 .svhs = 2,
1133 .gpiomask = 0xF,
1134 .muxsel = { 2, 3, 1, 0},
1135 .audiomux = { 2, 0, 0, 0, 10},
1136 .needs_tvaudio = 0,
1137 .pll = PLL_28,
1138 .tuner_type = TUNER_TEMIC_PAL,
1139 .tuner_addr = ADDR_UNSET,
1140},{
1141
1142/* ---- card 0x38 ---------------------------------- */
1143 /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
1144 .name = "Lifeview FlyVideo 98FM LR50",
1145 .video_inputs = 4,
1146 .audio_inputs = 3,
1147 .tuner = 0,
1148 .svhs = 2,
1149 .gpiomask = 0x1800,
1150 .muxsel = { 2, 3, 1, 1},
1151 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1152 .pll = PLL_28,
1153 .tuner_type = 5,
1154 .tuner_addr = ADDR_UNSET,
1155},{
1156 /* This is the ultimate cheapo capture card
1157 * just a BT848A on a small PCB!
1158 * Steve Hosgood <steve@equiinet.com> */
1159 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1160 .video_inputs = 2,
1161 .audio_inputs = 0,
1162 .tuner = -1,
1163 .svhs = 1,
1164 .gpiomask = 0,
1165 .muxsel = { 3, 1 },
1166 .audiomux = { 0 },
1167 .needs_tvaudio = 0,
1168 .no_msp34xx = 1,
1169 .pll = PLL_35,
1170 .tuner_type = -1,
1171 .tuner_addr = ADDR_UNSET,
1172},{
1173 /* Daniel Herrington <daniel.herrington@home.com> */
1174 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1175 .video_inputs = 3,
1176 .audio_inputs = 1,
1177 .tuner = 0,
1178 .svhs = 2,
1179 .gpiomask = 0xe00,
1180 .muxsel = { 2, 3, 1, 1},
1181 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
1182 .needs_tvaudio = 1,
1183 .pll = PLL_28,
1184 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1185 .tuner_addr = ADDR_UNSET,
1186},{
1187 /* Matti Mottus <mottus@physic.ut.ee> */
1188 .name = "Askey CPH03x TV Capturer",
1189 .video_inputs = 4,
1190 .audio_inputs = 1,
1191 .tuner = 0,
1192 .svhs = 2,
1193 .gpiomask = 0x03000F,
1194 .muxsel = { 2, 3, 1, 0},
1195 .audiomux = { 2,0,0,0,1 },
1196 .pll = PLL_28,
1197 .tuner_type = 0,
1198 .tuner_addr = ADDR_UNSET,
1199},{
1200
1201/* ---- card 0x3c ---------------------------------- */
1202 /* Philip Blundell <philb@gnu.org> */
1203 .name = "Modular Technology MM100PCTV",
1204 .video_inputs = 2,
1205 .audio_inputs = 2,
1206 .tuner = 0,
1207 .svhs = -1,
1208 .gpiomask = 11,
1209 .muxsel = { 2, 3, 1, 1},
1210 .audiomux = { 2, 0, 0, 1, 8},
1211 .pll = PLL_35,
1212 .tuner_type = TUNER_TEMIC_PAL,
1213 .tuner_addr = ADDR_UNSET,
1214},{
1215 /* Adrian Cox <adrian@humboldt.co.uk */
1216 .name = "AG Electronics GMV1",
1217 .video_inputs = 2,
1218 .audio_inputs = 0,
1219 .tuner = -1,
1220 .svhs = 1,
1221 .gpiomask = 0xF,
1222 .muxsel = { 2, 2},
1223 .audiomux = { },
1224 .no_msp34xx = 1,
1225 .needs_tvaudio = 0,
1226 .pll = PLL_28,
1227 .tuner_type = -1,
1228 .tuner_addr = ADDR_UNSET,
1229},{
1230 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1231 new Easy TV BT878 version (model CPH061)
1232 special thanks to Informatica Mieres for providing the card */
1233 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1234 .video_inputs = 3,
1235 .audio_inputs = 2,
1236 .tuner = 0,
1237 .svhs = 2,
1238 .gpiomask = 0xFF,
1239 .muxsel = { 2, 3, 1, 0},
1240 .audiomux = { 1, 0, 4, 4, 9},
1241 .needs_tvaudio = 0,
1242 .pll = PLL_28,
1243 .tuner_type = TUNER_PHILIPS_PAL,
1244 .tuner_addr = ADDR_UNSET,
1245},{
1246 /* Lukas Gebauer <geby@volny.cz> */
1247 .name = "ATI TV-Wonder",
1248 .video_inputs = 3,
1249 .audio_inputs = 1,
1250 .tuner = 0,
1251 .svhs = 2,
1252 .gpiomask = 0xf03f,
1253 .muxsel = { 2, 3, 1, 0 },
1254 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
1255 .pll = PLL_28,
1256 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1257 .tuner_addr = ADDR_UNSET,
1258},{
1259
1260/* ---- card 0x40 ---------------------------------- */
1261 /* Lukas Gebauer <geby@volny.cz> */
1262 .name = "ATI TV-Wonder VE",
1263 .video_inputs = 2,
1264 .audio_inputs = 1,
1265 .tuner = 0,
1266 .svhs = -1,
1267 .gpiomask = 1,
1268 .muxsel = { 2, 3, 0, 1},
1269 .audiomux = { 0, 0, 1, 0, 0},
1270 .no_msp34xx = 1,
1271 .pll = PLL_28,
1272 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1273 .tuner_addr = ADDR_UNSET,
1274},{
1275 /* DeeJay <deejay@westel900.net (2000S) */
1276 .name = "Lifeview FlyVideo 2000S LR90",
1277 .video_inputs = 3,
1278 .audio_inputs = 3,
1279 .tuner = 0,
1280 .svhs = 2,
1281 .gpiomask = 0x18e0,
1282 .muxsel = { 2, 3, 0, 1},
1283 /* Radio changed from 1e80 to 0x800 to make
1284 FlyVideo2000S in .hu happy (gm)*/
1285 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
1286 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
1287 .audio_hook = fv2000s_audio,
1288 .no_msp34xx = 1,
1289 .no_tda9875 = 1,
1290 .needs_tvaudio = 1,
1291 .pll = PLL_28,
1292 .tuner_type = 5,
1293 .tuner_addr = ADDR_UNSET,
1294},{
1295 .name = "Terratec TValueRadio",
1296 .video_inputs = 3,
1297 .audio_inputs = 1,
1298 .tuner = 0,
1299 .svhs = 2,
1300 .gpiomask = 0xffff00,
1301 .muxsel = { 2, 3, 1, 1},
1302 .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
1303 .needs_tvaudio = 1,
1304 .pll = PLL_28,
1305 .tuner_type = TUNER_PHILIPS_PAL,
1306 .tuner_addr = ADDR_UNSET,
1307 .has_radio = 1,
1308},{
1309 /* TANAKA Kei <peg00625@nifty.com> */
1310 .name = "IODATA GV-BCTV4/PCI",
1311 .video_inputs = 3,
1312 .audio_inputs = 1,
1313 .tuner = 0,
1314 .svhs = 2,
1315 .gpiomask = 0x010f00,
1316 .muxsel = {2, 3, 0, 0},
1317 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1318 .no_msp34xx = 1,
1319 .pll = PLL_28,
1320 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
1321 .tuner_addr = ADDR_UNSET,
1322 .audio_hook = gvbctv3pci_audio,
1323},{
1324
1325/* ---- card 0x44 ---------------------------------- */
1326 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
1327 /* try "insmod msp3400 simple=0" if you have
1328 * sound problems with this card. */
1329 .video_inputs = 4,
1330 .audio_inputs = 1,
1331 .tuner = 0,
1332 .svhs = -1,
1333 .gpiomask = 0x4f8a00,
1334 /* 0x100000: 1=MSP enabled (0=disable again)
1335 * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
1336 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
1337 /* tvtuner, radio, external,internal, mute, stereo
1338 * tuner, Composit, SVid, Composit-on-Svid-adapter */
1339 .muxsel = { 2, 3 ,0 ,1},
1340 .tuner_type = TUNER_MT2032,
1341 .tuner_addr = ADDR_UNSET,
1342 .pll = PLL_28,
1343 .has_radio = 1,
1344},{
1345 /* Philip Blundell <pb@nexus.co.uk> */
1346 .name = "Active Imaging AIMMS",
1347 .video_inputs = 1,
1348 .audio_inputs = 0,
1349 .tuner = -1,
1350 .tuner_type = -1,
1351 .tuner_addr = ADDR_UNSET,
1352 .pll = PLL_28,
1353 .muxsel = { 2 },
1354 .gpiomask = 0
1355},{
1356 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
1357 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
1358 .video_inputs = 3,
1359 .audio_inputs = 4,
1360 .tuner = 0,
1361 .svhs = 2,
1362 .gpiomask = 15,
1363 .muxsel = { 2, 3, 1, 1},
1364 .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
1365 .needs_tvaudio = 1,
1366 .pll = PLL_28,
1367 .tuner_type = 25,
1368 .tuner_addr = ADDR_UNSET,
1369 .has_remote = 1,
1370 /* GPIO wiring:
1371 GPIO0: U4.A0 (hef4052bt)
1372 GPIO1: U4.A1
1373 GPIO2: U4.A1 (second hef4052bt)
1374 GPIO3: U4.nEN, U5.A0, A5.nEN
1375 GPIO8-15: vrd866b ?
1376 */ 784 */
1377},{ 785
1378 .name = "Lifeview FlyVideo 98EZ (capture only) LR51", 786 },
1379 .video_inputs = 4, 787 [BTTV_BOARD_PXC200] = {
1380 .audio_inputs = 0, 788 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
1381 .tuner = -1, 789 .name = "Imagenation PXC200",
1382 .svhs = 2, 790 .video_inputs = 5,
1383 .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */ 791 .audio_inputs = 1,
1384 .pll = PLL_28, 792 .tuner = -1,
1385 .no_msp34xx = 1, 793 .svhs = 1, /* was: 4 */
1386 .tuner_type = UNSET, 794 .gpiomask = 0,
1387 .tuner_addr = ADDR_UNSET, 795 .muxsel = { 2, 3, 1, 0, 0},
1388},{ 796 .audiomux = { 0 },
1389 797 .needs_tvaudio = 1,
1390/* ---- card 0x48 ---------------------------------- */ 798 .tuner_type = -1,
1391 /* Dariusz Kowalewski <darekk@automex.pl> */ 799 .tuner_addr = ADDR_UNSET,
1392 .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", 800 .radio_addr = ADDR_UNSET,
1393 .video_inputs = 4, 801 .muxsel_hook = PXC200_muxsel,
1394 .audio_inputs = 1, 802
1395 .tuner = 0, 803 },
1396 .svhs = 2, 804 [BTTV_BOARD_FLYVIDEO_98] = {
1397 .gpiomask = 0x3f, 805 .name = "Lifeview FlyVideo 98 LR50",
1398 .muxsel = { 2, 3, 1, 1 }, 806 .video_inputs = 4,
1399 .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 }, 807 .audio_inputs = 1,
1400 .needs_tvaudio = 1, 808 .tuner = 0,
1401 .no_msp34xx = 1, 809 .svhs = 2,
1402 .no_tda9875 = 1, 810 .gpiomask = 0x1800, /* 0x8dfe00 */
1403 .pll = PLL_28, 811 .muxsel = { 2, 3, 1, 1},
1404 .tuner_type = 5, 812 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
1405 .tuner_addr = ADDR_UNSET, 813 .pll = PLL_28,
1406 .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */ 814 .tuner_type = -1,
1407 .has_radio = 1, /* Note: not all cards have radio */ 815 .tuner_addr = ADDR_UNSET,
1408 .has_remote = 1, 816 .radio_addr = ADDR_UNSET,
1409 /* GPIO wiring: 817 },
1410 GPIO0: A0 hef4052 818 [BTTV_BOARD_IPROTV] = {
1411 GPIO1: A1 hef4052 819 .name = "Formac iProTV, Formac ProTV I (bt848)",
1412 GPIO3: nEN hef4052 820 .video_inputs = 4,
1413 GPIO8-15: vrd866b 821 .audio_inputs = 1,
1414 GPIO20,22,23: R30,R29,R28 822 .tuner = 0,
1415 */ 823 .svhs = 3,
1416},{ 824 .gpiomask = 1,
1417 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */ 825 .muxsel = { 2, 3, 1, 1},
1418 /* you must jumper JP5 for the card to work */ 826 .audiomux = { 1, 0, 0, 0, 0 },
1419 .name = "Sensoray 311", 827 .pll = PLL_28,
1420 .video_inputs = 5, 828 .tuner_type = TUNER_PHILIPS_PAL,
1421 .audio_inputs = 0, 829 .tuner_addr = ADDR_UNSET,
1422 .tuner = -1, 830 .radio_addr = ADDR_UNSET,
1423 .svhs = 4, 831 },
1424 .gpiomask = 0, 832
1425 .muxsel = { 2, 3, 1, 0, 0}, 833 /* ---- card 0x20 ---------------------------------- */
1426 .audiomux = { 0 }, 834 [BTTV_BOARD_INTEL_C_S_PCI] = {
1427 .needs_tvaudio = 0, 835 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
1428 .tuner_type = -1, 836 .video_inputs = 4,
1429 .tuner_addr = ADDR_UNSET, 837 .audio_inputs = 0,
1430},{ 838 .tuner = -1,
1431 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */ 839 .svhs = 2,
1432 .name = "RemoteVision MX (RV605)", 840 .gpiomask = 0,
1433 .video_inputs = 16, 841 .muxsel = { 2, 3, 1, 1},
1434 .audio_inputs = 0, 842 .audiomux = { 0 },
1435 .tuner = -1, 843 .needs_tvaudio = 0,
1436 .svhs = -1, 844 .tuner_type = 4,
1437 .gpiomask = 0x00, 845 .tuner_addr = ADDR_UNSET,
1438 .gpiomask2 = 0x07ff, 846 .radio_addr = ADDR_UNSET,
1439 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, 847 },
1440 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, 848 [BTTV_BOARD_TERRATVALUE] = {
1441 .no_msp34xx = 1, 849 .name = "Terratec TerraTValue Version Bt878",
1442 .no_tda9875 = 1, 850 .video_inputs = 3,
1443 .tuner_type = -1, 851 .audio_inputs = 1,
1444 .tuner_addr = ADDR_UNSET, 852 .tuner = 0,
1445 .muxsel_hook = rv605_muxsel, 853 .svhs = 2,
1446},{ 854 .gpiomask = 0xffff00,
1447 .name = "Powercolor MTV878/ MTV878R/ MTV878F", 855 .muxsel = { 2, 3, 1, 1},
1448 .video_inputs = 3, 856 .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
1449 .audio_inputs = 2, 857 .needs_tvaudio = 1,
1450 .tuner = 0, 858 .pll = PLL_28,
1451 .svhs = 2, 859 .tuner_type = TUNER_PHILIPS_PAL,
1452 .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ 860 .tuner_addr = ADDR_UNSET,
1453 .muxsel = { 2, 1, 1, }, 861 .radio_addr = ADDR_UNSET,
1454 .audiomux = { 0, 1, 2, 2, 4 }, 862 },
1455 .needs_tvaudio = 0, 863 [BTTV_BOARD_WINFAST2000] = {
1456 .tuner_type = TUNER_PHILIPS_PAL, 864 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
1457 .tuner_addr = ADDR_UNSET, 865 .video_inputs = 4,
1458 .pll = PLL_28, 866 .audio_inputs = 1,
1459 .has_radio = 1, 867 .tuner = 0,
1460},{ 868 .svhs = 2,
1461 869 .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
1462/* ---- card 0x4c ---------------------------------- */ 870 #if 0
1463 /* Masaki Suzuki <masaki@btree.org> */ 871 .gpiomask = 0xc33000,
1464 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", 872 .audiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 },
1465 .video_inputs = 3, 873 #else
1466 .audio_inputs = 1, 874 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
1467 .tuner = 0, 875 .gpiomask = 0xb33000,
1468 .svhs = 2, 876 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
1469 .gpiomask = 0x140007, 877 #endif
1470 .muxsel = { 2, 3, 1, 1 }, 878 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
1471 .audiomux = { 0, 1, 2, 3, 4, 0 }, 879 gpio23 -- hef4052:nEnable (0x800000)
1472 .tuner_type = TUNER_PHILIPS_NTSC, 880 gpio12 -- hef4052:A1
1473 .tuner_addr = ADDR_UNSET, 881 gpio13 -- hef4052:A0
1474 .audio_hook = windvr_audio, 882 0x0000: external audio
1475},{ 883 0x1000: FM
1476 .name = "GrandTec Multi Capture Card (Bt878)", 884 0x2000: TV
1477 .video_inputs = 4, 885 0x3000: n.c.
1478 .audio_inputs = 0, 886 Note: There exists another variant "Winfast 2000" with tv stereo !?
1479 .tuner = -1, 887 Note: eeprom only contains FF and pci subsystem id 107d:6606
1480 .svhs = -1, 888 */
1481 .gpiomask = 0, 889 .needs_tvaudio = 0,
1482 .muxsel = { 2, 3, 1, 0 }, 890 .pll = PLL_28,
1483 .audiomux = { 0 }, 891 .has_radio = 1,
1484 .needs_tvaudio = 0, 892 .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
1485 .no_msp34xx = 1, 893 .tuner_addr = ADDR_UNSET,
1486 .pll = PLL_28, 894 .radio_addr = ADDR_UNSET,
1487 .tuner_type = -1, 895 .audio_hook = winfast2000_audio,
1488 .tuner_addr = ADDR_UNSET, 896 .has_remote = 1,
1489},{ 897 },
1490 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", 898 [BTTV_BOARD_CHRONOS_VS2] = {
1491 .video_inputs = 4, 899 .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
1492 .audio_inputs = 3, 900 .video_inputs = 4,
1493 .tuner = 0, 901 .audio_inputs = 3,
1494 .svhs = 2, 902 .tuner = 0,
1495 .gpiomask = 7, 903 .svhs = 2,
1496 .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */ 904 .gpiomask = 0x1800,
1497 .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio! 905 .muxsel = { 2, 3, 1, 1},
1498 * This card lacks external Audio In, so we mute it on Ext. & Int. 906 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
1499 * The PCB can take a sbx1637/sbx1673, wiring unknown. 907 .pll = PLL_28,
1500 * This card lacks PCI subsystem ID, sigh. 908 .tuner_type = -1,
1501 * audiomux=1: lower volume, 2+3: mute 909 .tuner_addr = ADDR_UNSET,
1502 * btwincap uses 0x80000/0x80003 910 .radio_addr = ADDR_UNSET,
1503 */ 911 },
1504 .needs_tvaudio = 0, 912
1505 .no_msp34xx = 1, 913 /* ---- card 0x24 ---------------------------------- */
1506 .pll = PLL_28, 914 [BTTV_BOARD_TYPHOON_TVIEW] = {
1507 .tuner_type = 5, 915 .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
1508 .tuner_addr = ADDR_UNSET, 916 .video_inputs = 4,
1509 /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and 917 .audio_inputs = 3,
1510 radio signal strength indicators work fine. */ 918 .tuner = 0,
1511 .has_radio = 1, 919 .svhs = 2,
1512 /* GPIO Info: 920 .gpiomask = 0x1800,
1513 GPIO0,1: HEF4052 A0,A1 921 .muxsel = { 2, 3, 1, 1},
1514 GPIO2: HEF4052 nENABLE 922 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1515 GPIO3-7: n.c. 923 .pll = PLL_28,
1516 GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card] 924 .tuner_type = -1,
1517 GPIO14,15: ?? 925 .tuner_addr = ADDR_UNSET,
1518 GPIO16-21: n.c. 926 .radio_addr = ADDR_UNSET,
1519 GPIO22,23: ?? 927 .has_radio = 1,
1520 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/ 928 },
1521},{ 929 [BTTV_BOARD_PXELVWPLTVPRO] = {
1522 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */ 930 .name = "Prolink PixelView PlayTV pro",
1523 .name = "DSP Design TCVIDEO", 931 .video_inputs = 3,
1524 .video_inputs = 4, 932 .audio_inputs = 1,
1525 .svhs = -1, 933 .tuner = 0,
1526 .muxsel = { 2, 3, 1, 0}, 934 .svhs = 2,
1527 .pll = PLL_28, 935 .gpiomask = 0xff,
1528 .tuner_type = -1, 936 .muxsel = { 2, 3, 1, 1 },
1529 .tuner_addr = ADDR_UNSET, 937 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
1530},{ 938 .no_msp34xx = 1,
1531 939 .pll = PLL_28,
1532 /* ---- card 0x50 ---------------------------------- */ 940 .tuner_type = -1,
1533 .name = "Hauppauge WinTV PVR", 941 .tuner_addr = ADDR_UNSET,
1534 .video_inputs = 4, 942 .radio_addr = ADDR_UNSET,
1535 .audio_inputs = 1, 943 },
1536 .tuner = 0, 944 [BTTV_BOARD_MAGICTVIEW063] = {
1537 .svhs = 2, 945 .name = "Askey CPH06X TView99",
1538 .muxsel = { 2, 0, 1, 1}, 946 .video_inputs = 4,
1539 .needs_tvaudio = 1, 947 .audio_inputs = 1,
1540 .pll = PLL_28, 948 .tuner = 0,
1541 .tuner_type = -1, 949 .svhs = 2,
1542 .tuner_addr = ADDR_UNSET, 950 .gpiomask = 0x551e00,
1543 951 .muxsel = { 2, 3, 1, 0},
1544 .gpiomask = 7, 952 .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
1545 .audiomux = {7}, 953 .needs_tvaudio = 1,
1546},{ 954 .pll = PLL_28,
1547 .name = "IODATA GV-BCTV5/PCI", 955 .tuner_type = 1,
1548 .video_inputs = 3, 956 .tuner_addr = ADDR_UNSET,
1549 .audio_inputs = 1, 957 .radio_addr = ADDR_UNSET,
1550 .tuner = 0, 958 .has_remote = 1,
1551 .svhs = 2, 959 },
1552 .gpiomask = 0x0f0f80, 960 [BTTV_BOARD_PINNACLE] = {
1553 .muxsel = {2, 3, 1, 0}, 961 .name = "Pinnacle PCTV Studio/Rave",
1554 .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0}, 962 .video_inputs = 3,
1555 .no_msp34xx = 1, 963 .audio_inputs = 1,
1556 .pll = PLL_28, 964 .tuner = 0,
1557 .tuner_type = TUNER_PHILIPS_NTSC_M, 965 .svhs = 2,
1558 .tuner_addr = ADDR_UNSET, 966 .gpiomask = 0x03000F,
1559 .audio_hook = gvbctv5pci_audio, 967 .muxsel = { 2, 3, 1, 1},
1560 .has_radio = 1, 968 .audiomux = { 2, 0xd0001, 0, 0, 1},
1561},{ 969 .needs_tvaudio = 0,
1562 .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ 970 .pll = PLL_28,
1563 .video_inputs = 4, /* id-inputs-clock */ 971 .tuner_type = -1,
1564 .audio_inputs = 0, 972 .tuner_addr = ADDR_UNSET,
1565 .tuner = -1, 973 .radio_addr = ADDR_UNSET,
1566 .svhs = 3, 974 },
1567 .muxsel = { 3, 2, 0, 1 }, 975
1568 .pll = PLL_28, 976 /* ---- card 0x28 ---------------------------------- */
1569 .tuner_type = -1, 977 [BTTV_BOARD_STB2] = {
1570 .tuner_addr = ADDR_UNSET, 978 .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
1571 .no_msp34xx = 1, 979 .video_inputs = 3,
1572 .no_tda9875 = 1, 980 .audio_inputs = 1,
1573 .no_tda7432 = 1, 981 .tuner = 0,
1574},{ 982 .svhs = 2,
1575 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ 983 .gpiomask = 7,
1576 .video_inputs = 3, 984 .muxsel = { 2, 3, 1, 1},
1577 .audio_inputs = 0, 985 .audiomux = { 4, 0, 2, 3, 1},
1578 .tuner = -1, 986 .no_msp34xx = 1,
1579 .svhs = 2, 987 .needs_tvaudio = 1,
1580 .muxsel = { 2, 3, 1 }, 988 .tuner_type = TUNER_PHILIPS_NTSC,
1581 .pll = PLL_28, 989 .tuner_addr = ADDR_UNSET,
1582 .tuner_type = -1, 990 .radio_addr = ADDR_UNSET,
1583 .tuner_addr = ADDR_UNSET, 991 .pll = PLL_28,
1584 .no_msp34xx = 1, 992 .has_radio = 1,
1585 .no_tda9875 = 1, 993 },
1586 .no_tda7432 = 1, 994 [BTTV_BOARD_AVPHONE98] = {
1587},{ 995 .name = "AVerMedia TVPhone 98",
1588 996 .video_inputs = 3,
1589 /* ---- card 0x54 ---------------------------------- */ 997 .audio_inputs = 4,
1590 .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ 998 .tuner = 0,
1591 .video_inputs = 2, 999 .svhs = 2,
1592 .audio_inputs = 0, 1000 .gpiomask = 15,
1593 .tuner = -1, 1001 .muxsel = { 2, 3, 1, 1},
1594 .svhs = 1, 1002 .audiomux = { 13, 4, 11, 7, 0, 0},
1595 .muxsel = { 3, 1 }, 1003 .needs_tvaudio = 1,
1596 .pll = PLL_28, 1004 .pll = PLL_28,
1597 .tuner_type = -1, 1005 .tuner_type = -1,
1598 .tuner_addr = ADDR_UNSET, 1006 .tuner_addr = ADDR_UNSET,
1599 .no_msp34xx = 1, 1007 .radio_addr = ADDR_UNSET,
1600 .no_tda9875 = 1, 1008 .has_radio = 1,
1601 .no_tda7432 = 1, 1009 .audio_hook = avermedia_tvphone_audio,
1602},{ 1010 },
1603 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ 1011 [BTTV_BOARD_PV951] = {
1604 .video_inputs = 1, 1012 .name = "ProVideo PV951", /* pic16c54 */
1605 .audio_inputs = 0, 1013 .video_inputs = 3,
1606 .tuner = -1, 1014 .audio_inputs = 1,
1607 .svhs = -1, 1015 .tuner = 0,
1608 .muxsel = { 0 }, 1016 .svhs = 2,
1609 .pll = PLL_28, 1017 .gpiomask = 0,
1610 .tuner_type = -1, 1018 .muxsel = { 2, 3, 1, 1},
1611 .tuner_addr = ADDR_UNSET, 1019 .audiomux = { 0, 0, 0, 0, 0},
1612 .no_msp34xx = 1, 1020 .needs_tvaudio = 1,
1613 .no_tda9875 = 1, 1021 .no_msp34xx = 1,
1614 .no_tda7432 = 1, 1022 .pll = PLL_28,
1615},{ 1023 .tuner_type = 1,
1616 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ 1024 .tuner_addr = ADDR_UNSET,
1617 .video_inputs = 2, 1025 .radio_addr = ADDR_UNSET,
1618 .audio_inputs = 0, 1026 },
1619 .tuner = -1, 1027 [BTTV_BOARD_ONAIR_TV] = {
1620 .svhs = 1, 1028 .name = "Little OnAir TV",
1621 .muxsel = { 0, 1 }, 1029 .video_inputs = 3,
1622 .pll = PLL_28, 1030 .audio_inputs = 1,
1623 .tuner_type = -1, 1031 .tuner = 0,
1624 .tuner_addr = ADDR_UNSET, 1032 .svhs = 2,
1625 .no_msp34xx = 1, 1033 .gpiomask = 0xe00b,
1626 .no_tda9875 = 1, 1034 .muxsel = {2, 3, 1, 1},
1627 .no_tda7432 = 1, 1035 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
1628},{ 1036 .no_msp34xx = 1,
1629 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ 1037 .tuner_type = -1,
1630 .video_inputs = 1, 1038 .tuner_addr = ADDR_UNSET,
1631 .audio_inputs = 1, 1039 .radio_addr = ADDR_UNSET,
1632 .tuner = -1, 1040 },
1633 .svhs = -1, 1041
1634 .muxsel = { 0 }, 1042 /* ---- card 0x2c ---------------------------------- */
1635 .pll = PLL_28, 1043 [BTTV_BOARD_SIGMA_TVII_FM] = {
1636 .tuner_type = UNSET, 1044 .name = "Sigma TVII-FM",
1637 .tuner_addr = ADDR_UNSET, 1045 .video_inputs = 2,
1638 .no_msp34xx = 1, 1046 .audio_inputs = 1,
1639 .no_tda9875 = 1, 1047 .tuner = 0,
1640 .no_tda7432 = 1, 1048 .svhs = -1,
1641},{ 1049 .gpiomask = 3,
1642 1050 .muxsel = {2, 3, 1, 1},
1643 /* ---- card 0x58 ---------------------------------- */ 1051 .audiomux = {1, 1, 0, 2, 3},
1644 .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ 1052 .no_msp34xx = 1,
1645 .video_inputs = 2, 1053 .pll = PLL_NONE,
1646 .audio_inputs = 1, 1054 .tuner_type = -1,
1647 .tuner = -1, 1055 .tuner_addr = ADDR_UNSET,
1648 .svhs = 1, 1056 .radio_addr = ADDR_UNSET,
1649 .muxsel = { 0, 1 }, 1057 },
1650 .pll = PLL_28, 1058 [BTTV_BOARD_MATRIX_VISION2] = {
1651 .tuner_type = UNSET, 1059 .name = "MATRIX-Vision MV-Delta 2",
1652 .tuner_addr = ADDR_UNSET, 1060 .video_inputs = 5,
1653 .no_msp34xx = 1, 1061 .audio_inputs = 1,
1654 .no_tda9875 = 1, 1062 .tuner = -1,
1655 .no_tda7432 = 1, 1063 .svhs = 3,
1656},{ 1064 .gpiomask = 0,
1657 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ 1065 .muxsel = { 2, 3, 1, 0, 0},
1658 .video_inputs = 2, 1066 .audiomux = {0 },
1659 .audio_inputs = 1, 1067 .no_msp34xx = 1,
1660 .tuner = -1, 1068 .pll = PLL_28,
1661 .svhs = 1, 1069 .tuner_type = -1,
1662 .muxsel = { 2, 3 }, 1070 .tuner_addr = ADDR_UNSET,
1663 .pll = PLL_28, 1071 .radio_addr = ADDR_UNSET,
1664 .tuner_type = UNSET, 1072 },
1665 .tuner_addr = ADDR_UNSET, 1073 [BTTV_BOARD_ZOLTRIX_GENIE] = {
1666 .no_msp34xx = 1, 1074 .name = "Zoltrix Genie TV/FM",
1667 .no_tda9875 = 1, 1075 .video_inputs = 3,
1668 .no_tda7432 = 1, 1076 .audio_inputs = 1,
1669},{ 1077 .tuner = 0,
1670 .name = "Osprey 500", /* 500 */ 1078 .svhs = 2,
1671 .video_inputs = 2, 1079 .gpiomask = 0xbcf03f,
1672 .audio_inputs = 1, 1080 .muxsel = { 2, 3, 1, 1},
1673 .tuner = -1, 1081 .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
1674 .svhs = 1, 1082 .no_msp34xx = 1,
1675 .muxsel = { 2, 3 }, 1083 .pll = PLL_28,
1676 .pll = PLL_28, 1084 .tuner_type = 21,
1677 .tuner_type = -1, 1085 .tuner_addr = ADDR_UNSET,
1678 .tuner_addr = ADDR_UNSET, 1086 .radio_addr = ADDR_UNSET,
1679 .no_msp34xx = 1, 1087 },
1680 .no_tda9875 = 1, 1088 [BTTV_BOARD_TERRATVRADIO] = {
1681 .no_tda7432 = 1, 1089 .name = "Terratec TV/Radio+",
1682},{ 1090 .video_inputs = 3,
1683 .name = "Osprey 540", /* 540 */ 1091 .audio_inputs = 1,
1684 .video_inputs = 4, 1092 .tuner = 0,
1685 .audio_inputs = 1, 1093 .svhs = 2,
1686 .tuner = -1, 1094 .gpiomask = 0x70000,
1687 .pll = PLL_28, 1095 .muxsel = { 2, 3, 1, 1},
1688 .tuner_type = -1, 1096 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
1689 .tuner_addr = ADDR_UNSET, 1097 .needs_tvaudio = 1,
1690 .no_msp34xx = 1, 1098 .no_msp34xx = 1,
1691 .no_tda9875 = 1, 1099 .pll = PLL_35,
1692 .no_tda7432 = 1, 1100 .tuner_type = 1,
1693},{ 1101 .tuner_addr = ADDR_UNSET,
1694 1102 .radio_addr = ADDR_UNSET,
1695 /* ---- card 0x5C ---------------------------------- */ 1103 .has_radio = 1,
1696 .name = "Osprey 2000", /* 2000 */ 1104 },
1697 .video_inputs = 2, 1105
1698 .audio_inputs = 1, 1106 /* ---- card 0x30 ---------------------------------- */
1699 .tuner = -1, 1107 [BTTV_BOARD_DYNALINK] = {
1700 .svhs = 1, 1108 .name = "Askey CPH03x/ Dynalink Magic TView",
1701 .muxsel = { 2, 3 }, 1109 .video_inputs = 3,
1702 .pll = PLL_28, 1110 .audio_inputs = 1,
1703 .tuner_type = UNSET, 1111 .tuner = 0,
1704 .tuner_addr = ADDR_UNSET, 1112 .svhs = 2,
1705 .no_msp34xx = 1, 1113 .gpiomask = 15,
1706 .no_tda9875 = 1, 1114 .muxsel = { 2, 3, 1, 1},
1707 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ 1115 .audiomux = {2,0,0,0,1},
1708},{ 1116 .needs_tvaudio = 1,
1709 /* M G Berberich <berberic@forwiss.uni-passau.de> */ 1117 .pll = PLL_28,
1710 .name = "IDS Eagle", 1118 .tuner_type = -1,
1711 .video_inputs = 4, 1119 .tuner_addr = ADDR_UNSET,
1712 .audio_inputs = 0, 1120 .radio_addr = ADDR_UNSET,
1713 .tuner = -1, 1121 },
1714 .tuner_type = -1, 1122 [BTTV_BOARD_GVBCTV3PCI] = {
1715 .tuner_addr = ADDR_UNSET, 1123 .name = "IODATA GV-BCTV3/PCI",
1716 .svhs = -1, 1124 .video_inputs = 3,
1717 .gpiomask = 0, 1125 .audio_inputs = 1,
1718 .muxsel = { 0, 1, 2, 3 }, 1126 .tuner = 0,
1719 .muxsel_hook = eagle_muxsel, 1127 .svhs = 2,
1720 .no_msp34xx = 1, 1128 .gpiomask = 0x010f00,
1721 .no_tda9875 = 1, 1129 .muxsel = {2, 3, 0, 0},
1722 .pll = PLL_28, 1130 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1723},{ 1131 .no_msp34xx = 1,
1724 .name = "Pinnacle PCTV Sat", 1132 .pll = PLL_28,
1725 .video_inputs = 2, 1133 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
1726 .audio_inputs = 0, 1134 .tuner_addr = ADDR_UNSET,
1727 .svhs = 1, 1135 .radio_addr = ADDR_UNSET,
1728 .tuner = -1, 1136 .audio_hook = gvbctv3pci_audio,
1729 .tuner_type = -1, 1137 },
1730 .tuner_addr = ADDR_UNSET, 1138 [BTTV_BOARD_PXELVWPLTVPAK] = {
1731 .no_msp34xx = 1, 1139 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
1732 .no_tda9875 = 1, 1140 .video_inputs = 5,
1733 .no_tda7432 = 1, 1141 .audio_inputs = 1,
1734 .gpiomask = 0x01, 1142 .tuner = 0,
1735 .audiomux = { 0, 0, 0, 0, 1 }, 1143 .svhs = 3,
1736 .muxsel = { 3, 0, 1, 2}, 1144 .gpiomask = 0xAA0000,
1737 .needs_tvaudio = 0, 1145 .muxsel = { 2,3,1,1,-1 },
1738 .pll = PLL_28, 1146 .digital_mode = DIGITAL_MODE_CAMERA,
1739 .no_gpioirq = 1, 1147 .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
1740 .has_dvb = 1, 1148 .no_msp34xx = 1,
1741},{ 1149 .pll = PLL_28,
1742 .name = "Formac ProTV II (bt878)", 1150 .tuner_type = TUNER_PHILIPS_PAL_I,
1743 .video_inputs = 4, 1151 .tuner_addr = ADDR_UNSET,
1744 .audio_inputs = 1, 1152 .radio_addr = ADDR_UNSET,
1745 .tuner = 0, 1153 .has_remote = 1,
1746 .svhs = 3, 1154 /* GPIO wiring: (different from Rev.4C !)
1747 .gpiomask = 2, 1155 GPIO17: U4.A0 (first hef4052bt)
1748 /* TV, Comp1, Composite over SVID con, SVID */ 1156 GPIO19: U4.A1
1749 .muxsel = { 2, 3, 1, 1}, 1157 GPIO20: U5.A1 (second hef4052bt)
1750 .audiomux = { 2, 2, 0, 0, 0 }, 1158 GPIO21: U4.nEN
1751 .pll = PLL_28, 1159 GPIO22: BT832 Reset Line
1752 .has_radio = 1, 1160 GPIO23: A5,A0, U5,nEN
1753 .tuner_type = TUNER_PHILIPS_PAL, 1161 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
1754 .tuner_addr = ADDR_UNSET, 1162 */
1755/* sound routing: 1163 },
1756 GPIO=0x00,0x01,0x03: mute (?) 1164 [BTTV_BOARD_EAGLE] = {
1757 0x02: both TV and radio (tuner: FM1216/I) 1165 .name = "Eagle Wireless Capricorn2 (bt878A)",
1758 The card has onboard audio connectors labeled "cdrom" and "board", 1166 .video_inputs = 4,
1759 not soldered here, though unknown wiring. 1167 .audio_inputs = 1,
1760 Card lacks: external audio in, pci subsystem id. 1168 .tuner = 0,
1761*/ 1169 .svhs = 2,
1762},{ 1170 .gpiomask = 7,
1763 1171 .muxsel = { 2, 0, 1, 1},
1764 /* ---- card 0x60 ---------------------------------- */ 1172 .audiomux = { 0, 1, 2, 3, 4},
1765 .name = "MachTV", 1173 .pll = PLL_28,
1766 .video_inputs = 3, 1174 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1767 .audio_inputs = 1, 1175 .tuner_addr = ADDR_UNSET,
1768 .tuner = 0, 1176 .radio_addr = ADDR_UNSET,
1769 .svhs = -1, 1177 },
1770 .gpiomask = 7, 1178
1771 .muxsel = { 2, 3, 1, 1}, 1179 /* ---- card 0x34 ---------------------------------- */
1772 .audiomux = { 0, 1, 2, 3, 4}, 1180 [BTTV_BOARD_PINNACLEPRO] = {
1773 .needs_tvaudio = 1, 1181 /* David Härdeman <david@2gen.com> */
1774 .tuner_type = 5, 1182 .name = "Pinnacle PCTV Studio Pro",
1775 .tuner_addr = ADDR_UNSET, 1183 .video_inputs = 4,
1776 .pll = 1, 1184 .audio_inputs = 1,
1777},{ 1185 .tuner = 0,
1778 .name = "Euresys Picolo", 1186 .svhs = 3,
1779 .video_inputs = 3, 1187 .gpiomask = 0x03000F,
1780 .audio_inputs = 0, 1188 .muxsel = { 2, 3, 1, 1},
1781 .tuner = -1, 1189 .audiomux = { 1, 0xd0001, 0, 0, 10},
1782 .svhs = 2, 1190 /* sound path (5 sources):
1783 .gpiomask = 0, 1191 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1784 .no_msp34xx = 1, 1192 0= ext. Audio IN
1785 .no_tda9875 = 1, 1193 1= from MUX2
1786 .no_tda7432 = 1, 1194 2= Mono TV sound from Tuner
1787 .muxsel = { 2, 0, 1}, 1195 3= not connected
1788 .pll = PLL_28, 1196 MUX2 (mask 0x30000):
1789 .tuner_type = UNSET, 1197 0,2,3= from MSP34xx
1790 .tuner_addr = ADDR_UNSET, 1198 1= FM stereo Radio from Tuner */
1791},{ 1199 .needs_tvaudio = 0,
1792 /* Luc Van Hoeylandt <luc@e-magic.be> */ 1200 .pll = PLL_28,
1793 .name = "ProVideo PV150", /* 0x4f */ 1201 .tuner_type = -1,
1794 .video_inputs = 2, 1202 .tuner_addr = ADDR_UNSET,
1795 .audio_inputs = 0, 1203 .radio_addr = ADDR_UNSET,
1796 .tuner = -1, 1204 },
1797 .svhs = -1, 1205 [BTTV_BOARD_TVIEW_RDS_FM] = {
1798 .gpiomask = 0, 1206 /* Claas Langbehn <claas@bigfoot.com>,
1799 .muxsel = { 2, 3 }, 1207 Sven Grothklags <sven@upb.de> */
1800 .audiomux = { 0 }, 1208 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1801 .needs_tvaudio = 0, 1209 .video_inputs = 4,
1802 .no_msp34xx = 1, 1210 .audio_inputs = 3,
1803 .pll = PLL_28, 1211 .tuner = 0,
1804 .tuner_type = UNSET, 1212 .svhs = 2,
1805 .tuner_addr = ADDR_UNSET, 1213 .gpiomask = 0x1c,
1806},{ 1214 .muxsel = { 2, 3, 1, 1},
1807 /* Hiroshi Takekawa <sian@big.or.jp> */ 1215 .audiomux = { 0, 0, 0x10, 8, 4 },
1808 /* This card lacks subsystem ID */ 1216 .needs_tvaudio = 1,
1809 .name = "AD-TVK503", /* 0x63 */ 1217 .pll = PLL_28,
1810 .video_inputs = 4, 1218 .tuner_type = TUNER_PHILIPS_PAL,
1811 .audio_inputs = 1, 1219 .tuner_addr = ADDR_UNSET,
1812 .tuner = 0, 1220 .radio_addr = ADDR_UNSET,
1813 .svhs = 2, 1221 .has_radio = 1,
1814 .gpiomask = 0x001e8007, 1222 },
1815 .muxsel = { 2, 3, 1, 0 }, 1223 [BTTV_BOARD_LIFETEC_9415] = {
1816 /* Tuner, Radio, external, internal, off, on */ 1224 /* Tim Röstermundt <rosterm@uni-muenster.de>
1817 .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 }, 1225 in de.comp.os.unix.linux.hardware:
1818 .needs_tvaudio = 0, 1226 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1819 .no_msp34xx = 1, 1227 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1820 .pll = PLL_28, 1228 options tuner type=5 */
1821 .tuner_type = 2, 1229 .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
1822 .tuner_addr = ADDR_UNSET, 1230 .video_inputs = 4,
1823 .audio_hook = adtvk503_audio, 1231 .audio_inputs = 1,
1824},{ 1232 .tuner = 0,
1825 1233 .svhs = 2,
1826 /* ---- card 0x64 ---------------------------------- */ 1234 .gpiomask = 0x18e0,
1827 .name = "Hercules Smart TV Stereo", 1235 .muxsel = { 2, 3, 1, 1},
1828 .video_inputs = 4, 1236 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
1829 .audio_inputs = 1, 1237 /* For cards with tda9820/tda9821:
1830 .tuner = 0, 1238 0x0000: Tuner normal stereo
1831 .svhs = 2, 1239 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1832 .gpiomask = 0x00, 1240 0x0880: Tuner A2 stereo */
1833 .muxsel = { 2, 3, 1, 1 }, 1241 .pll = PLL_28,
1834 .needs_tvaudio = 1, 1242 .tuner_type = -1,
1835 .no_msp34xx = 1, 1243 .tuner_addr = ADDR_UNSET,
1836 .pll = PLL_28, 1244 .radio_addr = ADDR_UNSET,
1837 .tuner_type = 5, 1245 },
1838 .tuner_addr = ADDR_UNSET, 1246 [BTTV_BOARD_BESTBUY_EASYTV] = {
1839 /* Notes: 1247 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1840 - card lacks subsystem ID 1248 old Easy TV BT848 version (model CPH031) */
1841 - stereo variant w/ daughter board with tda9874a @0xb0 1249 .name = "Askey CPH031/ BESTBUY Easy TV",
1842 - Audio Routing: 1250 .video_inputs = 4,
1843 always from tda9874 independent of GPIO (?) 1251 .audio_inputs = 1,
1844 external line in: unknown 1252 .tuner = 0,
1845 - Other chips: em78p156elp @ 0x96 (probably IR remote control) 1253 .svhs = 2,
1846 hef4053 (instead 4052) for unknown function 1254 .gpiomask = 0xF,
1847 */ 1255 .muxsel = { 2, 3, 1, 0},
1848},{ 1256 .audiomux = { 2, 0, 0, 0, 10},
1849 .name = "Pace TV & Radio Card", 1257 .needs_tvaudio = 0,
1850 .video_inputs = 4, 1258 .pll = PLL_28,
1851 .audio_inputs = 1, 1259 .tuner_type = TUNER_TEMIC_PAL,
1852 .tuner = 0, 1260 .tuner_addr = ADDR_UNSET,
1853 .svhs = 2, 1261 .radio_addr = ADDR_UNSET,
1854 .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */ 1262 },
1855 .gpiomask = 0, 1263
1856 .no_tda9875 = 1, 1264 /* ---- card 0x38 ---------------------------------- */
1857 .no_tda7432 = 1, 1265 [BTTV_BOARD_FLYVIDEO_98FM] = {
1858 .tuner_type = 1, 1266 /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
1859 .tuner_addr = ADDR_UNSET, 1267 .name = "Lifeview FlyVideo 98FM LR50",
1860 .has_radio = 1, 1268 .video_inputs = 4,
1861 .pll = PLL_28, 1269 .audio_inputs = 3,
1862 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id 1270 .tuner = 0,
1863 only internal line out: (4pin header) RGGL 1271 .svhs = 2,
1864 Radio must be decoded by msp3410d (not routed through)*/ 1272 .gpiomask = 0x1800,
1865 /* 1273 .muxsel = { 2, 3, 1, 1},
1866 .digital_mode = DIGITAL_MODE_CAMERA, todo! 1274 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1867 */ 1275 .pll = PLL_28,
1868},{ 1276 .tuner_type = 5,
1869 /* Chris Willing <chris@vislab.usyd.edu.au> */ 1277 .tuner_addr = ADDR_UNSET,
1870 .name = "IVC-200", 1278 .radio_addr = ADDR_UNSET,
1871 .video_inputs = 1, 1279 },
1872 .audio_inputs = 0, 1280 /* This is the ultimate cheapo capture card
1873 .tuner = -1, 1281 * just a BT848A on a small PCB!
1874 .tuner_type = -1, 1282 * Steve Hosgood <steve@equiinet.com> */
1875 .tuner_addr = ADDR_UNSET, 1283 [BTTV_BOARD_GRANDTEC] = {
1876 .svhs = -1, 1284 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1877 .gpiomask = 0xdf, 1285 .video_inputs = 2,
1878 .muxsel = { 2 }, 1286 .audio_inputs = 0,
1879 .pll = PLL_28, 1287 .tuner = -1,
1880},{ 1288 .svhs = 1,
1881 .name = "Grand X-Guard / Trust 814PCI", 1289 .gpiomask = 0,
1882 .video_inputs = 16, 1290 .muxsel = { 3, 1 },
1883 .audio_inputs = 0, 1291 .audiomux = { 0 },
1884 .tuner = -1, 1292 .needs_tvaudio = 0,
1885 .svhs = -1, 1293 .no_msp34xx = 1,
1886 .tuner_type = 4, 1294 .pll = PLL_35,
1887 .tuner_addr = ADDR_UNSET, 1295 .tuner_type = -1,
1888 .gpiomask2 = 0xff, 1296 .tuner_addr = ADDR_UNSET,
1889 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 }, 1297 .radio_addr = ADDR_UNSET,
1890 .muxsel_hook = xguard_muxsel, 1298 },
1891 .no_msp34xx = 1, 1299 [BTTV_BOARD_ASKEY_CPH060] = {
1892 .no_tda9875 = 1, 1300 /* Daniel Herrington <daniel.herrington@home.com> */
1893 .no_tda7432 = 1, 1301 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1894 .pll = PLL_28, 1302 .video_inputs = 3,
1895},{ 1303 .audio_inputs = 1,
1896 1304 .tuner = 0,
1897 /* ---- card 0x68 ---------------------------------- */ 1305 .svhs = 2,
1898 .name = "Nebula Electronics DigiTV", 1306 .gpiomask = 0xe00,
1899 .video_inputs = 1, 1307 .muxsel = { 2, 3, 1, 1},
1900 .tuner = -1, 1308 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
1901 .svhs = -1, 1309 .needs_tvaudio = 1,
1902 .muxsel = { 2, 3, 1, 0}, 1310 .pll = PLL_28,
1903 .no_msp34xx = 1, 1311 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1904 .no_tda9875 = 1, 1312 .tuner_addr = ADDR_UNSET,
1905 .no_tda7432 = 1, 1313 .radio_addr = ADDR_UNSET,
1906 .pll = PLL_28, 1314 },
1907 .tuner_type = -1, 1315 [BTTV_BOARD_ASKEY_CPH03X] = {
1908 .tuner_addr = ADDR_UNSET, 1316 /* Matti Mottus <mottus@physic.ut.ee> */
1909 .has_dvb = 1, 1317 .name = "Askey CPH03x TV Capturer",
1910 .no_gpioirq = 1, 1318 .video_inputs = 4,
1911},{ 1319 .audio_inputs = 1,
1912 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ 1320 .tuner = 0,
1913 .name = "ProVideo PV143", 1321 .svhs = 2,
1914 .video_inputs = 4, 1322 .gpiomask = 0x03000F,
1915 .audio_inputs = 0, 1323 .muxsel = { 2, 3, 1, 0},
1916 .tuner = -1, 1324 .audiomux = { 2,0,0,0,1 },
1917 .svhs = -1, 1325 .pll = PLL_28,
1918 .gpiomask = 0, 1326 .tuner_type = 0,
1919 .muxsel = { 2, 3, 1, 0 }, 1327 .tuner_addr = ADDR_UNSET,
1920 .audiomux = { 0 }, 1328 .radio_addr = ADDR_UNSET,
1921 .needs_tvaudio = 0, 1329 },
1922 .no_msp34xx = 1, 1330
1923 .pll = PLL_28, 1331 /* ---- card 0x3c ---------------------------------- */
1924 .tuner_type = -1, 1332 [BTTV_BOARD_MM100PCTV] = {
1925 .tuner_addr = ADDR_UNSET, 1333 /* Philip Blundell <philb@gnu.org> */
1926},{ 1334 .name = "Modular Technology MM100PCTV",
1927 /* M.Klahr@phytec.de */ 1335 .video_inputs = 2,
1928 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)", 1336 .audio_inputs = 2,
1929 .video_inputs = 4, 1337 .tuner = 0,
1930 .audio_inputs = 0, 1338 .svhs = -1,
1931 .tuner = -1, /* card has no tuner */ 1339 .gpiomask = 11,
1932 .svhs = 3, 1340 .muxsel = { 2, 3, 1, 1},
1933 .gpiomask = 0x00, 1341 .audiomux = { 2, 0, 0, 1, 8},
1934 .muxsel = { 2, 3, 1, 0}, 1342 .pll = PLL_35,
1935 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1343 .tuner_type = TUNER_TEMIC_PAL,
1936 .needs_tvaudio = 1, 1344 .tuner_addr = ADDR_UNSET,
1937 .pll = PLL_28, 1345 .radio_addr = ADDR_UNSET,
1938 .tuner_type = -1, 1346 },
1939 .tuner_addr = ADDR_UNSET, 1347 [BTTV_BOARD_GMV1] = {
1940},{ 1348 /* Adrian Cox <adrian@humboldt.co.uk */
1941 .name = "PHYTEC VD-009-X1 Combi (bt878)", 1349 .name = "AG Electronics GMV1",
1942 .video_inputs = 4, 1350 .video_inputs = 2,
1943 .audio_inputs = 0, 1351 .audio_inputs = 0,
1944 .tuner = -1, /* card has no tuner */ 1352 .tuner = -1,
1945 .svhs = 3, 1353 .svhs = 1,
1946 .gpiomask = 0x00, 1354 .gpiomask = 0xF,
1947 .muxsel = { 2, 3, 1, 1}, 1355 .muxsel = { 2, 2},
1948 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1356 .audiomux = { },
1949 .needs_tvaudio = 1, 1357 .no_msp34xx = 1,
1950 .pll = PLL_28, 1358 .needs_tvaudio = 0,
1951 .tuner_type = -1, 1359 .pll = PLL_28,
1952 .tuner_addr = ADDR_UNSET, 1360 .tuner_type = -1,
1953},{ 1361 .tuner_addr = ADDR_UNSET,
1954 1362 .radio_addr = ADDR_UNSET,
1955 /* ---- card 0x6c ---------------------------------- */ 1363 },
1956 .name = "PHYTEC VD-009 MiniDIN (bt878)", 1364 [BTTV_BOARD_BESTBUY_EASYTV2] = {
1957 .video_inputs = 10, 1365 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1958 .audio_inputs = 0, 1366 new Easy TV BT878 version (model CPH061)
1959 .tuner = -1, /* card has no tuner */ 1367 special thanks to Informatica Mieres for providing the card */
1960 .svhs = 9, 1368 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1961 .gpiomask = 0x00, 1369 .video_inputs = 3,
1962 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio 1370 .audio_inputs = 2,
1963 via the upper nibble of muxsel. here: used for 1371 .tuner = 0,
1964 xternal video-mux */ 1372 .svhs = 2,
1965 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 }, 1373 .gpiomask = 0xFF,
1966 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1374 .muxsel = { 2, 3, 1, 0},
1967 .needs_tvaudio = 1, 1375 .audiomux = { 1, 0, 4, 4, 9},
1968 .pll = PLL_28, 1376 .needs_tvaudio = 0,
1969 .tuner_type = -1, 1377 .pll = PLL_28,
1970 .tuner_addr = ADDR_UNSET, 1378 .tuner_type = TUNER_PHILIPS_PAL,
1971},{ 1379 .tuner_addr = ADDR_UNSET,
1972 .name = "PHYTEC VD-009 Combi (bt878)", 1380 .radio_addr = ADDR_UNSET,
1973 .video_inputs = 10, 1381 },
1974 .audio_inputs = 0, 1382 [BTTV_BOARD_ATI_TVWONDER] = {
1975 .tuner = -1, /* card has no tuner */ 1383 /* Lukas Gebauer <geby@volny.cz> */
1976 .svhs = 9, 1384 .name = "ATI TV-Wonder",
1977 .gpiomask = 0x00, 1385 .video_inputs = 3,
1978 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio 1386 .audio_inputs = 1,
1979 via the upper nibble of muxsel. here: used for 1387 .tuner = 0,
1980 xternal video-mux */ 1388 .svhs = 2,
1981 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 }, 1389 .gpiomask = 0xf03f,
1982 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1390 .muxsel = { 2, 3, 1, 0 },
1983 .needs_tvaudio = 1, 1391 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
1984 .pll = PLL_28, 1392 .pll = PLL_28,
1985 .tuner_type = -1, 1393 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1986 .tuner_addr = ADDR_UNSET, 1394 .tuner_addr = ADDR_UNSET,
1987},{ 1395 .radio_addr = ADDR_UNSET,
1988 .name = "IVC-100", 1396 },
1989 .video_inputs = 4, 1397
1990 .audio_inputs = 0, 1398 /* ---- card 0x40 ---------------------------------- */
1991 .tuner = -1, 1399 [BTTV_BOARD_ATI_TVWONDERVE] = {
1992 .tuner_type = -1, 1400 /* Lukas Gebauer <geby@volny.cz> */
1993 .tuner_addr = ADDR_UNSET, 1401 .name = "ATI TV-Wonder VE",
1994 .svhs = -1, 1402 .video_inputs = 2,
1995 .gpiomask = 0xdf, 1403 .audio_inputs = 1,
1996 .muxsel = { 2, 3, 1, 0 }, 1404 .tuner = 0,
1997 .pll = PLL_28, 1405 .svhs = -1,
1998},{ 1406 .gpiomask = 1,
1999 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */ 1407 .muxsel = { 2, 3, 0, 1},
2000 .name = "IVC-120G", 1408 .audiomux = { 0, 0, 1, 0, 0},
2001 .video_inputs = 16, 1409 .no_msp34xx = 1,
2002 .audio_inputs = 0, /* card has no audio */ 1410 .pll = PLL_28,
2003 .tuner = -1, /* card has no tuner */ 1411 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
2004 .tuner_type = -1, 1412 .tuner_addr = ADDR_UNSET,
2005 .tuner_addr = ADDR_UNSET, 1413 .radio_addr = ADDR_UNSET,
2006 .svhs = -1, /* card has no svhs */ 1414 },
2007 .needs_tvaudio = 0, 1415 [BTTV_BOARD_FLYVIDEO2000] = {
2008 .no_msp34xx = 1, 1416 /* DeeJay <deejay@westel900.net (2000S) */
2009 .no_tda9875 = 1, 1417 .name = "Lifeview FlyVideo 2000S LR90",
2010 .no_tda7432 = 1, 1418 .video_inputs = 3,
2011 .gpiomask = 0x00, 1419 .audio_inputs = 3,
2012 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 1420 .tuner = 0,
2013 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }, 1421 .svhs = 2,
2014 .muxsel_hook = ivc120_muxsel, 1422 .gpiomask = 0x18e0,
2015 .pll = PLL_28, 1423 .muxsel = { 2, 3, 0, 1},
2016},{ 1424 /* Radio changed from 1e80 to 0x800 to make
2017 1425 FlyVideo2000S in .hu happy (gm)*/
2018 /* ---- card 0x70 ---------------------------------- */ 1426 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
2019 .name = "pcHDTV HD-2000 TV", 1427 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
2020 .video_inputs = 4, 1428 .audio_hook = fv2000s_audio,
2021 .audio_inputs = 1, 1429 .no_msp34xx = 1,
2022 .tuner = 0, 1430 .no_tda9875 = 1,
2023 .svhs = 2, 1431 .needs_tvaudio = 1,
2024 .muxsel = { 2, 3, 1, 0}, 1432 .pll = PLL_28,
2025 .tuner_type = TUNER_PHILIPS_ATSC, 1433 .tuner_type = 5,
2026 .tuner_addr = ADDR_UNSET, 1434 .tuner_addr = ADDR_UNSET,
2027 .has_dvb = 1, 1435 .radio_addr = ADDR_UNSET,
2028},{ 1436 },
2029 .name = "Twinhan DST + clones", 1437 [BTTV_BOARD_TERRATVALUER] = {
2030 .no_msp34xx = 1, 1438 .name = "Terratec TValueRadio",
2031 .no_tda9875 = 1, 1439 .video_inputs = 3,
2032 .no_tda7432 = 1, 1440 .audio_inputs = 1,
2033 .tuner_type = TUNER_ABSENT, 1441 .tuner = 0,
2034 .tuner_addr = ADDR_UNSET, 1442 .svhs = 2,
2035 .no_video = 1, 1443 .gpiomask = 0xffff00,
2036 .has_dvb = 1, 1444 .muxsel = { 2, 3, 1, 1},
2037},{ 1445 .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
2038 .name = "Winfast VC100", 1446 .needs_tvaudio = 1,
2039 .video_inputs = 3, 1447 .pll = PLL_28,
2040 .audio_inputs = 0, 1448 .tuner_type = TUNER_PHILIPS_PAL,
2041 .svhs = 1, 1449 .tuner_addr = ADDR_UNSET,
2042 .tuner = -1, 1450 .radio_addr = ADDR_UNSET,
2043 .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */ 1451 .has_radio = 1,
2044 .no_msp34xx = 1, 1452 },
2045 .no_tda9875 = 1, 1453 [BTTV_BOARD_GVBCTV4PCI] = {
2046 .no_tda7432 = 1, 1454 /* TANAKA Kei <peg00625@nifty.com> */
2047 .tuner_type = TUNER_ABSENT, 1455 .name = "IODATA GV-BCTV4/PCI",
2048 .tuner_addr = ADDR_UNSET, 1456 .video_inputs = 3,
2049 .pll = PLL_28, 1457 .audio_inputs = 1,
2050},{ 1458 .tuner = 0,
2051 .name = "Teppro TEV-560/InterVision IV-560", 1459 .svhs = 2,
2052 .video_inputs = 3, 1460 .gpiomask = 0x010f00,
2053 .audio_inputs = 1, 1461 .muxsel = {2, 3, 0, 0},
2054 .tuner = 0, 1462 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
2055 .svhs = 2, 1463 .no_msp34xx = 1,
2056 .gpiomask = 3, 1464 .pll = PLL_28,
2057 .muxsel = { 2, 3, 1, 1}, 1465 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
2058 .audiomux = { 1, 1, 1, 1, 0}, 1466 .tuner_addr = ADDR_UNSET,
2059 .needs_tvaudio = 1, 1467 .radio_addr = ADDR_UNSET,
2060 .tuner_type = TUNER_PHILIPS_PAL, 1468 .audio_hook = gvbctv3pci_audio,
2061 .tuner_addr = ADDR_UNSET, 1469 },
2062 .pll = PLL_35, 1470
2063},{ 1471 /* ---- card 0x44 ---------------------------------- */
2064 1472 [BTTV_BOARD_VOODOOTV_FM] = {
2065 /* ---- card 0x74 ---------------------------------- */ 1473 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
2066 .name = "SIMUS GVC1100", 1474 /* try "insmod msp3400 simple=0" if you have
2067 .video_inputs = 4, 1475 * sound problems with this card. */
2068 .audio_inputs = 0, 1476 .video_inputs = 4,
2069 .tuner = -1, 1477 .audio_inputs = 1,
2070 .svhs = -1, 1478 .tuner = 0,
2071 .tuner_type = -1, 1479 .svhs = -1,
2072 .tuner_addr = ADDR_UNSET, 1480 .gpiomask = 0x4f8a00,
2073 .pll = PLL_28, 1481 /* 0x100000: 1=MSP enabled (0=disable again)
2074 .muxsel = { 2, 2, 2, 2}, 1482 * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
2075 .gpiomask = 0x3F, 1483 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
2076 .muxsel_hook = gvc1100_muxsel, 1484 /* tvtuner, radio, external,internal, mute, stereo
2077},{ 1485 * tuner, Composit, SVid, Composit-on-Svid-adapter */
2078 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */ 1486 .muxsel = { 2, 3 ,0 ,1},
2079 .name = "NGS NGSTV+", 1487 .tuner_type = TUNER_MT2032,
2080 .video_inputs = 3, 1488 .tuner_addr = ADDR_UNSET,
2081 .tuner = 0, 1489 .radio_addr = ADDR_UNSET,
2082 .svhs = 2, 1490 .pll = PLL_28,
2083 .gpiomask = 0x008007, 1491 .has_radio = 1,
2084 .muxsel = {2, 3, 0, 0}, 1492 },
2085 .audiomux = {0, 0, 0, 0, 0x000003, 0}, 1493 [BTTV_BOARD_AIMMS] = {
2086 .pll = PLL_28, 1494 /* Philip Blundell <pb@nexus.co.uk> */
2087 .tuner_type = TUNER_PHILIPS_PAL, 1495 .name = "Active Imaging AIMMS",
2088 .tuner_addr = ADDR_UNSET, 1496 .video_inputs = 1,
2089 .has_remote = 1, 1497 .audio_inputs = 0,
2090},{ 1498 .tuner = -1,
2091 /* http://linuxmedialabs.com */ 1499 .tuner_type = -1,
2092 .name = "LMLBT4", 1500 .tuner_addr = ADDR_UNSET,
2093 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ 1501 .radio_addr = ADDR_UNSET,
2094 .audio_inputs = 0, 1502 .pll = PLL_28,
2095 .tuner = -1, 1503 .muxsel = { 2 },
2096 .svhs = -1, 1504 .gpiomask = 0
2097 .muxsel = { 2, 3, 1, 0 }, 1505 },
2098 .no_msp34xx = 1, 1506 [BTTV_BOARD_PV_BT878P_PLUS] = {
2099 .no_tda9875 = 1, 1507 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
2100 .no_tda7432 = 1, 1508 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
2101 .needs_tvaudio = 0, 1509 .video_inputs = 3,
2102 .tuner_type = -1, 1510 .audio_inputs = 4,
2103 .tuner_addr = ADDR_UNSET, 1511 .tuner = 0,
2104},{ 1512 .svhs = 2,
2105 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */ 1513 .gpiomask = 15,
2106 .name = "Tekram M205 PRO", 1514 .muxsel = { 2, 3, 1, 1},
2107 .video_inputs = 3, 1515 .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
2108 .audio_inputs = 1, 1516 .needs_tvaudio = 1,
2109 .tuner = 0, 1517 .pll = PLL_28,
2110 .tuner_type = TUNER_PHILIPS_PAL, 1518 .tuner_type = 25,
2111 .tuner_addr = ADDR_UNSET, 1519 .tuner_addr = ADDR_UNSET,
2112 .svhs = 2, 1520 .radio_addr = ADDR_UNSET,
2113 .needs_tvaudio = 0, 1521 .has_remote = 1,
2114 .gpiomask = 0x68, 1522 /* GPIO wiring:
2115 .muxsel = { 2, 3, 1}, 1523 GPIO0: U4.A0 (hef4052bt)
2116 .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 }, 1524 GPIO1: U4.A1
2117 .pll = PLL_28, 1525 GPIO2: U4.A1 (second hef4052bt)
2118},{ 1526 GPIO3: U4.nEN, U5.A0, A5.nEN
2119 1527 GPIO8-15: vrd866b ?
2120 /* ---- card 0x78 ---------------------------------- */ 1528 */
2121 /* Javier Cendan Ares <jcendan@lycos.es> */ 1529 },
2122 /* bt878 TV + FM without subsystem ID */ 1530 [BTTV_BOARD_FLYVIDEO98EZ] = {
2123 .name = "Conceptronic CONTVFMi", 1531 .name = "Lifeview FlyVideo 98EZ (capture only) LR51",
2124 .video_inputs = 3, 1532 .video_inputs = 4,
2125 .audio_inputs = 1, 1533 .audio_inputs = 0,
2126 .tuner = 0, 1534 .tuner = -1,
2127 .svhs = 2, 1535 .svhs = 2,
2128 .gpiomask = 0x008007, 1536 .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */
2129 .muxsel = { 2, 3, 1, 1 }, 1537 .pll = PLL_28,
2130 .audiomux = { 0, 1, 2, 2, 3 }, 1538 .no_msp34xx = 1,
2131 .needs_tvaudio = 0, 1539 .tuner_type = UNSET,
2132 .pll = PLL_28, 1540 .tuner_addr = ADDR_UNSET,
2133 .tuner_type = TUNER_PHILIPS_PAL, 1541 .radio_addr = ADDR_UNSET,
2134 .tuner_addr = ADDR_UNSET, 1542 },
2135 .has_remote = 1, 1543
2136 .has_radio = 1, 1544 /* ---- card 0x48 ---------------------------------- */
2137},{ 1545 [BTTV_BOARD_PV_BT878P_9B] = {
2138 /*Eric DEBIEF <debief@telemsa.com>*/ 1546 /* Dariusz Kowalewski <darekk@automex.pl> */
2139 /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/ 1547 .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
2140 /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_PICOLO_TETRA_CHIP*/ 1548 .video_inputs = 4,
2141 /*0x79 in bttv.h*/ 1549 .audio_inputs = 1,
2142 .name = "Euresys Picolo Tetra", 1550 .tuner = 0,
2143 .video_inputs = 4, 1551 .svhs = 2,
2144 .audio_inputs = 0, 1552 .gpiomask = 0x3f,
2145 .tuner = -1, 1553 .muxsel = { 2, 3, 1, 1 },
2146 .svhs = -1, 1554 .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
2147 .gpiomask = 0, 1555 .needs_tvaudio = 1,
2148 .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ 1556 .no_msp34xx = 1,
2149 .no_msp34xx = 1, 1557 .no_tda9875 = 1,
2150 .no_tda9875 = 1, 1558 .pll = PLL_28,
2151 .no_tda7432 = 1, 1559 .tuner_type = 5,
2152 .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/ 1560 .tuner_addr = ADDR_UNSET,
2153 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1561 .radio_addr = ADDR_UNSET,
2154 .pll = PLL_28, 1562 .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */
2155 .needs_tvaudio = 0, 1563 .has_radio = 1, /* Note: not all cards have radio */
2156 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ 1564 .has_remote = 1,
2157 .tuner_type = -1, 1565 /* GPIO wiring:
2158 .tuner_addr = ADDR_UNSET, 1566 GPIO0: A0 hef4052
2159},{ 1567 GPIO1: A1 hef4052
2160 /* Spirit TV Tuner from http://spiritmodems.com.au */ 1568 GPIO3: nEN hef4052
2161 /* Stafford Goodsell <surge@goliath.homeunix.org> */ 1569 GPIO8-15: vrd866b
2162 .name = "Spirit TV Tuner", 1570 GPIO20,22,23: R30,R29,R28
2163 .video_inputs = 3, 1571 */
2164 .audio_inputs = 1, 1572 },
2165 .tuner = 0, 1573 [BTTV_BOARD_SENSORAY311] = {
2166 .svhs = 2, 1574 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */
2167 .gpiomask = 0x0000000f, 1575 /* you must jumper JP5 for the card to work */
2168 .muxsel = { 2, 1, 1 }, 1576 .name = "Sensoray 311",
2169 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00}, 1577 .video_inputs = 5,
2170 .tuner_type = TUNER_TEMIC_PAL, 1578 .audio_inputs = 0,
2171 .tuner_addr = ADDR_UNSET, 1579 .tuner = -1,
2172 .no_msp34xx = 1, 1580 .svhs = 4,
2173 .no_tda9875 = 1, 1581 .gpiomask = 0,
2174},{ 1582 .muxsel = { 2, 3, 1, 0, 0},
2175 /* Wolfram Joost <wojo@frokaschwei.de> */ 1583 .audiomux = { 0 },
2176 .name = "AVerMedia AVerTV DVB-T 771", 1584 .needs_tvaudio = 0,
2177 .video_inputs = 2, 1585 .tuner_type = -1,
2178 .svhs = 1, 1586 .tuner_addr = ADDR_UNSET,
2179 .tuner = -1, 1587 .radio_addr = ADDR_UNSET,
2180 .tuner_type = TUNER_ABSENT, 1588 },
2181 .tuner_addr = ADDR_UNSET, 1589 [BTTV_BOARD_RV605] = {
2182 .muxsel = { 3 , 3 }, 1590 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */
2183 .no_msp34xx = 1, 1591 .name = "RemoteVision MX (RV605)",
2184 .no_tda9875 = 1, 1592 .video_inputs = 16,
2185 .no_tda7432 = 1, 1593 .audio_inputs = 0,
2186 .pll = PLL_28, 1594 .tuner = -1,
2187 .has_dvb = 1, 1595 .svhs = -1,
2188 .no_gpioirq = 1, 1596 .gpiomask = 0x00,
2189 .has_remote = 1, 1597 .gpiomask2 = 0x07ff,
2190},{ 1598 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
2191 /* ---- card 0x7c ---------------------------------- */ 1599 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
2192 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */ 1600 .no_msp34xx = 1,
2193 /* Based on the Nebula card data - added remote and new card number - BTTV_AVDVBT_761, see also ir-kbd-gpio.c */ 1601 .no_tda9875 = 1,
2194 .name = "AverMedia AverTV DVB-T 761", 1602 .tuner_type = -1,
2195 .video_inputs = 2, 1603 .tuner_addr = ADDR_UNSET,
2196 .tuner = -1, 1604 .radio_addr = ADDR_UNSET,
2197 .svhs = 1, 1605 .muxsel_hook = rv605_muxsel,
2198 .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */ 1606 },
2199 .no_msp34xx = 1, 1607 [BTTV_BOARD_POWERCLR_MTV878] = {
2200 .no_tda9875 = 1, 1608 .name = "Powercolor MTV878/ MTV878R/ MTV878F",
2201 .no_tda7432 = 1, 1609 .video_inputs = 3,
2202 .pll = PLL_28, 1610 .audio_inputs = 2,
2203 .tuner_type = -1, 1611 .tuner = 0,
2204 .tuner_addr = ADDR_UNSET, 1612 .svhs = 2,
2205 .has_dvb = 1, 1613 .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
2206 .no_gpioirq = 1, 1614 .muxsel = { 2, 1, 1, },
2207 .has_remote = 1, 1615 .audiomux = { 0, 1, 2, 2, 4 },
2208},{ 1616 .needs_tvaudio = 0,
2209 /* andre.schwarz@matrix-vision.de */ 1617 .tuner_type = TUNER_PHILIPS_PAL,
2210 .name = "MATRIX Vision Sigma-SQ", 1618 .tuner_addr = ADDR_UNSET,
2211 .video_inputs = 16, 1619 .radio_addr = ADDR_UNSET,
2212 .audio_inputs = 0, 1620 .pll = PLL_28,
2213 .tuner = -1, 1621 .has_radio = 1,
2214 .svhs = -1, 1622 },
2215 .gpiomask = 0x0, 1623
2216 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 1624 /* ---- card 0x4c ---------------------------------- */
2217 3, 3, 3, 3, 3, 3, 3, 3 }, 1625 [BTTV_BOARD_WINDVR] = {
2218 .muxsel_hook = sigmaSQ_muxsel, 1626 /* Masaki Suzuki <masaki@btree.org> */
2219 .audiomux = { 0 }, 1627 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
2220 .no_msp34xx = 1, 1628 .video_inputs = 3,
2221 .pll = PLL_28, 1629 .audio_inputs = 1,
2222 .tuner_type = -1, 1630 .tuner = 0,
2223 .tuner_addr = ADDR_UNSET, 1631 .svhs = 2,
2224},{ 1632 .gpiomask = 0x140007,
2225 /* andre.schwarz@matrix-vision.de */ 1633 .muxsel = { 2, 3, 1, 1 },
2226 .name = "MATRIX Vision Sigma-SLC", 1634 .audiomux = { 0, 1, 2, 3, 4, 0 },
2227 .video_inputs = 4, 1635 .tuner_type = TUNER_PHILIPS_NTSC,
2228 .audio_inputs = 0, 1636 .tuner_addr = ADDR_UNSET,
2229 .tuner = -1, 1637 .radio_addr = ADDR_UNSET,
2230 .svhs = -1, 1638 .audio_hook = windvr_audio,
2231 .gpiomask = 0x0, 1639 },
2232 .muxsel = { 2, 2, 2, 2 }, 1640 [BTTV_BOARD_GRANDTEC_MULTI] = {
2233 .muxsel_hook = sigmaSLC_muxsel, 1641 .name = "GrandTec Multi Capture Card (Bt878)",
2234 .audiomux = { 0 }, 1642 .video_inputs = 4,
2235 .no_msp34xx = 1, 1643 .audio_inputs = 0,
2236 .pll = PLL_28, 1644 .tuner = -1,
2237 .tuner_type = -1, 1645 .svhs = -1,
2238 .tuner_addr = ADDR_UNSET, 1646 .gpiomask = 0,
2239},{ 1647 .muxsel = { 2, 3, 1, 0 },
2240 /* BTTV_APAC_VIEWCOMP */ 1648 .audiomux = { 0 },
2241 /* Attila Kondoros <attila.kondoros@chello.hu> */ 1649 .needs_tvaudio = 0,
2242 /* bt878 TV + FM 0x00000000 subsystem ID */ 1650 .no_msp34xx = 1,
2243 .name = "APAC Viewcomp 878(AMAX)", 1651 .pll = PLL_28,
2244 .video_inputs = 2, 1652 .tuner_type = -1,
2245 .audio_inputs = 1, 1653 .tuner_addr = ADDR_UNSET,
2246 .tuner = 0, 1654 .radio_addr = ADDR_UNSET,
2247 .svhs = -1, 1655 },
2248 .gpiomask = 0xFF, 1656 [BTTV_BOARD_KWORLD] = {
2249 .muxsel = { 2, 3, 1, 1}, 1657 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
2250 .audiomux = { 2, 0, 0, 0, 10}, 1658 .video_inputs = 4,
2251 .needs_tvaudio = 0, 1659 .audio_inputs = 3,
2252 .pll = PLL_28, 1660 .tuner = 0,
2253 .tuner_type = TUNER_PHILIPS_PAL, 1661 .svhs = 2,
2254 .tuner_addr = ADDR_UNSET, 1662 .gpiomask = 7,
2255 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ 1663 .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
2256 .has_radio = 1, /* not every card has radio */ 1664 .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio!
2257},{ 1665 * This card lacks external Audio In, so we mute it on Ext. & Int.
2258 1666 * The PCB can take a sbx1637/sbx1673, wiring unknown.
2259 /* ---- card 0x80 ---------------------------------- */ 1667 * This card lacks PCI subsystem ID, sigh.
2260 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */ 1668 * audiomux=1: lower volume, 2+3: mute
2261 .name = "DViCO FusionHDTV DVB-T Lite", 1669 * btwincap uses 0x80000/0x80003
2262 .tuner = -1, 1670 */
2263 .no_msp34xx = 1, 1671 .needs_tvaudio = 0,
2264 .no_tda9875 = 1, 1672 .no_msp34xx = 1,
2265 .no_tda7432 = 1, 1673 .pll = PLL_28,
2266 .pll = PLL_28, 1674 .tuner_type = 5,
2267 .no_video = 1, 1675 .tuner_addr = ADDR_UNSET,
2268 .has_dvb = 1, 1676 .radio_addr = ADDR_UNSET,
2269 .tuner_type = -1, 1677 /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
2270 .tuner_addr = ADDR_UNSET, 1678 radio signal strength indicators work fine. */
2271},{ 1679 .has_radio = 1,
2272 /* Steven <photon38@pchome.com.tw> */ 1680 /* GPIO Info:
2273 .name = "V-Gear MyVCD", 1681 GPIO0,1: HEF4052 A0,A1
2274 .video_inputs = 3, 1682 GPIO2: HEF4052 nENABLE
2275 .audio_inputs = 1, 1683 GPIO3-7: n.c.
2276 .tuner = 0, 1684 GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card]
2277 .svhs = 2, 1685 GPIO14,15: ??
2278 .gpiomask = 0x3f, 1686 GPIO16-21: n.c.
2279 .muxsel = {2, 3, 1, 0}, 1687 GPIO22,23: ??
2280 .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31}, 1688 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
2281 .no_msp34xx = 1, 1689 },
2282 .pll = PLL_28, 1690 [BTTV_BOARD_DSP_TCVIDEO] = {
2283 .tuner_type = TUNER_PHILIPS_NTSC_M, 1691 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
2284 .tuner_addr = ADDR_UNSET, 1692 .name = "DSP Design TCVIDEO",
2285 .has_radio = 0, 1693 .video_inputs = 4,
2286},{ 1694 .svhs = -1,
2287 /* Rick C <cryptdragoon@gmail.com> */ 1695 .muxsel = { 2, 3, 1, 0},
2288 .name = "Super TV Tuner", 1696 .pll = PLL_28,
2289 .video_inputs = 4, 1697 .tuner_type = -1,
2290 .audio_inputs = 1, 1698 .tuner_addr = ADDR_UNSET,
2291 .tuner = 0, 1699 .radio_addr = ADDR_UNSET,
2292 .svhs = 2, 1700 },
2293 .muxsel = { 2, 3, 1, 0}, 1701
2294 .tuner_type = TUNER_PHILIPS_NTSC, 1702 /* ---- card 0x50 ---------------------------------- */
2295 .tuner_addr = ADDR_UNSET, 1703 [BTTV_BOARD_HAUPPAUGEPVR] = {
2296 .gpiomask = 0x008007, 1704 .name = "Hauppauge WinTV PVR",
2297 .audiomux = { 0, 0x000001,0,0, 0}, 1705 .video_inputs = 4,
2298 .needs_tvaudio = 1, 1706 .audio_inputs = 1,
2299 .has_radio = 1, 1707 .tuner = 0,
2300},{ 1708 .svhs = 2,
2301 /* Chris Fanning <video4linux@haydon.net> */ 1709 .muxsel = { 2, 0, 1, 1},
2302 .name = "Tibet Systems 'Progress DVR' CS16", 1710 .needs_tvaudio = 1,
2303 .video_inputs = 16, 1711 .pll = PLL_28,
2304 .audio_inputs = 0, 1712 .tuner_type = -1,
2305 .tuner = -1, 1713 .tuner_addr = ADDR_UNSET,
2306 .svhs = -1, 1714 .radio_addr = ADDR_UNSET,
2307 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, 1715
2308 .pll = PLL_28, 1716 .gpiomask = 7,
2309 .no_msp34xx = 1, 1717 .audiomux = {7},
2310 .no_tda9875 = 1, 1718 },
2311 .no_tda7432 = 1, 1719 [BTTV_BOARD_GVBCTV5PCI] = {
2312 .tuner_type = -1, 1720 .name = "IODATA GV-BCTV5/PCI",
2313 .tuner_addr = ADDR_UNSET, 1721 .video_inputs = 3,
2314 .muxsel_hook = tibetCS16_muxsel, 1722 .audio_inputs = 1,
2315}, 1723 .tuner = 0,
2316{ 1724 .svhs = 2,
2317 /* Bill Brack <wbrack@mmm.com.hk> */ 1725 .gpiomask = 0x0f0f80,
2318 /* 1726 .muxsel = {2, 3, 1, 0},
2319 * Note that, because of the card's wiring, the "master" 1727 .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0},
2320 * BT878A chip (i.e. the one which controls the analog switch 1728 .no_msp34xx = 1,
2321 * and must use this card type) is the 2nd one detected. The 1729 .pll = PLL_28,
2322 * other 3 chips should use card type 0x85, whose description 1730 .tuner_type = TUNER_PHILIPS_NTSC_M,
2323 * follows this one. There is a EEPROM on the card (which is 1731 .tuner_addr = ADDR_UNSET,
2324 * connected to the I2C of one of those other chips), but is 1732 .radio_addr = ADDR_UNSET,
2325 * not currently handled. There is also a facility for a 1733 .audio_hook = gvbctv5pci_audio,
2326 * "monitor", which is also not currently implemented. 1734 .has_radio = 1,
2327 */ 1735 },
2328 .name = "Kodicom 4400R (master)", 1736 [BTTV_BOARD_OSPREY1x0] = {
2329 .video_inputs = 16, 1737 .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
2330 .audio_inputs = 0, 1738 .video_inputs = 4, /* id-inputs-clock */
2331 .tuner = -1, 1739 .audio_inputs = 0,
2332 .tuner_type = -1, 1740 .tuner = -1,
2333 .tuner_addr = ADDR_UNSET, 1741 .svhs = 3,
2334 .svhs = -1, 1742 .muxsel = { 3, 2, 0, 1 },
2335 /* GPIO bits 0-9 used for analog switch: 1743 .pll = PLL_28,
2336 * 00 - 03: camera selector 1744 .tuner_type = -1,
2337 * 04 - 06: channel (controller) selector 1745 .tuner_addr = ADDR_UNSET,
2338 * 07: data (1->on, 0->off) 1746 .radio_addr = ADDR_UNSET,
2339 * 08: strobe 1747 .no_msp34xx = 1,
2340 * 09: reset 1748 .no_tda9875 = 1,
2341 * bit 16 is input from sync separator for the channel 1749 .no_tda7432 = 1,
2342 */ 1750 },
2343 .gpiomask = 0x0003ff, 1751 [BTTV_BOARD_OSPREY1x0_848] = {
2344 .no_gpioirq = 1, 1752 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
2345 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 1753 .video_inputs = 3,
2346 .pll = PLL_28, 1754 .audio_inputs = 0,
2347 .no_msp34xx = 1, 1755 .tuner = -1,
2348 .no_tda7432 = 1, 1756 .svhs = 2,
2349 .no_tda9875 = 1, 1757 .muxsel = { 2, 3, 1 },
2350 .muxsel_hook = kodicom4400r_muxsel, 1758 .pll = PLL_28,
2351}, 1759 .tuner_type = -1,
2352{ 1760 .tuner_addr = ADDR_UNSET,
2353 /* Bill Brack <wbrack@mmm.com.hk> */ 1761 .radio_addr = ADDR_UNSET,
2354 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the 1762 .no_msp34xx = 1,
2355 * one which controls the analog switch, and must use the card type) 1763 .no_tda9875 = 1,
2356 * is the 2nd one detected. The other 3 chips should use this card 1764 .no_tda7432 = 1,
2357 * type 1765 },
1766
1767 /* ---- card 0x54 ---------------------------------- */
1768 [BTTV_BOARD_OSPREY101_848] = {
1769 .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
1770 .video_inputs = 2,
1771 .audio_inputs = 0,
1772 .tuner = -1,
1773 .svhs = 1,
1774 .muxsel = { 3, 1 },
1775 .pll = PLL_28,
1776 .tuner_type = -1,
1777 .tuner_addr = ADDR_UNSET,
1778 .radio_addr = ADDR_UNSET,
1779 .no_msp34xx = 1,
1780 .no_tda9875 = 1,
1781 .no_tda7432 = 1,
1782 },
1783 [BTTV_BOARD_OSPREY1x1] = {
1784 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
1785 .video_inputs = 1,
1786 .audio_inputs = 0,
1787 .tuner = -1,
1788 .svhs = -1,
1789 .muxsel = { 0 },
1790 .pll = PLL_28,
1791 .tuner_type = -1,
1792 .tuner_addr = ADDR_UNSET,
1793 .radio_addr = ADDR_UNSET,
1794 .no_msp34xx = 1,
1795 .no_tda9875 = 1,
1796 .no_tda7432 = 1,
1797 },
1798 [BTTV_BOARD_OSPREY1x1_SVID] = {
1799 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
1800 .video_inputs = 2,
1801 .audio_inputs = 0,
1802 .tuner = -1,
1803 .svhs = 1,
1804 .muxsel = { 0, 1 },
1805 .pll = PLL_28,
1806 .tuner_type = -1,
1807 .tuner_addr = ADDR_UNSET,
1808 .radio_addr = ADDR_UNSET,
1809 .no_msp34xx = 1,
1810 .no_tda9875 = 1,
1811 .no_tda7432 = 1,
1812 },
1813 [BTTV_BOARD_OSPREY2xx] = {
1814 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
1815 .video_inputs = 1,
1816 .audio_inputs = 1,
1817 .tuner = -1,
1818 .svhs = -1,
1819 .muxsel = { 0 },
1820 .pll = PLL_28,
1821 .tuner_type = UNSET,
1822 .tuner_addr = ADDR_UNSET,
1823 .radio_addr = ADDR_UNSET,
1824 .no_msp34xx = 1,
1825 .no_tda9875 = 1,
1826 .no_tda7432 = 1,
1827 },
1828
1829 /* ---- card 0x58 ---------------------------------- */
1830 [BTTV_BOARD_OSPREY2x0_SVID] = {
1831 .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
1832 .video_inputs = 2,
1833 .audio_inputs = 1,
1834 .tuner = -1,
1835 .svhs = 1,
1836 .muxsel = { 0, 1 },
1837 .pll = PLL_28,
1838 .tuner_type = UNSET,
1839 .tuner_addr = ADDR_UNSET,
1840 .radio_addr = ADDR_UNSET,
1841 .no_msp34xx = 1,
1842 .no_tda9875 = 1,
1843 .no_tda7432 = 1,
1844 },
1845 [BTTV_BOARD_OSPREY2x0] = {
1846 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */
1847 .video_inputs = 2,
1848 .audio_inputs = 1,
1849 .tuner = -1,
1850 .svhs = 1,
1851 .muxsel = { 2, 3 },
1852 .pll = PLL_28,
1853 .tuner_type = UNSET,
1854 .tuner_addr = ADDR_UNSET,
1855 .radio_addr = ADDR_UNSET,
1856 .no_msp34xx = 1,
1857 .no_tda9875 = 1,
1858 .no_tda7432 = 1,
1859 },
1860 [BTTV_BOARD_OSPREY500] = {
1861 .name = "Osprey 500", /* 500 */
1862 .video_inputs = 2,
1863 .audio_inputs = 1,
1864 .tuner = -1,
1865 .svhs = 1,
1866 .muxsel = { 2, 3 },
1867 .pll = PLL_28,
1868 .tuner_type = -1,
1869 .tuner_addr = ADDR_UNSET,
1870 .radio_addr = ADDR_UNSET,
1871 .no_msp34xx = 1,
1872 .no_tda9875 = 1,
1873 .no_tda7432 = 1,
1874 },
1875 [BTTV_BOARD_OSPREY540] = {
1876 .name = "Osprey 540", /* 540 */
1877 .video_inputs = 4,
1878 .audio_inputs = 1,
1879 .tuner = -1,
1880 #if 0 /* TODO ... */
1881 .svhs = OSPREY540_SVID_ANALOG,
1882 .muxsel = { [OSPREY540_COMP_ANALOG] = 2,
1883 [OSPREY540_SVID_ANALOG] = 3, },
1884 #endif
1885 .pll = PLL_28,
1886 .tuner_type = -1,
1887 .tuner_addr = ADDR_UNSET,
1888 .radio_addr = ADDR_UNSET,
1889 .no_msp34xx = 1,
1890 .no_tda9875 = 1,
1891 .no_tda7432 = 1,
1892 #if 0 /* TODO ... */
1893 .muxsel_hook = osprey_540_muxsel,
1894 .picture_hook = osprey_540_set_picture,
1895 #endif
1896 },
1897
1898 /* ---- card 0x5C ---------------------------------- */
1899 [BTTV_BOARD_OSPREY2000] = {
1900 .name = "Osprey 2000", /* 2000 */
1901 .video_inputs = 2,
1902 .audio_inputs = 1,
1903 .tuner = -1,
1904 .svhs = 1,
1905 .muxsel = { 2, 3 },
1906 .pll = PLL_28,
1907 .tuner_type = UNSET,
1908 .tuner_addr = ADDR_UNSET,
1909 .radio_addr = ADDR_UNSET,
1910 .no_msp34xx = 1,
1911 .no_tda9875 = 1,
1912 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
1913 },
1914 [BTTV_BOARD_IDS_EAGLE] = {
1915 /* M G Berberich <berberic@forwiss.uni-passau.de> */
1916 .name = "IDS Eagle",
1917 .video_inputs = 4,
1918 .audio_inputs = 0,
1919 .tuner = -1,
1920 .tuner_type = -1,
1921 .tuner_addr = ADDR_UNSET,
1922 .radio_addr = ADDR_UNSET,
1923 .svhs = -1,
1924 .gpiomask = 0,
1925 .muxsel = { 0, 1, 2, 3 },
1926 .muxsel_hook = eagle_muxsel,
1927 .no_msp34xx = 1,
1928 .no_tda9875 = 1,
1929 .pll = PLL_28,
1930 },
1931 [BTTV_BOARD_PINNACLESAT] = {
1932 .name = "Pinnacle PCTV Sat",
1933 .video_inputs = 2,
1934 .audio_inputs = 0,
1935 .svhs = 1,
1936 .tuner = -1,
1937 .tuner_type = -1,
1938 .tuner_addr = ADDR_UNSET,
1939 .radio_addr = ADDR_UNSET,
1940 .no_msp34xx = 1,
1941 .no_tda9875 = 1,
1942 .no_tda7432 = 1,
1943 .muxsel = { 3, 0, 1, 2},
1944 .pll = PLL_28,
1945 .no_gpioirq = 1,
1946 .has_dvb = 1,
1947 },
1948 [BTTV_BOARD_FORMAC_PROTV] = {
1949 .name = "Formac ProTV II (bt878)",
1950 .video_inputs = 4,
1951 .audio_inputs = 1,
1952 .tuner = 0,
1953 .svhs = 3,
1954 .gpiomask = 2,
1955 /* TV, Comp1, Composite over SVID con, SVID */
1956 .muxsel = { 2, 3, 1, 1},
1957 .audiomux = { 2, 2, 0, 0, 0 },
1958 .pll = PLL_28,
1959 .has_radio = 1,
1960 .tuner_type = TUNER_PHILIPS_PAL,
1961 .tuner_addr = ADDR_UNSET,
1962 .radio_addr = ADDR_UNSET,
1963 /* sound routing:
1964 GPIO=0x00,0x01,0x03: mute (?)
1965 0x02: both TV and radio (tuner: FM1216/I)
1966 The card has onboard audio connectors labeled "cdrom" and "board",
1967 not soldered here, though unknown wiring.
1968 Card lacks: external audio in, pci subsystem id.
2358 */ 1969 */
2359 .name = "Kodicom 4400R (slave)", 1970 },
2360 .video_inputs = 16, 1971
2361 .audio_inputs = 0, 1972 /* ---- card 0x60 ---------------------------------- */
2362 .tuner = -1, 1973 [BTTV_BOARD_MACHTV] = {
2363 .tuner_type = -1, 1974 .name = "MachTV",
2364 .tuner_addr = ADDR_UNSET, 1975 .video_inputs = 3,
2365 .svhs = -1, 1976 .audio_inputs = 1,
2366 .gpiomask = 0x010000, 1977 .tuner = 0,
2367 .no_gpioirq = 1, 1978 .svhs = -1,
2368 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 1979 .gpiomask = 7,
2369 .pll = PLL_28, 1980 .muxsel = { 2, 3, 1, 1},
2370 .no_msp34xx = 1, 1981 .audiomux = { 0, 1, 2, 3, 4},
2371 .no_tda7432 = 1, 1982 .needs_tvaudio = 1,
2372 .no_tda9875 = 1, 1983 .tuner_type = 5,
2373 .muxsel_hook = kodicom4400r_muxsel, 1984 .tuner_addr = ADDR_UNSET,
2374}, 1985 .radio_addr = ADDR_UNSET,
2375{ 1986 .pll = PLL_28,
2376 /* ---- card 0x86---------------------------------- */ 1987 },
2377 /* Michael Henson <mhenson@clarityvi.com> */ 1988 [BTTV_BOARD_EURESYS_PICOLO] = {
2378 /* Adlink RTV24 with special unlock codes */ 1989 .name = "Euresys Picolo",
2379 .name = "Adlink RTV24", 1990 .video_inputs = 3,
2380 .video_inputs = 4, 1991 .audio_inputs = 0,
2381 .audio_inputs = 1, 1992 .tuner = -1,
2382 .tuner = 0, 1993 .svhs = 2,
2383 .svhs = 2, 1994 .gpiomask = 0,
2384 .muxsel = { 2, 3, 1, 0}, 1995 .no_msp34xx = 1,
2385 .tuner_type = -1, 1996 .no_tda9875 = 1,
2386 .tuner_addr = ADDR_UNSET, 1997 .no_tda7432 = 1,
2387 .pll = PLL_28, 1998 .muxsel = { 2, 0, 1},
2388}, 1999 .pll = PLL_28,
2389{ 2000 .tuner_type = UNSET,
2390 /* ---- card 0x87---------------------------------- */ 2001 .tuner_addr = ADDR_UNSET,
2391 /* Michael Krufky <mkrufky@m1k.net> */ 2002 .radio_addr = ADDR_UNSET,
2392 .name = "DViCO FusionHDTV 5 Lite", 2003 },
2393 .tuner = 0, 2004 [BTTV_BOARD_PV150] = {
2394 .tuner_type = TUNER_LG_TDVS_H062F, 2005 /* Luc Van Hoeylandt <luc@e-magic.be> */
2395 .tuner_addr = ADDR_UNSET, 2006 .name = "ProVideo PV150", /* 0x4f */
2396 .video_inputs = 3, 2007 .video_inputs = 2,
2397 .audio_inputs = 1, 2008 .audio_inputs = 0,
2398 .svhs = 2, 2009 .tuner = -1,
2399 .muxsel = { 2, 3, 1 }, 2010 .svhs = -1,
2400 .gpiomask = 0x00e00007, 2011 .gpiomask = 0,
2401 .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 }, 2012 .muxsel = { 2, 3 },
2402 .no_msp34xx = 1, 2013 .audiomux = { 0 },
2403 .no_tda9875 = 1, 2014 .needs_tvaudio = 0,
2404 .no_tda7432 = 1, 2015 .no_msp34xx = 1,
2405},{ 2016 .pll = PLL_28,
2406 /* ---- card 0x88---------------------------------- */ 2017 .tuner_type = UNSET,
2407 /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */ 2018 .tuner_addr = ADDR_UNSET,
2408 .name = "Acorp Y878F", 2019 .radio_addr = ADDR_UNSET,
2409 .video_inputs = 3, 2020 },
2410 .audio_inputs = 1, 2021 [BTTV_BOARD_AD_TVK503] = {
2411 .tuner = 0, 2022 /* Hiroshi Takekawa <sian@big.or.jp> */
2412 .svhs = 2, 2023 /* This card lacks subsystem ID */
2413 .gpiomask = 0x01fe00, 2024 .name = "AD-TVK503", /* 0x63 */
2414 .muxsel = { 2, 3, 1, 1}, 2025 .video_inputs = 4,
2415 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, 2026 .audio_inputs = 1,
2416 .needs_tvaudio = 1, 2027 .tuner = 0,
2417 .pll = PLL_28, 2028 .svhs = 2,
2418 .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, 2029 .gpiomask = 0x001e8007,
2419 .tuner_addr = 0xc1 >>1, 2030 .muxsel = { 2, 3, 1, 0 },
2420 .has_radio = 1, 2031 /* Tuner, Radio, external, internal, off, on */
2421}}; 2032 .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 },
2033 .needs_tvaudio = 0,
2034 .no_msp34xx = 1,
2035 .pll = PLL_28,
2036 .tuner_type = 2,
2037 .tuner_addr = ADDR_UNSET,
2038 .radio_addr = ADDR_UNSET,
2039 .audio_hook = adtvk503_audio,
2040 },
2041
2042 /* ---- card 0x64 ---------------------------------- */
2043 [BTTV_BOARD_HERCULES_SM_TV] = {
2044 .name = "Hercules Smart TV Stereo",
2045 .video_inputs = 4,
2046 .audio_inputs = 1,
2047 .tuner = 0,
2048 .svhs = 2,
2049 .gpiomask = 0x00,
2050 .muxsel = { 2, 3, 1, 1 },
2051 .needs_tvaudio = 1,
2052 .no_msp34xx = 1,
2053 .pll = PLL_28,
2054 .tuner_type = 5,
2055 .tuner_addr = ADDR_UNSET,
2056 .radio_addr = ADDR_UNSET,
2057 /* Notes:
2058 - card lacks subsystem ID
2059 - stereo variant w/ daughter board with tda9874a @0xb0
2060 - Audio Routing:
2061 always from tda9874 independent of GPIO (?)
2062 external line in: unknown
2063 - Other chips: em78p156elp @ 0x96 (probably IR remote control)
2064 hef4053 (instead 4052) for unknown function
2065 */
2066 },
2067 [BTTV_BOARD_PACETV] = {
2068 .name = "Pace TV & Radio Card",
2069 .video_inputs = 4,
2070 .audio_inputs = 1,
2071 .tuner = 0,
2072 .svhs = 2,
2073 .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */
2074 .gpiomask = 0,
2075 .no_tda9875 = 1,
2076 .no_tda7432 = 1,
2077 .tuner_type = 1,
2078 .tuner_addr = ADDR_UNSET,
2079 .radio_addr = ADDR_UNSET,
2080 .has_radio = 1,
2081 .pll = PLL_28,
2082 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
2083 only internal line out: (4pin header) RGGL
2084 Radio must be decoded by msp3410d (not routed through)*/
2085 /*
2086 .digital_mode = DIGITAL_MODE_CAMERA, todo!
2087 */
2088 },
2089 [BTTV_BOARD_IVC200] = {
2090 /* Chris Willing <chris@vislab.usyd.edu.au> */
2091 .name = "IVC-200",
2092 .video_inputs = 1,
2093 .audio_inputs = 0,
2094 .tuner = -1,
2095 .tuner_type = -1,
2096 .tuner_addr = ADDR_UNSET,
2097 .radio_addr = ADDR_UNSET,
2098 .svhs = -1,
2099 .gpiomask = 0xdf,
2100 .muxsel = { 2 },
2101 .pll = PLL_28,
2102 },
2103 [BTTV_BOARD_XGUARD] = {
2104 .name = "Grand X-Guard / Trust 814PCI",
2105 .video_inputs = 16,
2106 .audio_inputs = 0,
2107 .tuner = -1,
2108 .svhs = -1,
2109 .tuner_type = 4,
2110 .tuner_addr = ADDR_UNSET,
2111 .radio_addr = ADDR_UNSET,
2112 .gpiomask2 = 0xff,
2113 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
2114 .muxsel_hook = xguard_muxsel,
2115 .no_msp34xx = 1,
2116 .no_tda9875 = 1,
2117 .no_tda7432 = 1,
2118 .pll = PLL_28,
2119 },
2120
2121 /* ---- card 0x68 ---------------------------------- */
2122 [BTTV_BOARD_NEBULA_DIGITV] = {
2123 .name = "Nebula Electronics DigiTV",
2124 .video_inputs = 1,
2125 .tuner = -1,
2126 .svhs = -1,
2127 .muxsel = { 2, 3, 1, 0},
2128 .no_msp34xx = 1,
2129 .no_tda9875 = 1,
2130 .no_tda7432 = 1,
2131 .pll = PLL_28,
2132 .tuner_type = -1,
2133 .tuner_addr = ADDR_UNSET,
2134 .radio_addr = ADDR_UNSET,
2135 .has_dvb = 1,
2136 .no_gpioirq = 1,
2137 },
2138 [BTTV_BOARD_PV143] = {
2139 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
2140 .name = "ProVideo PV143",
2141 .video_inputs = 4,
2142 .audio_inputs = 0,
2143 .tuner = -1,
2144 .svhs = -1,
2145 .gpiomask = 0,
2146 .muxsel = { 2, 3, 1, 0 },
2147 .audiomux = { 0 },
2148 .needs_tvaudio = 0,
2149 .no_msp34xx = 1,
2150 .pll = PLL_28,
2151 .tuner_type = -1,
2152 .tuner_addr = ADDR_UNSET,
2153 .radio_addr = ADDR_UNSET,
2154 },
2155 [BTTV_BOARD_VD009X1_MINIDIN] = {
2156 /* M.Klahr@phytec.de */
2157 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
2158 .video_inputs = 4,
2159 .audio_inputs = 0,
2160 .tuner = -1, /* card has no tuner */
2161 .svhs = 3,
2162 .gpiomask = 0x00,
2163 .muxsel = { 2, 3, 1, 0},
2164 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2165 .needs_tvaudio = 1,
2166 .pll = PLL_28,
2167 .tuner_type = -1,
2168 .tuner_addr = ADDR_UNSET,
2169 .radio_addr = ADDR_UNSET,
2170 },
2171 [BTTV_BOARD_VD009X1_COMBI] = {
2172 .name = "PHYTEC VD-009-X1 Combi (bt878)",
2173 .video_inputs = 4,
2174 .audio_inputs = 0,
2175 .tuner = -1, /* card has no tuner */
2176 .svhs = 3,
2177 .gpiomask = 0x00,
2178 .muxsel = { 2, 3, 1, 1},
2179 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2180 .needs_tvaudio = 1,
2181 .pll = PLL_28,
2182 .tuner_type = -1,
2183 .tuner_addr = ADDR_UNSET,
2184 .radio_addr = ADDR_UNSET,
2185 },
2186
2187 /* ---- card 0x6c ---------------------------------- */
2188 [BTTV_BOARD_VD009_MINIDIN] = {
2189 .name = "PHYTEC VD-009 MiniDIN (bt878)",
2190 .video_inputs = 10,
2191 .audio_inputs = 0,
2192 .tuner = -1, /* card has no tuner */
2193 .svhs = 9,
2194 .gpiomask = 0x00,
2195 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
2196 via the upper nibble of muxsel. here: used for
2197 xternal video-mux */
2198 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
2199 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2200 .needs_tvaudio = 1,
2201 .pll = PLL_28,
2202 .tuner_type = -1,
2203 .tuner_addr = ADDR_UNSET,
2204 .radio_addr = ADDR_UNSET,
2205 },
2206 [BTTV_BOARD_VD009_COMBI] = {
2207 .name = "PHYTEC VD-009 Combi (bt878)",
2208 .video_inputs = 10,
2209 .audio_inputs = 0,
2210 .tuner = -1, /* card has no tuner */
2211 .svhs = 9,
2212 .gpiomask = 0x00,
2213 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
2214 via the upper nibble of muxsel. here: used for
2215 xternal video-mux */
2216 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
2217 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2218 .needs_tvaudio = 1,
2219 .pll = PLL_28,
2220 .tuner_type = -1,
2221 .tuner_addr = ADDR_UNSET,
2222 .radio_addr = ADDR_UNSET,
2223 },
2224 [BTTV_BOARD_IVC100] = {
2225 .name = "IVC-100",
2226 .video_inputs = 4,
2227 .audio_inputs = 0,
2228 .tuner = -1,
2229 .tuner_type = -1,
2230 .tuner_addr = ADDR_UNSET,
2231 .radio_addr = ADDR_UNSET,
2232 .svhs = -1,
2233 .gpiomask = 0xdf,
2234 .muxsel = { 2, 3, 1, 0 },
2235 .pll = PLL_28,
2236 },
2237 [BTTV_BOARD_IVC120] = {
2238 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */
2239 .name = "IVC-120G",
2240 .video_inputs = 16,
2241 .audio_inputs = 0, /* card has no audio */
2242 .tuner = -1, /* card has no tuner */
2243 .tuner_type = -1,
2244 .tuner_addr = ADDR_UNSET,
2245 .radio_addr = ADDR_UNSET,
2246 .svhs = -1, /* card has no svhs */
2247 .needs_tvaudio = 0,
2248 .no_msp34xx = 1,
2249 .no_tda9875 = 1,
2250 .no_tda7432 = 1,
2251 .gpiomask = 0x00,
2252 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
2253 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
2254 .muxsel_hook = ivc120_muxsel,
2255 .pll = PLL_28,
2256 },
2257
2258 /* ---- card 0x70 ---------------------------------- */
2259 [BTTV_BOARD_PC_HDTV] = {
2260 .name = "pcHDTV HD-2000 TV",
2261 .video_inputs = 4,
2262 .audio_inputs = 1,
2263 .tuner = 0,
2264 .svhs = 2,
2265 .muxsel = { 2, 3, 1, 0},
2266 .tuner_type = TUNER_PHILIPS_ATSC,
2267 .tuner_addr = ADDR_UNSET,
2268 .radio_addr = ADDR_UNSET,
2269 .has_dvb = 1,
2270 },
2271 [BTTV_BOARD_TWINHAN_DST] = {
2272 .name = "Twinhan DST + clones",
2273 .no_msp34xx = 1,
2274 .no_tda9875 = 1,
2275 .no_tda7432 = 1,
2276 .tuner_type = TUNER_ABSENT,
2277 .tuner_addr = ADDR_UNSET,
2278 .radio_addr = ADDR_UNSET,
2279 .no_video = 1,
2280 .has_dvb = 1,
2281 },
2282 [BTTV_BOARD_WINFASTVC100] = {
2283 .name = "Winfast VC100",
2284 .video_inputs = 3,
2285 .audio_inputs = 0,
2286 .svhs = 1,
2287 .tuner = -1,
2288 .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */
2289 .no_msp34xx = 1,
2290 .no_tda9875 = 1,
2291 .no_tda7432 = 1,
2292 .tuner_type = TUNER_ABSENT,
2293 .tuner_addr = ADDR_UNSET,
2294 .radio_addr = ADDR_UNSET,
2295 .pll = PLL_28,
2296 },
2297 [BTTV_BOARD_TEV560] = {
2298 .name = "Teppro TEV-560/InterVision IV-560",
2299 .video_inputs = 3,
2300 .audio_inputs = 1,
2301 .tuner = 0,
2302 .svhs = 2,
2303 .gpiomask = 3,
2304 .muxsel = { 2, 3, 1, 1},
2305 .audiomux = { 1, 1, 1, 1, 0},
2306 .needs_tvaudio = 1,
2307 .tuner_type = TUNER_PHILIPS_PAL,
2308 .tuner_addr = ADDR_UNSET,
2309 .radio_addr = ADDR_UNSET,
2310 .pll = PLL_35,
2311 },
2312
2313 /* ---- card 0x74 ---------------------------------- */
2314 [BTTV_BOARD_SIMUS_GVC1100] = {
2315 .name = "SIMUS GVC1100",
2316 .video_inputs = 4,
2317 .audio_inputs = 0,
2318 .tuner = -1,
2319 .svhs = -1,
2320 .tuner_type = -1,
2321 .tuner_addr = ADDR_UNSET,
2322 .radio_addr = ADDR_UNSET,
2323 .pll = PLL_28,
2324 .muxsel = { 2, 2, 2, 2},
2325 .gpiomask = 0x3F,
2326 .muxsel_hook = gvc1100_muxsel,
2327 },
2328 [BTTV_BOARD_NGSTV_PLUS] = {
2329 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
2330 .name = "NGS NGSTV+",
2331 .video_inputs = 3,
2332 .tuner = 0,
2333 .svhs = 2,
2334 .gpiomask = 0x008007,
2335 .muxsel = {2, 3, 0, 0},
2336 .audiomux = {0, 0, 0, 0, 0x000003, 0},
2337 .pll = PLL_28,
2338 .tuner_type = TUNER_PHILIPS_PAL,
2339 .tuner_addr = ADDR_UNSET,
2340 .radio_addr = ADDR_UNSET,
2341 .has_remote = 1,
2342 },
2343 [BTTV_BOARD_LMLBT4] = {
2344 /* http://linuxmedialabs.com */
2345 .name = "LMLBT4",
2346 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
2347 .audio_inputs = 0,
2348 .tuner = -1,
2349 .svhs = -1,
2350 .muxsel = { 2, 3, 1, 0 },
2351 .no_msp34xx = 1,
2352 .no_tda9875 = 1,
2353 .no_tda7432 = 1,
2354 .needs_tvaudio = 0,
2355 .tuner_type = -1,
2356 .tuner_addr = ADDR_UNSET,
2357 .radio_addr = ADDR_UNSET,
2358 },
2359 [BTTV_BOARD_TEKRAM_M205] = {
2360 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */
2361 .name = "Tekram M205 PRO",
2362 .video_inputs = 3,
2363 .audio_inputs = 1,
2364 .tuner = 0,
2365 .tuner_type = TUNER_PHILIPS_PAL,
2366 .tuner_addr = ADDR_UNSET,
2367 .radio_addr = ADDR_UNSET,
2368 .svhs = 2,
2369 .needs_tvaudio = 0,
2370 .gpiomask = 0x68,
2371 .muxsel = { 2, 3, 1},
2372 .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 },
2373 .pll = PLL_28,
2374 },
2375
2376 /* ---- card 0x78 ---------------------------------- */
2377 [BTTV_BOARD_CONTVFMI] = {
2378 /* Javier Cendan Ares <jcendan@lycos.es> */
2379 /* bt878 TV + FM without subsystem ID */
2380 .name = "Conceptronic CONTVFMi",
2381 .video_inputs = 3,
2382 .audio_inputs = 1,
2383 .tuner = 0,
2384 .svhs = 2,
2385 .gpiomask = 0x008007,
2386 .muxsel = { 2, 3, 1, 1 },
2387 .audiomux = { 0, 1, 2, 2, 3 },
2388 .needs_tvaudio = 0,
2389 .pll = PLL_28,
2390 .tuner_type = TUNER_PHILIPS_PAL,
2391 .tuner_addr = ADDR_UNSET,
2392 .radio_addr = ADDR_UNSET,
2393 .has_remote = 1,
2394 .has_radio = 1,
2395 },
2396 [BTTV_BOARD_PICOLO_TETRA_CHIP] = {
2397 /*Eric DEBIEF <debief@telemsa.com>*/
2398 /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/
2399 /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/
2400 /*0x79 in bttv.h*/
2401 .name = "Euresys Picolo Tetra",
2402 .video_inputs = 4,
2403 .audio_inputs = 0,
2404 .tuner = -1,
2405 .svhs = -1,
2406 .gpiomask = 0,
2407 .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
2408 .no_msp34xx = 1,
2409 .no_tda9875 = 1,
2410 .no_tda7432 = 1,
2411 .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
2412 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2413 .pll = PLL_28,
2414 .needs_tvaudio = 0,
2415 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
2416 .tuner_type = -1,
2417 .tuner_addr = ADDR_UNSET,
2418 .radio_addr = ADDR_UNSET,
2419 },
2420 [BTTV_BOARD_SPIRIT_TV] = {
2421 /* Spirit TV Tuner from http://spiritmodems.com.au */
2422 /* Stafford Goodsell <surge@goliath.homeunix.org> */
2423 .name = "Spirit TV Tuner",
2424 .video_inputs = 3,
2425 .audio_inputs = 1,
2426 .tuner = 0,
2427 .svhs = 2,
2428 .gpiomask = 0x0000000f,
2429 .muxsel = { 2, 1, 1 },
2430 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00},
2431 .tuner_type = TUNER_TEMIC_PAL,
2432 .tuner_addr = ADDR_UNSET,
2433 .radio_addr = ADDR_UNSET,
2434 .no_msp34xx = 1,
2435 .no_tda9875 = 1,
2436 },
2437 [BTTV_BOARD_AVDVBT_771] = {
2438 /* Wolfram Joost <wojo@frokaschwei.de> */
2439 .name = "AVerMedia AVerTV DVB-T 771",
2440 .video_inputs = 2,
2441 .svhs = 1,
2442 .tuner = -1,
2443 .tuner_type = TUNER_ABSENT,
2444 .tuner_addr = ADDR_UNSET,
2445 .radio_addr = ADDR_UNSET,
2446 .muxsel = { 3 , 3 },
2447 .no_msp34xx = 1,
2448 .no_tda9875 = 1,
2449 .no_tda7432 = 1,
2450 .pll = PLL_28,
2451 .has_dvb = 1,
2452 .no_gpioirq = 1,
2453 .has_remote = 1,
2454 },
2455 /* ---- card 0x7c ---------------------------------- */
2456 [BTTV_BOARD_AVDVBT_761] = {
2457 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */
2458 /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */
2459 .name = "AverMedia AverTV DVB-T 761",
2460 .video_inputs = 2,
2461 .tuner = -1,
2462 .svhs = 1,
2463 .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */
2464 .no_msp34xx = 1,
2465 .no_tda9875 = 1,
2466 .no_tda7432 = 1,
2467 .pll = PLL_28,
2468 .tuner_type = -1,
2469 .tuner_addr = ADDR_UNSET,
2470 .radio_addr = ADDR_UNSET,
2471 .has_dvb = 1,
2472 .no_gpioirq = 1,
2473 .has_remote = 1,
2474 },
2475 [BTTV_BOARD_MATRIX_VISIONSQ] = {
2476 /* andre.schwarz@matrix-vision.de */
2477 .name = "MATRIX Vision Sigma-SQ",
2478 .video_inputs = 16,
2479 .audio_inputs = 0,
2480 .tuner = -1,
2481 .svhs = -1,
2482 .gpiomask = 0x0,
2483 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
2484 3, 3, 3, 3, 3, 3, 3, 3 },
2485 .muxsel_hook = sigmaSQ_muxsel,
2486 .audiomux = { 0 },
2487 .no_msp34xx = 1,
2488 .pll = PLL_28,
2489 .tuner_type = -1,
2490 .tuner_addr = ADDR_UNSET,
2491 .radio_addr = ADDR_UNSET,
2492 },
2493 [BTTV_BOARD_MATRIX_VISIONSLC] = {
2494 /* andre.schwarz@matrix-vision.de */
2495 .name = "MATRIX Vision Sigma-SLC",
2496 .video_inputs = 4,
2497 .audio_inputs = 0,
2498 .tuner = -1,
2499 .svhs = -1,
2500 .gpiomask = 0x0,
2501 .muxsel = { 2, 2, 2, 2 },
2502 .muxsel_hook = sigmaSLC_muxsel,
2503 .audiomux = { 0 },
2504 .no_msp34xx = 1,
2505 .pll = PLL_28,
2506 .tuner_type = -1,
2507 .tuner_addr = ADDR_UNSET,
2508 .radio_addr = ADDR_UNSET,
2509 },
2510 /* BTTV_BOARD_APAC_VIEWCOMP */
2511 [BTTV_BOARD_APAC_VIEWCOMP] = {
2512 /* Attila Kondoros <attila.kondoros@chello.hu> */
2513 /* bt878 TV + FM 0x00000000 subsystem ID */
2514 .name = "APAC Viewcomp 878(AMAX)",
2515 .video_inputs = 2,
2516 .audio_inputs = 1,
2517 .tuner = 0,
2518 .svhs = -1,
2519 .gpiomask = 0xFF,
2520 .muxsel = { 2, 3, 1, 1},
2521 .audiomux = { 2, 0, 0, 0, 10},
2522 .needs_tvaudio = 0,
2523 .pll = PLL_28,
2524 .tuner_type = TUNER_PHILIPS_PAL,
2525 .tuner_addr = ADDR_UNSET,
2526 .radio_addr = ADDR_UNSET,
2527 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
2528 .has_radio = 1, /* not every card has radio */
2529 },
2530
2531 /* ---- card 0x80 ---------------------------------- */
2532 [BTTV_BOARD_DVICO_DVBT_LITE] = {
2533 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
2534 .name = "DViCO FusionHDTV DVB-T Lite",
2535 .tuner = -1,
2536 .no_msp34xx = 1,
2537 .no_tda9875 = 1,
2538 .no_tda7432 = 1,
2539 .pll = PLL_28,
2540 .no_video = 1,
2541 .has_dvb = 1,
2542 .tuner_type = -1,
2543 .tuner_addr = ADDR_UNSET,
2544 .radio_addr = ADDR_UNSET,
2545 },
2546 [BTTV_BOARD_VGEAR_MYVCD] = {
2547 /* Steven <photon38@pchome.com.tw> */
2548 .name = "V-Gear MyVCD",
2549 .video_inputs = 3,
2550 .audio_inputs = 1,
2551 .tuner = 0,
2552 .svhs = 2,
2553 .gpiomask = 0x3f,
2554 .muxsel = {2, 3, 1, 0},
2555 .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31},
2556 .no_msp34xx = 1,
2557 .pll = PLL_28,
2558 .tuner_type = TUNER_PHILIPS_NTSC_M,
2559 .tuner_addr = ADDR_UNSET,
2560 .radio_addr = ADDR_UNSET,
2561 .has_radio = 0,
2562 #if 0
2563 .has_remote = 1,
2564 #endif
2565 },
2566 [BTTV_BOARD_SUPER_TV] = {
2567 /* Rick C <cryptdragoon@gmail.com> */
2568 .name = "Super TV Tuner",
2569 .video_inputs = 4,
2570 .audio_inputs = 1,
2571 .tuner = 0,
2572 .svhs = 2,
2573 .muxsel = { 2, 3, 1, 0},
2574 .tuner_type = TUNER_PHILIPS_NTSC,
2575 .tuner_addr = ADDR_UNSET,
2576 .radio_addr = ADDR_UNSET,
2577 .gpiomask = 0x008007,
2578 .audiomux = { 0, 0x000001,0,0, 0},
2579 .needs_tvaudio = 1,
2580 .has_radio = 1,
2581 },
2582 [BTTV_BOARD_TIBET_CS16] = {
2583 /* Chris Fanning <video4linux@haydon.net> */
2584 .name = "Tibet Systems 'Progress DVR' CS16",
2585 .video_inputs = 16,
2586 .audio_inputs = 0,
2587 .tuner = -1,
2588 .svhs = -1,
2589 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2590 .pll = PLL_28,
2591 .no_msp34xx = 1,
2592 .no_tda9875 = 1,
2593 .no_tda7432 = 1,
2594 .tuner_type = -1,
2595 .tuner_addr = ADDR_UNSET,
2596 .radio_addr = ADDR_UNSET,
2597 .muxsel_hook = tibetCS16_muxsel,
2598 },
2599 [BTTV_BOARD_KODICOM_4400R] = {
2600 /* Bill Brack <wbrack@mmm.com.hk> */
2601 /*
2602 * Note that, because of the card's wiring, the "master"
2603 * BT878A chip (i.e. the one which controls the analog switch
2604 * and must use this card type) is the 2nd one detected. The
2605 * other 3 chips should use card type 0x85, whose description
2606 * follows this one. There is a EEPROM on the card (which is
2607 * connected to the I2C of one of those other chips), but is
2608 * not currently handled. There is also a facility for a
2609 * "monitor", which is also not currently implemented.
2610 */
2611 .name = "Kodicom 4400R (master)",
2612 .video_inputs = 16,
2613 .audio_inputs = 0,
2614 .tuner = -1,
2615 .tuner_type = -1,
2616 .tuner_addr = ADDR_UNSET,
2617 .radio_addr = ADDR_UNSET,
2618 .svhs = -1,
2619 /* GPIO bits 0-9 used for analog switch:
2620 * 00 - 03: camera selector
2621 * 04 - 06: channel (controller) selector
2622 * 07: data (1->on, 0->off)
2623 * 08: strobe
2624 * 09: reset
2625 * bit 16 is input from sync separator for the channel
2626 */
2627 .gpiomask = 0x0003ff,
2628 .no_gpioirq = 1,
2629 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2630 .pll = PLL_28,
2631 .no_msp34xx = 1,
2632 .no_tda7432 = 1,
2633 .no_tda9875 = 1,
2634 .muxsel_hook = kodicom4400r_muxsel,
2635 },
2636 [BTTV_BOARD_KODICOM_4400R_SL] = {
2637 /* Bill Brack <wbrack@mmm.com.hk> */
2638 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
2639 * one which controls the analog switch, and must use the card type)
2640 * is the 2nd one detected. The other 3 chips should use this card
2641 * type
2642 */
2643 .name = "Kodicom 4400R (slave)",
2644 .video_inputs = 16,
2645 .audio_inputs = 0,
2646 .tuner = -1,
2647 .tuner_type = -1,
2648 .tuner_addr = ADDR_UNSET,
2649 .radio_addr = ADDR_UNSET,
2650 .svhs = -1,
2651 .gpiomask = 0x010000,
2652 .no_gpioirq = 1,
2653 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2654 .pll = PLL_28,
2655 .no_msp34xx = 1,
2656 .no_tda7432 = 1,
2657 .no_tda9875 = 1,
2658 .muxsel_hook = kodicom4400r_muxsel,
2659 },
2660 /* ---- card 0x86---------------------------------- */
2661 [BTTV_BOARD_ADLINK_RTV24] = {
2662 /* Michael Henson <mhenson@clarityvi.com> */
2663 /* Adlink RTV24 with special unlock codes */
2664 .name = "Adlink RTV24",
2665 .video_inputs = 4,
2666 .audio_inputs = 1,
2667 .tuner = 0,
2668 .svhs = 2,
2669 .muxsel = { 2, 3, 1, 0},
2670 .tuner_type = -1,
2671 .tuner_addr = ADDR_UNSET,
2672 .radio_addr = ADDR_UNSET,
2673 .pll = PLL_28,
2674 },
2675 /* ---- card 0x87---------------------------------- */
2676 [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = {
2677 /* Michael Krufky <mkrufky@m1k.net> */
2678 .name = "DViCO FusionHDTV 5 Lite",
2679 .tuner = 0,
2680 .tuner_type = TUNER_LG_TDVS_H062F,
2681 .tuner_addr = ADDR_UNSET,
2682 .radio_addr = ADDR_UNSET,
2683 .video_inputs = 3,
2684 .audio_inputs = 1,
2685 .svhs = 2,
2686 .muxsel = { 2, 3, 1 },
2687 .gpiomask = 0x00e00007,
2688 .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 },
2689 .no_msp34xx = 1,
2690 .no_tda9875 = 1,
2691 .no_tda7432 = 1,
2692 .has_dvb = 1,
2693 },
2694 /* ---- card 0x88---------------------------------- */
2695 [BTTV_BOARD_ACORP_Y878F] = {
2696 /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */
2697 .name = "Acorp Y878F",
2698 .video_inputs = 3,
2699 .audio_inputs = 1,
2700 .tuner = 0,
2701 .svhs = 2,
2702 .gpiomask = 0x01fe00,
2703 .muxsel = { 2, 3, 1, 1},
2704 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
2705 .needs_tvaudio = 1,
2706 .pll = PLL_28,
2707 .tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
2708 .tuner_addr = 0xc1 >>1,
2709 .radio_addr = 0xc1 >>1,
2710 .has_radio = 1,
2711 },
2712 /* ---- card 0x89 ---------------------------------- */
2713 [BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
2714 .name = "Conceptronic CTVFMi v2",
2715 .video_inputs = 3,
2716 .audio_inputs = 1,
2717 .tuner = 0,
2718 .svhs = 2,
2719 .gpiomask = 0x001c0007,
2720 .muxsel = { 2, 3, 1, 1 },
2721 .audiomux = { 0, 1, 2, 2, 3 },
2722 .needs_tvaudio = 0,
2723 .pll = PLL_28,
2724 .tuner_type = TUNER_TENA_9533_DI,
2725 .tuner_addr = ADDR_UNSET,
2726 .radio_addr = ADDR_UNSET,
2727 .has_remote = 1,
2728 .has_radio = 1,
2729 },
2730 /* ---- card 0x8a ---------------------------------- */
2731 [BTTV_BOARD_PV_BT878P_2E] = {
2732 .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
2733 .video_inputs = 5,
2734 .audio_inputs = 1,
2735 .tuner = 0,
2736 .svhs = 3,
2737 .gpiomask = 0x01fe00,
2738 .muxsel = { 2,3,1,1,-1 },
2739 .digital_mode = DIGITAL_MODE_CAMERA,
2740 .audiomux = { 0x00400, 0x10400, 0x04400, 0x80000, 0x12400, 0x46000 },
2741 .no_msp34xx = 1,
2742 .pll = PLL_28,
2743 .tuner_type = TUNER_LG_PAL_FM,
2744 .tuner_addr = ADDR_UNSET,
2745 .radio_addr = ADDR_UNSET,
2746 .has_remote = 1,
2747 },
2748 /* ---- card 0x8b ---------------------------------- */
2749 [BTTV_BOARD_PV_M4900] = {
2750 /* Sérgio Fortier <sergiofortier@yahoo.com.br> */
2751 .name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
2752 .video_inputs = 3,
2753 .audio_inputs = 1,
2754 .tuner = 0,
2755 .svhs = 2,
2756 .gpiomask = 0x3f,
2757 .muxsel = { 2, 3, 1, 1 },
2758 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
2759 .no_msp34xx = 1,
2760 .pll = PLL_28,
2761 .tuner_type = TUNER_YMEC_TVF_5533MF,
2762 .tuner_addr = ADDR_UNSET,
2763 .radio_addr = ADDR_UNSET,
2764 .has_radio = 1,
2765 .has_remote = 1,
2766 },
2767 /* ---- card 0x8c ---------------------------------- */
2768 [BTTV_BOARD_OSPREY440] = {
2769 .name = "Osprey 440",
2770 .video_inputs = 1,
2771 .audio_inputs = 1,
2772 .tuner = -1,
2773 .svhs = 1,
2774 .muxsel = { 2 },
2775 .pll = PLL_28,
2776 .tuner_type = UNSET,
2777 .tuner_addr = ADDR_UNSET,
2778 .radio_addr = ADDR_UNSET,
2779 .no_msp34xx = 1,
2780 .no_tda9875 = 1,
2781 .no_tda7432 = 1,
2782 },
2783 /* ---- card 0x8d ---------------------------------- */
2784 [BTTV_BOARD_ASOUND_SKYEYE] = {
2785 .name = "Asound Skyeye PCTV",
2786 .video_inputs = 3,
2787 .audio_inputs = 1,
2788 .tuner = 0,
2789 .svhs = 2,
2790 .gpiomask = 15,
2791 .muxsel = { 2, 3, 1, 1},
2792 .audiomux = {2,0,0,0,1},
2793 .needs_tvaudio = 1,
2794 .pll = PLL_28,
2795 .tuner_type = 2,
2796 .tuner_addr = ADDR_UNSET,
2797 .radio_addr = ADDR_UNSET,
2798 },
2799
2800};
2422 2801
2423static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); 2802static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
2424 2803
@@ -2461,7 +2840,7 @@ void __devinit bttv_idcard(struct bttv *btv)
2461 btv->c.nr, btv->cardid & 0xffff, 2840 btv->c.nr, btv->cardid & 0xffff,
2462 (btv->cardid >> 16) & 0xffff); 2841 (btv->cardid >> 16) & 0xffff);
2463 printk(KERN_DEBUG "please mail id, board name and " 2842 printk(KERN_DEBUG "please mail id, board name and "
2464 "the correct card= insmod option to kraxel@bytesex.org\n"); 2843 "the correct card= insmod option to video4linux-list@redhat.com\n");
2465 } 2844 }
2466 } 2845 }
2467 2846
@@ -2510,11 +2889,11 @@ void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
2510 int type = -1; 2889 int type = -1;
2511 2890
2512 if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13)) 2891 if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13))
2513 type = BTTV_MODTEC_205; 2892 type = BTTV_BOARD_MODTEC_205;
2514 else if (0 == strncmp(eeprom_data+20,"Picolo",7)) 2893 else if (0 == strncmp(eeprom_data+20,"Picolo",7))
2515 type = BTTV_EURESYS_PICOLO; 2894 type = BTTV_BOARD_EURESYS_PICOLO;
2516 else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0) 2895 else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
2517 type = BTTV_HAUPPAUGE; /* old bt848 */ 2896 type = BTTV_BOARD_HAUPPAUGE; /* old bt848 */
2518 2897
2519 if (-1 != type) { 2898 if (-1 != type) {
2520 btv->c.type = type; 2899 btv->c.type = type;
@@ -2548,7 +2927,7 @@ static void flyvideo_gpio(struct bttv *btv)
2548 switch(ttype) { 2927 switch(ttype) {
2549 case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */ 2928 case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */
2550 break; 2929 break;
2551 case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */ 2930 case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */
2552 break; 2931 break;
2553 case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */ 2932 case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
2554 break; 2933 break;
@@ -2564,7 +2943,7 @@ static void flyvideo_gpio(struct bttv *btv)
2564 has_radio = gpio & 0x400000; 2943 has_radio = gpio & 0x400000;
2565 /* unknown 0x200000; 2944 /* unknown 0x200000;
2566 * unknown2 0x100000; */ 2945 * unknown2 0x100000; */
2567 is_capture_only = !(gpio & 0x008000); /* GPIO15 */ 2946 is_capture_only = !(gpio & 0x008000); /* GPIO15 */
2568 has_tda9820_tda9821 = !(gpio & 0x004000); 2947 has_tda9820_tda9821 = !(gpio & 0x004000);
2569 is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */ 2948 is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */
2570 /* 2949 /*
@@ -2601,7 +2980,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2601 char *info; 2980 char *info;
2602 2981
2603 gpio_inout(0xffffff, 0); 2982 gpio_inout(0xffffff, 0);
2604 gpio = gpio_read(); 2983 gpio = gpio_read();
2605 id = ((gpio>>10) & 63) -1; 2984 id = ((gpio>>10) & 63) -1;
2606 msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx"); 2985 msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx");
2607 if (id < 32) { 2986 if (id < 32) {
@@ -2620,10 +2999,10 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2620 btv->has_radio = 0; 2999 btv->has_radio = 0;
2621 } 3000 }
2622 if (-1 != msp) { 3001 if (-1 != msp) {
2623 if (btv->c.type == BTTV_MIRO) 3002 if (btv->c.type == BTTV_BOARD_MIRO)
2624 btv->c.type = BTTV_MIROPRO; 3003 btv->c.type = BTTV_BOARD_MIROPRO;
2625 if (btv->c.type == BTTV_PINNACLE) 3004 if (btv->c.type == BTTV_BOARD_PINNACLE)
2626 btv->c.type = BTTV_PINNACLEPRO; 3005 btv->c.type = BTTV_BOARD_PINNACLEPRO;
2627 } 3006 }
2628 printk(KERN_INFO 3007 printk(KERN_INFO
2629 "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n", 3008 "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
@@ -2664,7 +3043,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2664 break; 3043 break;
2665 } 3044 }
2666 if (-1 != msp) 3045 if (-1 != msp)
2667 btv->c.type = BTTV_PINNACLEPRO; 3046 btv->c.type = BTTV_BOARD_PINNACLEPRO;
2668 printk(KERN_INFO 3047 printk(KERN_INFO
2669 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", 3048 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
2670 btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); 3049 btv->c.nr, id, info, btv->has_radio ? "yes" : "no");
@@ -2712,7 +3091,7 @@ static void eagle_muxsel(struct bttv *btv, unsigned int input)
2712 3091
2713static void gvc1100_muxsel(struct bttv *btv, unsigned int input) 3092static void gvc1100_muxsel(struct bttv *btv, unsigned int input)
2714{ 3093{
2715 static const int masks[] = {0x30, 0x01, 0x12, 0x23}; 3094 static const int masks[] = {0x30, 0x01, 0x12, 0x23};
2716 gpio_write(masks[input%4]); 3095 gpio_write(masks[input%4]);
2717} 3096}
2718 3097
@@ -2778,26 +3157,27 @@ static void bttv_reset_audio(struct bttv *btv)
2778void __devinit bttv_init_card1(struct bttv *btv) 3157void __devinit bttv_init_card1(struct bttv *btv)
2779{ 3158{
2780 switch (btv->c.type) { 3159 switch (btv->c.type) {
2781 case BTTV_HAUPPAUGE: 3160 case BTTV_BOARD_HAUPPAUGE:
2782 case BTTV_HAUPPAUGE878: 3161 case BTTV_BOARD_HAUPPAUGE878:
2783 boot_msp34xx(btv,5); 3162 boot_msp34xx(btv,5);
2784 break; 3163 break;
2785 case BTTV_VOODOOTV_FM: 3164 case BTTV_BOARD_VOODOOTV_FM:
2786 boot_msp34xx(btv,20); 3165 boot_msp34xx(btv,20);
2787 break; 3166 break;
2788 case BTTV_AVERMEDIA98: 3167 case BTTV_BOARD_AVERMEDIA98:
2789 boot_msp34xx(btv,11); 3168 boot_msp34xx(btv,11);
2790 break; 3169 break;
2791 case BTTV_HAUPPAUGEPVR: 3170 case BTTV_BOARD_HAUPPAUGEPVR:
2792 pvr_boot(btv); 3171 pvr_boot(btv);
2793 break; 3172 break;
2794 case BTTV_TWINHAN_DST: 3173 case BTTV_BOARD_TWINHAN_DST:
2795 case BTTV_AVDVBT_771: 3174 case BTTV_BOARD_AVDVBT_771:
3175 case BTTV_BOARD_PINNACLESAT:
2796 btv->use_i2c_hw = 1; 3176 btv->use_i2c_hw = 1;
2797 break; 3177 break;
2798 case BTTV_ADLINK_RTV24: 3178 case BTTV_BOARD_ADLINK_RTV24:
2799 init_RTV24( btv ); 3179 init_RTV24( btv );
2800 break; 3180 break;
2801 3181
2802 } 3182 }
2803 if (!bttv_tvcards[btv->c.type].has_dvb) 3183 if (!bttv_tvcards[btv->c.type].has_dvb)
@@ -2810,53 +3190,53 @@ void __devinit bttv_init_card2(struct bttv *btv)
2810 int tda9887; 3190 int tda9887;
2811 int addr=ADDR_UNSET; 3191 int addr=ADDR_UNSET;
2812 3192
2813 btv->tuner_type = -1; 3193 btv->tuner_type = -1;
2814 3194
2815 if (BTTV_UNKNOWN == btv->c.type) { 3195 if (BTTV_BOARD_UNKNOWN == btv->c.type) {
2816 bttv_readee(btv,eeprom_data,0xa0); 3196 bttv_readee(btv,eeprom_data,0xa0);
2817 identify_by_eeprom(btv,eeprom_data); 3197 identify_by_eeprom(btv,eeprom_data);
2818 } 3198 }
2819 3199
2820 switch (btv->c.type) { 3200 switch (btv->c.type) {
2821 case BTTV_MIRO: 3201 case BTTV_BOARD_MIRO:
2822 case BTTV_MIROPRO: 3202 case BTTV_BOARD_MIROPRO:
2823 case BTTV_PINNACLE: 3203 case BTTV_BOARD_PINNACLE:
2824 case BTTV_PINNACLEPRO: 3204 case BTTV_BOARD_PINNACLEPRO:
2825 /* miro/pinnacle */ 3205 /* miro/pinnacle */
2826 miro_pinnacle_gpio(btv); 3206 miro_pinnacle_gpio(btv);
2827 break; 3207 break;
2828 case BTTV_FLYVIDEO_98: 3208 case BTTV_BOARD_FLYVIDEO_98:
2829 case BTTV_MAXI: 3209 case BTTV_BOARD_MAXI:
2830 case BTTV_LIFE_FLYKIT: 3210 case BTTV_BOARD_LIFE_FLYKIT:
2831 case BTTV_FLYVIDEO: 3211 case BTTV_BOARD_FLYVIDEO:
2832 case BTTV_TYPHOON_TVIEW: 3212 case BTTV_BOARD_TYPHOON_TVIEW:
2833 case BTTV_CHRONOS_VS2: 3213 case BTTV_BOARD_CHRONOS_VS2:
2834 case BTTV_FLYVIDEO_98FM: 3214 case BTTV_BOARD_FLYVIDEO_98FM:
2835 case BTTV_FLYVIDEO2000: 3215 case BTTV_BOARD_FLYVIDEO2000:
2836 case BTTV_FLYVIDEO98EZ: 3216 case BTTV_BOARD_FLYVIDEO98EZ:
2837 case BTTV_CONFERENCETV: 3217 case BTTV_BOARD_CONFERENCETV:
2838 case BTTV_LIFETEC_9415: 3218 case BTTV_BOARD_LIFETEC_9415:
2839 flyvideo_gpio(btv); 3219 flyvideo_gpio(btv);
2840 break; 3220 break;
2841 case BTTV_HAUPPAUGE: 3221 case BTTV_BOARD_HAUPPAUGE:
2842 case BTTV_HAUPPAUGE878: 3222 case BTTV_BOARD_HAUPPAUGE878:
2843 case BTTV_HAUPPAUGEPVR: 3223 case BTTV_BOARD_HAUPPAUGEPVR:
2844 /* pick up some config infos from the eeprom */ 3224 /* pick up some config infos from the eeprom */
2845 bttv_readee(btv,eeprom_data,0xa0); 3225 bttv_readee(btv,eeprom_data,0xa0);
2846 hauppauge_eeprom(btv); 3226 hauppauge_eeprom(btv);
2847 break; 3227 break;
2848 case BTTV_AVERMEDIA98: 3228 case BTTV_BOARD_AVERMEDIA98:
2849 case BTTV_AVPHONE98: 3229 case BTTV_BOARD_AVPHONE98:
2850 bttv_readee(btv,eeprom_data,0xa0); 3230 bttv_readee(btv,eeprom_data,0xa0);
2851 avermedia_eeprom(btv); 3231 avermedia_eeprom(btv);
2852 break; 3232 break;
2853 case BTTV_PXC200: 3233 case BTTV_BOARD_PXC200:
2854 init_PXC200(btv); 3234 init_PXC200(btv);
2855 break; 3235 break;
2856 case BTTV_PICOLO_TETRA_CHIP: 3236 case BTTV_BOARD_PICOLO_TETRA_CHIP:
2857 picolo_tetra_init(btv); 3237 picolo_tetra_init(btv);
2858 break; 3238 break;
2859 case BTTV_VHX: 3239 case BTTV_BOARD_VHX:
2860 btv->has_radio = 1; 3240 btv->has_radio = 1;
2861 btv->has_matchbox = 1; 3241 btv->has_matchbox = 1;
2862 btv->mbox_we = 0x20; 3242 btv->mbox_we = 0x20;
@@ -2865,58 +3245,58 @@ void __devinit bttv_init_card2(struct bttv *btv)
2865 btv->mbox_data = 0x10; 3245 btv->mbox_data = 0x10;
2866 btv->mbox_mask = 0x38; 3246 btv->mbox_mask = 0x38;
2867 break; 3247 break;
2868 case BTTV_VOBIS_BOOSTAR: 3248 case BTTV_BOARD_VOBIS_BOOSTAR:
2869 case BTTV_TERRATV: 3249 case BTTV_BOARD_TERRATV:
2870 terratec_active_radio_upgrade(btv); 3250 terratec_active_radio_upgrade(btv);
2871 break; 3251 break;
2872 case BTTV_MAGICTVIEW061: 3252 case BTTV_BOARD_MAGICTVIEW061:
2873 if (btv->cardid == 0x3002144f) { 3253 if (btv->cardid == 0x3002144f) {
2874 btv->has_radio=1; 3254 btv->has_radio=1;
2875 printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr); 3255 printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr);
2876 } 3256 }
2877 break; 3257 break;
2878 case BTTV_STB2: 3258 case BTTV_BOARD_STB2:
2879 if (btv->cardid == 0x3060121a) { 3259 if (btv->cardid == 0x3060121a) {
2880 /* Fix up entry for 3DFX VoodooTV 100, 3260 /* Fix up entry for 3DFX VoodooTV 100,
2881 which is an OEM STB card variant. */ 3261 which is an OEM STB card variant. */
2882 btv->has_radio=0; 3262 btv->has_radio=0;
2883 btv->tuner_type=TUNER_TEMIC_NTSC; 3263 btv->tuner_type=TUNER_TEMIC_NTSC;
2884 } 3264 }
2885 break; 3265 break;
2886 case BTTV_OSPREY1x0: 3266 case BTTV_BOARD_OSPREY1x0:
2887 case BTTV_OSPREY1x0_848: 3267 case BTTV_BOARD_OSPREY1x0_848:
2888 case BTTV_OSPREY101_848: 3268 case BTTV_BOARD_OSPREY101_848:
2889 case BTTV_OSPREY1x1: 3269 case BTTV_BOARD_OSPREY1x1:
2890 case BTTV_OSPREY1x1_SVID: 3270 case BTTV_BOARD_OSPREY1x1_SVID:
2891 case BTTV_OSPREY2xx: 3271 case BTTV_BOARD_OSPREY2xx:
2892 case BTTV_OSPREY2x0_SVID: 3272 case BTTV_BOARD_OSPREY2x0_SVID:
2893 case BTTV_OSPREY2x0: 3273 case BTTV_BOARD_OSPREY2x0:
2894 case BTTV_OSPREY500: 3274 case BTTV_BOARD_OSPREY500:
2895 case BTTV_OSPREY540: 3275 case BTTV_BOARD_OSPREY540:
2896 case BTTV_OSPREY2000: 3276 case BTTV_BOARD_OSPREY2000:
2897 bttv_readee(btv,eeprom_data,0xa0); 3277 bttv_readee(btv,eeprom_data,0xa0);
2898 osprey_eeprom(btv); 3278 osprey_eeprom(btv);
2899 break; 3279 break;
2900 case BTTV_IDS_EAGLE: 3280 case BTTV_BOARD_IDS_EAGLE:
2901 init_ids_eagle(btv); 3281 init_ids_eagle(btv);
2902 break; 3282 break;
2903 case BTTV_MODTEC_205: 3283 case BTTV_BOARD_MODTEC_205:
2904 bttv_readee(btv,eeprom_data,0xa0); 3284 bttv_readee(btv,eeprom_data,0xa0);
2905 modtec_eeprom(btv); 3285 modtec_eeprom(btv);
2906 break; 3286 break;
2907 case BTTV_LMLBT4: 3287 case BTTV_BOARD_LMLBT4:
2908 init_lmlbt4x(btv); 3288 init_lmlbt4x(btv);
2909 break; 3289 break;
2910 case BTTV_TIBET_CS16: 3290 case BTTV_BOARD_TIBET_CS16:
2911 tibetCS16_init(btv); 3291 tibetCS16_init(btv);
2912 break; 3292 break;
2913 case BTTV_KODICOM_4400R: 3293 case BTTV_BOARD_KODICOM_4400R:
2914 kodicom4400r_init(btv); 3294 kodicom4400r_init(btv);
2915 break; 3295 break;
2916 } 3296 }
2917 3297
2918 /* pll configuration */ 3298 /* pll configuration */
2919 if (!(btv->id==848 && btv->revision==0x11)) { 3299 if (!(btv->id==848 && btv->revision==0x11)) {
2920 /* defaults from card list */ 3300 /* defaults from card list */
2921 if (PLL_28 == bttv_tvcards[btv->c.type].pll) { 3301 if (PLL_28 == bttv_tvcards[btv->c.type].pll) {
2922 btv->pll.pll_ifreq=28636363; 3302 btv->pll.pll_ifreq=28636363;
@@ -2927,26 +3307,26 @@ void __devinit bttv_init_card2(struct bttv *btv)
2927 btv->pll.pll_crystal=BT848_IFORM_XT1; 3307 btv->pll.pll_crystal=BT848_IFORM_XT1;
2928 } 3308 }
2929 /* insmod options can override */ 3309 /* insmod options can override */
2930 switch (pll[btv->c.nr]) { 3310 switch (pll[btv->c.nr]) {
2931 case 0: /* none */ 3311 case 0: /* none */
2932 btv->pll.pll_crystal = 0; 3312 btv->pll.pll_crystal = 0;
2933 btv->pll.pll_ifreq = 0; 3313 btv->pll.pll_ifreq = 0;
2934 btv->pll.pll_ofreq = 0; 3314 btv->pll.pll_ofreq = 0;
2935 break; 3315 break;
2936 case 1: /* 28 MHz */ 3316 case 1: /* 28 MHz */
2937 case 28: 3317 case 28:
2938 btv->pll.pll_ifreq = 28636363; 3318 btv->pll.pll_ifreq = 28636363;
2939 btv->pll.pll_ofreq = 0; 3319 btv->pll.pll_ofreq = 0;
2940 btv->pll.pll_crystal = BT848_IFORM_XT0; 3320 btv->pll.pll_crystal = BT848_IFORM_XT0;
2941 break; 3321 break;
2942 case 2: /* 35 MHz */ 3322 case 2: /* 35 MHz */
2943 case 35: 3323 case 35:
2944 btv->pll.pll_ifreq = 35468950; 3324 btv->pll.pll_ifreq = 35468950;
2945 btv->pll.pll_ofreq = 0; 3325 btv->pll.pll_ofreq = 0;
2946 btv->pll.pll_crystal = BT848_IFORM_XT1; 3326 btv->pll.pll_crystal = BT848_IFORM_XT1;
2947 break; 3327 break;
2948 } 3328 }
2949 } 3329 }
2950 btv->pll.pll_current = -1; 3330 btv->pll.pll_current = -1;
2951 3331
2952 /* tuner configuration (from card list / autodetect / insmod option) */ 3332 /* tuner configuration (from card list / autodetect / insmod option) */
@@ -2955,23 +3335,26 @@ void __devinit bttv_init_card2(struct bttv *btv)
2955 3335
2956 if (UNSET != bttv_tvcards[btv->c.type].tuner_type) 3336 if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
2957 if(UNSET == btv->tuner_type) 3337 if(UNSET == btv->tuner_type)
2958 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; 3338 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
2959 if (UNSET != tuner[btv->c.nr]) 3339 if (UNSET != tuner[btv->c.nr])
2960 btv->tuner_type = tuner[btv->c.nr]; 3340 btv->tuner_type = tuner[btv->c.nr];
2961 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type); 3341 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type);
2962 if (btv->pinnacle_id != UNSET) 3342
2963 bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
2964 &btv->pinnacle_id);
2965 if (btv->tuner_type != UNSET) { 3343 if (btv->tuner_type != UNSET) {
2966 struct tuner_setup tun_setup; 3344 struct tuner_setup tun_setup;
2967 3345
2968 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; 3346 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
2969 tun_setup.type = btv->tuner_type; 3347 tun_setup.type = btv->tuner_type;
2970 tun_setup.addr = addr; 3348 tun_setup.addr = addr;
2971 3349
2972 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); 3350 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
2973 } 3351 }
2974 3352
3353 if (btv->pinnacle_id != UNSET) {
3354 bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
3355 &btv->pinnacle_id);
3356 }
3357
2975 btv->svhs = bttv_tvcards[btv->c.type].svhs; 3358 btv->svhs = bttv_tvcards[btv->c.type].svhs;
2976 if (svhs[btv->c.nr] != UNSET) 3359 if (svhs[btv->c.nr] != UNSET)
2977 btv->svhs = svhs[btv->c.nr]; 3360 btv->svhs = svhs[btv->c.nr];
@@ -2982,8 +3365,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
2982 btv->has_radio=1; 3365 btv->has_radio=1;
2983 if (bttv_tvcards[btv->c.type].has_remote) 3366 if (bttv_tvcards[btv->c.type].has_remote)
2984 btv->has_remote=1; 3367 btv->has_remote=1;
2985 if (bttv_tvcards[btv->c.type].no_gpioirq) 3368 if (!bttv_tvcards[btv->c.type].no_gpioirq)
2986 btv->gpioirq=0; 3369 btv->gpioirq=1;
2987 if (bttv_tvcards[btv->c.type].audio_hook) 3370 if (bttv_tvcards[btv->c.type].audio_hook)
2988 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; 3371 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
2989 3372
@@ -3024,6 +3407,9 @@ void __devinit bttv_init_card2(struct bttv *btv)
3024 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && 3407 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
3025 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) 3408 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0)
3026 tda9887 = 1; 3409 tda9887 = 1;
3410 /* Hybrid DVB card, DOES have a tda9887 */
3411 if (btv->c.type == BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE)
3412 tda9887 = 1;
3027 if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) || 3413 if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) ||
3028 (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) || 3414 (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) ||
3029 (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) || 3415 (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) ||
@@ -3045,11 +3431,11 @@ static void modtec_eeprom(struct bttv *btv)
3045 } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) { 3431 } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) {
3046 btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I; 3432 btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I;
3047 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", 3433 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
3048 btv->c.nr,&eeprom_data[0x1e]); 3434 btv->c.nr,&eeprom_data[0x1e]);
3049 } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) { 3435 } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) {
3050 btv->tuner_type=TUNER_PHILIPS_NTSC; 3436 btv->tuner_type=TUNER_PHILIPS_NTSC;
3051 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", 3437 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
3052 btv->c.nr,&eeprom_data[0x1e]); 3438 btv->c.nr,&eeprom_data[0x1e]);
3053 } else { 3439 } else {
3054 printk("bttv%d: Modtec: Unknown TunerString: %s\n", 3440 printk("bttv%d: Modtec: Unknown TunerString: %s\n",
3055 btv->c.nr,&eeprom_data[0x1e]); 3441 btv->c.nr,&eeprom_data[0x1e]);
@@ -3114,7 +3500,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv)
3114static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) 3500static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
3115{ 3501{
3116 u32 n; 3502 u32 n;
3117 u8 bits; 3503 u8 bits;
3118 int i; 3504 int i;
3119 3505
3120 gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG); 3506 gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG);
@@ -3150,19 +3536,19 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
3150 3536
3151static int __devinit pvr_boot(struct bttv *btv) 3537static int __devinit pvr_boot(struct bttv *btv)
3152{ 3538{
3153 const struct firmware *fw_entry; 3539 const struct firmware *fw_entry;
3154 int rc; 3540 int rc;
3155 3541
3156 rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); 3542 rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev);
3157 if (rc != 0) { 3543 if (rc != 0) {
3158 printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n", 3544 printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n",
3159 btv->c.nr); 3545 btv->c.nr);
3160 return rc; 3546 return rc;
3161 } 3547 }
3162 rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); 3548 rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
3163 printk(KERN_INFO "bttv%d: altera firmware upload %s\n", 3549 printk(KERN_INFO "bttv%d: altera firmware upload %s\n",
3164 btv->c.nr, (rc < 0) ? "failed" : "ok"); 3550 btv->c.nr, (rc < 0) ? "failed" : "ok");
3165 release_firmware(fw_entry); 3551 release_firmware(fw_entry);
3166 return rc; 3552 return rc;
3167} 3553}
3168 3554
@@ -3176,33 +3562,33 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3176 unsigned long serial = 0; 3562 unsigned long serial = 0;
3177 3563
3178 if (btv->c.type == 0) { 3564 if (btv->c.type == 0) {
3179 /* this might be an antique... check for MMAC label in eeprom */ 3565 /* this might be an antique... check for MMAC label in eeprom */
3180 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) { 3566 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
3181 unsigned char checksum = 0; 3567 unsigned char checksum = 0;
3182 for (i =0; i<21; i++) 3568 for (i =0; i<21; i++)
3183 checksum += ee[i]; 3569 checksum += ee[i];
3184 if (checksum != ee[21]) 3570 if (checksum != ee[21])
3185 return; 3571 return;
3186 btv->c.type = BTTV_OSPREY1x0_848; 3572 btv->c.type = BTTV_BOARD_OSPREY1x0_848;
3187 for (i = 12; i < 21; i++) 3573 for (i = 12; i < 21; i++)
3188 serial *= 10, serial += ee[i] - '0'; 3574 serial *= 10, serial += ee[i] - '0';
3189 } 3575 }
3190 } else { 3576 } else {
3191 unsigned short type; 3577 unsigned short type;
3192 int offset = 4*16; 3578 int offset = 4*16;
3193 3579
3194 for(; offset < 8*16; offset += 16) { 3580 for(; offset < 8*16; offset += 16) {
3195 unsigned short checksum = 0; 3581 unsigned short checksum = 0;
3196 /* verify the checksum */ 3582 /* verify the checksum */
3197 for(i = 0; i<14; i++) checksum += ee[i+offset]; 3583 for(i = 0; i<14; i++) checksum += ee[i+offset];
3198 checksum = ~checksum; /* no idea why */ 3584 checksum = ~checksum; /* no idea why */
3199 if ((((checksum>>8)&0x0FF) == ee[offset+14]) && 3585 if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
3200 ((checksum & 0x0FF) == ee[offset+15])) { 3586 ((checksum & 0x0FF) == ee[offset+15])) {
3201 break; 3587 break;
3202 } 3588 }
3203 } 3589 }
3204 3590
3205 if (offset >= 8*16) 3591 if (offset >= 8*16)
3206 return; 3592 return;
3207 3593
3208 /* found a valid descriptor */ 3594 /* found a valid descriptor */
@@ -3212,47 +3598,47 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3212 3598
3213 /* 848 based */ 3599 /* 848 based */
3214 case 0x0004: 3600 case 0x0004:
3215 btv->c.type = BTTV_OSPREY1x0_848; 3601 btv->c.type = BTTV_BOARD_OSPREY1x0_848;
3216 break; 3602 break;
3217 case 0x0005: 3603 case 0x0005:
3218 btv->c.type = BTTV_OSPREY101_848; 3604 btv->c.type = BTTV_BOARD_OSPREY101_848;
3219 break; 3605 break;
3220 3606
3221 /* 878 based */ 3607 /* 878 based */
3222 case 0x0012: 3608 case 0x0012:
3223 case 0x0013: 3609 case 0x0013:
3224 btv->c.type = BTTV_OSPREY1x0; 3610 btv->c.type = BTTV_BOARD_OSPREY1x0;
3225 break; 3611 break;
3226 case 0x0014: 3612 case 0x0014:
3227 case 0x0015: 3613 case 0x0015:
3228 btv->c.type = BTTV_OSPREY1x1; 3614 btv->c.type = BTTV_BOARD_OSPREY1x1;
3229 break; 3615 break;
3230 case 0x0016: 3616 case 0x0016:
3231 case 0x0017: 3617 case 0x0017:
3232 case 0x0020: 3618 case 0x0020:
3233 btv->c.type = BTTV_OSPREY1x1_SVID; 3619 btv->c.type = BTTV_BOARD_OSPREY1x1_SVID;
3234 break; 3620 break;
3235 case 0x0018: 3621 case 0x0018:
3236 case 0x0019: 3622 case 0x0019:
3237 case 0x001E: 3623 case 0x001E:
3238 case 0x001F: 3624 case 0x001F:
3239 btv->c.type = BTTV_OSPREY2xx; 3625 btv->c.type = BTTV_BOARD_OSPREY2xx;
3240 break; 3626 break;
3241 case 0x001A: 3627 case 0x001A:
3242 case 0x001B: 3628 case 0x001B:
3243 btv->c.type = BTTV_OSPREY2x0_SVID; 3629 btv->c.type = BTTV_BOARD_OSPREY2x0_SVID;
3244 break; 3630 break;
3245 case 0x0040: 3631 case 0x0040:
3246 btv->c.type = BTTV_OSPREY500; 3632 btv->c.type = BTTV_BOARD_OSPREY500;
3247 break; 3633 break;
3248 case 0x0050: 3634 case 0x0050:
3249 case 0x0056: 3635 case 0x0056:
3250 btv->c.type = BTTV_OSPREY540; 3636 btv->c.type = BTTV_BOARD_OSPREY540;
3251 /* bttv_osprey_540_init(btv); */ 3637 /* bttv_osprey_540_init(btv); */
3252 break; 3638 break;
3253 case 0x0060: 3639 case 0x0060:
3254 case 0x0070: 3640 case 0x0070:
3255 btv->c.type = BTTV_OSPREY2x0; 3641 btv->c.type = BTTV_BOARD_OSPREY2x0;
3256 /* enable output on select control lines */ 3642 /* enable output on select control lines */
3257 gpio_inout(0xffffff,0x000303); 3643 gpio_inout(0xffffff,0x000303);
3258 break; 3644 break;
@@ -3274,27 +3660,27 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3274/* AVermedia specific stuff, from bktr_card.c */ 3660/* AVermedia specific stuff, from bktr_card.c */
3275 3661
3276static int tuner_0_table[] = { 3662static int tuner_0_table[] = {
3277 TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/, 3663 TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/,
3278 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/, 3664 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/,
3279 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, 3665 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
3280 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM, 3666 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
3281 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL, 3667 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
3282 TUNER_PHILIPS_FM1216ME_MK3 }; 3668 TUNER_PHILIPS_FM1216ME_MK3 };
3283 3669
3284static int tuner_1_table[] = { 3670static int tuner_1_table[] = {
3285 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL, 3671 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
3286 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, 3672 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3287 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, 3673 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3288 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */ 3674 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */
3289 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL}; 3675 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
3290 3676
3291static void __devinit avermedia_eeprom(struct bttv *btv) 3677static void __devinit avermedia_eeprom(struct bttv *btv)
3292{ 3678{
3293 int tuner_make,tuner_tv_fm,tuner_format,tuner=0; 3679 int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
3294 3680
3295 tuner_make = (eeprom_data[0x41] & 0x7); 3681 tuner_make = (eeprom_data[0x41] & 0x7);
3296 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; 3682 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
3297 tuner_format = (eeprom_data[0x42] & 0xf0) >> 4; 3683 tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
3298 btv->has_remote = (eeprom_data[0x42] & 0x01); 3684 btv->has_remote = (eeprom_data[0x42] & 0x01);
3299 3685
3300 if (tuner_make == 0 || tuner_make == 2) 3686 if (tuner_make == 0 || tuner_make == 2)
@@ -3325,13 +3711,13 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3325{ 3711{
3326 /* fix up our card entry */ 3712 /* fix up our card entry */
3327 if(norm==VIDEO_MODE_NTSC) { 3713 if(norm==VIDEO_MODE_NTSC) {
3328 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff; 3714 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x957fff;
3329 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff; 3715 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x957fff;
3330 dprintk("bttv_tda9880_setnorm to NTSC\n"); 3716 dprintk("bttv_tda9880_setnorm to NTSC\n");
3331 } 3717 }
3332 else { 3718 else {
3333 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x947fff; 3719 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x947fff;
3334 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff; 3720 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x947fff;
3335 dprintk("bttv_tda9880_setnorm to PAL\n"); 3721 dprintk("bttv_tda9880_setnorm to PAL\n");
3336 } 3722 }
3337 /* set GPIO according */ 3723 /* set GPIO according */
@@ -3342,7 +3728,7 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3342 3728
3343/* 3729/*
3344 * reset/enable the MSP on some Hauppauge cards 3730 * reset/enable the MSP on some Hauppauge cards
3345 * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)! 3731 * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)!
3346 * 3732 *
3347 * Hauppauge: pin 5 3733 * Hauppauge: pin 5
3348 * Voodoo: pin 20 3734 * Voodoo: pin 20
@@ -3353,7 +3739,7 @@ static void __devinit boot_msp34xx(struct bttv *btv, int pin)
3353 3739
3354 gpio_inout(mask,mask); 3740 gpio_inout(mask,mask);
3355 gpio_bits(mask,0); 3741 gpio_bits(mask,0);
3356 udelay(2500); 3742 udelay(2500);
3357 gpio_bits(mask,mask); 3743 gpio_bits(mask,mask);
3358 3744
3359 if (bttv_gpio) 3745 if (bttv_gpio)
@@ -3429,7 +3815,7 @@ static void __devinit init_PXC200(struct bttv *btv)
3429 udelay(10); 3815 udelay(10);
3430 gpio_write(1<<2); 3816 gpio_write(1<<2);
3431 3817
3432 for (i = 0; i < ARRAY_SIZE(vals); i++) { 3818 for (i = 0; i < ARRAY_SIZE(vals); i++) {
3433 tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1); 3819 tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1);
3434 if (tmp != -1) { 3820 if (tmp != -1) {
3435 printk(KERN_INFO 3821 printk(KERN_INFO
@@ -3872,30 +4258,30 @@ avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set)
3872static void 4258static void
3873lt9415_audio(struct bttv *btv, struct video_audio *v, int set) 4259lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
3874{ 4260{
3875 int val = 0; 4261 int val = 0;
3876 4262
3877 if (gpio_read() & 0x4000) { 4263 if (gpio_read() & 0x4000) {
3878 v->mode = VIDEO_SOUND_MONO; 4264 v->mode = VIDEO_SOUND_MONO;
3879 return; 4265 return;
3880 } 4266 }
3881 4267
3882 if (set) { 4268 if (set) {
3883 if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */ 4269 if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */
3884 val = 0x0080; 4270 val = 0x0080;
3885 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */ 4271 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */
3886 val = 0x0880; 4272 val = 0x0880;
3887 if ((v->mode & VIDEO_SOUND_LANG1) || 4273 if ((v->mode & VIDEO_SOUND_LANG1) ||
3888 (v->mode & VIDEO_SOUND_MONO)) 4274 (v->mode & VIDEO_SOUND_MONO))
3889 val = 0; 4275 val = 0;
3890 gpio_bits(0x0880, val); 4276 gpio_bits(0x0880, val);
3891 if (bttv_gpio) 4277 if (bttv_gpio)
3892 bttv_gpio_tracking(btv,"lt9415"); 4278 bttv_gpio_tracking(btv,"lt9415");
3893 } else { 4279 } else {
3894 /* autodetect doesn't work with this card :-( */ 4280 /* autodetect doesn't work with this card :-( */
3895 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | 4281 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3896 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 4282 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3897 return; 4283 return;
3898 } 4284 }
3899} 4285}
3900 4286
3901/* TDA9821 on TerraTV+ Bt848, Bt878 */ 4287/* TDA9821 on TerraTV+ Bt848, Bt878 */
@@ -4018,26 +4404,26 @@ fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
4018static void 4404static void
4019windvr_audio(struct bttv *btv, struct video_audio *v, int set) 4405windvr_audio(struct bttv *btv, struct video_audio *v, int set)
4020{ 4406{
4021 unsigned long val = 0; 4407 unsigned long val = 0;
4022 4408
4023 if (set) { 4409 if (set) {
4024 if (v->mode & VIDEO_SOUND_MONO) 4410 if (v->mode & VIDEO_SOUND_MONO)
4025 val = 0x040000; 4411 val = 0x040000;
4026 if (v->mode & VIDEO_SOUND_LANG1) 4412 if (v->mode & VIDEO_SOUND_LANG1)
4027 val = 0; 4413 val = 0;
4028 if (v->mode & VIDEO_SOUND_LANG2) 4414 if (v->mode & VIDEO_SOUND_LANG2)
4029 val = 0x100000; 4415 val = 0x100000;
4030 if (v->mode & VIDEO_SOUND_STEREO) 4416 if (v->mode & VIDEO_SOUND_STEREO)
4031 val = 0; 4417 val = 0;
4032 if (val) { 4418 if (val) {
4033 gpio_bits(0x140000, val); 4419 gpio_bits(0x140000, val);
4034 if (bttv_gpio) 4420 if (bttv_gpio)
4035 bttv_gpio_tracking(btv,"windvr"); 4421 bttv_gpio_tracking(btv,"windvr");
4036 } 4422 }
4037 } else { 4423 } else {
4038 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | 4424 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4039 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 4425 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4040 } 4426 }
4041} 4427}
4042 4428
4043/* 4429/*
@@ -4280,10 +4666,10 @@ static void kodicom4400r_init(struct bttv *btv)
4280static void xguard_muxsel(struct bttv *btv, unsigned int input) 4666static void xguard_muxsel(struct bttv *btv, unsigned int input)
4281{ 4667{
4282 static const int masks[] = { 4668 static const int masks[] = {
4283 ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10, 4669 ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
4284 ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10, 4670 ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
4285 ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11, 4671 ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
4286 ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11, 4672 ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
4287 }; 4673 };
4288 gpio_write(masks[input%16]); 4674 gpio_write(masks[input%16]);
4289} 4675}
@@ -4388,10 +4774,10 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input)
4388 4774
4389static void PXC200_muxsel(struct bttv *btv, unsigned int input) 4775static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4390{ 4776{
4391 int rc; 4777 int rc;
4392 long mux; 4778 long mux;
4393 int bitmask; 4779 int bitmask;
4394 unsigned char buf[2]; 4780 unsigned char buf[2];
4395 4781
4396 /* Read PIC config to determine if this is a PXC200F */ 4782 /* Read PIC config to determine if this is a PXC200F */
4397 /* PX_I2C_CMD_CFG*/ 4783 /* PX_I2C_CMD_CFG*/
@@ -4421,14 +4807,14 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4421 /* bitmask=0x30f; */ 4807 /* bitmask=0x30f; */
4422 bitmask=0x302; 4808 bitmask=0x302;
4423 /* check whether we have a PXC200A */ 4809 /* check whether we have a PXC200A */
4424 if (btv->cardid == PX_PXC200A_CARDID) { 4810 if (btv->cardid == PX_PXC200A_CARDID) {
4425 bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */ 4811 bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */
4426 bitmask |= 7<<4; /* the DAC */ 4812 bitmask |= 7<<4; /* the DAC */
4427 } 4813 }
4428 btwrite(bitmask, BT848_GPIO_OUT_EN); 4814 btwrite(bitmask, BT848_GPIO_OUT_EN);
4429 4815
4430 bitmask = btread(BT848_GPIO_DATA); 4816 bitmask = btread(BT848_GPIO_DATA);
4431 if (btv->cardid == PX_PXC200A_CARDID) 4817 if (btv->cardid == PX_PXC200A_CARDID)
4432 bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7); 4818 bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7);
4433 else /* older device */ 4819 else /* older device */
4434 bitmask = (bitmask & ~0x300) | ((mux & 3) << 8); 4820 bitmask = (bitmask & ~0x300) | ((mux & 3) << 8);
@@ -4441,7 +4827,7 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4441 * 4827 *
4442 * needed because bttv-driver sets mux before calling this function 4828 * needed because bttv-driver sets mux before calling this function
4443 */ 4829 */
4444 if (btv->cardid == PX_PXC200A_CARDID) 4830 if (btv->cardid == PX_PXC200A_CARDID)
4445 btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM); 4831 btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM);
4446 else /* older device */ 4832 else /* older device */
4447 btand(~BT848_IFORM_MUXSEL,BT848_IFORM); 4833 btand(~BT848_IFORM_MUXSEL,BT848_IFORM);
@@ -4485,10 +4871,9 @@ void __devinit bttv_check_chipset(void)
4485 } 4871 }
4486 if (UNSET != latency) 4872 if (UNSET != latency)
4487 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency); 4873 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency);
4488 4874 while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL,
4489 while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL,
4490 PCI_DEVICE_ID_INTEL_82441, dev))) { 4875 PCI_DEVICE_ID_INTEL_82441, dev))) {
4491 unsigned char b; 4876 unsigned char b;
4492 pci_read_config_byte(dev, 0x53, &b); 4877 pci_read_config_byte(dev, 0x53, &b);
4493 if (bttv_debug) 4878 if (bttv_debug)
4494 printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, " 4879 printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "
@@ -4498,7 +4883,7 @@ void __devinit bttv_check_chipset(void)
4498 4883
4499int __devinit bttv_handle_chipset(struct bttv *btv) 4884int __devinit bttv_handle_chipset(struct bttv *btv)
4500{ 4885{
4501 unsigned char command; 4886 unsigned char command;
4502 4887
4503 if (!triton1 && !vsfx && UNSET == latency) 4888 if (!triton1 && !vsfx && UNSET == latency)
4504 return 0; 4889 return 0;
@@ -4519,13 +4904,13 @@ int __devinit bttv_handle_chipset(struct bttv *btv)
4519 btv->triton1 = BT848_INT_ETBF; 4904 btv->triton1 = BT848_INT_ETBF;
4520 } else { 4905 } else {
4521 /* bt878 has a bit in the pci config space for it */ 4906 /* bt878 has a bit in the pci config space for it */
4522 pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command); 4907 pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command);
4523 if (triton1) 4908 if (triton1)
4524 command |= BT878_EN_TBFX; 4909 command |= BT878_EN_TBFX;
4525 if (vsfx) 4910 if (vsfx)
4526 command |= BT878_EN_VSFX; 4911 command |= BT878_EN_VSFX;
4527 pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command); 4912 pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command);
4528 } 4913 }
4529 if (UNSET != latency) 4914 if (UNSET != latency)
4530 pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency); 4915 pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency);
4531 return 0; 4916 return 0;
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index d538a994ff04..0005741d5514 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -3,7 +3,7 @@
3 bttv - Bt848 frame grabber driver 3 bttv - Bt848 frame grabber driver
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de> 5 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de>
6 & Marcus Metzler <mocm@thp.uni-koeln.de> 6 & Marcus Metzler <mocm@thp.uni-koeln.de>
7 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org> 7 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>
8 8
9 some v4l2 code lines are taken from Justin's bttv2 driver which is 9 some v4l2 code lines are taken from Justin's bttv2 driver which is
@@ -192,8 +192,8 @@ static u8 SRAM_Table[][60] =
192 192
193const struct bttv_tvnorm bttv_tvnorms[] = { 193const struct bttv_tvnorm bttv_tvnorms[] = {
194 /* PAL-BDGHI */ 194 /* PAL-BDGHI */
195 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ 195 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
196 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ 196 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
197 { 197 {
198 .v4l2_id = V4L2_STD_PAL, 198 .v4l2_id = V4L2_STD_PAL,
199 .name = "PAL", 199 .name = "PAL",
@@ -806,9 +806,9 @@ static void bt848A_set_timing(struct bttv *btv)
806 btv->c.nr,table_idx); 806 btv->c.nr,table_idx);
807 807
808 /* timing change...reset timing generator address */ 808 /* timing change...reset timing generator address */
809 btwrite(0x00, BT848_TGCTRL); 809 btwrite(0x00, BT848_TGCTRL);
810 btwrite(0x02, BT848_TGCTRL); 810 btwrite(0x02, BT848_TGCTRL);
811 btwrite(0x00, BT848_TGCTRL); 811 btwrite(0x00, BT848_TGCTRL);
812 812
813 len=SRAM_Table[table_idx][0]; 813 len=SRAM_Table[table_idx][0];
814 for(i = 1; i <= len; i++) 814 for(i = 1; i <= len; i++)
@@ -847,7 +847,7 @@ static void bt848_hue(struct bttv *btv, int hue)
847 847
848 /* -128 to 127 */ 848 /* -128 to 127 */
849 value = (hue >> 8) - 128; 849 value = (hue >> 8) - 128;
850 btwrite(value & 0xff, BT848_HUE); 850 btwrite(value & 0xff, BT848_HUE);
851} 851}
852 852
853static void bt848_contrast(struct bttv *btv, int cont) 853static void bt848_contrast(struct bttv *btv, int cont)
@@ -859,9 +859,9 @@ static void bt848_contrast(struct bttv *btv, int cont)
859 /* 0-511 */ 859 /* 0-511 */
860 value = (cont >> 7); 860 value = (cont >> 7);
861 hibit = (value >> 6) & 4; 861 hibit = (value >> 6) & 4;
862 btwrite(value & 0xff, BT848_CONTRAST_LO); 862 btwrite(value & 0xff, BT848_CONTRAST_LO);
863 btaor(hibit, ~4, BT848_E_CONTROL); 863 btaor(hibit, ~4, BT848_E_CONTROL);
864 btaor(hibit, ~4, BT848_O_CONTROL); 864 btaor(hibit, ~4, BT848_O_CONTROL);
865} 865}
866 866
867static void bt848_sat(struct bttv *btv, int color) 867static void bt848_sat(struct bttv *btv, int color)
@@ -873,12 +873,12 @@ static void bt848_sat(struct bttv *btv, int color)
873 /* 0-511 for the color */ 873 /* 0-511 for the color */
874 val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; 874 val_u = ((color * btv->opt_uv_ratio) / 50) >> 7;
875 val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; 875 val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
876 hibits = (val_u >> 7) & 2; 876 hibits = (val_u >> 7) & 2;
877 hibits |= (val_v >> 8) & 1; 877 hibits |= (val_v >> 8) & 1;
878 btwrite(val_u & 0xff, BT848_SAT_U_LO); 878 btwrite(val_u & 0xff, BT848_SAT_U_LO);
879 btwrite(val_v & 0xff, BT848_SAT_V_LO); 879 btwrite(val_v & 0xff, BT848_SAT_V_LO);
880 btaor(hibits, ~3, BT848_E_CONTROL); 880 btaor(hibits, ~3, BT848_E_CONTROL);
881 btaor(hibits, ~3, BT848_O_CONTROL); 881 btaor(hibits, ~3, BT848_O_CONTROL);
882} 882}
883 883
884/* ----------------------------------------------------------------------- */ 884/* ----------------------------------------------------------------------- */
@@ -891,7 +891,7 @@ video_mux(struct bttv *btv, unsigned int input)
891 if (input >= bttv_tvcards[btv->c.type].video_inputs) 891 if (input >= bttv_tvcards[btv->c.type].video_inputs)
892 return -EINVAL; 892 return -EINVAL;
893 893
894 /* needed by RemoteVideo MX */ 894 /* needed by RemoteVideo MX */
895 mask2 = bttv_tvcards[btv->c.type].gpiomask2; 895 mask2 = bttv_tvcards[btv->c.type].gpiomask2;
896 if (mask2) 896 if (mask2)
897 gpio_inout(mask2,mask2); 897 gpio_inout(mask2,mask2);
@@ -964,7 +964,7 @@ i2c_vidiocschan(struct bttv *btv)
964 c.norm = btv->tvnorm; 964 c.norm = btv->tvnorm;
965 c.channel = btv->input; 965 c.channel = btv->input;
966 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c); 966 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c);
967 if (btv->c.type == BTTV_VOODOOTV_FM) 967 if (btv->c.type == BTTV_BOARD_VOODOOTV_FM)
968 bttv_tda9880_setnorm(btv,c.norm); 968 bttv_tda9880_setnorm(btv,c.norm);
969} 969}
970 970
@@ -988,7 +988,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
988 bt848A_set_timing(btv); 988 bt848A_set_timing(btv);
989 989
990 switch (btv->c.type) { 990 switch (btv->c.type) {
991 case BTTV_VOODOOTV_FM: 991 case BTTV_BOARD_VOODOOTV_FM:
992 bttv_tda9880_setnorm(btv,norm); 992 bttv_tda9880_setnorm(btv,norm);
993 break; 993 break;
994 } 994 }
@@ -1055,22 +1055,22 @@ static void init_bt848(struct bttv *btv)
1055 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); 1055 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
1056 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM); 1056 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM);
1057 1057
1058 /* set planar and packed mode trigger points and */ 1058 /* set planar and packed mode trigger points and */
1059 /* set rising edge of inverted GPINTR pin as irq trigger */ 1059 /* set rising edge of inverted GPINTR pin as irq trigger */
1060 btwrite(BT848_GPIO_DMA_CTL_PKTP_32| 1060 btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
1061 BT848_GPIO_DMA_CTL_PLTP1_16| 1061 BT848_GPIO_DMA_CTL_PLTP1_16|
1062 BT848_GPIO_DMA_CTL_PLTP23_16| 1062 BT848_GPIO_DMA_CTL_PLTP23_16|
1063 BT848_GPIO_DMA_CTL_GPINTC| 1063 BT848_GPIO_DMA_CTL_GPINTC|
1064 BT848_GPIO_DMA_CTL_GPINTI, 1064 BT848_GPIO_DMA_CTL_GPINTI,
1065 BT848_GPIO_DMA_CTL); 1065 BT848_GPIO_DMA_CTL);
1066 1066
1067 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; 1067 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
1068 btwrite(val, BT848_E_SCLOOP); 1068 btwrite(val, BT848_E_SCLOOP);
1069 btwrite(val, BT848_O_SCLOOP); 1069 btwrite(val, BT848_O_SCLOOP);
1070 1070
1071 btwrite(0x20, BT848_E_VSCALE_HI); 1071 btwrite(0x20, BT848_E_VSCALE_HI);
1072 btwrite(0x20, BT848_O_VSCALE_HI); 1072 btwrite(0x20, BT848_O_VSCALE_HI);
1073 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), 1073 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1074 BT848_ADC); 1074 BT848_ADC);
1075 1075
1076 btwrite(whitecrush_upper, BT848_WC_UP); 1076 btwrite(whitecrush_upper, BT848_WC_UP);
@@ -1089,7 +1089,7 @@ static void init_bt848(struct bttv *btv)
1089 bt848_contrast(btv, btv->contrast); 1089 bt848_contrast(btv, btv->contrast);
1090 bt848_sat(btv, btv->saturation); 1090 bt848_sat(btv, btv->saturation);
1091 1091
1092 /* interrupt */ 1092 /* interrupt */
1093 init_irqreg(btv); 1093 init_irqreg(btv);
1094} 1094}
1095 1095
@@ -1105,7 +1105,7 @@ static void bttv_reinit_bt848(struct bttv *btv)
1105 spin_unlock_irqrestore(&btv->s_lock,flags); 1105 spin_unlock_irqrestore(&btv->s_lock,flags);
1106 1106
1107 init_bt848(btv); 1107 init_bt848(btv);
1108 btv->pll.pll_current = -1; 1108 btv->pll.pll_current = -1;
1109 set_input(btv,btv->input); 1109 set_input(btv,btv->input);
1110} 1110}
1111 1111
@@ -1398,7 +1398,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
1398/* video4linux (1) interface */ 1398/* video4linux (1) interface */
1399 1399
1400static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf, 1400static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
1401 const struct bttv_format *fmt, 1401 const struct bttv_format *fmt,
1402 unsigned int width, unsigned int height, 1402 unsigned int width, unsigned int height,
1403 enum v4l2_field field) 1403 enum v4l2_field field)
1404{ 1404{
@@ -1521,8 +1521,8 @@ static const char *v4l1_ioctls[] = {
1521static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) 1521static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1522{ 1522{
1523 switch (cmd) { 1523 switch (cmd) {
1524 case BTTV_VERSION: 1524 case BTTV_VERSION:
1525 return BTTV_VERSION_CODE; 1525 return BTTV_VERSION_CODE;
1526 1526
1527 /* *** v4l1 *** ************************************************ */ 1527 /* *** v4l1 *** ************************************************ */
1528 case VIDIOCGFREQ: 1528 case VIDIOCGFREQ:
@@ -1576,32 +1576,32 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1576 return 0; 1576 return 0;
1577 } 1577 }
1578 1578
1579 case VIDIOCGCHAN: 1579 case VIDIOCGCHAN:
1580 { 1580 {
1581 struct video_channel *v = arg; 1581 struct video_channel *v = arg;
1582 unsigned int channel = v->channel; 1582 unsigned int channel = v->channel;
1583 1583
1584 if (channel >= bttv_tvcards[btv->c.type].video_inputs) 1584 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1585 return -EINVAL; 1585 return -EINVAL;
1586 v->tuners=0; 1586 v->tuners=0;
1587 v->flags = VIDEO_VC_AUDIO; 1587 v->flags = VIDEO_VC_AUDIO;
1588 v->type = VIDEO_TYPE_CAMERA; 1588 v->type = VIDEO_TYPE_CAMERA;
1589 v->norm = btv->tvnorm; 1589 v->norm = btv->tvnorm;
1590 if (channel == bttv_tvcards[btv->c.type].tuner) { 1590 if (channel == bttv_tvcards[btv->c.type].tuner) {
1591 strcpy(v->name,"Television"); 1591 strcpy(v->name,"Television");
1592 v->flags|=VIDEO_VC_TUNER; 1592 v->flags|=VIDEO_VC_TUNER;
1593 v->type=VIDEO_TYPE_TV; 1593 v->type=VIDEO_TYPE_TV;
1594 v->tuners=1; 1594 v->tuners=1;
1595 } else if (channel == btv->svhs) { 1595 } else if (channel == btv->svhs) {
1596 strcpy(v->name,"S-Video"); 1596 strcpy(v->name,"S-Video");
1597 } else { 1597 } else {
1598 sprintf(v->name,"Composite%d",channel); 1598 sprintf(v->name,"Composite%d",channel);
1599 } 1599 }
1600 return 0; 1600 return 0;
1601 } 1601 }
1602 case VIDIOCSCHAN: 1602 case VIDIOCSCHAN:
1603 { 1603 {
1604 struct video_channel *v = arg; 1604 struct video_channel *v = arg;
1605 unsigned int channel = v->channel; 1605 unsigned int channel = v->channel;
1606 1606
1607 if (channel >= bttv_tvcards[btv->c.type].video_inputs) 1607 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
@@ -1623,7 +1623,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1623 return 0; 1623 return 0;
1624 } 1624 }
1625 1625
1626 case VIDIOCGAUDIO: 1626 case VIDIOCGAUDIO:
1627 { 1627 {
1628 struct video_audio *v = arg; 1628 struct video_audio *v = arg;
1629 1629
@@ -1728,7 +1728,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1728 } else if (i->index == btv->svhs) { 1728 } else if (i->index == btv->svhs) {
1729 sprintf(i->name, "S-Video"); 1729 sprintf(i->name, "S-Video");
1730 } else { 1730 } else {
1731 sprintf(i->name,"Composite%d",i->index); 1731 sprintf(i->name,"Composite%d",i->index);
1732 } 1732 }
1733 if (i->index == btv->input) { 1733 if (i->index == btv->input) {
1734 __u32 dstatus = btread(BT848_DSTATUS); 1734 __u32 dstatus = btread(BT848_DSTATUS);
@@ -1851,6 +1851,11 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1851 up(&btv->lock); 1851 up(&btv->lock);
1852 return 0; 1852 return 0;
1853 } 1853 }
1854 case VIDIOC_LOG_STATUS:
1855 {
1856 bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, 0);
1857 return 0;
1858 }
1854 1859
1855 default: 1860 default:
1856 return -ENOIOCTLCMD; 1861 return -ENOIOCTLCMD;
@@ -2163,7 +2168,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
2163 if (0 != retval) 2168 if (0 != retval)
2164 return retval; 2169 return retval;
2165 if (locked_btres(fh->btv, RESOURCE_VBI)) 2170 if (locked_btres(fh->btv, RESOURCE_VBI))
2166 return -EBUSY; 2171 return -EBUSY;
2167 bttv_vbi_try_fmt(fh,f); 2172 bttv_vbi_try_fmt(fh,f);
2168 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]); 2173 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
2169 bttv_vbi_get_fmt(fh,f); 2174 bttv_vbi_get_fmt(fh,f);
@@ -2201,9 +2206,9 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2201 bttv_reinit_bt848(btv); 2206 bttv_reinit_bt848(btv);
2202 2207
2203 switch (cmd) { 2208 switch (cmd) {
2204 case VIDIOCSFREQ: 2209 case VIDIOCSFREQ:
2205 case VIDIOCSTUNER: 2210 case VIDIOCSTUNER:
2206 case VIDIOCSCHAN: 2211 case VIDIOCSCHAN:
2207 case VIDIOC_S_CTRL: 2212 case VIDIOC_S_CTRL:
2208 case VIDIOC_S_STD: 2213 case VIDIOC_S_STD:
2209 case VIDIOC_S_INPUT: 2214 case VIDIOC_S_INPUT:
@@ -2219,10 +2224,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2219 /* *** v4l1 *** ************************************************ */ 2224 /* *** v4l1 *** ************************************************ */
2220 case VIDIOCGCAP: 2225 case VIDIOCGCAP:
2221 { 2226 {
2222 struct video_capability *cap = arg; 2227 struct video_capability *cap = arg;
2223 2228
2224 memset(cap,0,sizeof(*cap)); 2229 memset(cap,0,sizeof(*cap));
2225 strcpy(cap->name,btv->video_dev->name); 2230 strcpy(cap->name,btv->video_dev->name);
2226 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { 2231 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
2227 /* vbi */ 2232 /* vbi */
2228 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT; 2233 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
@@ -2242,7 +2247,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2242 } 2247 }
2243 cap->channels = bttv_tvcards[btv->c.type].video_inputs; 2248 cap->channels = bttv_tvcards[btv->c.type].video_inputs;
2244 cap->audios = bttv_tvcards[btv->c.type].audio_inputs; 2249 cap->audios = bttv_tvcards[btv->c.type].audio_inputs;
2245 return 0; 2250 return 0;
2246 } 2251 }
2247 2252
2248 case VIDIOCGPICT: 2253 case VIDIOCGPICT:
@@ -2291,7 +2296,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2291 bt848_hue(btv,pic->hue); 2296 bt848_hue(btv,pic->hue);
2292 bt848_sat(btv,pic->colour); 2297 bt848_sat(btv,pic->colour);
2293 up(&fh->cap.lock); 2298 up(&fh->cap.lock);
2294 return 0; 2299 return 0;
2295 } 2300 }
2296 2301
2297 case VIDIOCGWIN: 2302 case VIDIOCGWIN:
@@ -2352,8 +2357,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2352 unsigned long end; 2357 unsigned long end;
2353 2358
2354 if(!capable(CAP_SYS_ADMIN) && 2359 if(!capable(CAP_SYS_ADMIN) &&
2355 !capable(CAP_SYS_RAWIO)) 2360 !capable(CAP_SYS_RAWIO))
2356 return -EPERM; 2361 return -EPERM;
2357 end = (unsigned long)fbuf->base + 2362 end = (unsigned long)fbuf->base +
2358 fbuf->height * fbuf->bytesperline; 2363 fbuf->height * fbuf->bytesperline;
2359 down(&fh->cap.lock); 2364 down(&fh->cap.lock);
@@ -2427,7 +2432,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2427 } 2432 }
2428 2433
2429 /* switch over */ 2434 /* switch over */
2430 retval = bttv_switch_overlay(btv,fh,new); 2435 retval = bttv_switch_overlay(btv,fh,new);
2431 up(&fh->cap.lock); 2436 up(&fh->cap.lock);
2432 return retval; 2437 return retval;
2433 } 2438 }
@@ -2566,13 +2571,13 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2566 return 0; 2571 return 0;
2567 } 2572 }
2568 2573
2569 case BTTV_VERSION: 2574 case BTTV_VERSION:
2570 case VIDIOCGFREQ: 2575 case VIDIOCGFREQ:
2571 case VIDIOCSFREQ: 2576 case VIDIOCSFREQ:
2572 case VIDIOCGTUNER: 2577 case VIDIOCGTUNER:
2573 case VIDIOCSTUNER: 2578 case VIDIOCSTUNER:
2574 case VIDIOCGCHAN: 2579 case VIDIOCGCHAN:
2575 case VIDIOCSCHAN: 2580 case VIDIOCSCHAN:
2576 case VIDIOCGAUDIO: 2581 case VIDIOCGAUDIO:
2577 case VIDIOCSAUDIO: 2582 case VIDIOCSAUDIO:
2578 return bttv_common_ioctls(btv,cmd,arg); 2583 return bttv_common_ioctls(btv,cmd,arg);
@@ -2584,8 +2589,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2584 2589
2585 if (0 == v4l2) 2590 if (0 == v4l2)
2586 return -EINVAL; 2591 return -EINVAL;
2587 strcpy(cap->driver,"bttv"); 2592 strcpy(cap->driver,"bttv");
2588 strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card)); 2593 strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card));
2589 sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci)); 2594 sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci));
2590 cap->version = BTTV_VERSION_CODE; 2595 cap->version = BTTV_VERSION_CODE;
2591 cap->capabilities = 2596 cap->capabilities =
@@ -2856,6 +2861,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2856 case VIDIOC_S_TUNER: 2861 case VIDIOC_S_TUNER:
2857 case VIDIOC_G_FREQUENCY: 2862 case VIDIOC_G_FREQUENCY:
2858 case VIDIOC_S_FREQUENCY: 2863 case VIDIOC_S_FREQUENCY:
2864 case VIDIOC_LOG_STATUS:
2859 return bttv_common_ioctls(btv,cmd,arg); 2865 return bttv_common_ioctls(btv,cmd,arg);
2860 2866
2861 default: 2867 default:
@@ -3091,7 +3097,7 @@ static struct video_device bttv_video_template =
3091{ 3097{
3092 .name = "UNSET", 3098 .name = "UNSET",
3093 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| 3099 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
3094 VID_TYPE_CLIPPING|VID_TYPE_SCALES, 3100 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
3095 .hardware = VID_HARDWARE_BT848, 3101 .hardware = VID_HARDWARE_BT848,
3096 .fops = &bttv_fops, 3102 .fops = &bttv_fops,
3097 .minor = -1, 3103 .minor = -1,
@@ -3137,7 +3143,7 @@ static int radio_open(struct inode *inode, struct file *file)
3137 audio_mux(btv,AUDIO_RADIO); 3143 audio_mux(btv,AUDIO_RADIO);
3138 3144
3139 up(&btv->lock); 3145 up(&btv->lock);
3140 return 0; 3146 return 0;
3141} 3147}
3142 3148
3143static int radio_release(struct inode *inode, struct file *file) 3149static int radio_release(struct inode *inode, struct file *file)
@@ -3160,34 +3166,34 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
3160 switch (cmd) { 3166 switch (cmd) {
3161 case VIDIOCGCAP: 3167 case VIDIOCGCAP:
3162 { 3168 {
3163 struct video_capability *cap = arg; 3169 struct video_capability *cap = arg;
3164 3170
3165 memset(cap,0,sizeof(*cap)); 3171 memset(cap,0,sizeof(*cap));
3166 strcpy(cap->name,btv->radio_dev->name); 3172 strcpy(cap->name,btv->radio_dev->name);
3167 cap->type = VID_TYPE_TUNER; 3173 cap->type = VID_TYPE_TUNER;
3168 cap->channels = 1; 3174 cap->channels = 1;
3169 cap->audios = 1; 3175 cap->audios = 1;
3170 return 0; 3176 return 0;
3171 } 3177 }
3172 3178
3173 case VIDIOCGTUNER: 3179 case VIDIOCGTUNER:
3174 { 3180 {
3175 struct video_tuner *v = arg; 3181 struct video_tuner *v = arg;
3176 3182
3177 if(v->tuner) 3183 if(v->tuner)
3178 return -EINVAL; 3184 return -EINVAL;
3179 memset(v,0,sizeof(*v)); 3185 memset(v,0,sizeof(*v));
3180 strcpy(v->name, "Radio"); 3186 strcpy(v->name, "Radio");
3181 bttv_call_i2c_clients(btv,cmd,v); 3187 bttv_call_i2c_clients(btv,cmd,v);
3182 return 0; 3188 return 0;
3183 } 3189 }
3184 case VIDIOCSTUNER: 3190 case VIDIOCSTUNER:
3185 /* nothing to do */ 3191 /* nothing to do */
3186 return 0; 3192 return 0;
3187 3193
3188 case BTTV_VERSION: 3194 case BTTV_VERSION:
3189 case VIDIOCGFREQ: 3195 case VIDIOCGFREQ:
3190 case VIDIOCSFREQ: 3196 case VIDIOCSFREQ:
3191 case VIDIOCGAUDIO: 3197 case VIDIOCGAUDIO:
3192 case VIDIOCSAUDIO: 3198 case VIDIOCSAUDIO:
3193 return bttv_common_ioctls(btv,cmd,arg); 3199 return bttv_common_ioctls(btv,cmd,arg);
@@ -3693,7 +3699,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3693 } 3699 }
3694 3700
3695 if (astat&BT848_INT_VSYNC) 3701 if (astat&BT848_INT_VSYNC)
3696 btv->field_count++; 3702 btv->field_count++;
3697 3703
3698 if (astat & BT848_INT_GPINT) { 3704 if (astat & BT848_INT_GPINT) {
3699 wake_up(&btv->gpioq); 3705 wake_up(&btv->gpioq);
@@ -3705,13 +3711,13 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3705 wake_up(&btv->i2c_queue); 3711 wake_up(&btv->i2c_queue);
3706 } 3712 }
3707 3713
3708 if ((astat & BT848_INT_RISCI) && (stat & (4<<28))) 3714 if ((astat & BT848_INT_RISCI) && (stat & (4<<28)))
3709 bttv_irq_switch_vbi(btv); 3715 bttv_irq_switch_vbi(btv);
3710 3716
3711 if ((astat & BT848_INT_RISCI) && (stat & (2<<28))) 3717 if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
3712 bttv_irq_wakeup_top(btv); 3718 bttv_irq_wakeup_top(btv);
3713 3719
3714 if ((astat & BT848_INT_RISCI) && (stat & (1<<28))) 3720 if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
3715 bttv_irq_switch_video(btv); 3721 bttv_irq_switch_video(btv);
3716 3722
3717 if ((astat & BT848_INT_HLOCK) && btv->opt_automute) 3723 if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
@@ -3736,10 +3742,22 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3736 3742
3737 count++; 3743 count++;
3738 if (count > 4) { 3744 if (count > 4) {
3739 btwrite(0, BT848_INT_MASK); 3745
3740 printk(KERN_ERR 3746 if (count > 8 || !(astat & BT848_INT_GPINT)) {
3741 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr); 3747 btwrite(0, BT848_INT_MASK);
3748
3749 printk(KERN_ERR
3750 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr);
3751 } else {
3752 printk(KERN_ERR
3753 "bttv%d: IRQ lockup, clearing GPINT from int mask [", btv->c.nr);
3754
3755 btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT),
3756 BT848_INT_MASK);
3757 };
3758
3742 bttv_print_irqbits(stat,astat); 3759 bttv_print_irqbits(stat,astat);
3760
3743 printk("]\n"); 3761 printk("]\n");
3744 } 3762 }
3745 } 3763 }
@@ -3808,7 +3826,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
3808 3826
3809 /* video */ 3827 /* video */
3810 btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); 3828 btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
3811 if (NULL == btv->video_dev) 3829 if (NULL == btv->video_dev)
3812 goto err; 3830 goto err;
3813 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) 3831 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
3814 goto err; 3832 goto err;
@@ -3818,18 +3836,18 @@ static int __devinit bttv_register_video(struct bttv *btv)
3818 3836
3819 /* vbi */ 3837 /* vbi */
3820 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi"); 3838 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi");
3821 if (NULL == btv->vbi_dev) 3839 if (NULL == btv->vbi_dev)
3822 goto err; 3840 goto err;
3823 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) 3841 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
3824 goto err; 3842 goto err;
3825 printk(KERN_INFO "bttv%d: registered device vbi%d\n", 3843 printk(KERN_INFO "bttv%d: registered device vbi%d\n",
3826 btv->c.nr,btv->vbi_dev->minor & 0x1f); 3844 btv->c.nr,btv->vbi_dev->minor & 0x1f);
3827 3845
3828 if (!btv->has_radio) 3846 if (!btv->has_radio)
3829 return 0; 3847 return 0;
3830 /* radio */ 3848 /* radio */
3831 btv->radio_dev = vdev_init(btv, &radio_template, "radio"); 3849 btv->radio_dev = vdev_init(btv, &radio_template, "radio");
3832 if (NULL == btv->radio_dev) 3850 if (NULL == btv->radio_dev)
3833 goto err; 3851 goto err;
3834 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) 3852 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
3835 goto err; 3853 goto err;
@@ -3850,11 +3868,11 @@ static int __devinit bttv_register_video(struct bttv *btv)
3850static void pci_set_command(struct pci_dev *dev) 3868static void pci_set_command(struct pci_dev *dev)
3851{ 3869{
3852#if defined(__powerpc__) 3870#if defined(__powerpc__)
3853 unsigned int cmd; 3871 unsigned int cmd;
3854 3872
3855 pci_read_config_dword(dev, PCI_COMMAND, &cmd); 3873 pci_read_config_dword(dev, PCI_COMMAND, &cmd);
3856 cmd = (cmd | PCI_COMMAND_MEMORY ); 3874 cmd = (cmd | PCI_COMMAND_MEMORY );
3857 pci_write_config_dword(dev, PCI_COMMAND, cmd); 3875 pci_write_config_dword(dev, PCI_COMMAND, cmd);
3858#endif 3876#endif
3859} 3877}
3860 3878
@@ -3868,63 +3886,62 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3868 if (bttv_num == BTTV_MAX) 3886 if (bttv_num == BTTV_MAX)
3869 return -ENOMEM; 3887 return -ENOMEM;
3870 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num); 3888 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
3871 btv=&bttvs[bttv_num]; 3889 btv=&bttvs[bttv_num];
3872 memset(btv,0,sizeof(*btv)); 3890 memset(btv,0,sizeof(*btv));
3873 btv->c.nr = bttv_num; 3891 btv->c.nr = bttv_num;
3874 sprintf(btv->c.name,"bttv%d",btv->c.nr); 3892 sprintf(btv->c.name,"bttv%d",btv->c.nr);
3875 3893
3876 /* initialize structs / fill in defaults */ 3894 /* initialize structs / fill in defaults */
3877 init_MUTEX(&btv->lock); 3895 init_MUTEX(&btv->lock);
3878 init_MUTEX(&btv->reslock); 3896 init_MUTEX(&btv->reslock);
3879 spin_lock_init(&btv->s_lock); 3897 spin_lock_init(&btv->s_lock);
3880 spin_lock_init(&btv->gpio_lock); 3898 spin_lock_init(&btv->gpio_lock);
3881 init_waitqueue_head(&btv->gpioq); 3899 init_waitqueue_head(&btv->gpioq);
3882 init_waitqueue_head(&btv->i2c_queue); 3900 init_waitqueue_head(&btv->i2c_queue);
3883 INIT_LIST_HEAD(&btv->c.subs); 3901 INIT_LIST_HEAD(&btv->c.subs);
3884 INIT_LIST_HEAD(&btv->capture); 3902 INIT_LIST_HEAD(&btv->capture);
3885 INIT_LIST_HEAD(&btv->vcapture); 3903 INIT_LIST_HEAD(&btv->vcapture);
3886 v4l2_prio_init(&btv->prio); 3904 v4l2_prio_init(&btv->prio);
3887 3905
3888 init_timer(&btv->timeout); 3906 init_timer(&btv->timeout);
3889 btv->timeout.function = bttv_irq_timeout; 3907 btv->timeout.function = bttv_irq_timeout;
3890 btv->timeout.data = (unsigned long)btv; 3908 btv->timeout.data = (unsigned long)btv;
3891 3909
3892 btv->i2c_rc = -1; 3910 btv->i2c_rc = -1;
3893 btv->tuner_type = UNSET; 3911 btv->tuner_type = UNSET;
3894 btv->pinnacle_id = UNSET; 3912 btv->pinnacle_id = UNSET;
3895 btv->new_input = UNSET; 3913 btv->new_input = UNSET;
3896 btv->gpioirq = 1;
3897 btv->has_radio=radio[btv->c.nr]; 3914 btv->has_radio=radio[btv->c.nr];
3898 3915
3899 /* pci stuff (init, get irq/mmio, ... */ 3916 /* pci stuff (init, get irq/mmio, ... */
3900 btv->c.pci = dev; 3917 btv->c.pci = dev;
3901 btv->id = dev->device; 3918 btv->id = dev->device;
3902 if (pci_enable_device(dev)) { 3919 if (pci_enable_device(dev)) {
3903 printk(KERN_WARNING "bttv%d: Can't enable device.\n", 3920 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
3904 btv->c.nr); 3921 btv->c.nr);
3905 return -EIO; 3922 return -EIO;
3906 } 3923 }
3907 if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { 3924 if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
3908 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n", 3925 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
3909 btv->c.nr); 3926 btv->c.nr);
3910 return -EIO; 3927 return -EIO;
3911 } 3928 }
3912 if (!request_mem_region(pci_resource_start(dev,0), 3929 if (!request_mem_region(pci_resource_start(dev,0),
3913 pci_resource_len(dev,0), 3930 pci_resource_len(dev,0),
3914 btv->c.name)) { 3931 btv->c.name)) {
3915 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n", 3932 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n",
3916 btv->c.nr, pci_resource_start(dev,0)); 3933 btv->c.nr, pci_resource_start(dev,0));
3917 return -EBUSY; 3934 return -EBUSY;
3918 } 3935 }
3919 pci_set_master(dev); 3936 pci_set_master(dev);
3920 pci_set_command(dev); 3937 pci_set_command(dev);
3921 pci_set_drvdata(dev,btv); 3938 pci_set_drvdata(dev,btv);
3922 3939
3923 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision); 3940 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
3924 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); 3941 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
3925 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", 3942 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
3926 bttv_num,btv->id, btv->revision, pci_name(dev)); 3943 bttv_num,btv->id, btv->revision, pci_name(dev));
3927 printk("irq: %d, latency: %d, mmio: 0x%lx\n", 3944 printk("irq: %d, latency: %d, mmio: 0x%lx\n",
3928 btv->c.pci->irq, lat, pci_resource_start(dev,0)); 3945 btv->c.pci->irq, lat, pci_resource_start(dev,0));
3929 schedule(); 3946 schedule();
3930 3947
@@ -3935,23 +3952,23 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3935 goto fail1; 3952 goto fail1;
3936 } 3953 }
3937 3954
3938 /* identify card */ 3955 /* identify card */
3939 bttv_idcard(btv); 3956 bttv_idcard(btv);
3940 3957
3941 /* disable irqs, register irq handler */ 3958 /* disable irqs, register irq handler */
3942 btwrite(0, BT848_INT_MASK); 3959 btwrite(0, BT848_INT_MASK);
3943 result = request_irq(btv->c.pci->irq, bttv_irq, 3960 result = request_irq(btv->c.pci->irq, bttv_irq,
3944 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv); 3961 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv);
3945 if (result < 0) { 3962 if (result < 0) {
3946 printk(KERN_ERR "bttv%d: can't get IRQ %d\n", 3963 printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
3947 bttv_num,btv->c.pci->irq); 3964 bttv_num,btv->c.pci->irq);
3948 goto fail1; 3965 goto fail1;
3949 } 3966 }
3950 3967
3951 if (0 != bttv_handle_chipset(btv)) { 3968 if (0 != bttv_handle_chipset(btv)) {
3952 result = -EIO; 3969 result = -EIO;
3953 goto fail2; 3970 goto fail2;
3954 } 3971 }
3955 3972
3956 /* init options from insmod args */ 3973 /* init options from insmod args */
3957 btv->opt_combfilter = combfilter; 3974 btv->opt_combfilter = combfilter;
@@ -3977,29 +3994,29 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3977 btv->input = 0; 3994 btv->input = 0;
3978 3995
3979 /* initialize hardware */ 3996 /* initialize hardware */
3980 if (bttv_gpio) 3997 if (bttv_gpio)
3981 bttv_gpio_tracking(btv,"pre-init"); 3998 bttv_gpio_tracking(btv,"pre-init");
3982 3999
3983 bttv_risc_init_main(btv); 4000 bttv_risc_init_main(btv);
3984 init_bt848(btv); 4001 init_bt848(btv);
3985 4002
3986 /* gpio */ 4003 /* gpio */
3987 btwrite(0x00, BT848_GPIO_REG_INP); 4004 btwrite(0x00, BT848_GPIO_REG_INP);
3988 btwrite(0x00, BT848_GPIO_OUT_EN); 4005 btwrite(0x00, BT848_GPIO_OUT_EN);
3989 if (bttv_verbose) 4006 if (bttv_verbose)
3990 bttv_gpio_tracking(btv,"init"); 4007 bttv_gpio_tracking(btv,"init");
3991 4008
3992 /* needs to be done before i2c is registered */ 4009 /* needs to be done before i2c is registered */
3993 bttv_init_card1(btv); 4010 bttv_init_card1(btv);
3994 4011
3995 /* register i2c + gpio */ 4012 /* register i2c + gpio */
3996 init_bttv_i2c(btv); 4013 init_bttv_i2c(btv);
3997 4014
3998 /* some card-specific stuff (needs working i2c) */ 4015 /* some card-specific stuff (needs working i2c) */
3999 bttv_init_card2(btv); 4016 bttv_init_card2(btv);
4000 init_irqreg(btv); 4017 init_irqreg(btv);
4001 4018
4002 /* register video4linux + input */ 4019 /* register video4linux + input */
4003 if (!bttv_tvcards[btv->c.type].no_video) { 4020 if (!bttv_tvcards[btv->c.type].no_video) {
4004 bttv_register_video(btv); 4021 bttv_register_video(btv);
4005 bt848_bright(btv,32768); 4022 bt848_bright(btv,32768);
@@ -4018,10 +4035,10 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4018 4035
4019 /* everything is fine */ 4036 /* everything is fine */
4020 bttv_num++; 4037 bttv_num++;
4021 return 0; 4038 return 0;
4022 4039
4023 fail2: 4040 fail2:
4024 free_irq(btv->c.pci->irq,btv); 4041 free_irq(btv->c.pci->irq,btv);
4025 4042
4026 fail1: 4043 fail1:
4027 if (btv->bt848_mmio) 4044 if (btv->bt848_mmio)
@@ -4034,12 +4051,12 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4034 4051
4035static void __devexit bttv_remove(struct pci_dev *pci_dev) 4052static void __devexit bttv_remove(struct pci_dev *pci_dev)
4036{ 4053{
4037 struct bttv *btv = pci_get_drvdata(pci_dev); 4054 struct bttv *btv = pci_get_drvdata(pci_dev);
4038 4055
4039 if (bttv_verbose) 4056 if (bttv_verbose)
4040 printk("bttv%d: unloading\n",btv->c.nr); 4057 printk("bttv%d: unloading\n",btv->c.nr);
4041 4058
4042 /* shutdown everything (DMA+IRQs) */ 4059 /* shutdown everything (DMA+IRQs) */
4043 btand(~15, BT848_GPIO_DMA_CTL); 4060 btand(~15, BT848_GPIO_DMA_CTL);
4044 btwrite(0, BT848_INT_MASK); 4061 btwrite(0, BT848_INT_MASK);
4045 btwrite(~0x0, BT848_INT_STAT); 4062 btwrite(~0x0, BT848_INT_STAT);
@@ -4052,7 +4069,7 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
4052 wake_up(&btv->gpioq); 4069 wake_up(&btv->gpioq);
4053 bttv_sub_del_devices(&btv->c); 4070 bttv_sub_del_devices(&btv->c);
4054 4071
4055 /* unregister i2c_bus + input */ 4072 /* unregister i2c_bus + input */
4056 fini_bttv_i2c(btv); 4073 fini_bttv_i2c(btv);
4057 4074
4058 /* unregister video4linux */ 4075 /* unregister video4linux */
@@ -4062,18 +4079,18 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
4062 btcx_riscmem_free(btv->c.pci,&btv->main); 4079 btcx_riscmem_free(btv->c.pci,&btv->main);
4063 4080
4064 /* free ressources */ 4081 /* free ressources */
4065 free_irq(btv->c.pci->irq,btv); 4082 free_irq(btv->c.pci->irq,btv);
4066 iounmap(btv->bt848_mmio); 4083 iounmap(btv->bt848_mmio);
4067 release_mem_region(pci_resource_start(btv->c.pci,0), 4084 release_mem_region(pci_resource_start(btv->c.pci,0),
4068 pci_resource_len(btv->c.pci,0)); 4085 pci_resource_len(btv->c.pci,0));
4069 4086
4070 pci_set_drvdata(pci_dev, NULL); 4087 pci_set_drvdata(pci_dev, NULL);
4071 return; 4088 return;
4072} 4089}
4073 4090
4074static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) 4091static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
4075{ 4092{
4076 struct bttv *btv = pci_get_drvdata(pci_dev); 4093 struct bttv *btv = pci_get_drvdata(pci_dev);
4077 struct bttv_buffer_set idle; 4094 struct bttv_buffer_set idle;
4078 unsigned long flags; 4095 unsigned long flags;
4079 4096
@@ -4108,7 +4125,7 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
4108 4125
4109static int bttv_resume(struct pci_dev *pci_dev) 4126static int bttv_resume(struct pci_dev *pci_dev)
4110{ 4127{
4111 struct bttv *btv = pci_get_drvdata(pci_dev); 4128 struct bttv *btv = pci_get_drvdata(pci_dev);
4112 unsigned long flags; 4129 unsigned long flags;
4113 int err; 4130 int err;
4114 4131
@@ -4153,24 +4170,24 @@ static int bttv_resume(struct pci_dev *pci_dev)
4153} 4170}
4154 4171
4155static struct pci_device_id bttv_pci_tbl[] = { 4172static struct pci_device_id bttv_pci_tbl[] = {
4156 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848, 4173 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
4157 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4174 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4158 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849, 4175 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
4159 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4176 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4160 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878, 4177 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
4161 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4178 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4162 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879, 4179 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
4163 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4180 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4164 {0,} 4181 {0,}
4165}; 4182};
4166 4183
4167MODULE_DEVICE_TABLE(pci, bttv_pci_tbl); 4184MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
4168 4185
4169static struct pci_driver bttv_pci_driver = { 4186static struct pci_driver bttv_pci_driver = {
4170 .name = "bttv", 4187 .name = "bttv",
4171 .id_table = bttv_pci_tbl, 4188 .id_table = bttv_pci_tbl,
4172 .probe = bttv_probe, 4189 .probe = bttv_probe,
4173 .remove = __devexit_p(bttv_remove), 4190 .remove = __devexit_p(bttv_remove),
4174 .suspend = bttv_suspend, 4191 .suspend = bttv_suspend,
4175 .resume = bttv_resume, 4192 .resume = bttv_resume,
4176}; 4193};
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index 6b280c03e398..575ce8b8e714 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -7,7 +7,7 @@
7 7
8 8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de) 10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
12 12
13 This program is free software; you can redistribute it and/or modify 13 This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index e684df37eb0e..77619eb131f6 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -5,7 +5,7 @@
5 bttv - Bt848 frame grabber driver 5 bttv - Bt848 frame grabber driver
6 6
7 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 7 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
8 & Marcus Metzler (mocm@thp.uni-koeln.de) 8 & Marcus Metzler (mocm@thp.uni-koeln.de)
9 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 9 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
10 10
11 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
@@ -237,7 +237,7 @@ bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
237 err: 237 err:
238 if (i2c_debug) 238 if (i2c_debug)
239 printk(" ERR: %d\n",retval); 239 printk(" ERR: %d\n",retval);
240 return retval; 240 return retval;
241} 241}
242 242
243static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 243static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
@@ -290,7 +290,13 @@ static struct i2c_adapter bttv_i2c_adap_hw_template = {
290 290
291static int attach_inform(struct i2c_client *client) 291static int attach_inform(struct i2c_client *client)
292{ 292{
293 struct bttv *btv = i2c_get_adapdata(client->adapter); 293 struct bttv *btv = i2c_get_adapdata(client->adapter);
294 int addr=ADDR_UNSET;
295
296
297 if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
298 addr = bttv_tvcards[btv->c.type].tuner_addr;
299
294 300
295 if (bttv_debug) 301 if (bttv_debug)
296 printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n", 302 printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
@@ -300,19 +306,20 @@ static int attach_inform(struct i2c_client *client)
300 return 0; 306 return 0;
301 307
302 if (btv->tuner_type != UNSET) { 308 if (btv->tuner_type != UNSET) {
303 struct tuner_setup tun_setup; 309 struct tuner_setup tun_setup;
310
311 if ((addr==ADDR_UNSET) ||
312 (addr==client->addr)) {
304 313
305 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; 314 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO;
306 tun_setup.type = btv->tuner_type; 315 tun_setup.type = btv->tuner_type;
307 tun_setup.addr = ADDR_UNSET; 316 tun_setup.addr = addr;
317 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
318 }
308 319
309 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
310 } 320 }
311 321
312 if (btv->pinnacle_id != UNSET) 322 return 0;
313 client->driver->command(client,AUDC_CONFIG_PINNACLE,
314 &btv->pinnacle_id);
315 return 0;
316} 323}
317 324
318void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) 325void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
@@ -330,43 +337,43 @@ static struct i2c_client bttv_i2c_client_template = {
330/* read I2C */ 337/* read I2C */
331int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) 338int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
332{ 339{
333 unsigned char buffer = 0; 340 unsigned char buffer = 0;
334 341
335 if (0 != btv->i2c_rc) 342 if (0 != btv->i2c_rc)
336 return -1; 343 return -1;
337 if (bttv_verbose && NULL != probe_for) 344 if (bttv_verbose && NULL != probe_for)
338 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ", 345 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ",
339 btv->c.nr,probe_for,addr); 346 btv->c.nr,probe_for,addr);
340 btv->i2c_client.addr = addr >> 1; 347 btv->i2c_client.addr = addr >> 1;
341 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { 348 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
342 if (NULL != probe_for) { 349 if (NULL != probe_for) {
343 if (bttv_verbose) 350 if (bttv_verbose)
344 printk("not found\n"); 351 printk("not found\n");
345 } else 352 } else
346 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n", 353 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n",
347 btv->c.nr,addr); 354 btv->c.nr,addr);
348 return -1; 355 return -1;
349 } 356 }
350 if (bttv_verbose && NULL != probe_for) 357 if (bttv_verbose && NULL != probe_for)
351 printk("found\n"); 358 printk("found\n");
352 return buffer; 359 return buffer;
353} 360}
354 361
355/* write I2C */ 362/* write I2C */
356int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, 363int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
357 unsigned char b2, int both) 364 unsigned char b2, int both)
358{ 365{
359 unsigned char buffer[2]; 366 unsigned char buffer[2];
360 int bytes = both ? 2 : 1; 367 int bytes = both ? 2 : 1;
361 368
362 if (0 != btv->i2c_rc) 369 if (0 != btv->i2c_rc)
363 return -1; 370 return -1;
364 btv->i2c_client.addr = addr >> 1; 371 btv->i2c_client.addr = addr >> 1;
365 buffer[0] = b1; 372 buffer[0] = b1;
366 buffer[1] = b2; 373 buffer[1] = b2;
367 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) 374 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
368 return -1; 375 return -1;
369 return 0; 376 return 0;
370} 377}
371 378
372/* read EEPROM content */ 379/* read EEPROM content */
@@ -431,8 +438,8 @@ int __devinit init_bttv_i2c(struct bttv *btv)
431 "bt%d #%d [%s]", btv->id, btv->c.nr, 438 "bt%d #%d [%s]", btv->id, btv->c.nr,
432 btv->use_i2c_hw ? "hw" : "sw"); 439 btv->use_i2c_hw ? "hw" : "sw");
433 440
434 i2c_set_adapdata(&btv->c.i2c_adap, btv); 441 i2c_set_adapdata(&btv->c.i2c_adap, btv);
435 btv->i2c_client.adapter = &btv->c.i2c_adap; 442 btv->i2c_client.adapter = &btv->c.i2c_adap;
436 443
437#ifdef I2C_CLASS_TV_ANALOG 444#ifdef I2C_CLASS_TV_ANALOG
438 if (bttv_tvcards[btv->c.type].no_video) 445 if (bttv_tvcards[btv->c.type].no_video)
diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
index e8aada772b89..19b564ab0e92 100644
--- a/drivers/media/video/bttv-if.c
+++ b/drivers/media/video/bttv-if.c
@@ -1,13 +1,13 @@
1/* 1/*
2 2
3 bttv-if.c -- old gpio interface to other kernel modules 3 bttv-if.c -- old gpio interface to other kernel modules
4 don't use in new code, will go away in 2.7 4 don't use in new code, will go away in 2.7
5 have a look at bttv-gpio.c instead. 5 have a look at bttv-gpio.c instead.
6 6
7 bttv - Bt848 frame grabber driver 7 bttv - Bt848 frame grabber driver
8 8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de) 10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
12 12
13 This program is free software; you can redistribute it and/or modify 13 This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
index a5ed99b89445..b40e9734bf08 100644
--- a/drivers/media/video/bttv-risc.c
+++ b/drivers/media/video/bttv-risc.c
@@ -74,27 +74,27 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
74 } 74 }
75 if (bpl <= sg_dma_len(sg)-offset) { 75 if (bpl <= sg_dma_len(sg)-offset) {
76 /* fits into current chunk */ 76 /* fits into current chunk */
77 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| 77 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
78 BT848_RISC_EOL|bpl); 78 BT848_RISC_EOL|bpl);
79 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 79 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
80 offset+=bpl; 80 offset+=bpl;
81 } else { 81 } else {
82 /* scanline needs to be splitted */ 82 /* scanline needs to be splitted */
83 todo = bpl; 83 todo = bpl;
84 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| 84 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
85 (sg_dma_len(sg)-offset)); 85 (sg_dma_len(sg)-offset));
86 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 86 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
87 todo -= (sg_dma_len(sg)-offset); 87 todo -= (sg_dma_len(sg)-offset);
88 offset = 0; 88 offset = 0;
89 sg++; 89 sg++;
90 while (todo > sg_dma_len(sg)) { 90 while (todo > sg_dma_len(sg)) {
91 *(rp++)=cpu_to_le32(BT848_RISC_WRITE| 91 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
92 sg_dma_len(sg)); 92 sg_dma_len(sg));
93 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 93 *(rp++)=cpu_to_le32(sg_dma_address(sg));
94 todo -= sg_dma_len(sg); 94 todo -= sg_dma_len(sg);
95 sg++; 95 sg++;
96 } 96 }
97 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL| 97 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
98 todo); 98 todo);
99 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 99 *(rp++)=cpu_to_le32(sg_dma_address(sg));
100 offset += todo; 100 offset += todo;
@@ -201,8 +201,8 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
201 ri |= BT848_RISC_EOL; 201 ri |= BT848_RISC_EOL;
202 202
203 /* write risc instruction */ 203 /* write risc instruction */
204 *(rp++)=cpu_to_le32(ri | ylen); 204 *(rp++)=cpu_to_le32(ri | ylen);
205 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) | 205 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
206 (ylen >> hshift)); 206 (ylen >> hshift));
207 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset); 207 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
208 yoffset += ylen; 208 yoffset += ylen;
@@ -319,7 +319,7 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
319 int width, int height, int interleaved, int norm) 319 int width, int height, int interleaved, int norm)
320{ 320{
321 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm]; 321 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
322 u32 xsf, sr; 322 u32 xsf, sr;
323 int vdelay; 323 int vdelay;
324 324
325 int swidth = tvnorm->swidth; 325 int swidth = tvnorm->swidth;
@@ -334,52 +334,52 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
334 334
335 vdelay = tvnorm->vdelay; 335 vdelay = tvnorm->vdelay;
336 336
337 xsf = (width*scaledtwidth)/swidth; 337 xsf = (width*scaledtwidth)/swidth;
338 geo->hscale = ((totalwidth*4096UL)/xsf-4096); 338 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
339 geo->hdelay = tvnorm->hdelayx1; 339 geo->hdelay = tvnorm->hdelayx1;
340 geo->hdelay = (geo->hdelay*width)/swidth; 340 geo->hdelay = (geo->hdelay*width)/swidth;
341 geo->hdelay &= 0x3fe; 341 geo->hdelay &= 0x3fe;
342 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512; 342 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
343 geo->vscale = (0x10000UL-sr) & 0x1fff; 343 geo->vscale = (0x10000UL-sr) & 0x1fff;
344 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) | 344 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
345 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0); 345 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
346 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0; 346 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
347 geo->vdelay = vdelay; 347 geo->vdelay = vdelay;
348 geo->width = width; 348 geo->width = width;
349 geo->sheight = tvnorm->sheight; 349 geo->sheight = tvnorm->sheight;
350 geo->vtotal = tvnorm->vtotal; 350 geo->vtotal = tvnorm->vtotal;
351 351
352 if (btv->opt_combfilter) { 352 if (btv->opt_combfilter) {
353 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); 353 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
354 geo->comb = (width < 769) ? 1 : 0; 354 geo->comb = (width < 769) ? 1 : 0;
355 } else { 355 } else {
356 geo->vtc = 0; 356 geo->vtc = 0;
357 geo->comb = 0; 357 geo->comb = 0;
358 } 358 }
359} 359}
360 360
361static void 361static void
362bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) 362bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
363{ 363{
364 int off = odd ? 0x80 : 0x00; 364 int off = odd ? 0x80 : 0x00;
365 365
366 if (geo->comb) 366 if (geo->comb)
367 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 367 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
368 else 368 else
369 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 369 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
370 370
371 btwrite(geo->vtc, BT848_E_VTC+off); 371 btwrite(geo->vtc, BT848_E_VTC+off);
372 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off); 372 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
373 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off); 373 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
374 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off); 374 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
375 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off); 375 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
376 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off); 376 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
377 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off); 377 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
378 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off); 378 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
379 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off); 379 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
380 btwrite(geo->crop, BT848_E_CROP+off); 380 btwrite(geo->crop, BT848_E_CROP+off);
381 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI); 381 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
382 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO); 382 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
383} 383}
384 384
385/* ---------------------------------------------------------- */ 385/* ---------------------------------------------------------- */
@@ -420,7 +420,7 @@ bttv_set_dma(struct bttv *btv, int override)
420 } else { 420 } else {
421 del_timer(&btv->timeout); 421 del_timer(&btv->timeout);
422 } 422 }
423 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd); 423 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
424 424
425 btaor(capctl, ~0x0f, BT848_CAP_CTL); 425 btaor(capctl, ~0x0f, BT848_CAP_CTL);
426 if (capctl) { 426 if (capctl) {
@@ -432,7 +432,7 @@ bttv_set_dma(struct bttv *btv, int override)
432 } else { 432 } else {
433 if (!btv->dma_on) 433 if (!btv->dma_on)
434 return; 434 return;
435 btand(~3, BT848_GPIO_DMA_CTL); 435 btand(~3, BT848_GPIO_DMA_CTL);
436 btv->dma_on = 0; 436 btv->dma_on = 0;
437 } 437 }
438 return; 438 return;
@@ -460,19 +460,19 @@ bttv_risc_init_main(struct bttv *btv)
460 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP); 460 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
461 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2)); 461 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
462 462
463 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | 463 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
464 BT848_FIFO_STATUS_VRO); 464 BT848_FIFO_STATUS_VRO);
465 btv->main.cpu[9] = cpu_to_le32(0); 465 btv->main.cpu[9] = cpu_to_le32(0);
466 466
467 /* bottom field */ 467 /* bottom field */
468 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP); 468 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
469 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2)); 469 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
470 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP); 470 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
471 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2)); 471 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
472 472
473 /* jump back to top field */ 473 /* jump back to top field */
474 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP); 474 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
475 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2)); 475 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
476 476
477 return 0; 477 return 0;
478} 478}
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index d254e90e3bb9..124ea41dada4 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -20,123 +20,148 @@
20/* ---------------------------------------------------------- */ 20/* ---------------------------------------------------------- */
21/* exported by bttv-cards.c */ 21/* exported by bttv-cards.c */
22 22
23#define BTTV_UNKNOWN 0x00 23#define BTTV_BOARD_UNKNOWN 0x00
24#define BTTV_MIRO 0x01 24#define BTTV_BOARD_MIRO 0x01
25#define BTTV_HAUPPAUGE 0x02 25#define BTTV_BOARD_HAUPPAUGE 0x02
26#define BTTV_STB 0x03 26#define BTTV_BOARD_STB 0x03
27#define BTTV_INTEL 0x04 27#define BTTV_BOARD_INTEL 0x04
28#define BTTV_DIAMOND 0x05 28#define BTTV_BOARD_DIAMOND 0x05
29#define BTTV_AVERMEDIA 0x06 29#define BTTV_BOARD_AVERMEDIA 0x06
30#define BTTV_MATRIX_VISION 0x07 30#define BTTV_BOARD_MATRIX_VISION 0x07
31#define BTTV_FLYVIDEO 0x08 31#define BTTV_BOARD_FLYVIDEO 0x08
32#define BTTV_TURBOTV 0x09 32#define BTTV_BOARD_TURBOTV 0x09
33#define BTTV_HAUPPAUGE878 0x0a 33#define BTTV_BOARD_HAUPPAUGE878 0x0a
34#define BTTV_MIROPRO 0x0b 34#define BTTV_BOARD_MIROPRO 0x0b
35#define BTTV_ADSTECH_TV 0x0c 35#define BTTV_BOARD_ADSTECH_TV 0x0c
36#define BTTV_AVERMEDIA98 0x0d 36#define BTTV_BOARD_AVERMEDIA98 0x0d
37#define BTTV_VHX 0x0e 37#define BTTV_BOARD_VHX 0x0e
38#define BTTV_ZOLTRIX 0x0f 38#define BTTV_BOARD_ZOLTRIX 0x0f
39#define BTTV_PIXVIEWPLAYTV 0x10 39#define BTTV_BOARD_PIXVIEWPLAYTV 0x10
40#define BTTV_WINVIEW_601 0x11 40#define BTTV_BOARD_WINVIEW_601 0x11
41#define BTTV_AVEC_INTERCAP 0x12 41#define BTTV_BOARD_AVEC_INTERCAP 0x12
42#define BTTV_LIFE_FLYKIT 0x13 42#define BTTV_BOARD_LIFE_FLYKIT 0x13
43#define BTTV_CEI_RAFFLES 0x14 43#define BTTV_BOARD_CEI_RAFFLES 0x14
44#define BTTV_CONFERENCETV 0x15 44#define BTTV_BOARD_CONFERENCETV 0x15
45#define BTTV_PHOEBE_TVMAS 0x16 45#define BTTV_BOARD_PHOEBE_TVMAS 0x16
46#define BTTV_MODTEC_205 0x17 46#define BTTV_BOARD_MODTEC_205 0x17
47#define BTTV_MAGICTVIEW061 0x18 47#define BTTV_BOARD_MAGICTVIEW061 0x18
48#define BTTV_VOBIS_BOOSTAR 0x19 48#define BTTV_BOARD_VOBIS_BOOSTAR 0x19
49#define BTTV_HAUPPAUG_WCAM 0x1a 49#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a
50#define BTTV_MAXI 0x1b 50#define BTTV_BOARD_MAXI 0x1b
51#define BTTV_TERRATV 0x1c 51#define BTTV_BOARD_TERRATV 0x1c
52#define BTTV_PXC200 0x1d 52#define BTTV_BOARD_PXC200 0x1d
53#define BTTV_FLYVIDEO_98 0x1e 53#define BTTV_BOARD_FLYVIDEO_98 0x1e
54#define BTTV_IPROTV 0x1f 54#define BTTV_BOARD_IPROTV 0x1f
55#define BTTV_INTEL_C_S_PCI 0x20 55#define BTTV_BOARD_INTEL_C_S_PCI 0x20
56#define BTTV_TERRATVALUE 0x21 56#define BTTV_BOARD_TERRATVALUE 0x21
57#define BTTV_WINFAST2000 0x22 57#define BTTV_BOARD_WINFAST2000 0x22
58#define BTTV_CHRONOS_VS2 0x23 58#define BTTV_BOARD_CHRONOS_VS2 0x23
59#define BTTV_TYPHOON_TVIEW 0x24 59#define BTTV_BOARD_TYPHOON_TVIEW 0x24
60#define BTTV_PXELVWPLTVPRO 0x25 60#define BTTV_BOARD_PXELVWPLTVPRO 0x25
61#define BTTV_MAGICTVIEW063 0x26 61#define BTTV_BOARD_MAGICTVIEW063 0x26
62#define BTTV_PINNACLE 0x27 62#define BTTV_BOARD_PINNACLE 0x27
63#define BTTV_STB2 0x28 63#define BTTV_BOARD_STB2 0x28
64#define BTTV_AVPHONE98 0x29 64#define BTTV_BOARD_AVPHONE98 0x29
65#define BTTV_PV951 0x2a 65#define BTTV_BOARD_PV951 0x2a
66#define BTTV_ONAIR_TV 0x2b 66#define BTTV_BOARD_ONAIR_TV 0x2b
67#define BTTV_SIGMA_TVII_FM 0x2c 67#define BTTV_BOARD_SIGMA_TVII_FM 0x2c
68#define BTTV_MATRIX_VISION2 0x2d 68#define BTTV_BOARD_MATRIX_VISION2 0x2d
69#define BTTV_ZOLTRIX_GENIE 0x2e 69#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e
70#define BTTV_TERRATVRADIO 0x2f 70#define BTTV_BOARD_TERRATVRADIO 0x2f
71#define BTTV_DYNALINK 0x30 71#define BTTV_BOARD_DYNALINK 0x30
72#define BTTV_GVBCTV3PCI 0x31 72#define BTTV_BOARD_GVBCTV3PCI 0x31
73#define BTTV_PXELVWPLTVPAK 0x32 73#define BTTV_BOARD_PXELVWPLTVPAK 0x32
74#define BTTV_EAGLE 0x33 74#define BTTV_BOARD_EAGLE 0x33
75#define BTTV_PINNACLEPRO 0x34 75#define BTTV_BOARD_PINNACLEPRO 0x34
76#define BTTV_TVIEW_RDS_FM 0x35 76#define BTTV_BOARD_TVIEW_RDS_FM 0x35
77#define BTTV_LIFETEC_9415 0x36 77#define BTTV_BOARD_LIFETEC_9415 0x36
78#define BTTV_BESTBUY_EASYTV 0x37 78#define BTTV_BOARD_BESTBUY_EASYTV 0x37
79#define BTTV_FLYVIDEO_98FM 0x38 79#define BTTV_BOARD_FLYVIDEO_98FM 0x38
80#define BTTV_GMV1 0x3d 80#define BTTV_BOARD_GRANDTEC 0x39
81#define BTTV_BESTBUY_EASYTV2 0x3e 81#define BTTV_BOARD_ASKEY_CPH060 0x3a
82#define BTTV_ATI_TVWONDER 0x3f 82#define BTTV_BOARD_ASKEY_CPH03X 0x3b
83#define BTTV_ATI_TVWONDERVE 0x40 83#define BTTV_BOARD_MM100PCTV 0x3c
84#define BTTV_FLYVIDEO2000 0x41 84#define BTTV_BOARD_GMV1 0x3d
85#define BTTV_TERRATVALUER 0x42 85#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e
86#define BTTV_GVBCTV4PCI 0x43 86#define BTTV_BOARD_ATI_TVWONDER 0x3f
87#define BTTV_VOODOOTV_FM 0x44 87#define BTTV_BOARD_ATI_TVWONDERVE 0x40
88#define BTTV_AIMMS 0x45 88#define BTTV_BOARD_FLYVIDEO2000 0x41
89#define BTTV_PV_BT878P_PLUS 0x46 89#define BTTV_BOARD_TERRATVALUER 0x42
90#define BTTV_FLYVIDEO98EZ 0x47 90#define BTTV_BOARD_GVBCTV4PCI 0x43
91#define BTTV_PV_BT878P_9B 0x48 91#define BTTV_BOARD_VOODOOTV_FM 0x44
92#define BTTV_SENSORAY311 0x49 92#define BTTV_BOARD_AIMMS 0x45
93#define BTTV_RV605 0x4a 93#define BTTV_BOARD_PV_BT878P_PLUS 0x46
94#define BTTV_WINDVR 0x4c 94#define BTTV_BOARD_FLYVIDEO98EZ 0x47
95#define BTTV_GRANDTEC 0x4d 95#define BTTV_BOARD_PV_BT878P_9B 0x48
96#define BTTV_KWORLD 0x4e 96#define BTTV_BOARD_SENSORAY311 0x49
97#define BTTV_HAUPPAUGEPVR 0x50 97#define BTTV_BOARD_RV605 0x4a
98#define BTTV_GVBCTV5PCI 0x51 98#define BTTV_BOARD_POWERCLR_MTV878 0x4b
99#define BTTV_OSPREY1x0 0x52 99#define BTTV_BOARD_WINDVR 0x4c
100#define BTTV_OSPREY1x0_848 0x53 100#define BTTV_BOARD_GRANDTEC_MULTI 0x4d
101#define BTTV_OSPREY101_848 0x54 101#define BTTV_BOARD_KWORLD 0x4e
102#define BTTV_OSPREY1x1 0x55 102#define BTTV_BOARD_DSP_TCVIDEO 0x4f
103#define BTTV_OSPREY1x1_SVID 0x56 103#define BTTV_BOARD_HAUPPAUGEPVR 0x50
104#define BTTV_OSPREY2xx 0x57 104#define BTTV_BOARD_GVBCTV5PCI 0x51
105#define BTTV_OSPREY2x0_SVID 0x58 105#define BTTV_BOARD_OSPREY1x0 0x52
106#define BTTV_OSPREY2x0 0x59 106#define BTTV_BOARD_OSPREY1x0_848 0x53
107#define BTTV_OSPREY500 0x5a 107#define BTTV_BOARD_OSPREY101_848 0x54
108#define BTTV_OSPREY540 0x5b 108#define BTTV_BOARD_OSPREY1x1 0x55
109#define BTTV_OSPREY2000 0x5c 109#define BTTV_BOARD_OSPREY1x1_SVID 0x56
110#define BTTV_IDS_EAGLE 0x5d 110#define BTTV_BOARD_OSPREY2xx 0x57
111#define BTTV_PINNACLESAT 0x5e 111#define BTTV_BOARD_OSPREY2x0_SVID 0x58
112#define BTTV_FORMAC_PROTV 0x5f 112#define BTTV_BOARD_OSPREY2x0 0x59
113#define BTTV_EURESYS_PICOLO 0x61 113#define BTTV_BOARD_OSPREY500 0x5a
114#define BTTV_PV150 0x62 114#define BTTV_BOARD_OSPREY540 0x5b
115#define BTTV_AD_TVK503 0x63 115#define BTTV_BOARD_OSPREY2000 0x5c
116#define BTTV_IVC200 0x66 116#define BTTV_BOARD_IDS_EAGLE 0x5d
117#define BTTV_XGUARD 0x67 117#define BTTV_BOARD_PINNACLESAT 0x5e
118#define BTTV_NEBULA_DIGITV 0x68 118#define BTTV_BOARD_FORMAC_PROTV 0x5f
119#define BTTV_PV143 0x69 119#define BTTV_BOARD_MACHTV 0x60
120#define BTTV_IVC100 0x6e 120#define BTTV_BOARD_EURESYS_PICOLO 0x61
121#define BTTV_IVC120 0x6f 121#define BTTV_BOARD_PV150 0x62
122#define BTTV_PC_HDTV 0x70 122#define BTTV_BOARD_AD_TVK503 0x63
123#define BTTV_TWINHAN_DST 0x71 123#define BTTV_BOARD_HERCULES_SM_TV 0x64
124#define BTTV_WINFASTVC100 0x72 124#define BTTV_BOARD_PACETV 0x65
125#define BTTV_SIMUS_GVC1100 0x74 125#define BTTV_BOARD_IVC200 0x66
126#define BTTV_NGSTV_PLUS 0x75 126#define BTTV_BOARD_XGUARD 0x67
127#define BTTV_LMLBT4 0x76 127#define BTTV_BOARD_NEBULA_DIGITV 0x68
128#define BTTV_PICOLO_TETRA_CHIP 0x79 128#define BTTV_BOARD_PV143 0x69
129#define BTTV_AVDVBT_771 0x7b 129#define BTTV_BOARD_VD009X1_MINIDIN 0x6a
130#define BTTV_AVDVBT_761 0x7c 130#define BTTV_BOARD_VD009X1_COMBI 0x6b
131#define BTTV_MATRIX_VISIONSQ 0x7d 131#define BTTV_BOARD_VD009_MINIDIN 0x6c
132#define BTTV_MATRIX_VISIONSLC 0x7e 132#define BTTV_BOARD_VD009_COMBI 0x6d
133#define BTTV_APAC_VIEWCOMP 0x7f 133#define BTTV_BOARD_IVC100 0x6e
134#define BTTV_DVICO_DVBT_LITE 0x80 134#define BTTV_BOARD_IVC120 0x6f
135#define BTTV_TIBET_CS16 0x83 135#define BTTV_BOARD_PC_HDTV 0x70
136#define BTTV_KODICOM_4400R 0x84 136#define BTTV_BOARD_TWINHAN_DST 0x71
137#define BTTV_ADLINK_RTV24 0x86 137#define BTTV_BOARD_WINFASTVC100 0x72
138#define BTTV_DVICO_FUSIONHDTV_5_LITE 0x87 138#define BTTV_BOARD_TEV560 0x73
139#define BTTV_ACORP_Y878F 0x88 139#define BTTV_BOARD_SIMUS_GVC1100 0x74
140#define BTTV_BOARD_NGSTV_PLUS 0x75
141#define BTTV_BOARD_LMLBT4 0x76
142#define BTTV_BOARD_TEKRAM_M205 0x77
143#define BTTV_BOARD_CONTVFMI 0x78
144#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79
145#define BTTV_BOARD_SPIRIT_TV 0x7a
146#define BTTV_BOARD_AVDVBT_771 0x7b
147#define BTTV_BOARD_AVDVBT_761 0x7c
148#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d
149#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e
150#define BTTV_BOARD_APAC_VIEWCOMP 0x7f
151#define BTTV_BOARD_DVICO_DVBT_LITE 0x80
152#define BTTV_BOARD_VGEAR_MYVCD 0x81
153#define BTTV_BOARD_SUPER_TV 0x82
154#define BTTV_BOARD_TIBET_CS16 0x83
155#define BTTV_BOARD_KODICOM_4400R 0x84
156#define BTTV_BOARD_KODICOM_4400R_SL 0x85
157#define BTTV_BOARD_ADLINK_RTV24 0x86
158#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
159#define BTTV_BOARD_ACORP_Y878F 0x88
160#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89
161#define BTTV_BOARD_PV_BT878P_2E 0x8a
162#define BTTV_BOARD_PV_M4900 0x8b
163#define BTTV_BOARD_OSPREY440 0x8c
164#define BTTV_BOARD_ASOUND_SKYEYE 0x8d
140 165
141/* i2c address list */ 166/* i2c address list */
142#define I2C_TSA5522 0xc2 167#define I2C_TSA5522 0xc2
@@ -177,7 +202,7 @@ struct bttv_core {
177 struct list_head subs; /* struct bttv_sub_device */ 202 struct list_head subs; /* struct bttv_sub_device */
178 203
179 /* device config */ 204 /* device config */
180 unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ 205 unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
181 unsigned int type; /* card type (pointer into tvcards[]) */ 206 unsigned int type; /* card type (pointer into tvcards[]) */
182 char name[8]; /* dev name */ 207 char name[8]; /* dev name */
183}; 208};
@@ -186,16 +211,16 @@ struct bttv;
186 211
187struct tvcard 212struct tvcard
188{ 213{
189 char *name; 214 char *name;
190 unsigned int video_inputs; 215 unsigned int video_inputs;
191 unsigned int audio_inputs; 216 unsigned int audio_inputs;
192 unsigned int tuner; 217 unsigned int tuner;
193 unsigned int svhs; 218 unsigned int svhs;
194 unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO 219 unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
195 u32 gpiomask; 220 u32 gpiomask;
196 u32 muxsel[16]; 221 u32 muxsel[16];
197 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */ 222 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
198 u32 gpiomask2; /* GPIO MUX mask */ 223 u32 gpiomask2; /* GPIO MUX mask */
199 224
200 /* i2c audio flags */ 225 /* i2c audio flags */
201 unsigned int no_msp34xx:1; 226 unsigned int no_msp34xx:1;
@@ -218,6 +243,7 @@ struct tvcard
218 243
219 unsigned int tuner_type; 244 unsigned int tuner_type;
220 unsigned int tuner_addr; 245 unsigned int tuner_addr;
246 unsigned int radio_addr;
221 247
222 unsigned int has_radio; 248 unsigned int has_radio;
223 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); 249 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
@@ -246,7 +272,7 @@ extern int bttv_handle_chipset(struct bttv *btv);
246 interface below for new code */ 272 interface below for new code */
247 273
248/* returns card type + card ID (for bt878-based ones) 274/* returns card type + card ID (for bt878-based ones)
249 for possible values see lines below beginning with #define BTTV_UNKNOWN 275 for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN
250 returns negative value if error occurred 276 returns negative value if error occurred
251*/ 277*/
252extern int bttv_get_cardinfo(unsigned int card, int *type, 278extern int bttv_get_cardinfo(unsigned int card, int *type,
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index e0e7c7a84bc5..386f546f7d11 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -77,14 +77,14 @@
77struct bttv_tvnorm { 77struct bttv_tvnorm {
78 int v4l2_id; 78 int v4l2_id;
79 char *name; 79 char *name;
80 u32 Fsc; 80 u32 Fsc;
81 u16 swidth, sheight; /* scaled standard width, height */ 81 u16 swidth, sheight; /* scaled standard width, height */
82 u16 totalwidth; 82 u16 totalwidth;
83 u8 adelay, bdelay, iform; 83 u8 adelay, bdelay, iform;
84 u32 scaledtwidth; 84 u32 scaledtwidth;
85 u16 hdelayx1, hactivex1; 85 u16 hdelayx1, hactivex1;
86 u16 vdelay; 86 u16 vdelay;
87 u8 vbipack; 87 u8 vbipack;
88 u16 vtotal; 88 u16 vtotal;
89 int sram; 89 int sram;
90}; 90};
@@ -267,8 +267,8 @@ struct bttv {
267 267
268 /* card configuration info */ 268 /* card configuration info */
269 unsigned int cardid; /* pci subsystem id (bt878 based ones) */ 269 unsigned int cardid; /* pci subsystem id (bt878 based ones) */
270 unsigned int tuner_type; /* tuner chip type */ 270 unsigned int tuner_type; /* tuner chip type */
271 unsigned int pinnacle_id; 271 unsigned int pinnacle_id;
272 unsigned int svhs; 272 unsigned int svhs;
273 struct bttv_pll_info pll; 273 struct bttv_pll_info pll;
274 int triton1; 274 int triton1;
@@ -301,9 +301,9 @@ struct bttv {
301 301
302 /* locking */ 302 /* locking */
303 spinlock_t s_lock; 303 spinlock_t s_lock;
304 struct semaphore lock; 304 struct semaphore lock;
305 int resources; 305 int resources;
306 struct semaphore reslock; 306 struct semaphore reslock;
307#ifdef VIDIOC_G_PRIORITY 307#ifdef VIDIOC_G_PRIORITY
308 struct v4l2_prio_state prio; 308 struct v4l2_prio_state prio;
309#endif 309#endif
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
new file mode 100644
index 000000000000..780b352ec119
--- /dev/null
+++ b/drivers/media/video/cs53l32a.c
@@ -0,0 +1,240 @@
1/*
2 * cs53l32a (Adaptec AVC-2010 and AVC-2410) i2c ivtv driver.
3 * Copyright (C) 2005 Martin Vaughan
4 *
5 * Audio source switching for Adaptec AVC-2410 added by Trev Jackson
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22
23#include <linux/module.h>
24#include <linux/types.h>
25#include <linux/ioctl.h>
26#include <asm/uaccess.h>
27#include <linux/i2c.h>
28#include <linux/i2c-id.h>
29#include <linux/videodev.h>
30#include <media/audiochip.h>
31
32MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
33MODULE_AUTHOR("Martin Vaughan");
34MODULE_LICENSE("GPL");
35
36static int debug = 0;
37
38module_param(debug, bool, 0644);
39
40MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On");
41
42#define cs53l32a_dbg(fmt, arg...) \
43 do { \
44 if (debug) \
45 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
46 i2c_adapter_id(client->adapter), client->addr , ## arg); \
47 } while (0)
48
49#define cs53l32a_err(fmt, arg...) do { \
50 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
51 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
52#define cs53l32a_info(fmt, arg...) do { \
53 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
54 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
55
56static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
57
58
59I2C_CLIENT_INSMOD;
60
61/* ----------------------------------------------------------------------- */
62
63static int cs53l32a_write(struct i2c_client *client, u8 reg, u8 value)
64{
65 return i2c_smbus_write_byte_data(client, reg, value);
66}
67
68static int cs53l32a_read(struct i2c_client *client, u8 reg)
69{
70 return i2c_smbus_read_byte_data(client, reg);
71}
72
73static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
74 void *arg)
75{
76 int *input = arg;
77
78 switch (cmd) {
79 case AUDC_SET_INPUT:
80 switch (*input) {
81 case AUDIO_TUNER:
82 cs53l32a_write(client, 0x01, 0x01);
83 break;
84 case AUDIO_EXTERN:
85 cs53l32a_write(client, 0x01, 0x21);
86 break;
87 case AUDIO_MUTE:
88 cs53l32a_write(client, 0x03, 0xF0);
89 break;
90 case AUDIO_UNMUTE:
91 cs53l32a_write(client, 0x03, 0x30);
92 break;
93 default:
94 cs53l32a_err("Invalid input %d.\n", *input);
95 return -EINVAL;
96 }
97 break;
98
99 case VIDIOC_S_CTRL:
100 {
101 struct v4l2_control *ctrl = arg;
102
103 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
104 return -EINVAL;
105 if (ctrl->value > 12 || ctrl->value < -90)
106 return -EINVAL;
107 cs53l32a_write(client, 0x04, (u8) ctrl->value);
108 cs53l32a_write(client, 0x05, (u8) ctrl->value);
109 break;
110 }
111
112 case VIDIOC_LOG_STATUS:
113 {
114 u8 v = cs53l32a_read(client, 0x01);
115 u8 m = cs53l32a_read(client, 0x03);
116
117 cs53l32a_info("Input: %s%s\n",
118 v == 0x21 ? "external line in" : "tuner",
119 (m & 0xC0) ? " (muted)" : "");
120 break;
121 }
122
123 default:
124 return -EINVAL;
125 }
126 return 0;
127}
128
129/* ----------------------------------------------------------------------- */
130
131/* i2c implementation */
132
133/*
134 * Generic i2c probe
135 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
136 */
137
138static struct i2c_driver i2c_driver;
139
140static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind)
141{
142 struct i2c_client *client;
143 int i;
144
145 /* Check if the adapter supports the needed features */
146 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
147 return 0;
148
149 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
150 if (client == 0)
151 return -ENOMEM;
152
153 memset(client, 0, sizeof(struct i2c_client));
154 client->addr = address;
155 client->adapter = adapter;
156 client->driver = &i2c_driver;
157 client->flags = I2C_CLIENT_ALLOW_USE;
158 snprintf(client->name, sizeof(client->name) - 1, "cs53l32a");
159
160 cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
161
162 for (i = 1; i <= 7; i++) {
163 u8 v = cs53l32a_read(client, i);
164
165 cs53l32a_dbg("Read Reg %d %02x\n", i, v);
166 }
167
168 /* Set cs53l32a internal register for Adaptec 2010/2410 setup */
169
170 cs53l32a_write(client, 0x01, (u8) 0x21);
171 cs53l32a_write(client, 0x02, (u8) 0x29);
172 cs53l32a_write(client, 0x03, (u8) 0x30);
173 cs53l32a_write(client, 0x04, (u8) 0x00);
174 cs53l32a_write(client, 0x05, (u8) 0x00);
175 cs53l32a_write(client, 0x06, (u8) 0x00);
176 cs53l32a_write(client, 0x07, (u8) 0x00);
177
178 /* Display results, should be 0x21,0x29,0x30,0x00,0x00,0x00,0x00 */
179
180 for (i = 1; i <= 7; i++) {
181 u8 v = cs53l32a_read(client, i);
182
183 cs53l32a_dbg("Read Reg %d %02x\n", i, v);
184 }
185
186 i2c_attach_client(client);
187
188 return 0;
189}
190
191static int cs53l32a_probe(struct i2c_adapter *adapter)
192{
193#ifdef I2C_CLASS_TV_ANALOG
194 if (adapter->class & I2C_CLASS_TV_ANALOG)
195#else
196 if (adapter->id == I2C_HW_B_BT848)
197#endif
198 return i2c_probe(adapter, &addr_data, cs53l32a_attach);
199 return 0;
200}
201
202static int cs53l32a_detach(struct i2c_client *client)
203{
204 int err;
205
206 err = i2c_detach_client(client);
207 if (err) {
208 return err;
209 }
210 kfree(client);
211
212 return 0;
213}
214
215/* ----------------------------------------------------------------------- */
216
217/* i2c implementation */
218static struct i2c_driver i2c_driver = {
219 .name = "cs53l32a",
220 .id = I2C_DRIVERID_CS53L32A,
221 .flags = I2C_DF_NOTIFY,
222 .attach_adapter = cs53l32a_probe,
223 .detach_client = cs53l32a_detach,
224 .command = cs53l32a_command,
225 .owner = THIS_MODULE,
226};
227
228
229static int __init cs53l32a_init_module(void)
230{
231 return i2c_add_driver(&i2c_driver);
232}
233
234static void __exit cs53l32a_cleanup_module(void)
235{
236 i2c_del_driver(&i2c_driver);
237}
238
239module_init(cs53l32a_init_module);
240module_exit(cs53l32a_cleanup_module);
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
new file mode 100644
index 000000000000..41818b6205b3
--- /dev/null
+++ b/drivers/media/video/cx88/Kconfig
@@ -0,0 +1,91 @@
1config VIDEO_CX88
2 tristate "Conexant 2388x (bt878 successor) support"
3 depends on VIDEO_DEV && PCI && I2C
4 select I2C_ALGOBIT
5 select FW_LOADER
6 select VIDEO_BTCX
7 select VIDEO_BUF
8 select VIDEO_TUNER
9 select VIDEO_TVEEPROM
10 select VIDEO_IR
11 ---help---
12 This is a video4linux driver for Conexant 2388x based
13 TV cards.
14
15 To compile this driver as a module, choose M here: the
16 module will be called cx8800
17
18config VIDEO_CX88_DVB
19 tristate "DVB/ATSC Support for cx2388x based TV cards"
20 depends on VIDEO_CX88 && DVB_CORE
21 select VIDEO_BUF_DVB
22 ---help---
23 This adds support for DVB/ATSC cards based on the
24 Connexant 2388x chip.
25
26 To compile this driver as a module, choose M here: the
27 module will be called cx88-dvb.
28
29 You must also select one or more DVB/ATSC demodulators.
30 If you are unsure which you need, choose all of them.
31
32config VIDEO_CX88_DVB_ALL_FRONTENDS
33 bool "Build all supported frontends for cx2388x based TV cards"
34 default y
35 depends on VIDEO_CX88_DVB
36 select DVB_MT352
37 select DVB_OR51132
38 select DVB_CX22702
39 select DVB_LGDT330X
40 select DVB_NXT200X
41 ---help---
42 This builds cx88-dvb with all currently supported frontend
43 demodulators. If you wish to tweak your configuration, and
44 only include support for the hardware that you need, choose N here.
45
46 If you are unsure, choose Y.
47
48config VIDEO_CX88_DVB_MT352
49 tristate "Zarlink MT352 DVB-T Support"
50 default m
51 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
52 select DVB_MT352
53 ---help---
54 This adds DVB-T support for cards based on the
55 Connexant 2388x chip and the MT352 demodulator.
56
57config VIDEO_CX88_DVB_OR51132
58 tristate "OR51132 ATSC Support"
59 default m
60 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
61 select DVB_OR51132
62 ---help---
63 This adds ATSC 8VSB and QAM64/256 support for cards based on the
64 Connexant 2388x chip and the OR51132 demodulator.
65
66config VIDEO_CX88_DVB_CX22702
67 tristate "Conexant CX22702 DVB-T Support"
68 default m
69 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
70 select DVB_CX22702
71 ---help---
72 This adds DVB-T support for cards based on the
73 Connexant 2388x chip and the CX22702 demodulator.
74
75config VIDEO_CX88_DVB_LGDT330X
76 tristate "LG Electronics DT3302/DT3303 ATSC Support"
77 default m
78 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
79 select DVB_LGDT330X
80 ---help---
81 This adds ATSC 8VSB and QAM64/256 support for cards based on the
82 Connexant 2388x chip and the LGDT3302/LGDT3303 demodulator.
83
84config VIDEO_CX88_DVB_NXT200X
85 tristate "NXT2002/NXT2004 ATSC Support"
86 default m
87 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
88 select DVB_NXT200X
89 ---help---
90 This adds ATSC 8VSB and QAM64/256 support for cards based on the
91 Connexant 2388x chip and the NXT2002/NXT2004 demodulator.
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 107e48645e3a..0df40b773454 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -9,6 +9,9 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
9EXTRA_CFLAGS += -I$(src)/.. 9EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core 10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends 11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
12ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
13 EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
14endif
12ifneq ($(CONFIG_DVB_CX22702),n) 15ifneq ($(CONFIG_DVB_CX22702),n)
13 EXTRA_CFLAGS += -DHAVE_CX22702=1 16 EXTRA_CFLAGS += -DHAVE_CX22702=1
14endif 17endif
@@ -21,3 +24,6 @@ endif
21ifneq ($(CONFIG_DVB_MT352),n) 24ifneq ($(CONFIG_DVB_MT352),n)
22 EXTRA_CFLAGS += -DHAVE_MT352=1 25 EXTRA_CFLAGS += -DHAVE_MT352=1
23endif 26endif
27ifneq ($(CONFIG_DVB_NXT200X),n)
28 EXTRA_CFLAGS += -DHAVE_NXT200X=1
29endif
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 0c0c59e94774..4ae3f78cccf2 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -38,7 +38,7 @@ MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40 40
41static unsigned int mpegbufs = 8; 41static unsigned int mpegbufs = 32;
42module_param(mpegbufs,int,0644); 42module_param(mpegbufs,int,0644);
43MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); 43MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
44 44
@@ -436,7 +436,7 @@ static int memory_write(struct cx88_core *core, u32 address, u32 value)
436 436
437static int memory_read(struct cx88_core *core, u32 address, u32 *value) 437static int memory_read(struct cx88_core *core, u32 address, u32 *value)
438{ 438{
439 int retval; 439 int retval;
440 u32 val; 440 u32 val;
441 441
442 /* Warning: address is dword address (4 bytes) */ 442 /* Warning: address is dword address (4 bytes) */
@@ -605,11 +605,11 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
605 u32 *dataptr; 605 u32 *dataptr;
606 606
607 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED); 607 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
608 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 608 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
609 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640); 609 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
610 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); 610 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
611 msleep(1); 611 msleep(1);
612 retval |= register_write(dev->core, IVTV_REG_APU, 0); 612 retval |= register_write(dev->core, IVTV_REG_APU, 0);
613 613
614 if (retval < 0) 614 if (retval < 0)
615 dprintk(0, "Error with register_write\n"); 615 dprintk(0, "Error with register_write\n");
@@ -657,13 +657,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
657 release_firmware(firmware); 657 release_firmware(firmware);
658 dprintk(0, "Firmware upload successful.\n"); 658 dprintk(0, "Firmware upload successful.\n");
659 659
660 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 660 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
661 retval |= register_read(dev->core, IVTV_REG_SPU, &value); 661 retval |= register_read(dev->core, IVTV_REG_SPU, &value);
662 retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE); 662 retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
663 msleep(1); 663 msleep(1);
664 664
665 retval |= register_read(dev->core, IVTV_REG_VPU, &value); 665 retval |= register_read(dev->core, IVTV_REG_VPU, &value);
666 retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8); 666 retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
667 667
668 if (retval < 0) 668 if (retval < 0)
669 dprintk(0, "Error with register_write\n"); 669 dprintk(0, "Error with register_write\n");
@@ -683,84 +683,560 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M
683================================================================================================================= 683=================================================================================================================
684*DB: "DirectBurn" 684*DB: "DirectBurn"
685*/ 685*/
686static void blackbird_codec_settings(struct cx8802_dev *dev) 686
687static struct blackbird_dnr default_dnr_params = {
688 .mode = BLACKBIRD_DNR_BITS_MANUAL,
689 .type = BLACKBIRD_MEDIAN_FILTER_DISABLED,
690 .spatial = 0,
691 .temporal = 0
692};
693static struct v4l2_mpeg_compression default_mpeg_params = {
694 .st_type = V4L2_MPEG_PS_2,
695 .st_bitrate = {
696 .mode = V4L2_BITRATE_CBR,
697 .min = 0,
698 .target = 0,
699 .max = 0
700 },
701 .ts_pid_pmt = 16,
702 .ts_pid_audio = 260,
703 .ts_pid_video = 256,
704 .ts_pid_pcr = 259,
705 .ps_size = 0,
706 .au_type = V4L2_MPEG_AU_2_II,
707 .au_bitrate = {
708 .mode = V4L2_BITRATE_CBR,
709 .min = 224,
710 .target = 224,
711 .max = 224
712 },
713 .au_sample_rate = 44100,
714 .au_pesid = 0,
715 .vi_type = V4L2_MPEG_VI_2,
716 .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
717 .vi_bitrate = {
718 .mode = V4L2_BITRATE_CBR,
719 .min = 4000,
720 .target = 4500,
721 .max = 6000
722 },
723 .vi_frame_rate = 25,
724 .vi_frames_per_gop = 15,
725 .vi_bframes_count = 2,
726 .vi_pesid = 0,
727 .closed_gops = 0,
728 .pulldown = 0
729};
730
731static enum blackbird_stream_type mpeg_stream_types[] = {
732 [V4L2_MPEG_SS_1] = BLACKBIRD_STREAM_MPEG1,
733 [V4L2_MPEG_PS_2] = BLACKBIRD_STREAM_PROGRAM,
734 [V4L2_MPEG_TS_2] = BLACKBIRD_STREAM_TRANSPORT,
735 [V4L2_MPEG_PS_DVD] = BLACKBIRD_STREAM_DVD,
736};
737static enum blackbird_aspect_ratio mpeg_stream_ratios[] = {
738 [V4L2_MPEG_ASPECT_SQUARE] = BLACKBIRD_ASPECT_RATIO_1_1_SQUARE,
739 [V4L2_MPEG_ASPECT_4_3] = BLACKBIRD_ASPECT_RATIO_4_3,
740 [V4L2_MPEG_ASPECT_16_9] = BLACKBIRD_ASPECT_RATIO_16_9,
741 [V4L2_MPEG_ASPECT_1_221] = BLACKBIRD_ASPECT_RATIO_221_100,
742};
743static enum blackbird_video_bitrate_type mpeg_video_bitrates[] = {
744 [V4L2_BITRATE_NONE] = BLACKBIRD_VIDEO_CBR,
745 [V4L2_BITRATE_CBR] = BLACKBIRD_VIDEO_CBR,
746 [V4L2_BITRATE_VBR] = BLACKBIRD_VIDEO_VBR,
747};
748/* find the best layer I/II bitrate to fit a given numeric value */
749struct bitrate_bits {
750 u32 bits; /* layer bits for the best fit */
751 u32 rate; /* actual numeric value for the layer best fit */
752};
753struct bitrate_approximation {
754 u32 target; /* numeric value of the rate we want */
755 struct bitrate_bits layer[2];
756};
757static struct bitrate_approximation mpeg_audio_bitrates[] = {
758 /* target layer[0].bits layer[0].rate layer[1].bits layer[1].rate */
759 { 0, { { 0, 0, }, { 0, 0, }, }, },
760 { 32, { { BLACKBIRD_AUDIO_BITS_LAYER_1_32 , 32, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_32 , 32, }, }, },
761 { 48, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_48 , 48, }, }, },
762 { 56, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_56 , 56, }, }, },
763 { 64, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_64 , 64, }, }, },
764 { 80, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_80 , 80, }, }, },
765 { 96, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_96 , 96, }, }, },
766 { 112, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_112, 112, }, }, },
767 { 128, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_128, 128, }, }, },
768 { 160, { { BLACKBIRD_AUDIO_BITS_LAYER_1_160, 160, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_160, 160, }, }, },
769 { 192, { { BLACKBIRD_AUDIO_BITS_LAYER_1_192, 192, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_192, 192, }, }, },
770 { 224, { { BLACKBIRD_AUDIO_BITS_LAYER_1_224, 224, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_224, 224, }, }, },
771 { 256, { { BLACKBIRD_AUDIO_BITS_LAYER_1_256, 256, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_256, 256, }, }, },
772 { 288, { { BLACKBIRD_AUDIO_BITS_LAYER_1_288, 288, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
773 { 320, { { BLACKBIRD_AUDIO_BITS_LAYER_1_320, 320, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
774 { 352, { { BLACKBIRD_AUDIO_BITS_LAYER_1_352, 352, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
775 { 384, { { BLACKBIRD_AUDIO_BITS_LAYER_1_384, 384, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
776 { 416, { { BLACKBIRD_AUDIO_BITS_LAYER_1_416, 416, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
777 { 448, { { BLACKBIRD_AUDIO_BITS_LAYER_1_448, 448, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
778};
779static const int BITRATES_SIZE = ARRAY_SIZE(mpeg_audio_bitrates);
780
781static void blackbird_set_default_params(struct cx8802_dev *dev)
687{ 782{
688 int bitrate_mode = 1; 783 struct v4l2_mpeg_compression *params = &dev->params;
689 int bitrate = 7500000; 784 u32 au_params;
690 int bitrate_peak = 7500000;
691 bitrate_mode = BLACKBIRD_VIDEO_CBR;
692 bitrate = 4000*1024;
693 bitrate_peak = 4000*1024;
694 785
695 /* assign stream type */ 786 /* assign stream type */
696 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM); 787 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
697 788 params->st_type = V4L2_MPEG_PS_2;
698 /* assign output port */ 789 if( params->st_type == V4L2_MPEG_SS_1 )
699 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ 790 params->vi_type = V4L2_MPEG_VI_1;
791 else
792 params->vi_type = V4L2_MPEG_VI_2;
793 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
700 794
701 /* assign framerate */ 795 /* assign framerate */
702 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); 796 if( params->vi_frame_rate <= 25 )
703 797 {
704 /* assign frame size */ 798 params->vi_frame_rate = 25;
705 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0, 799 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
706 dev->height, dev->width); 800 }
801 else
802 {
803 params->vi_frame_rate = 30;
804 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
805 }
707 806
708 /* assign aspect ratio */ 807 /* assign aspect ratio */
709 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, BLACKBIRD_ASPECT_RATIO_4_3); 808 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
710 809 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
711 /* assign bitrates */ 810 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
712 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 5, 0,
713 bitrate_mode, /* mode */
714 bitrate, /* bps */
715 bitrate_peak / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
716 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
717 811
718 /* assign gop properties */ 812 /* assign gop properties */
719 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, 15, 3); 813 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
814
815 /* assign gop closure */
816 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
720 817
721 /* assign 3 2 pulldown */ 818 /* assign 3 2 pulldown */
722 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, BLACKBIRD_3_2_PULLDOWN_DISABLED); 819 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
820
821 /* make sure the params are within bounds */
822 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
823 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
824 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
825 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
826 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
827 params->au_bitrate.mode = V4L2_BITRATE_NONE;
723 828
724 /* assign audio properties */ 829 /* assign audio properties */
725 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ 830 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
726 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4)); 831 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
727 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); */
728 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0,
729 BLACKBIRD_AUDIO_BITS_44100HZ |
730 BLACKBIRD_AUDIO_BITS_LAYER_2 |
731 BLACKBIRD_AUDIO_BITS_LAYER_2_224 |
732 BLACKBIRD_AUDIO_BITS_STEREO |
733 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ 832 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
734 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | 833 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
735 BLACKBIRD_AUDIO_BITS_CRC_OFF | 834 BLACKBIRD_AUDIO_BITS_CRC_OFF |
736 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | 835 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
737 BLACKBIRD_AUDIO_BITS_COPY 836 BLACKBIRD_AUDIO_BITS_COPY |
738 ); 837 0;
838 if( params->au_sample_rate <= 32000 )
839 {
840 params->au_sample_rate = 32000;
841 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
842 }
843 else if( params->au_sample_rate <= 44100 )
844 {
845 params->au_sample_rate = 44100;
846 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
847 }
848 else
849 {
850 params->au_sample_rate = 48000;
851 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
852 }
853 if( params->au_type == V4L2_MPEG_AU_2_I )
854 {
855 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
856 }
857 else
858 {
859 /* TODO: try to handle the other formats more gracefully */
860 params->au_type = V4L2_MPEG_AU_2_II;
861 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
862 }
863 if( params->au_bitrate.mode )
864 {
865 int layer;
866
867 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
868 params->au_bitrate.max = params->vi_bitrate.target;
869 else
870 params->au_bitrate.target = params->vi_bitrate.max;
871
872 layer = params->au_type;
873 if( params->au_bitrate.target == 0 )
874 {
875 /* TODO: use the minimum possible bitrate instead of 0 ? */
876 au_params |= 0;
877 }
878 else if( params->au_bitrate.target >=
879 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
880 {
881 /* clamp the bitrate to the max supported by the standard */
882 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
883 params->au_bitrate.max = params->au_bitrate.target;
884 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
885 }
886 else
887 {
888 /* round up to the nearest supported bitrate */
889 int i;
890 for(i = 1; i < BITRATES_SIZE; i++)
891 {
892 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
893 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
894 {
895 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
896 params->au_bitrate.max = params->au_bitrate.target;
897 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
898 break;
899 }
900 }
901 }
902 }
903 else
904 {
905 /* TODO: ??? */
906 params->au_bitrate.target = params->au_bitrate.max = 0;
907 au_params |= 0;
908 }
909 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
910
911 /* assign bitrates */
912 if( params->vi_bitrate.mode )
913 {
914 /* bitrate is set, let's figure out the cbr/vbr mess */
915 if( params->vi_bitrate.max < params->vi_bitrate.target )
916 {
917 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
918 params->vi_bitrate.max = params->vi_bitrate.target;
919 else
920 params->vi_bitrate.target = params->vi_bitrate.max;
921 }
922 }
923 else
924 {
925 if( params->st_bitrate.max < params->st_bitrate.target )
926 {
927 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
928 params->st_bitrate.target = params->st_bitrate.max;
929 else
930 params->st_bitrate.max = params->st_bitrate.target;
931 }
932 /* calculate vi_bitrate = st_bitrate - au_bitrate */
933 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
934 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
935 }
936 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
937 mpeg_video_bitrates[params->vi_bitrate.mode],
938 params->vi_bitrate.target * 1000, /* kbps -> bps */
939 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
940 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
941
942 /* TODO: implement the stream ID stuff:
943 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
944 ps_size, au_pesid, vi_pesid
945 */
946}
947#define CHECK_PARAM( name ) ( dev->params.name != params->name )
948#define IF_PARAM( name ) if( CHECK_PARAM( name ) )
949#define UPDATE_PARAM( name ) dev->params.name = params->name
950void blackbird_set_params(struct cx8802_dev *dev, struct v4l2_mpeg_compression *params)
951{
952 u32 au_params;
953
954 /* assign stream type */
955 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
956 params->st_type = V4L2_MPEG_PS_2;
957 if( params->st_type == V4L2_MPEG_SS_1 )
958 params->vi_type = V4L2_MPEG_VI_1;
959 else
960 params->vi_type = V4L2_MPEG_VI_2;
961 if( CHECK_PARAM( st_type ) || CHECK_PARAM( vi_type ) )
962 {
963 UPDATE_PARAM( st_type );
964 UPDATE_PARAM( vi_type );
965 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
966 }
967
968 /* assign framerate */
969 if( params->vi_frame_rate <= 25 )
970 params->vi_frame_rate = 25;
971 else
972 params->vi_frame_rate = 30;
973 IF_PARAM( vi_frame_rate )
974 {
975 UPDATE_PARAM( vi_frame_rate );
976 if( params->vi_frame_rate == 25 )
977 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
978 else
979 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
980 }
981
982 /* assign aspect ratio */
983 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
984 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
985 IF_PARAM( vi_aspect_ratio )
986 {
987 UPDATE_PARAM( vi_aspect_ratio );
988 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
989 }
990
991 /* assign gop properties */
992 if( CHECK_PARAM( vi_frames_per_gop ) || CHECK_PARAM( vi_bframes_count ) )
993 {
994 UPDATE_PARAM( vi_frames_per_gop );
995 UPDATE_PARAM( vi_bframes_count );
996 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
997 }
739 998
740 /* assign gop closure */ 999 /* assign gop closure */
741 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, BLACKBIRD_GOP_CLOSURE_OFF); 1000 IF_PARAM( closed_gops )
1001 {
1002 UPDATE_PARAM( closed_gops );
1003 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
1004 }
1005
1006 /* assign 3 2 pulldown */
1007 IF_PARAM( pulldown )
1008 {
1009 UPDATE_PARAM( pulldown );
1010 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
1011 }
1012
1013 /* make sure the params are within bounds */
1014 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1015 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1016 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1017 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1018 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1019 params->au_bitrate.mode = V4L2_BITRATE_NONE;
1020
1021 /* assign audio properties */
1022 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
1023 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
1024 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
1025 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
1026 BLACKBIRD_AUDIO_BITS_CRC_OFF |
1027 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
1028 BLACKBIRD_AUDIO_BITS_COPY |
1029 0;
1030 if( params->au_sample_rate < 32000 )
1031 {
1032 params->au_sample_rate = 32000;
1033 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
1034 }
1035 else if( params->au_sample_rate < 44100 )
1036 {
1037 params->au_sample_rate = 44100;
1038 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
1039 }
1040 else
1041 {
1042 params->au_sample_rate = 48000;
1043 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
1044 }
1045 if( params->au_type == V4L2_MPEG_AU_2_I )
1046 {
1047 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
1048 }
1049 else
1050 {
1051 /* TODO: try to handle the other formats more gracefully */
1052 params->au_type = V4L2_MPEG_AU_2_II;
1053 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
1054 }
1055 if( params->au_bitrate.mode )
1056 {
1057 int layer;
1058
1059 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
1060 params->au_bitrate.max = params->vi_bitrate.target;
1061 else
1062 params->au_bitrate.target = params->vi_bitrate.max;
1063
1064 layer = params->au_type;
1065 if( params->au_bitrate.target == 0 )
1066 {
1067 /* TODO: use the minimum possible bitrate instead of 0 ? */
1068 au_params |= 0;
1069 }
1070 else if( params->au_bitrate.target >=
1071 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
1072 {
1073 /* clamp the bitrate to the max supported by the standard */
1074 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
1075 params->au_bitrate.max = params->au_bitrate.target;
1076 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
1077 }
1078 else
1079 {
1080 /* round up to the nearest supported bitrate */
1081 int i;
1082 for(i = 1; i < BITRATES_SIZE; i++)
1083 {
1084 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
1085 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
1086 {
1087 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
1088 params->au_bitrate.max = params->au_bitrate.target;
1089 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
1090 break;
1091 }
1092 }
1093 }
1094 }
1095 else
1096 {
1097 /* TODO: ??? */
1098 params->au_bitrate.target = params->au_bitrate.max = 0;
1099 au_params |= 0;
1100 }
1101 if( CHECK_PARAM( au_type ) || CHECK_PARAM( au_sample_rate )
1102 || CHECK_PARAM( au_bitrate.mode ) || CHECK_PARAM( au_bitrate.max )
1103 || CHECK_PARAM( au_bitrate.target )
1104 )
1105 {
1106 UPDATE_PARAM( au_type );
1107 UPDATE_PARAM( au_sample_rate );
1108 UPDATE_PARAM( au_bitrate );
1109 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
1110 }
1111
1112 /* assign bitrates */
1113 if( params->vi_bitrate.mode )
1114 {
1115 /* bitrate is set, let's figure out the cbr/vbr mess */
1116 if( params->vi_bitrate.max < params->vi_bitrate.target )
1117 {
1118 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
1119 params->vi_bitrate.max = params->vi_bitrate.target;
1120 else
1121 params->vi_bitrate.target = params->vi_bitrate.max;
1122 }
1123 }
1124 else
1125 {
1126 if( params->st_bitrate.max < params->st_bitrate.target )
1127 {
1128 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
1129 params->st_bitrate.target = params->st_bitrate.max;
1130 else
1131 params->st_bitrate.max = params->st_bitrate.target;
1132 }
1133 /* calculate vi_bitrate = st_bitrate - au_bitrate */
1134 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
1135 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
1136 }
1137 UPDATE_PARAM( st_bitrate );
1138 if( CHECK_PARAM( vi_bitrate.mode ) || CHECK_PARAM( vi_bitrate.max )
1139 || CHECK_PARAM( vi_bitrate.target )
1140 )
1141 {
1142 UPDATE_PARAM( vi_bitrate );
1143 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
1144 mpeg_video_bitrates[params->vi_bitrate.mode],
1145 params->vi_bitrate.target * 1000, /* kbps -> bps */
1146 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
1147 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
1148 }
742 1149
1150 /* TODO: implement the stream ID stuff:
1151 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
1152 ps_size, au_pesid, vi_pesid
1153 */
1154 UPDATE_PARAM( ts_pid_pmt );
1155 UPDATE_PARAM( ts_pid_audio );
1156 UPDATE_PARAM( ts_pid_video );
1157 UPDATE_PARAM( ts_pid_pcr );
1158 UPDATE_PARAM( ps_size );
1159 UPDATE_PARAM( au_pesid );
1160 UPDATE_PARAM( vi_pesid );
1161}
743 1162
1163static void blackbird_set_default_dnr_params(struct cx8802_dev *dev)
1164{
744 /* assign dnr filter mode */ 1165 /* assign dnr filter mode */
1166 if( dev->dnr_params.mode > BLACKBIRD_DNR_BITS_AUTO )
1167 dev->dnr_params.mode = BLACKBIRD_DNR_BITS_MANUAL;
1168 if( dev->dnr_params.type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1169 dev->dnr_params.type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
745 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, 1170 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0,
746 BLACKBIRD_DNR_BITS_MANUAL, 1171 dev->dnr_params.mode,
747 BLACKBIRD_MEDIAN_FILTER_DISABLED 1172 dev->dnr_params.type
748 ); 1173 );
749 1174
750 /* assign dnr filter props*/ 1175 /* assign dnr filter props*/
751 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, 0, 0); 1176 if( dev->dnr_params.spatial > 15 )
1177 dev->dnr_params.spatial = 15;
1178 if( dev->dnr_params.temporal > 31 )
1179 dev->dnr_params.temporal = 31;
1180 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0,
1181 dev->dnr_params.spatial,
1182 dev->dnr_params.temporal
1183 );
1184}
1185#define CHECK_DNR_PARAM( name ) ( dev->dnr_params.name != dnr_params->name )
1186#define UPDATE_DNR_PARAM( name ) dev->dnr_params.name = dnr_params->name
1187void blackbird_set_dnr_params(struct cx8802_dev *dev, struct blackbird_dnr* dnr_params)
1188{
1189 /* assign dnr filter mode */
1190 /* clamp values */
1191 if( dnr_params->mode > BLACKBIRD_DNR_BITS_AUTO )
1192 dnr_params->mode = BLACKBIRD_DNR_BITS_MANUAL;
1193 if( dnr_params->type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1194 dnr_params->type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
1195 /* check if the params actually changed */
1196 if( CHECK_DNR_PARAM( mode ) || CHECK_DNR_PARAM( type ) )
1197 {
1198 UPDATE_DNR_PARAM( mode );
1199 UPDATE_DNR_PARAM( type );
1200 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, dnr_params->mode, dnr_params->type);
1201 }
1202
1203 /* assign dnr filter props*/
1204 if( dnr_params->spatial > 15 )
1205 dnr_params->spatial = 15;
1206 if( dnr_params->temporal > 31 )
1207 dnr_params->temporal = 31;
1208 if( CHECK_DNR_PARAM( spatial ) || CHECK_DNR_PARAM( temporal ) )
1209 {
1210 UPDATE_DNR_PARAM( spatial );
1211 UPDATE_DNR_PARAM( temporal );
1212 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, dnr_params->spatial, dnr_params->temporal);
1213 }
1214}
1215
1216static void blackbird_codec_settings(struct cx8802_dev *dev)
1217{
1218
1219 /* assign output port */
1220 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
1221
1222 /* assign frame size */
1223 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0,
1224 dev->height, dev->width);
752 1225
753 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ 1226 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
754 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255); 1227 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255);
755 1228
756 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */ 1229 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */
757 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0, 1230 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0,
758 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, 1231 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
759 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ 1232 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
760 ); 1233 );
761 1234
762 /* assign frame drop rate */ 1235 /* assign frame drop rate */
763 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */ 1236 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */
1237
1238 blackbird_set_default_params(dev);
1239 blackbird_set_default_dnr_params(dev);
764} 1240}
765 1241
766static int blackbird_initialize_codec(struct cx8802_dev *dev) 1242static int blackbird_initialize_codec(struct cx8802_dev *dev)
@@ -851,15 +1327,10 @@ static int bb_buf_setup(struct videobuf_queue *q,
851 struct cx8802_fh *fh = q->priv_data; 1327 struct cx8802_fh *fh = q->priv_data;
852 1328
853 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */ 1329 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
854 fh->dev->ts_packet_count = 32; /* was: 100 */ 1330 fh->dev->ts_packet_count = mpegbufs; /* was: 100 */
855 1331
856 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count; 1332 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
857 if (0 == *count) 1333 *count = fh->dev->ts_packet_count;
858 *count = mpegbufs;
859 if (*count < 2)
860 *count = 2;
861 if (*count > 32)
862 *count = 32;
863 return 0; 1334 return 0;
864} 1335}
865 1336
@@ -868,7 +1339,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
868 enum v4l2_field field) 1339 enum v4l2_field field)
869{ 1340{
870 struct cx8802_fh *fh = q->priv_data; 1341 struct cx8802_fh *fh = q->priv_data;
871 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb); 1342 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb, field);
872} 1343}
873 1344
874static void 1345static void
@@ -920,8 +1391,6 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
920 V4L2_CAP_VIDEO_CAPTURE | 1391 V4L2_CAP_VIDEO_CAPTURE |
921 V4L2_CAP_READWRITE | 1392 V4L2_CAP_READWRITE |
922 V4L2_CAP_STREAMING | 1393 V4L2_CAP_STREAMING |
923 V4L2_CAP_VBI_CAPTURE |
924 V4L2_CAP_VIDEO_OVERLAY |
925 0; 1394 0;
926 if (UNSET != core->tuner_type) 1395 if (UNSET != core->tuner_type)
927 cap->capabilities |= V4L2_CAP_TUNER; 1396 cap->capabilities |= V4L2_CAP_TUNER;
@@ -941,27 +1410,52 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
941 1410
942 memset(f,0,sizeof(*f)); 1411 memset(f,0,sizeof(*f));
943 f->index = index; 1412 f->index = index;
944 strlcpy(f->description, "MPEG TS", sizeof(f->description)); 1413 strlcpy(f->description, "MPEG", sizeof(f->description));
945 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1414 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
946 f->pixelformat = V4L2_PIX_FMT_MPEG; 1415 f->pixelformat = V4L2_PIX_FMT_MPEG;
947 return 0; 1416 return 0;
948 } 1417 }
949 case VIDIOC_G_FMT: 1418 case VIDIOC_G_FMT:
950 case VIDIOC_S_FMT:
951 case VIDIOC_TRY_FMT:
952 { 1419 {
953 /* FIXME -- quick'n'dirty for exactly one size ... */
954 struct v4l2_format *f = arg; 1420 struct v4l2_format *f = arg;
955 1421
956 memset(f,0,sizeof(*f)); 1422 memset(f,0,sizeof(*f));
957 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1423 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1424 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
1425 f->fmt.pix.bytesperline = 0;
1426 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */
1427 f->fmt.pix.colorspace = 0;
958 f->fmt.pix.width = dev->width; 1428 f->fmt.pix.width = dev->width;
959 f->fmt.pix.height = dev->height; 1429 f->fmt.pix.height = dev->height;
1430 f->fmt.pix.field = fh->mpegq.field;
1431 dprintk(0,"VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
1432 dev->width, dev->height, fh->mpegq.field );
1433 return 0;
1434 }
1435 case VIDIOC_TRY_FMT:
1436 {
1437 struct v4l2_format *f = arg;
1438
1439 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1440 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
1441 f->fmt.pix.bytesperline = 0;
1442 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
1443 f->fmt.pix.colorspace = 0;
1444 dprintk(0,"VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
1445 dev->width, dev->height, fh->mpegq.field );
1446 return 0;
1447 }
1448 case VIDIOC_S_FMT:
1449 {
1450 struct v4l2_format *f = arg;
1451
1452 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
960 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 1453 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
961 f->fmt.pix.field = V4L2_FIELD_NONE;
962 f->fmt.pix.bytesperline = 0; 1454 f->fmt.pix.bytesperline = 0;
963 f->fmt.pix.sizeimage = 188 * 4 * 1024; /* 1024 * 512 */ /* FIXME: BUFFER_SIZE */; 1455 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
964 f->fmt.pix.colorspace = 0; 1456 f->fmt.pix.colorspace = 0;
1457 dprintk(0,"VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
1458 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
965 return 0; 1459 return 0;
966 } 1460 }
967 1461
@@ -985,6 +1479,22 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
985 case VIDIOC_STREAMOFF: 1479 case VIDIOC_STREAMOFF:
986 return videobuf_streamoff(&fh->mpegq); 1480 return videobuf_streamoff(&fh->mpegq);
987 1481
1482 /* --- mpeg compression -------------------------------------- */
1483 case VIDIOC_G_MPEGCOMP:
1484 {
1485 struct v4l2_mpeg_compression *f = arg;
1486
1487 memcpy(f,&dev->params,sizeof(*f));
1488 return 0;
1489 }
1490 case VIDIOC_S_MPEGCOMP:
1491 {
1492 struct v4l2_mpeg_compression *f = arg;
1493
1494 blackbird_set_params(dev, f);
1495 return 0;
1496 }
1497
988 default: 1498 default:
989 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook ); 1499 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook );
990 } 1500 }
@@ -1034,16 +1544,17 @@ static int mpeg_open(struct inode *inode, struct file *file)
1034 file->private_data = fh; 1544 file->private_data = fh;
1035 fh->dev = dev; 1545 fh->dev = dev;
1036 1546
1037 /* FIXME: locking against other video device */
1038 cx88_set_scale(dev->core, dev->width, dev->height,
1039 V4L2_FIELD_INTERLACED);
1040
1041 videobuf_queue_init(&fh->mpegq, &blackbird_qops, 1547 videobuf_queue_init(&fh->mpegq, &blackbird_qops,
1042 dev->pci, &dev->slock, 1548 dev->pci, &dev->slock,
1043 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1549 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1044 V4L2_FIELD_TOP, 1550 V4L2_FIELD_INTERLACED,
1045 sizeof(struct cx88_buffer), 1551 sizeof(struct cx88_buffer),
1046 fh); 1552 fh);
1553
1554 /* FIXME: locking against other video device */
1555 cx88_set_scale(dev->core, dev->width, dev->height,
1556 fh->mpegq.field);
1557
1047 return 0; 1558 return 0;
1048} 1559}
1049 1560
@@ -1173,6 +1684,8 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1173 dev->core = core; 1684 dev->core = core;
1174 dev->width = 720; 1685 dev->width = 720;
1175 dev->height = 576; 1686 dev->height = 576;
1687 memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params));
1688 memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params));
1176 1689
1177 err = cx8802_init_common(dev); 1690 err = cx8802_init_common(dev);
1178 if (0 != err) 1691 if (0 != err)
@@ -1199,7 +1712,7 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1199 1712
1200static void __devexit blackbird_remove(struct pci_dev *pci_dev) 1713static void __devexit blackbird_remove(struct pci_dev *pci_dev)
1201{ 1714{
1202 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 1715 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
1203 1716
1204 /* blackbird */ 1717 /* blackbird */
1205 blackbird_unregister_video(dev); 1718 blackbird_unregister_video(dev);
@@ -1215,8 +1728,8 @@ static struct pci_device_id cx8802_pci_tbl[] = {
1215 { 1728 {
1216 .vendor = 0x14f1, 1729 .vendor = 0x14f1,
1217 .device = 0x8802, 1730 .device = 0x8802,
1218 .subvendor = PCI_ANY_ID, 1731 .subvendor = PCI_ANY_ID,
1219 .subdevice = PCI_ANY_ID, 1732 .subdevice = PCI_ANY_ID,
1220 },{ 1733 },{
1221 /* --- end of list --- */ 1734 /* --- end of list --- */
1222 } 1735 }
@@ -1224,10 +1737,10 @@ static struct pci_device_id cx8802_pci_tbl[] = {
1224MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); 1737MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
1225 1738
1226static struct pci_driver blackbird_pci_driver = { 1739static struct pci_driver blackbird_pci_driver = {
1227 .name = "cx88-blackbird", 1740 .name = "cx88-blackbird",
1228 .id_table = cx8802_pci_tbl, 1741 .id_table = cx8802_pci_tbl,
1229 .probe = blackbird_probe, 1742 .probe = blackbird_probe,
1230 .remove = __devexit_p(blackbird_remove), 1743 .remove = __devexit_p(blackbird_remove),
1231 .suspend = cx8802_suspend_common, 1744 .suspend = cx8802_suspend_common,
1232 .resume = cx8802_resume_common, 1745 .resume = cx8802_resume_common,
1233}; 1746};
@@ -1257,6 +1770,8 @@ module_exit(blackbird_fini);
1257 1770
1258EXPORT_SYMBOL(cx88_ioctl_hook); 1771EXPORT_SYMBOL(cx88_ioctl_hook);
1259EXPORT_SYMBOL(cx88_ioctl_translator); 1772EXPORT_SYMBOL(cx88_ioctl_translator);
1773EXPORT_SYMBOL(blackbird_set_params);
1774EXPORT_SYMBOL(blackbird_set_dnr_params);
1260 1775
1261/* ----------------------------------------------------------- */ 1776/* ----------------------------------------------------------- */
1262/* 1777/*
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 4da91d535a5b..f2268631b7c0 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -126,27 +126,27 @@ struct cx88_board cx88_boards[] = {
126 .input = {{ 126 .input = {{
127 .type = CX88_VMUX_TELEVISION, 127 .type = CX88_VMUX_TELEVISION,
128 .vmux = 0, 128 .vmux = 0,
129 .gpio0 = 0x03ff, 129 .gpio0 = 0x03ff,
130 },{ 130 },{
131 .type = CX88_VMUX_COMPOSITE1, 131 .type = CX88_VMUX_COMPOSITE1,
132 .vmux = 1, 132 .vmux = 1,
133 .gpio0 = 0x03fe, 133 .gpio0 = 0x03fe,
134 },{ 134 },{
135 .type = CX88_VMUX_SVIDEO, 135 .type = CX88_VMUX_SVIDEO,
136 .vmux = 2, 136 .vmux = 2,
137 .gpio0 = 0x03fe, 137 .gpio0 = 0x03fe,
138 }}, 138 }},
139 }, 139 },
140 [CX88_BOARD_WINFAST2000XP_EXPERT] = { 140 [CX88_BOARD_WINFAST2000XP_EXPERT] = {
141 .name = "Leadtek Winfast 2000XP Expert", 141 .name = "Leadtek Winfast 2000XP Expert",
142 .tuner_type = TUNER_PHILIPS_4IN1, 142 .tuner_type = TUNER_PHILIPS_4IN1,
143 .radio_type = UNSET, 143 .radio_type = UNSET,
144 .tuner_addr = ADDR_UNSET, 144 .tuner_addr = ADDR_UNSET,
145 .radio_addr = ADDR_UNSET, 145 .radio_addr = ADDR_UNSET,
146 .tda9887_conf = TDA9887_PRESENT, 146 .tda9887_conf = TDA9887_PRESENT,
147 .input = {{ 147 .input = {{
148 .type = CX88_VMUX_TELEVISION, 148 .type = CX88_VMUX_TELEVISION,
149 .vmux = 0, 149 .vmux = 0,
150 .gpio0 = 0x00F5e700, 150 .gpio0 = 0x00F5e700,
151 .gpio1 = 0x00003004, 151 .gpio1 = 0x00003004,
152 .gpio2 = 0x00F5e700, 152 .gpio2 = 0x00F5e700,
@@ -165,16 +165,16 @@ struct cx88_board cx88_boards[] = {
165 .gpio1 = 0x00003004, 165 .gpio1 = 0x00003004,
166 .gpio2 = 0x00F5c700, 166 .gpio2 = 0x00F5c700,
167 .gpio3 = 0x02000000, 167 .gpio3 = 0x02000000,
168 }}, 168 }},
169 .radio = { 169 .radio = {
170 .type = CX88_RADIO, 170 .type = CX88_RADIO,
171 .gpio0 = 0x00F5d700, 171 .gpio0 = 0x00F5d700,
172 .gpio1 = 0x00003004, 172 .gpio1 = 0x00003004,
173 .gpio2 = 0x00F5d700, 173 .gpio2 = 0x00F5d700,
174 .gpio3 = 0x02000000, 174 .gpio3 = 0x02000000,
175 }, 175 },
176 }, 176 },
177 [CX88_BOARD_AVERTV_303] = { 177 [CX88_BOARD_AVERTV_STUDIO_303] = {
178 .name = "AverTV Studio 303 (M126)", 178 .name = "AverTV Studio 303 (M126)",
179 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 179 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
180 .radio_type = UNSET, 180 .radio_type = UNSET,
@@ -206,7 +206,7 @@ struct cx88_board cx88_boards[] = {
206 .radio_type = UNSET, 206 .radio_type = UNSET,
207 .tuner_addr = ADDR_UNSET, 207 .tuner_addr = ADDR_UNSET,
208 .radio_addr = ADDR_UNSET, 208 .radio_addr = ADDR_UNSET,
209 .tda9887_conf = TDA9887_PRESENT, 209 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER_NTSC,
210 .input = {{ 210 .input = {{
211 .type = CX88_VMUX_TELEVISION, 211 .type = CX88_VMUX_TELEVISION,
212 .vmux = 0, 212 .vmux = 0,
@@ -214,32 +214,32 @@ struct cx88_board cx88_boards[] = {
214 .gpio1 = 0x000080c0, 214 .gpio1 = 0x000080c0,
215 .gpio2 = 0x0000ff40, 215 .gpio2 = 0x0000ff40,
216 },{ 216 },{
217 .type = CX88_VMUX_COMPOSITE1, 217 .type = CX88_VMUX_COMPOSITE1,
218 .vmux = 1, 218 .vmux = 1,
219 .gpio0 = 0x000040bf, 219 .gpio0 = 0x000040bf,
220 .gpio1 = 0x000080c0, 220 .gpio1 = 0x000080c0,
221 .gpio2 = 0x0000ff40, 221 .gpio2 = 0x0000ff40,
222 },{ 222 },{
223 .type = CX88_VMUX_SVIDEO, 223 .type = CX88_VMUX_SVIDEO,
224 .vmux = 2, 224 .vmux = 2,
225 .gpio0 = 0x000040bf, 225 .gpio0 = 0x000040bf,
226 .gpio1 = 0x000080c0, 226 .gpio1 = 0x000080c0,
227 .gpio2 = 0x0000ff40, 227 .gpio2 = 0x0000ff40,
228 }}, 228 }},
229 .radio = { 229 .radio = {
230 .type = CX88_RADIO, 230 .type = CX88_RADIO,
231 }, 231 },
232 }, 232 },
233 [CX88_BOARD_WINFAST_DV2000] = { 233 [CX88_BOARD_WINFAST_DV2000] = {
234 .name = "Leadtek Winfast DV2000", 234 .name = "Leadtek Winfast DV2000",
235 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 235 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
236 .radio_type = UNSET, 236 .radio_type = UNSET,
237 .tuner_addr = ADDR_UNSET, 237 .tuner_addr = ADDR_UNSET,
238 .radio_addr = ADDR_UNSET, 238 .radio_addr = ADDR_UNSET,
239 .tda9887_conf = TDA9887_PRESENT, 239 .tda9887_conf = TDA9887_PRESENT,
240 .input = {{ 240 .input = {{
241 .type = CX88_VMUX_TELEVISION, 241 .type = CX88_VMUX_TELEVISION,
242 .vmux = 0, 242 .vmux = 0,
243 .gpio0 = 0x0035e700, 243 .gpio0 = 0x0035e700,
244 .gpio1 = 0x00003004, 244 .gpio1 = 0x00003004,
245 .gpio2 = 0x0035e700, 245 .gpio2 = 0x0035e700,
@@ -260,14 +260,14 @@ struct cx88_board cx88_boards[] = {
260 .gpio2 = 0x02000000, 260 .gpio2 = 0x02000000,
261 .gpio3 = 0x02000000, 261 .gpio3 = 0x02000000,
262 }}, 262 }},
263 .radio = { 263 .radio = {
264 .type = CX88_RADIO, 264 .type = CX88_RADIO,
265 .gpio0 = 0x0035d700, 265 .gpio0 = 0x0035d700,
266 .gpio1 = 0x00007004, 266 .gpio1 = 0x00007004,
267 .gpio2 = 0x0035d700, 267 .gpio2 = 0x0035d700,
268 .gpio3 = 0x02000000, 268 .gpio3 = 0x02000000,
269 }, 269 },
270 }, 270 },
271 [CX88_BOARD_LEADTEK_PVR2000] = { 271 [CX88_BOARD_LEADTEK_PVR2000] = {
272 // gpio values for PAL version from regspy by DScaler 272 // gpio values for PAL version from regspy by DScaler
273 .name = "Leadtek PVR 2000", 273 .name = "Leadtek PVR 2000",
@@ -296,25 +296,25 @@ struct cx88_board cx88_boards[] = {
296 .blackbird = 1, 296 .blackbird = 1,
297 }, 297 },
298 [CX88_BOARD_IODATA_GVVCP3PCI] = { 298 [CX88_BOARD_IODATA_GVVCP3PCI] = {
299 .name = "IODATA GV-VCP3/PCI", 299 .name = "IODATA GV-VCP3/PCI",
300 .tuner_type = TUNER_ABSENT, 300 .tuner_type = TUNER_ABSENT,
301 .radio_type = UNSET, 301 .radio_type = UNSET,
302 .tuner_addr = ADDR_UNSET, 302 .tuner_addr = ADDR_UNSET,
303 .radio_addr = ADDR_UNSET, 303 .radio_addr = ADDR_UNSET,
304 .input = {{ 304 .input = {{
305 .type = CX88_VMUX_COMPOSITE1, 305 .type = CX88_VMUX_COMPOSITE1,
306 .vmux = 0, 306 .vmux = 0,
307 },{ 307 },{
308 .type = CX88_VMUX_COMPOSITE2, 308 .type = CX88_VMUX_COMPOSITE2,
309 .vmux = 1, 309 .vmux = 1,
310 },{ 310 },{
311 .type = CX88_VMUX_SVIDEO, 311 .type = CX88_VMUX_SVIDEO,
312 .vmux = 2, 312 .vmux = 2,
313 }}, 313 }},
314 }, 314 },
315 [CX88_BOARD_PROLINK_PLAYTVPVR] = { 315 [CX88_BOARD_PROLINK_PLAYTVPVR] = {
316 .name = "Prolink PlayTV PVR", 316 .name = "Prolink PlayTV PVR",
317 .tuner_type = TUNER_PHILIPS_FM1236_MK3, 317 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
318 .radio_type = UNSET, 318 .radio_type = UNSET,
319 .tuner_addr = ADDR_UNSET, 319 .tuner_addr = ADDR_UNSET,
320 .radio_addr = ADDR_UNSET, 320 .radio_addr = ADDR_UNSET,
@@ -348,15 +348,15 @@ struct cx88_board cx88_boards[] = {
348 .type = CX88_VMUX_TELEVISION, 348 .type = CX88_VMUX_TELEVISION,
349 .vmux = 0, 349 .vmux = 0,
350 .gpio0 = 0x0000fde6, 350 .gpio0 = 0x0000fde6,
351 },{ 351 },{
352 .type = CX88_VMUX_SVIDEO, 352 .type = CX88_VMUX_SVIDEO,
353 .vmux = 2, 353 .vmux = 2,
354 .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in? 354 .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in?
355 }}, 355 }},
356 .radio = { 356 .radio = {
357 .type = CX88_RADIO, 357 .type = CX88_RADIO,
358 .gpio0 = 0x0000fde2, 358 .gpio0 = 0x0000fde2,
359 }, 359 },
360 .blackbird = 1, 360 .blackbird = 1,
361 }, 361 },
362 [CX88_BOARD_MSI_TVANYWHERE] = { 362 [CX88_BOARD_MSI_TVANYWHERE] = {
@@ -372,34 +372,34 @@ struct cx88_board cx88_boards[] = {
372 .gpio0 = 0x00000fbf, 372 .gpio0 = 0x00000fbf,
373 .gpio2 = 0x0000fc08, 373 .gpio2 = 0x0000fc08,
374 },{ 374 },{
375 .type = CX88_VMUX_COMPOSITE1, 375 .type = CX88_VMUX_COMPOSITE1,
376 .vmux = 1, 376 .vmux = 1,
377 .gpio0 = 0x00000fbf, 377 .gpio0 = 0x00000fbf,
378 .gpio2 = 0x0000fc68, 378 .gpio2 = 0x0000fc68,
379 },{ 379 },{
380 .type = CX88_VMUX_SVIDEO, 380 .type = CX88_VMUX_SVIDEO,
381 .vmux = 2, 381 .vmux = 2,
382 .gpio0 = 0x00000fbf, 382 .gpio0 = 0x00000fbf,
383 .gpio2 = 0x0000fc68, 383 .gpio2 = 0x0000fc68,
384 }}, 384 }},
385 }, 385 },
386 [CX88_BOARD_KWORLD_DVB_T] = { 386 [CX88_BOARD_KWORLD_DVB_T] = {
387 .name = "KWorld/VStream XPert DVB-T", 387 .name = "KWorld/VStream XPert DVB-T",
388 .tuner_type = TUNER_ABSENT, 388 .tuner_type = TUNER_ABSENT,
389 .radio_type = UNSET, 389 .radio_type = UNSET,
390 .tuner_addr = ADDR_UNSET, 390 .tuner_addr = ADDR_UNSET,
391 .radio_addr = ADDR_UNSET, 391 .radio_addr = ADDR_UNSET,
392 .input = {{ 392 .input = {{
393 .type = CX88_VMUX_COMPOSITE1, 393 .type = CX88_VMUX_COMPOSITE1,
394 .vmux = 1, 394 .vmux = 1,
395 .gpio0 = 0x0700, 395 .gpio0 = 0x0700,
396 .gpio2 = 0x0101, 396 .gpio2 = 0x0101,
397 },{ 397 },{
398 .type = CX88_VMUX_SVIDEO, 398 .type = CX88_VMUX_SVIDEO,
399 .vmux = 2, 399 .vmux = 2,
400 .gpio0 = 0x0700, 400 .gpio0 = 0x0700,
401 .gpio2 = 0x0101, 401 .gpio2 = 0x0101,
402 }}, 402 }},
403 .dvb = 1, 403 .dvb = 1,
404 }, 404 },
405 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = { 405 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
@@ -425,27 +425,27 @@ struct cx88_board cx88_boards[] = {
425 .radio_type = UNSET, 425 .radio_type = UNSET,
426 .tuner_addr = ADDR_UNSET, 426 .tuner_addr = ADDR_UNSET,
427 .radio_addr = ADDR_UNSET, 427 .radio_addr = ADDR_UNSET,
428 .input = {{ 428 .input = {{
429 .type = CX88_VMUX_TELEVISION, 429 .type = CX88_VMUX_TELEVISION,
430 .vmux = 0, 430 .vmux = 0,
431 .gpio0 = 0x07f8, 431 .gpio0 = 0x07f8,
432 },{ 432 },{
433 .type = CX88_VMUX_DEBUG, 433 .type = CX88_VMUX_DEBUG,
434 .vmux = 0, 434 .vmux = 0,
435 .gpio0 = 0x07f9, // mono from tuner chip 435 .gpio0 = 0x07f9, // mono from tuner chip
436 },{ 436 },{
437 .type = CX88_VMUX_COMPOSITE1, 437 .type = CX88_VMUX_COMPOSITE1,
438 .vmux = 1, 438 .vmux = 1,
439 .gpio0 = 0x000007fa, 439 .gpio0 = 0x000007fa,
440 },{ 440 },{
441 .type = CX88_VMUX_SVIDEO, 441 .type = CX88_VMUX_SVIDEO,
442 .vmux = 2, 442 .vmux = 2,
443 .gpio0 = 0x000007fa, 443 .gpio0 = 0x000007fa,
444 }}, 444 }},
445 .radio = { 445 .radio = {
446 .type = CX88_RADIO, 446 .type = CX88_RADIO,
447 .gpio0 = 0x000007f8, 447 .gpio0 = 0x000007f8,
448 }, 448 },
449 }, 449 },
450 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = { 450 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = {
451 .name = "DViCO FusionHDTV 3 Gold-Q", 451 .name = "DViCO FusionHDTV 3 Gold-Q",
@@ -489,28 +489,28 @@ struct cx88_board cx88_boards[] = {
489 }}, 489 }},
490 .dvb = 1, 490 .dvb = 1,
491 }, 491 },
492 [CX88_BOARD_HAUPPAUGE_DVB_T1] = { 492 [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
493 .name = "Hauppauge Nova-T DVB-T", 493 .name = "Hauppauge Nova-T DVB-T",
494 .tuner_type = TUNER_ABSENT, 494 .tuner_type = TUNER_ABSENT,
495 .radio_type = UNSET, 495 .radio_type = UNSET,
496 .tuner_addr = ADDR_UNSET, 496 .tuner_addr = ADDR_UNSET,
497 .radio_addr = ADDR_UNSET, 497 .radio_addr = ADDR_UNSET,
498 .input = {{ 498 .input = {{
499 .type = CX88_VMUX_DVB, 499 .type = CX88_VMUX_DVB,
500 .vmux = 0, 500 .vmux = 0,
501 }}, 501 }},
502 .dvb = 1, 502 .dvb = 1,
503 }, 503 },
504 [CX88_BOARD_CONEXANT_DVB_T1] = { 504 [CX88_BOARD_CONEXANT_DVB_T1] = {
505 .name = "Conexant DVB-T reference design", 505 .name = "Conexant DVB-T reference design",
506 .tuner_type = TUNER_ABSENT, 506 .tuner_type = TUNER_ABSENT,
507 .radio_type = UNSET, 507 .radio_type = UNSET,
508 .tuner_addr = ADDR_UNSET, 508 .tuner_addr = ADDR_UNSET,
509 .radio_addr = ADDR_UNSET, 509 .radio_addr = ADDR_UNSET,
510 .input = {{ 510 .input = {{
511 .type = CX88_VMUX_DVB, 511 .type = CX88_VMUX_DVB,
512 .vmux = 0, 512 .vmux = 0,
513 }}, 513 }},
514 .dvb = 1, 514 .dvb = 1,
515 }, 515 },
516 [CX88_BOARD_PROVIDEO_PV259] = { 516 [CX88_BOARD_PROVIDEO_PV259] = {
@@ -543,12 +543,12 @@ struct cx88_board cx88_boards[] = {
543 .dvb = 1, 543 .dvb = 1,
544 }, 544 },
545 [CX88_BOARD_DNTV_LIVE_DVB_T] = { 545 [CX88_BOARD_DNTV_LIVE_DVB_T] = {
546 .name = "digitalnow DNTV Live! DVB-T", 546 .name = "digitalnow DNTV Live! DVB-T",
547 .tuner_type = TUNER_ABSENT, 547 .tuner_type = TUNER_ABSENT,
548 .radio_type = UNSET, 548 .radio_type = UNSET,
549 .tuner_addr = ADDR_UNSET, 549 .tuner_addr = ADDR_UNSET,
550 .radio_addr = ADDR_UNSET, 550 .radio_addr = ADDR_UNSET,
551 .input = {{ 551 .input = {{
552 .type = CX88_VMUX_COMPOSITE1, 552 .type = CX88_VMUX_COMPOSITE1,
553 .vmux = 1, 553 .vmux = 1,
554 .gpio0 = 0x00000700, 554 .gpio0 = 0x00000700,
@@ -705,44 +705,44 @@ struct cx88_board cx88_boards[] = {
705 .gpio0 = 0xbf60, 705 .gpio0 = 0xbf60,
706 }, 706 },
707 }, 707 },
708 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { 708 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
709 .name = "DViCO FusionHDTV 3 Gold-T", 709 .name = "DViCO FusionHDTV 3 Gold-T",
710 .tuner_type = TUNER_THOMSON_DTT7611, 710 .tuner_type = TUNER_THOMSON_DTT7611,
711 .radio_type = UNSET, 711 .radio_type = UNSET,
712 .tuner_addr = ADDR_UNSET, 712 .tuner_addr = ADDR_UNSET,
713 .radio_addr = ADDR_UNSET, 713 .radio_addr = ADDR_UNSET,
714 .input = {{ 714 .input = {{
715 .type = CX88_VMUX_TELEVISION, 715 .type = CX88_VMUX_TELEVISION,
716 .vmux = 0, 716 .vmux = 0,
717 .gpio0 = 0x97ed, 717 .gpio0 = 0x97ed,
718 },{ 718 },{
719 .type = CX88_VMUX_COMPOSITE1, 719 .type = CX88_VMUX_COMPOSITE1,
720 .vmux = 1, 720 .vmux = 1,
721 .gpio0 = 0x97e9, 721 .gpio0 = 0x97e9,
722 },{ 722 },{
723 .type = CX88_VMUX_SVIDEO, 723 .type = CX88_VMUX_SVIDEO,
724 .vmux = 2, 724 .vmux = 2,
725 .gpio0 = 0x97e9, 725 .gpio0 = 0x97e9,
726 }}, 726 }},
727 .dvb = 1, 727 .dvb = 1,
728 }, 728 },
729 [CX88_BOARD_ADSTECH_DVB_T_PCI] = { 729 [CX88_BOARD_ADSTECH_DVB_T_PCI] = {
730 .name = "ADS Tech Instant TV DVB-T PCI", 730 .name = "ADS Tech Instant TV DVB-T PCI",
731 .tuner_type = TUNER_ABSENT, 731 .tuner_type = TUNER_ABSENT,
732 .radio_type = UNSET, 732 .radio_type = UNSET,
733 .tuner_addr = ADDR_UNSET, 733 .tuner_addr = ADDR_UNSET,
734 .radio_addr = ADDR_UNSET, 734 .radio_addr = ADDR_UNSET,
735 .input = {{ 735 .input = {{
736 .type = CX88_VMUX_COMPOSITE1, 736 .type = CX88_VMUX_COMPOSITE1,
737 .vmux = 1, 737 .vmux = 1,
738 .gpio0 = 0x0700, 738 .gpio0 = 0x0700,
739 .gpio2 = 0x0101, 739 .gpio2 = 0x0101,
740 },{ 740 },{
741 .type = CX88_VMUX_SVIDEO, 741 .type = CX88_VMUX_SVIDEO,
742 .vmux = 2, 742 .vmux = 2,
743 .gpio0 = 0x0700, 743 .gpio0 = 0x0700,
744 .gpio2 = 0x0101, 744 .gpio2 = 0x0101,
745 }}, 745 }},
746 .dvb = 1, 746 .dvb = 1,
747 }, 747 },
748 [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = { 748 [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
@@ -762,20 +762,139 @@ struct cx88_board cx88_boards[] = {
762 .radio_addr = ADDR_UNSET, 762 .radio_addr = ADDR_UNSET,
763 .tda9887_conf = TDA9887_PRESENT, 763 .tda9887_conf = TDA9887_PRESENT,
764 .input = {{ 764 .input = {{
765 .type = CX88_VMUX_TELEVISION, 765 .type = CX88_VMUX_TELEVISION,
766 .vmux = 0, 766 .vmux = 0,
767 .gpio0 = 0x87fd, 767 .gpio0 = 0x87fd,
768 },{ 768 },{
769 .type = CX88_VMUX_COMPOSITE1, 769 .type = CX88_VMUX_COMPOSITE1,
770 .vmux = 1, 770 .vmux = 1,
771 .gpio0 = 0x87f9, 771 .gpio0 = 0x87f9,
772 },{ 772 },{
773 .type = CX88_VMUX_SVIDEO, 773 .type = CX88_VMUX_SVIDEO,
774 .vmux = 2, 774 .vmux = 2,
775 .gpio0 = 0x87f9, 775 .gpio0 = 0x87f9,
776 }}, 776 }},
777 .dvb = 1,
778 },
779 [CX88_BOARD_AVERMEDIA_ULTRATV_MC_550] = {
780 .name = "AverMedia UltraTV Media Center PCI 550",
781 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
782 .radio_type = UNSET,
783 .tuner_addr = ADDR_UNSET,
784 .radio_addr = ADDR_UNSET,
785 .tda9887_conf = TDA9887_PRESENT,
786 .blackbird = 1,
787 .input = {{
788 .type = CX88_VMUX_COMPOSITE1,
789 .vmux = 0,
790 .gpio0 = 0x0000cd73,
791 },{
792 .type = CX88_VMUX_SVIDEO,
793 .vmux = 1,
794 .gpio0 = 0x0000cd73,
795 },{
796 .type = CX88_VMUX_TELEVISION,
797 .vmux = 3,
798 .gpio0 = 0x0000cdb3,
799 }},
800 .radio = {
801 .type = CX88_RADIO,
802 .vmux = 2,
803 .gpio0 = 0x0000cdf3,
804 },
805 },
806 [CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD] = {
807 /* Alexander Wold <awold@bigfoot.com> */
808 .name = "Kworld V-Stream Xpert DVD",
809 .tuner_type = UNSET,
810 .input = {{
811 .type = CX88_VMUX_COMPOSITE1,
812 .vmux = 1,
813 .gpio0 = 0x03000000,
814 .gpio1 = 0x01000000,
815 .gpio2 = 0x02000000,
816 .gpio3 = 0x00100000,
817 },{
818 .type = CX88_VMUX_SVIDEO,
819 .vmux = 2,
820 .gpio0 = 0x03000000,
821 .gpio1 = 0x01000000,
822 .gpio2 = 0x02000000,
823 .gpio3 = 0x00100000,
824 }},
825 },
826 [CX88_BOARD_ATI_HDTVWONDER] = {
827 .name = "ATI HDTV Wonder",
828 .tuner_type = TUNER_PHILIPS_TUV1236D,
829 .radio_type = UNSET,
830 .tuner_addr = ADDR_UNSET,
831 .radio_addr = ADDR_UNSET,
832 .input = {{
833 .type = CX88_VMUX_TELEVISION,
834 .vmux = 0,
835 .gpio0 = 0x00000ff7,
836 .gpio1 = 0x000000ff,
837 .gpio2 = 0x00000001,
838 .gpio3 = 0x00000000,
839 },{
840 .type = CX88_VMUX_COMPOSITE1,
841 .vmux = 1,
842 .gpio0 = 0x00000ffe,
843 .gpio1 = 0x000000ff,
844 .gpio2 = 0x00000001,
845 .gpio3 = 0x00000000,
846 },{
847 .type = CX88_VMUX_SVIDEO,
848 .vmux = 2,
849 .gpio0 = 0x00000ffe,
850 .gpio1 = 0x000000ff,
851 .gpio2 = 0x00000001,
852 .gpio3 = 0x00000000,
853 }},
777 .dvb = 1, 854 .dvb = 1,
778 }, 855 },
856 [CX88_BOARD_WINFAST_DTV1000] = {
857 .name = "WinFast DTV1000-T",
858 .tuner_type = TUNER_ABSENT,
859 .radio_type = UNSET,
860 .tuner_addr = ADDR_UNSET,
861 .radio_addr = ADDR_UNSET,
862 .input = {{
863 .type = CX88_VMUX_DVB,
864 .vmux = 0,
865 }},
866 .dvb = 1,
867 },
868 [CX88_BOARD_AVERTV_303] = {
869 .name = "AVerTV 303 (M126)",
870 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
871 .radio_type = UNSET,
872 .tuner_addr = ADDR_UNSET,
873 .radio_addr = ADDR_UNSET,
874 .tda9887_conf = TDA9887_PRESENT,
875 .input = {{
876 .type = CX88_VMUX_TELEVISION,
877 .vmux = 0,
878 .gpio0 = 0x00ff,
879 .gpio1 = 0xe09f,
880 .gpio2 = 0x0010,
881 .gpio3 = 0x0000,
882 },{
883 .type = CX88_VMUX_COMPOSITE1,
884 .vmux = 1,
885 .gpio0 = 0x00ff,
886 .gpio1 = 0xe05f,
887 .gpio2 = 0x0010,
888 .gpio3 = 0x0000,
889 },{
890 .type = CX88_VMUX_SVIDEO,
891 .vmux = 2,
892 .gpio0 = 0x00ff,
893 .gpio1 = 0xe05f,
894 .gpio2 = 0x0010,
895 .gpio3 = 0x0000,
896 }},
897 },
779}; 898};
780const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 899const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
781 900
@@ -804,41 +923,41 @@ struct cx88_subid cx88_subids[] = {
804 .subdevice = 0x00f8, 923 .subdevice = 0x00f8,
805 .card = CX88_BOARD_ATI_WONDER_PRO, 924 .card = CX88_BOARD_ATI_WONDER_PRO,
806 },{ 925 },{
807 .subvendor = 0x107d, 926 .subvendor = 0x107d,
808 .subdevice = 0x6611, 927 .subdevice = 0x6611,
809 .card = CX88_BOARD_WINFAST2000XP_EXPERT, 928 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
929 },{
930 .subvendor = 0x107d,
931 .subdevice = 0x6613, /* NTSC */
932 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
810 },{ 933 },{
811 .subvendor = 0x107d, 934 .subvendor = 0x107d,
812 .subdevice = 0x6613, /* NTSC */ 935 .subdevice = 0x6620,
813 .card = CX88_BOARD_WINFAST2000XP_EXPERT, 936 .card = CX88_BOARD_WINFAST_DV2000,
937 },{
938 .subvendor = 0x107d,
939 .subdevice = 0x663b,
940 .card = CX88_BOARD_LEADTEK_PVR2000,
814 },{ 941 },{
815 .subvendor = 0x107d, 942 .subvendor = 0x107d,
816 .subdevice = 0x6620, 943 .subdevice = 0x663C,
817 .card = CX88_BOARD_WINFAST_DV2000, 944 .card = CX88_BOARD_LEADTEK_PVR2000,
818 },{ 945 },{
819 .subvendor = 0x107d,
820 .subdevice = 0x663b,
821 .card = CX88_BOARD_LEADTEK_PVR2000,
822 },{
823 .subvendor = 0x107d,
824 .subdevice = 0x663C,
825 .card = CX88_BOARD_LEADTEK_PVR2000,
826 },{
827 .subvendor = 0x1461, 946 .subvendor = 0x1461,
828 .subdevice = 0x000b, 947 .subdevice = 0x000b,
829 .card = CX88_BOARD_AVERTV_303, 948 .card = CX88_BOARD_AVERTV_STUDIO_303,
830 },{ 949 },{
831 .subvendor = 0x1462, 950 .subvendor = 0x1462,
832 .subdevice = 0x8606, 951 .subdevice = 0x8606,
833 .card = CX88_BOARD_MSI_TVANYWHERE_MASTER, 952 .card = CX88_BOARD_MSI_TVANYWHERE_MASTER,
834 },{ 953 },{
835 .subvendor = 0x10fc, 954 .subvendor = 0x10fc,
836 .subdevice = 0xd003, 955 .subdevice = 0xd003,
837 .card = CX88_BOARD_IODATA_GVVCP3PCI, 956 .card = CX88_BOARD_IODATA_GVVCP3PCI,
838 },{ 957 },{
839 .subvendor = 0x1043, 958 .subvendor = 0x1043,
840 .subdevice = 0x4823, /* with mpeg encoder */ 959 .subdevice = 0x4823, /* with mpeg encoder */
841 .card = CX88_BOARD_ASUS_PVR_416, 960 .card = CX88_BOARD_ASUS_PVR_416,
842 },{ 961 },{
843 .subvendor = 0x17de, 962 .subvendor = 0x17de,
844 .subdevice = 0x08a6, 963 .subdevice = 0x08a6,
@@ -852,43 +971,43 @@ struct cx88_subid cx88_subids[] = {
852 .subdevice = 0xd820, 971 .subdevice = 0xd820,
853 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T, 972 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,
854 },{ 973 },{
855 .subvendor = 0x18AC, 974 .subvendor = 0x18ac,
856 .subdevice = 0xDB00, 975 .subdevice = 0xdb00,
857 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1, 976 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
858 },{ 977 },{
859 .subvendor = 0x0070, 978 .subvendor = 0x0070,
860 .subdevice = 0x9002, 979 .subdevice = 0x9002,
861 .card = CX88_BOARD_HAUPPAUGE_DVB_T1, 980 .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
862 },{ 981 },{
863 .subvendor = 0x14f1, 982 .subvendor = 0x14f1,
864 .subdevice = 0x0187, 983 .subdevice = 0x0187,
865 .card = CX88_BOARD_CONEXANT_DVB_T1, 984 .card = CX88_BOARD_CONEXANT_DVB_T1,
866 },{ 985 },{
867 .subvendor = 0x1540, 986 .subvendor = 0x1540,
868 .subdevice = 0x2580, 987 .subdevice = 0x2580,
869 .card = CX88_BOARD_PROVIDEO_PV259, 988 .card = CX88_BOARD_PROVIDEO_PV259,
870 },{ 989 },{
871 .subvendor = 0x18AC, 990 .subvendor = 0x18ac,
872 .subdevice = 0xDB10, 991 .subdevice = 0xdb10,
873 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, 992 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
874 },{ 993 },{
875 .subvendor = 0x1554, 994 .subvendor = 0x1554,
876 .subdevice = 0x4811, 995 .subdevice = 0x4811,
877 .card = CX88_BOARD_PIXELVIEW, 996 .card = CX88_BOARD_PIXELVIEW,
878 },{ 997 },{
879 .subvendor = 0x7063, 998 .subvendor = 0x7063,
880 .subdevice = 0x3000, /* HD-3000 card */ 999 .subdevice = 0x3000, /* HD-3000 card */
881 .card = CX88_BOARD_PCHDTV_HD3000, 1000 .card = CX88_BOARD_PCHDTV_HD3000,
882 },{ 1001 },{
883 .subvendor = 0x17DE, 1002 .subvendor = 0x17de,
884 .subdevice = 0xA8A6, 1003 .subdevice = 0xa8a6,
885 .card = CX88_BOARD_DNTV_LIVE_DVB_T, 1004 .card = CX88_BOARD_DNTV_LIVE_DVB_T,
886 },{ 1005 },{
887 .subvendor = 0x0070, 1006 .subvendor = 0x0070,
888 .subdevice = 0x2801, 1007 .subdevice = 0x2801,
889 .card = CX88_BOARD_HAUPPAUGE_ROSLYN, 1008 .card = CX88_BOARD_HAUPPAUGE_ROSLYN,
890 },{ 1009 },{
891 .subvendor = 0x14F1, 1010 .subvendor = 0x14f1,
892 .subdevice = 0x0342, 1011 .subdevice = 0x0342,
893 .card = CX88_BOARD_DIGITALLOGIC_MEC, 1012 .card = CX88_BOARD_DIGITALLOGIC_MEC,
894 },{ 1013 },{
@@ -899,14 +1018,30 @@ struct cx88_subid cx88_subids[] = {
899 .subvendor = 0x1421, 1018 .subvendor = 0x1421,
900 .subdevice = 0x0334, 1019 .subdevice = 0x0334,
901 .card = CX88_BOARD_ADSTECH_DVB_T_PCI, 1020 .card = CX88_BOARD_ADSTECH_DVB_T_PCI,
902 },{ 1021 },{
903 .subvendor = 0x153b, 1022 .subvendor = 0x153b,
904 .subdevice = 0x1166, 1023 .subdevice = 0x1166,
905 .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1, 1024 .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1,
906 },{ 1025 },{
907 .subvendor = 0x18ac, 1026 .subvendor = 0x18ac,
908 .subdevice = 0xd500, 1027 .subdevice = 0xd500,
909 .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD, 1028 .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD,
1029 },{
1030 .subvendor = 0x1461,
1031 .subdevice = 0x8011,
1032 .card = CX88_BOARD_AVERMEDIA_ULTRATV_MC_550,
1033 },{
1034 .subvendor = PCI_VENDOR_ID_ATI,
1035 .subdevice = 0xa101,
1036 .card = CX88_BOARD_ATI_HDTVWONDER,
1037 },{
1038 .subvendor = 0x107d,
1039 .subdevice = 0x665f,
1040 .card = CX88_BOARD_WINFAST_DTV1000,
1041 },{
1042 .subvendor = 0x1461,
1043 .subdevice = 0x000a,
1044 .card = CX88_BOARD_AVERTV_303,
910 }, 1045 },
911}; 1046};
912const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); 1047const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1108,6 +1243,19 @@ void cx88_card_setup(struct cx88_core *core)
1108 cx_clear(MO_GP0_IO, 0x00000007); 1243 cx_clear(MO_GP0_IO, 0x00000007);
1109 cx_set(MO_GP2_IO, 0x00000101); 1244 cx_set(MO_GP2_IO, 0x00000101);
1110 break; 1245 break;
1246 case CX88_BOARD_ATI_HDTVWONDER:
1247 if (0 == core->i2c_rc) {
1248 /* enable tuner */
1249 int i;
1250 u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
1251 core->i2c_client.addr = 0x0a;
1252
1253 for (i = 0; i < 5; i++)
1254 if (2 != i2c_master_send(&core->i2c_client,&buffer[i*2],2))
1255 printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n",
1256 core->name, i);
1257 }
1258 break;
1111 } 1259 }
1112 if (cx88_boards[core->board].radio.type == CX88_RADIO) 1260 if (cx88_boards[core->board].radio.type == CX88_RADIO)
1113 core->has_radio = 1; 1261 core->has_radio = 1;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index dc5c5c1f3461..eb806af17182 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -31,7 +31,7 @@
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/pci.h> 32#include <linux/pci.h>
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/videodev.h> 34#include <linux/videodev2.h>
35 35
36#include "cx88.h" 36#include "cx88.h"
37 37
@@ -153,26 +153,26 @@ static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
153 } 153 }
154 if (bpl <= sg_dma_len(sg)-offset) { 154 if (bpl <= sg_dma_len(sg)-offset) {
155 /* fits into current chunk */ 155 /* fits into current chunk */
156 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); 156 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
157 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 157 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
158 offset+=bpl; 158 offset+=bpl;
159 } else { 159 } else {
160 /* scanline needs to be splitted */ 160 /* scanline needs to be splitted */
161 todo = bpl; 161 todo = bpl;
162 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL| 162 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
163 (sg_dma_len(sg)-offset)); 163 (sg_dma_len(sg)-offset));
164 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 164 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
165 todo -= (sg_dma_len(sg)-offset); 165 todo -= (sg_dma_len(sg)-offset);
166 offset = 0; 166 offset = 0;
167 sg++; 167 sg++;
168 while (todo > sg_dma_len(sg)) { 168 while (todo > sg_dma_len(sg)) {
169 *(rp++)=cpu_to_le32(RISC_WRITE| 169 *(rp++)=cpu_to_le32(RISC_WRITE|
170 sg_dma_len(sg)); 170 sg_dma_len(sg));
171 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 171 *(rp++)=cpu_to_le32(sg_dma_address(sg));
172 todo -= sg_dma_len(sg); 172 todo -= sg_dma_len(sg);
173 sg++; 173 sg++;
174 } 174 }
175 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); 175 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
176 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 176 *(rp++)=cpu_to_le32(sg_dma_address(sg));
177 offset += todo; 177 offset += todo;
178 } 178 }
@@ -309,7 +309,7 @@ struct sram_channel cx88_sram_channels[] = {
309 .name = "video y / packed", 309 .name = "video y / packed",
310 .cmds_start = 0x180040, 310 .cmds_start = 0x180040,
311 .ctrl_start = 0x180400, 311 .ctrl_start = 0x180400,
312 .cdt = 0x180400 + 64, 312 .cdt = 0x180400 + 64,
313 .fifo_start = 0x180c00, 313 .fifo_start = 0x180c00,
314 .fifo_size = 0x002800, 314 .fifo_size = 0x002800,
315 .ptr1_reg = MO_DMA21_PTR1, 315 .ptr1_reg = MO_DMA21_PTR1,
@@ -321,7 +321,7 @@ struct sram_channel cx88_sram_channels[] = {
321 .name = "video u", 321 .name = "video u",
322 .cmds_start = 0x180080, 322 .cmds_start = 0x180080,
323 .ctrl_start = 0x1804a0, 323 .ctrl_start = 0x1804a0,
324 .cdt = 0x1804a0 + 64, 324 .cdt = 0x1804a0 + 64,
325 .fifo_start = 0x183400, 325 .fifo_start = 0x183400,
326 .fifo_size = 0x000800, 326 .fifo_size = 0x000800,
327 .ptr1_reg = MO_DMA22_PTR1, 327 .ptr1_reg = MO_DMA22_PTR1,
@@ -333,7 +333,7 @@ struct sram_channel cx88_sram_channels[] = {
333 .name = "video v", 333 .name = "video v",
334 .cmds_start = 0x1800c0, 334 .cmds_start = 0x1800c0,
335 .ctrl_start = 0x180540, 335 .ctrl_start = 0x180540,
336 .cdt = 0x180540 + 64, 336 .cdt = 0x180540 + 64,
337 .fifo_start = 0x183c00, 337 .fifo_start = 0x183c00,
338 .fifo_size = 0x000800, 338 .fifo_size = 0x000800,
339 .ptr1_reg = MO_DMA23_PTR1, 339 .ptr1_reg = MO_DMA23_PTR1,
@@ -345,7 +345,7 @@ struct sram_channel cx88_sram_channels[] = {
345 .name = "vbi", 345 .name = "vbi",
346 .cmds_start = 0x180100, 346 .cmds_start = 0x180100,
347 .ctrl_start = 0x1805e0, 347 .ctrl_start = 0x1805e0,
348 .cdt = 0x1805e0 + 64, 348 .cdt = 0x1805e0 + 64,
349 .fifo_start = 0x184400, 349 .fifo_start = 0x184400,
350 .fifo_size = 0x001000, 350 .fifo_size = 0x001000,
351 .ptr1_reg = MO_DMA24_PTR1, 351 .ptr1_reg = MO_DMA24_PTR1,
@@ -357,7 +357,7 @@ struct sram_channel cx88_sram_channels[] = {
357 .name = "audio from", 357 .name = "audio from",
358 .cmds_start = 0x180140, 358 .cmds_start = 0x180140,
359 .ctrl_start = 0x180680, 359 .ctrl_start = 0x180680,
360 .cdt = 0x180680 + 64, 360 .cdt = 0x180680 + 64,
361 .fifo_start = 0x185400, 361 .fifo_start = 0x185400,
362 .fifo_size = 0x000200, 362 .fifo_size = 0x000200,
363 .ptr1_reg = MO_DMA25_PTR1, 363 .ptr1_reg = MO_DMA25_PTR1,
@@ -369,7 +369,7 @@ struct sram_channel cx88_sram_channels[] = {
369 .name = "audio to", 369 .name = "audio to",
370 .cmds_start = 0x180180, 370 .cmds_start = 0x180180,
371 .ctrl_start = 0x180720, 371 .ctrl_start = 0x180720,
372 .cdt = 0x180680 + 64, /* same as audio IN */ 372 .cdt = 0x180680 + 64, /* same as audio IN */
373 .fifo_start = 0x185400, /* same as audio IN */ 373 .fifo_start = 0x185400, /* same as audio IN */
374 .fifo_size = 0x000200, /* same as audio IN */ 374 .fifo_size = 0x000200, /* same as audio IN */
375 .ptr1_reg = MO_DMA26_PTR1, 375 .ptr1_reg = MO_DMA26_PTR1,
@@ -431,7 +431,7 @@ int cx88_sram_channel_setup(struct cx88_core *core,
431/* ------------------------------------------------------------------ */ 431/* ------------------------------------------------------------------ */
432/* debug helper code */ 432/* debug helper code */
433 433
434int cx88_risc_decode(u32 risc) 434static int cx88_risc_decode(u32 risc)
435{ 435{
436 static char *instr[16] = { 436 static char *instr[16] = {
437 [ RISC_SYNC >> 28 ] = "sync", 437 [ RISC_SYNC >> 28 ] = "sync",
@@ -845,19 +845,19 @@ static int set_tvaudio(struct cx88_core *core)
845 return 0; 845 return 0;
846 846
847 if (V4L2_STD_PAL_BG & norm->id) { 847 if (V4L2_STD_PAL_BG & norm->id) {
848 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG; 848 core->tvaudio = WW_BG;
849 849
850 } else if (V4L2_STD_PAL_DK & norm->id) { 850 } else if (V4L2_STD_PAL_DK & norm->id) {
851 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK; 851 core->tvaudio = WW_DK;
852 852
853 } else if (V4L2_STD_PAL_I & norm->id) { 853 } else if (V4L2_STD_PAL_I & norm->id) {
854 core->tvaudio = WW_NICAM_I; 854 core->tvaudio = WW_I;
855 855
856 } else if (V4L2_STD_SECAM_L & norm->id) { 856 } else if (V4L2_STD_SECAM_L & norm->id) {
857 core->tvaudio = WW_SYSTEM_L_AM; 857 core->tvaudio = WW_L;
858 858
859 } else if (V4L2_STD_SECAM_DK & norm->id) { 859 } else if (V4L2_STD_SECAM_DK & norm->id) {
860 core->tvaudio = WW_A2_DK; 860 core->tvaudio = WW_DK;
861 861
862 } else if ((V4L2_STD_NTSC_M & norm->id) || 862 } else if ((V4L2_STD_NTSC_M & norm->id) ||
863 (V4L2_STD_PAL_M & norm->id)) { 863 (V4L2_STD_PAL_M & norm->id)) {
@@ -1137,7 +1137,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1137 if (!core->radio_addr) 1137 if (!core->radio_addr)
1138 core->radio_addr = cx88_boards[core->board].radio_addr; 1138 core->radio_addr = cx88_boards[core->board].radio_addr;
1139 1139
1140 printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n", 1140 printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
1141 core->tuner_type, core->tuner_addr<<1, 1141 core->tuner_type, core->tuner_addr<<1,
1142 core->radio_type, core->radio_addr<<1); 1142 core->radio_type, core->radio_addr<<1);
1143 1143
@@ -1146,6 +1146,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1146 /* init hardware */ 1146 /* init hardware */
1147 cx88_reset(core); 1147 cx88_reset(core);
1148 cx88_i2c_init(core,pci); 1148 cx88_i2c_init(core,pci);
1149 cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
1149 cx88_card_setup(core); 1150 cx88_card_setup(core);
1150 cx88_ir_init(core,pci); 1151 cx88_ir_init(core,pci);
1151 1152
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 4334744652de..9cce91ec334b 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -29,7 +29,6 @@
29#include <linux/file.h> 29#include <linux/file.h>
30#include <linux/suspend.h> 30#include <linux/suspend.h>
31 31
32
33#include "cx88.h" 32#include "cx88.h"
34#include "dvb-pll.h" 33#include "dvb-pll.h"
35 34
@@ -46,6 +45,9 @@
46#ifdef HAVE_LGDT330X 45#ifdef HAVE_LGDT330X
47# include "lgdt330x.h" 46# include "lgdt330x.h"
48#endif 47#endif
48#ifdef HAVE_NXT200X
49# include "nxt200x.h"
50#endif
49 51
50MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 52MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
51MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 53MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -78,7 +80,7 @@ static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
78 enum v4l2_field field) 80 enum v4l2_field field)
79{ 81{
80 struct cx8802_dev *dev = q->priv_data; 82 struct cx8802_dev *dev = q->priv_data;
81 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb); 83 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb,field);
82} 84}
83 85
84static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 86static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
@@ -129,7 +131,7 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
129 static u8 reset [] = { 0x50, 0x80 }; 131 static u8 reset [] = { 0x50, 0x80 };
130 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 132 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
131 static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, 133 static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
132 0x00, 0xFF, 0x00, 0x40, 0x40 }; 134 0x00, 0xFF, 0x00, 0x40, 0x40 };
133 static u8 dntv_extra[] = { 0xB5, 0x7A }; 135 static u8 dntv_extra[] = { 0xB5, 0x7A };
134 static u8 capt_range_cfg[] = { 0x75, 0x32 }; 136 static u8 capt_range_cfg[] = { 0x75, 0x32 };
135 137
@@ -285,6 +287,33 @@ static struct lgdt330x_config fusionhdtv_5_gold = {
285}; 287};
286#endif 288#endif
287 289
290#ifdef HAVE_NXT200X
291static int nxt200x_set_ts_param(struct dvb_frontend* fe,
292 int is_punctured)
293{
294 struct cx8802_dev *dev= fe->dvb->priv;
295 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
296 return 0;
297}
298
299static int nxt200x_set_pll_input(u8* buf, int input)
300{
301 if (input)
302 buf[3] |= 0x08;
303 else
304 buf[3] &= ~0x08;
305 return 0;
306}
307
308static struct nxt200x_config ati_hdtvwonder = {
309 .demod_address = 0x0a,
310 .pll_address = 0x61,
311 .pll_desc = &dvb_pll_tuv1236d,
312 .set_pll_input = nxt200x_set_pll_input,
313 .set_ts_params = nxt200x_set_ts_param,
314};
315#endif
316
288static int dvb_register(struct cx8802_dev *dev) 317static int dvb_register(struct cx8802_dev *dev)
289{ 318{
290 /* init struct videobuf_dvb */ 319 /* init struct videobuf_dvb */
@@ -300,6 +329,7 @@ static int dvb_register(struct cx8802_dev *dev)
300 break; 329 break;
301 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 330 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
302 case CX88_BOARD_CONEXANT_DVB_T1: 331 case CX88_BOARD_CONEXANT_DVB_T1:
332 case CX88_BOARD_WINFAST_DTV1000:
303 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, 333 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
304 &dev->core->i2c_adap); 334 &dev->core->i2c_adap);
305 break; 335 break;
@@ -385,6 +415,12 @@ static int dvb_register(struct cx8802_dev *dev)
385 } 415 }
386 break; 416 break;
387#endif 417#endif
418#ifdef HAVE_NXT200X
419 case CX88_BOARD_ATI_HDTVWONDER:
420 dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder,
421 &dev->core->i2c_adap);
422 break;
423#endif
388 default: 424 default:
389 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 425 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
390 dev->core->name); 426 dev->core->name);
@@ -403,6 +439,9 @@ static int dvb_register(struct cx8802_dev *dev)
403 /* Put the analog decoder in standby to keep it quiet */ 439 /* Put the analog decoder in standby to keep it quiet */
404 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); 440 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
405 441
442 /* Put the analog decoder in standby to keep it quiet */
443 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
444
406 /* register everything */ 445 /* register everything */
407 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); 446 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
408} 447}
@@ -461,7 +500,7 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
461 500
462static void __devexit dvb_remove(struct pci_dev *pci_dev) 501static void __devexit dvb_remove(struct pci_dev *pci_dev)
463{ 502{
464 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 503 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
465 504
466 /* dvb */ 505 /* dvb */
467 videobuf_dvb_unregister(&dev->dvb); 506 videobuf_dvb_unregister(&dev->dvb);
@@ -476,8 +515,8 @@ static struct pci_device_id cx8802_pci_tbl[] = {
476 { 515 {
477 .vendor = 0x14f1, 516 .vendor = 0x14f1,
478 .device = 0x8802, 517 .device = 0x8802,
479 .subvendor = PCI_ANY_ID, 518 .subvendor = PCI_ANY_ID,
480 .subdevice = PCI_ANY_ID, 519 .subdevice = PCI_ANY_ID,
481 },{ 520 },{
482 /* --- end of list --- */ 521 /* --- end of list --- */
483 } 522 }
@@ -485,10 +524,10 @@ static struct pci_device_id cx8802_pci_tbl[] = {
485MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); 524MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
486 525
487static struct pci_driver dvb_pci_driver = { 526static struct pci_driver dvb_pci_driver = {
488 .name = "cx88-dvb", 527 .name = "cx88-dvb",
489 .id_table = cx8802_pci_tbl, 528 .id_table = cx8802_pci_tbl,
490 .probe = dvb_probe, 529 .probe = dvb_probe,
491 .remove = __devexit_p(dvb_remove), 530 .remove = __devexit_p(dvb_remove),
492 .suspend = cx8802_suspend_common, 531 .suspend = cx8802_suspend_common,
493 .resume = cx8802_resume_common, 532 .resume = cx8802_resume_common,
494}; 533};
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 761cebd40dbd..9790d412f192 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -3,7 +3,7 @@
3 cx88-i2c.c -- all the i2c code is here 3 cx88-i2c.c -- all the i2c code is here
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
6 & Marcus Metzler (mocm@thp.uni-koeln.de) 6 & Marcus Metzler (mocm@thp.uni-koeln.de)
7 (c) 2002 Yurij Sysoev <yurij@naturesoft.net> 7 (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
8 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 8 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
9 9
@@ -90,7 +90,7 @@ static int cx8800_bit_getsda(void *data)
90 90
91static int attach_inform(struct i2c_client *client) 91static int attach_inform(struct i2c_client *client)
92{ 92{
93 struct tuner_setup tun_setup; 93 struct tuner_setup tun_setup;
94 struct cx88_core *core = i2c_get_adapdata(client->adapter); 94 struct cx88_core *core = i2c_get_adapdata(client->adapter);
95 95
96 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", 96 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
@@ -98,7 +98,7 @@ static int attach_inform(struct i2c_client *client)
98 if (!client->driver->command) 98 if (!client->driver->command)
99 return 0; 99 return 0;
100 100
101 if (core->radio_type != UNSET) { 101 if (core->radio_type != UNSET) {
102 if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) { 102 if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) {
103 tun_setup.mode_mask = T_RADIO; 103 tun_setup.mode_mask = T_RADIO;
104 tun_setup.type = core->radio_type; 104 tun_setup.type = core->radio_type;
@@ -106,8 +106,8 @@ static int attach_inform(struct i2c_client *client)
106 106
107 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup); 107 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
108 } 108 }
109 } 109 }
110 if (core->tuner_type != UNSET) { 110 if (core->tuner_type != UNSET) {
111 if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) { 111 if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) {
112 112
113 tun_setup.mode_mask = T_ANALOG_TV; 113 tun_setup.mode_mask = T_ANALOG_TV;
@@ -116,7 +116,7 @@ static int attach_inform(struct i2c_client *client)
116 116
117 client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup); 117 client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
118 } 118 }
119 } 119 }
120 120
121 if (core->tda9887_conf) 121 if (core->tda9887_conf)
122 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf); 122 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
@@ -159,7 +159,7 @@ static struct i2c_adapter cx8800_i2c_adap_template = {
159}; 159};
160 160
161static struct i2c_client cx8800_i2c_client_template = { 161static struct i2c_client cx8800_i2c_client_template = {
162 .name = "cx88xx internal", 162 .name = "cx88xx internal",
163}; 163};
164 164
165static char *i2c_devs[128] = { 165static char *i2c_devs[128] = {
@@ -202,10 +202,10 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
202 202
203 core->i2c_adap.dev.parent = &pci->dev; 203 core->i2c_adap.dev.parent = &pci->dev;
204 strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); 204 strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
205 core->i2c_algo.data = core; 205 core->i2c_algo.data = core;
206 i2c_set_adapdata(&core->i2c_adap,core); 206 i2c_set_adapdata(&core->i2c_adap,core);
207 core->i2c_adap.algo_data = &core->i2c_algo; 207 core->i2c_adap.algo_data = &core->i2c_algo;
208 core->i2c_client.adapter = &core->i2c_adap; 208 core->i2c_client.adapter = &core->i2c_adap;
209 209
210 cx8800_bit_setscl(core,1); 210 cx8800_bit_setscl(core,1);
211 cx8800_bit_setsda(core,1); 211 cx8800_bit_setsda(core,1);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index c27fe4c36f69..38b12ebaa49e 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -553,7 +553,7 @@ void cx88_ir_irq(struct cx88_core *core)
553 553
554 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */ 554 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */
555 ir_dprintk("pulse distance decoded wrong address\n"); 555 ir_dprintk("pulse distance decoded wrong address\n");
556 break; 556 break;
557 } 557 }
558 558
559 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */ 559 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index ee2300e1ae0b..35e6d0c2b872 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -54,7 +54,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
54{ 54{
55 struct cx88_core *core = dev->core; 55 struct cx88_core *core = dev->core;
56 56
57 dprintk(0, "cx8802_start_dma %d\n", buf->vb.width); 57 dprintk(0, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field);
58 58
59 /* setup fifo + format */ 59 /* setup fifo + format */
60 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 60 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -158,7 +158,8 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
158 158
159/* ------------------------------------------------------------------ */ 159/* ------------------------------------------------------------------ */
160 160
161int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf) 161int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
162 enum v4l2_field field)
162{ 163{
163 int size = dev->ts_packet_size * dev->ts_packet_count; 164 int size = dev->ts_packet_size * dev->ts_packet_count;
164 int rc; 165 int rc;
@@ -171,7 +172,7 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf)
171 buf->vb.width = dev->ts_packet_size; 172 buf->vb.width = dev->ts_packet_size;
172 buf->vb.height = dev->ts_packet_count; 173 buf->vb.height = dev->ts_packet_count;
173 buf->vb.size = size; 174 buf->vb.size = size;
174 buf->vb.field = V4L2_FIELD_TOP; 175 buf->vb.field = field /*V4L2_FIELD_TOP*/;
175 176
176 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) 177 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
177 goto fail; 178 goto fail;
@@ -315,14 +316,14 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
315 spin_unlock(&dev->slock); 316 spin_unlock(&dev->slock);
316 } 317 }
317 318
318 /* other general errors */ 319 /* other general errors */
319 if (status & 0x1f0100) { 320 if (status & 0x1f0100) {
320 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 ); 321 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
321 spin_lock(&dev->slock); 322 spin_lock(&dev->slock);
322 cx8802_stop_dma(dev); 323 cx8802_stop_dma(dev);
323 cx8802_restart_queue(dev,&dev->mpegq); 324 cx8802_restart_queue(dev,&dev->mpegq);
324 spin_unlock(&dev->slock); 325 spin_unlock(&dev->slock);
325 } 326 }
326} 327}
327 328
328#define MAX_IRQ_LOOP 10 329#define MAX_IRQ_LOOP 10
@@ -378,8 +379,8 @@ int cx8802_init_common(struct cx8802_dev *dev)
378 } 379 }
379 380
380 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); 381 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev);
381 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); 382 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
382 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " 383 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
383 "latency: %d, mmio: 0x%lx\n", dev->core->name, 384 "latency: %d, mmio: 0x%lx\n", dev->core->name,
384 pci_name(dev->pci), dev->pci_rev, dev->pci->irq, 385 pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
385 dev->pci_lat,pci_resource_start(dev->pci,0)); 386 dev->pci_lat,pci_resource_start(dev->pci,0));
@@ -429,7 +430,7 @@ void cx8802_fini_common(struct cx8802_dev *dev)
429 430
430int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) 431int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
431{ 432{
432 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 433 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
433 struct cx88_core *core = dev->core; 434 struct cx88_core *core = dev->core;
434 435
435 /* stop mpeg dma */ 436 /* stop mpeg dma */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
index 0a3a62fc9bbb..d3bf5b17b1d4 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -3,9 +3,9 @@
3 cx88x-hw.h - CX2388x register offsets 3 cx88x-hw.h - CX2388x register offsets
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
6 2001 Michael Eskin 6 2001 Michael Eskin
7 2002 Yurij Sysoev <yurij@naturesoft.net> 7 2002 Yurij Sysoev <yurij@naturesoft.net>
8 2003 Gerd Knorr <kraxel@bytesex.org> 8 2003 Gerd Knorr <kraxel@bytesex.org>
9 9
10 This program is free software; you can redistribute it and/or modify 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 11 it under the terms of the GNU General Public License as published by
@@ -728,13 +728,13 @@
728#define ColorFormatGamma 0x1000 728#define ColorFormatGamma 0x1000
729 729
730#define Interlaced 0x1 730#define Interlaced 0x1
731#define NonInterlaced 0x0 731#define NonInterlaced 0x0
732 732
733#define FieldEven 0x1 733#define FieldEven 0x1
734#define FieldOdd 0x0 734#define FieldOdd 0x0
735 735
736#define TGReadWriteMode 0x0 736#define TGReadWriteMode 0x0
737#define TGEnableMode 0x1 737#define TGEnableMode 0x1
738 738
739#define DV_CbAlign 0x0 739#define DV_CbAlign 0x0
740#define DV_Y0Align 0x1 740#define DV_Y0Align 0x1
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 2765acee0285..6d9bec1c583b 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -57,39 +57,38 @@
57#include "cx88.h" 57#include "cx88.h"
58 58
59static unsigned int audio_debug = 0; 59static unsigned int audio_debug = 0;
60module_param(audio_debug,int,0644); 60module_param(audio_debug, int, 0644);
61MODULE_PARM_DESC(audio_debug,"enable debug messages [audio]"); 61MODULE_PARM_DESC(audio_debug, "enable debug messages [audio]");
62 62
63#define dprintk(fmt, arg...) if (audio_debug) \ 63#define dprintk(fmt, arg...) if (audio_debug) \
64 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) 64 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
65 65
66/* ----------------------------------------------------------- */ 66/* ----------------------------------------------------------- */
67 67
68static char *aud_ctl_names[64] = 68static char *aud_ctl_names[64] = {
69{ 69 [EN_BTSC_FORCE_MONO] = "BTSC_FORCE_MONO",
70 [ EN_BTSC_FORCE_MONO ] = "BTSC_FORCE_MONO", 70 [EN_BTSC_FORCE_STEREO] = "BTSC_FORCE_STEREO",
71 [ EN_BTSC_FORCE_STEREO ] = "BTSC_FORCE_STEREO", 71 [EN_BTSC_FORCE_SAP] = "BTSC_FORCE_SAP",
72 [ EN_BTSC_FORCE_SAP ] = "BTSC_FORCE_SAP", 72 [EN_BTSC_AUTO_STEREO] = "BTSC_AUTO_STEREO",
73 [ EN_BTSC_AUTO_STEREO ] = "BTSC_AUTO_STEREO", 73 [EN_BTSC_AUTO_SAP] = "BTSC_AUTO_SAP",
74 [ EN_BTSC_AUTO_SAP ] = "BTSC_AUTO_SAP", 74 [EN_A2_FORCE_MONO1] = "A2_FORCE_MONO1",
75 [ EN_A2_FORCE_MONO1 ] = "A2_FORCE_MONO1", 75 [EN_A2_FORCE_MONO2] = "A2_FORCE_MONO2",
76 [ EN_A2_FORCE_MONO2 ] = "A2_FORCE_MONO2", 76 [EN_A2_FORCE_STEREO] = "A2_FORCE_STEREO",
77 [ EN_A2_FORCE_STEREO ] = "A2_FORCE_STEREO", 77 [EN_A2_AUTO_MONO2] = "A2_AUTO_MONO2",
78 [ EN_A2_AUTO_MONO2 ] = "A2_AUTO_MONO2", 78 [EN_A2_AUTO_STEREO] = "A2_AUTO_STEREO",
79 [ EN_A2_AUTO_STEREO ] = "A2_AUTO_STEREO", 79 [EN_EIAJ_FORCE_MONO1] = "EIAJ_FORCE_MONO1",
80 [ EN_EIAJ_FORCE_MONO1 ] = "EIAJ_FORCE_MONO1", 80 [EN_EIAJ_FORCE_MONO2] = "EIAJ_FORCE_MONO2",
81 [ EN_EIAJ_FORCE_MONO2 ] = "EIAJ_FORCE_MONO2", 81 [EN_EIAJ_FORCE_STEREO] = "EIAJ_FORCE_STEREO",
82 [ EN_EIAJ_FORCE_STEREO ] = "EIAJ_FORCE_STEREO", 82 [EN_EIAJ_AUTO_MONO2] = "EIAJ_AUTO_MONO2",
83 [ EN_EIAJ_AUTO_MONO2 ] = "EIAJ_AUTO_MONO2", 83 [EN_EIAJ_AUTO_STEREO] = "EIAJ_AUTO_STEREO",
84 [ EN_EIAJ_AUTO_STEREO ] = "EIAJ_AUTO_STEREO", 84 [EN_NICAM_FORCE_MONO1] = "NICAM_FORCE_MONO1",
85 [ EN_NICAM_FORCE_MONO1 ] = "NICAM_FORCE_MONO1", 85 [EN_NICAM_FORCE_MONO2] = "NICAM_FORCE_MONO2",
86 [ EN_NICAM_FORCE_MONO2 ] = "NICAM_FORCE_MONO2", 86 [EN_NICAM_FORCE_STEREO] = "NICAM_FORCE_STEREO",
87 [ EN_NICAM_FORCE_STEREO ] = "NICAM_FORCE_STEREO", 87 [EN_NICAM_AUTO_MONO2] = "NICAM_AUTO_MONO2",
88 [ EN_NICAM_AUTO_MONO2 ] = "NICAM_AUTO_MONO2", 88 [EN_NICAM_AUTO_STEREO] = "NICAM_AUTO_STEREO",
89 [ EN_NICAM_AUTO_STEREO ] = "NICAM_AUTO_STEREO", 89 [EN_FMRADIO_FORCE_MONO] = "FMRADIO_FORCE_MONO",
90 [ EN_FMRADIO_FORCE_MONO ] = "FMRADIO_FORCE_MONO", 90 [EN_FMRADIO_FORCE_STEREO] = "FMRADIO_FORCE_STEREO",
91 [ EN_FMRADIO_FORCE_STEREO ] = "FMRADIO_FORCE_STEREO", 91 [EN_FMRADIO_AUTO_STEREO] = "FMRADIO_AUTO_STEREO",
92 [ EN_FMRADIO_AUTO_STEREO ] = "FMRADIO_AUTO_STEREO",
93}; 92};
94 93
95struct rlist { 94struct rlist {
@@ -97,8 +96,7 @@ struct rlist {
97 u32 val; 96 u32 val;
98}; 97};
99 98
100static void set_audio_registers(struct cx88_core *core, 99static void set_audio_registers(struct cx88_core *core, const struct rlist *l)
101 const struct rlist *l)
102{ 100{
103 int i; 101 int i;
104 102
@@ -119,17 +117,18 @@ static void set_audio_registers(struct cx88_core *core,
119 } 117 }
120} 118}
121 119
122static void set_audio_start(struct cx88_core *core, 120static void set_audio_start(struct cx88_core *core, u32 mode)
123 u32 mode)
124{ 121{
125 // mute 122 // mute
126 cx_write(AUD_VOL_CTL, (1 << 6)); 123 cx_write(AUD_VOL_CTL, (1 << 6));
127 124
128 // start programming 125 // start programming
129 cx_write(AUD_CTL, 0x0000); 126 cx_write(MO_AUD_DMACNTRL, 0x0000);
130 cx_write(AUD_INIT, mode); 127 msleep(100);
131 cx_write(AUD_INIT_LD, 0x0001); 128 //cx_write(AUD_CTL, 0x0000);
132 cx_write(AUD_SOFT_RESET, 0x0001); 129 cx_write(AUD_INIT, mode);
130 cx_write(AUD_INIT_LD, 0x0001);
131 cx_write(AUD_SOFT_RESET, 0x0001);
133} 132}
134 133
135static void set_audio_finish(struct cx88_core *core, u32 ctl) 134static void set_audio_finish(struct cx88_core *core, u32 ctl)
@@ -148,12 +147,13 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
148 cx_write(AUD_I2SCNTL, 0); 147 cx_write(AUD_I2SCNTL, 0);
149 //cx_write(AUD_APB_IN_RATE_ADJ, 0); 148 //cx_write(AUD_APB_IN_RATE_ADJ, 0);
150 } else { 149 } else {
151 ctl |= EN_DAC_ENABLE; 150 ctl |= EN_DAC_ENABLE;
152 cx_write(AUD_CTL, ctl); 151 cx_write(AUD_CTL, ctl);
153 } 152 }
154 153
155 /* finish programming */ 154 /* finish programming */
156 cx_write(AUD_SOFT_RESET, 0x0000); 155 cx_write(AUD_SOFT_RESET, 0x0000);
156 cx_write(MO_AUD_DMACNTRL, 0x0003);
157 157
158 /* unmute */ 158 /* unmute */
159 volume = cx_sread(SHADOW_AUD_VOL_CTL); 159 volume = cx_sread(SHADOW_AUD_VOL_CTL);
@@ -162,486 +162,463 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
162 162
163/* ----------------------------------------------------------- */ 163/* ----------------------------------------------------------- */
164 164
165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, u32 mode) 165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap,
166 u32 mode)
166{ 167{
167 static const struct rlist btsc[] = { 168 static const struct rlist btsc[] = {
168 { AUD_AFE_12DB_EN, 0x00000001 }, 169 {AUD_AFE_12DB_EN, 0x00000001},
169 { AUD_OUT1_SEL, 0x00000013 }, 170 {AUD_OUT1_SEL, 0x00000013},
170 { AUD_OUT1_SHIFT, 0x00000000 }, 171 {AUD_OUT1_SHIFT, 0x00000000},
171 { AUD_POLY0_DDS_CONSTANT, 0x0012010c }, 172 {AUD_POLY0_DDS_CONSTANT, 0x0012010c},
172 { AUD_DMD_RA_DDS, 0x00c3e7aa }, 173 {AUD_DMD_RA_DDS, 0x00c3e7aa},
173 { AUD_DBX_IN_GAIN, 0x00004734 }, 174 {AUD_DBX_IN_GAIN, 0x00004734},
174 { AUD_DBX_WBE_GAIN, 0x00004640 }, 175 {AUD_DBX_WBE_GAIN, 0x00004640},
175 { AUD_DBX_SE_GAIN, 0x00008d31 }, 176 {AUD_DBX_SE_GAIN, 0x00008d31},
176 { AUD_DCOC_0_SRC, 0x0000001a }, 177 {AUD_DCOC_0_SRC, 0x0000001a},
177 { AUD_IIR1_4_SEL, 0x00000021 }, 178 {AUD_IIR1_4_SEL, 0x00000021},
178 { AUD_DCOC_PASS_IN, 0x00000003 }, 179 {AUD_DCOC_PASS_IN, 0x00000003},
179 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, 180 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
180 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, 181 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
181 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, 182 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
182 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, 183 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
183 { AUD_DN0_FREQ, 0x0000283b }, 184 {AUD_DN0_FREQ, 0x0000283b},
184 { AUD_DN2_SRC_SEL, 0x00000008 }, 185 {AUD_DN2_SRC_SEL, 0x00000008},
185 { AUD_DN2_FREQ, 0x00003000 }, 186 {AUD_DN2_FREQ, 0x00003000},
186 { AUD_DN2_AFC, 0x00000002 }, 187 {AUD_DN2_AFC, 0x00000002},
187 { AUD_DN2_SHFT, 0x00000000 }, 188 {AUD_DN2_SHFT, 0x00000000},
188 { AUD_IIR2_2_SEL, 0x00000020 }, 189 {AUD_IIR2_2_SEL, 0x00000020},
189 { AUD_IIR2_2_SHIFT, 0x00000000 }, 190 {AUD_IIR2_2_SHIFT, 0x00000000},
190 { AUD_IIR2_3_SEL, 0x0000001f }, 191 {AUD_IIR2_3_SEL, 0x0000001f},
191 { AUD_IIR2_3_SHIFT, 0x00000000 }, 192 {AUD_IIR2_3_SHIFT, 0x00000000},
192 { AUD_CRDC1_SRC_SEL, 0x000003ce }, 193 {AUD_CRDC1_SRC_SEL, 0x000003ce},
193 { AUD_CRDC1_SHIFT, 0x00000000 }, 194 {AUD_CRDC1_SHIFT, 0x00000000},
194 { AUD_CORDIC_SHIFT_1, 0x00000007 }, 195 {AUD_CORDIC_SHIFT_1, 0x00000007},
195 { AUD_DCOC_1_SRC, 0x0000001b }, 196 {AUD_DCOC_1_SRC, 0x0000001b},
196 { AUD_DCOC1_SHIFT, 0x00000000 }, 197 {AUD_DCOC1_SHIFT, 0x00000000},
197 { AUD_RDSI_SEL, 0x00000008 }, 198 {AUD_RDSI_SEL, 0x00000008},
198 { AUD_RDSQ_SEL, 0x00000008 }, 199 {AUD_RDSQ_SEL, 0x00000008},
199 { AUD_RDSI_SHIFT, 0x00000000 }, 200 {AUD_RDSI_SHIFT, 0x00000000},
200 { AUD_RDSQ_SHIFT, 0x00000000 }, 201 {AUD_RDSQ_SHIFT, 0x00000000},
201 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 202 {AUD_POLYPH80SCALEFAC, 0x00000003},
202 { /* end of list */ }, 203 { /* end of list */ },
203 }; 204 };
204 static const struct rlist btsc_sap[] = { 205 static const struct rlist btsc_sap[] = {
205 { AUD_AFE_12DB_EN, 0x00000001 }, 206 {AUD_AFE_12DB_EN, 0x00000001},
206 { AUD_DBX_IN_GAIN, 0x00007200 }, 207 {AUD_DBX_IN_GAIN, 0x00007200},
207 { AUD_DBX_WBE_GAIN, 0x00006200 }, 208 {AUD_DBX_WBE_GAIN, 0x00006200},
208 { AUD_DBX_SE_GAIN, 0x00006200 }, 209 {AUD_DBX_SE_GAIN, 0x00006200},
209 { AUD_IIR1_1_SEL, 0x00000000 }, 210 {AUD_IIR1_1_SEL, 0x00000000},
210 { AUD_IIR1_3_SEL, 0x00000001 }, 211 {AUD_IIR1_3_SEL, 0x00000001},
211 { AUD_DN1_SRC_SEL, 0x00000007 }, 212 {AUD_DN1_SRC_SEL, 0x00000007},
212 { AUD_IIR1_4_SHIFT, 0x00000006 }, 213 {AUD_IIR1_4_SHIFT, 0x00000006},
213 { AUD_IIR2_1_SHIFT, 0x00000000 }, 214 {AUD_IIR2_1_SHIFT, 0x00000000},
214 { AUD_IIR2_2_SHIFT, 0x00000000 }, 215 {AUD_IIR2_2_SHIFT, 0x00000000},
215 { AUD_IIR3_0_SHIFT, 0x00000000 }, 216 {AUD_IIR3_0_SHIFT, 0x00000000},
216 { AUD_IIR3_1_SHIFT, 0x00000000 }, 217 {AUD_IIR3_1_SHIFT, 0x00000000},
217 { AUD_IIR3_0_SEL, 0x0000000d }, 218 {AUD_IIR3_0_SEL, 0x0000000d},
218 { AUD_IIR3_1_SEL, 0x0000000e }, 219 {AUD_IIR3_1_SEL, 0x0000000e},
219 { AUD_DEEMPH1_SRC_SEL, 0x00000014 }, 220 {AUD_DEEMPH1_SRC_SEL, 0x00000014},
220 { AUD_DEEMPH1_SHIFT, 0x00000000 }, 221 {AUD_DEEMPH1_SHIFT, 0x00000000},
221 { AUD_DEEMPH1_G0, 0x00004000 }, 222 {AUD_DEEMPH1_G0, 0x00004000},
222 { AUD_DEEMPH1_A0, 0x00000000 }, 223 {AUD_DEEMPH1_A0, 0x00000000},
223 { AUD_DEEMPH1_B0, 0x00000000 }, 224 {AUD_DEEMPH1_B0, 0x00000000},
224 { AUD_DEEMPH1_A1, 0x00000000 }, 225 {AUD_DEEMPH1_A1, 0x00000000},
225 { AUD_DEEMPH1_B1, 0x00000000 }, 226 {AUD_DEEMPH1_B1, 0x00000000},
226 { AUD_OUT0_SEL, 0x0000003f }, 227 {AUD_OUT0_SEL, 0x0000003f},
227 { AUD_OUT1_SEL, 0x0000003f }, 228 {AUD_OUT1_SEL, 0x0000003f},
228 { AUD_DN1_AFC, 0x00000002 }, 229 {AUD_DN1_AFC, 0x00000002},
229 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, 230 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
230 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, 231 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
231 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, 232 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
232 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, 233 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
233 { AUD_IIR1_0_SEL, 0x0000001d }, 234 {AUD_IIR1_0_SEL, 0x0000001d},
234 { AUD_IIR1_2_SEL, 0x0000001e }, 235 {AUD_IIR1_2_SEL, 0x0000001e},
235 { AUD_IIR2_1_SEL, 0x00000002 }, 236 {AUD_IIR2_1_SEL, 0x00000002},
236 { AUD_IIR2_2_SEL, 0x00000004 }, 237 {AUD_IIR2_2_SEL, 0x00000004},
237 { AUD_IIR3_2_SEL, 0x0000000f }, 238 {AUD_IIR3_2_SEL, 0x0000000f},
238 { AUD_DCOC2_SHIFT, 0x00000001 }, 239 {AUD_DCOC2_SHIFT, 0x00000001},
239 { AUD_IIR3_2_SHIFT, 0x00000001 }, 240 {AUD_IIR3_2_SHIFT, 0x00000001},
240 { AUD_DEEMPH0_SRC_SEL, 0x00000014 }, 241 {AUD_DEEMPH0_SRC_SEL, 0x00000014},
241 { AUD_CORDIC_SHIFT_1, 0x00000006 }, 242 {AUD_CORDIC_SHIFT_1, 0x00000006},
242 { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 }, 243 {AUD_POLY0_DDS_CONSTANT, 0x000e4db2},
243 { AUD_DMD_RA_DDS, 0x00f696e6 }, 244 {AUD_DMD_RA_DDS, 0x00f696e6},
244 { AUD_IIR2_3_SEL, 0x00000025 }, 245 {AUD_IIR2_3_SEL, 0x00000025},
245 { AUD_IIR1_4_SEL, 0x00000021 }, 246 {AUD_IIR1_4_SEL, 0x00000021},
246 { AUD_DN1_FREQ, 0x0000c965 }, 247 {AUD_DN1_FREQ, 0x0000c965},
247 { AUD_DCOC_PASS_IN, 0x00000003 }, 248 {AUD_DCOC_PASS_IN, 0x00000003},
248 { AUD_DCOC_0_SRC, 0x0000001a }, 249 {AUD_DCOC_0_SRC, 0x0000001a},
249 { AUD_DCOC_1_SRC, 0x0000001b }, 250 {AUD_DCOC_1_SRC, 0x0000001b},
250 { AUD_DCOC1_SHIFT, 0x00000000 }, 251 {AUD_DCOC1_SHIFT, 0x00000000},
251 { AUD_RDSI_SEL, 0x00000009 }, 252 {AUD_RDSI_SEL, 0x00000009},
252 { AUD_RDSQ_SEL, 0x00000009 }, 253 {AUD_RDSQ_SEL, 0x00000009},
253 { AUD_RDSI_SHIFT, 0x00000000 }, 254 {AUD_RDSI_SHIFT, 0x00000000},
254 { AUD_RDSQ_SHIFT, 0x00000000 }, 255 {AUD_RDSQ_SHIFT, 0x00000000},
255 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 256 {AUD_POLYPH80SCALEFAC, 0x00000003},
256 { /* end of list */ }, 257 { /* end of list */ },
257 }; 258 };
258 259
259 mode |= EN_FMRADIO_EN_RDS; 260 mode |= EN_FMRADIO_EN_RDS;
260 261
261 if (sap) { 262 if (sap) {
262 dprintk("%s SAP (status: unknown)\n",__FUNCTION__); 263 dprintk("%s SAP (status: unknown)\n", __FUNCTION__);
263 set_audio_start(core, SEL_SAP); 264 set_audio_start(core, SEL_SAP);
264 set_audio_registers(core, btsc_sap); 265 set_audio_registers(core, btsc_sap);
265 set_audio_finish(core, mode); 266 set_audio_finish(core, mode);
266 } else { 267 } else {
267 dprintk("%s (status: known-good)\n",__FUNCTION__); 268 dprintk("%s (status: known-good)\n", __FUNCTION__);
268 set_audio_start(core, SEL_BTSC); 269 set_audio_start(core, SEL_BTSC);
269 set_audio_registers(core, btsc); 270 set_audio_registers(core, btsc);
270 set_audio_finish(core, mode); 271 set_audio_finish(core, mode);
271 } 272 }
272} 273}
273 274
274 275static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode)
275static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
276{ 276{
277 /* This is probably weird.. 277 static const struct rlist nicam_l[] = {
278 * Let's operate and find out. */ 278 {AUD_AFE_12DB_EN, 0x00000001},
279 279 {AUD_RATE_ADJ1, 0x00000060},
280 static const struct rlist nicam_l_mono[] = { 280 {AUD_RATE_ADJ2, 0x000000F9},
281 { AUD_ERRLOGPERIOD_R, 0x00000064 }, 281 {AUD_RATE_ADJ3, 0x000001CC},
282 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, 282 {AUD_RATE_ADJ4, 0x000002B3},
283 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, 283 {AUD_RATE_ADJ5, 0x00000726},
284 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, 284 {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
285 285 {AUD_DEEMPHDENOM2_R, 0x00000000},
286 { AUD_PDF_DDS_CNST_BYTE2, 0x48 }, 286 {AUD_ERRLOGPERIOD_R, 0x00000064},
287 { AUD_PDF_DDS_CNST_BYTE1, 0x3D }, 287 {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
288 { AUD_QAM_MODE, 0x00 }, 288 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
289 { AUD_PDF_DDS_CNST_BYTE0, 0xf5 }, 289 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
290 { AUD_PHACC_FREQ_8MSB, 0x3a }, 290 {AUD_POLYPH80SCALEFAC, 0x00000003},
291 { AUD_PHACC_FREQ_8LSB, 0x4a }, 291 {AUD_DMD_RA_DDS, 0x00C00000},
292 292 {AUD_PLL_INT, 0x0000001E},
293 { AUD_DEEMPHGAIN_R, 0x6680 }, 293 {AUD_PLL_DDS, 0x00000000},
294 { AUD_DEEMPHNUMER1_R, 0x353DE }, 294 {AUD_PLL_FRAC, 0x0000E542},
295 { AUD_DEEMPHNUMER2_R, 0x1B1 }, 295 {AUD_START_TIMER, 0x00000000},
296 { AUD_DEEMPHDENOM1_R, 0x0F3D0 }, 296 {AUD_DEEMPHNUMER1_R, 0x000353DE},
297 { AUD_DEEMPHDENOM2_R, 0x0 }, 297 {AUD_DEEMPHNUMER2_R, 0x000001B1},
298 { AUD_FM_MODE_ENABLE, 0x7 }, 298 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
299 { AUD_POLYPH80SCALEFAC, 0x3 }, 299 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
300 { AUD_AFE_12DB_EN, 0x1 }, 300 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
301 { AAGC_GAIN, 0x0 }, 301 {AUD_QAM_MODE, 0x05},
302 { AAGC_HYST, 0x18 }, 302 {AUD_PHACC_FREQ_8MSB, 0x34},
303 { AAGC_DEF, 0x20 }, 303 {AUD_PHACC_FREQ_8LSB, 0x4C},
304 { AUD_DN0_FREQ, 0x0 }, 304 {AUD_DEEMPHGAIN_R, 0x00006680},
305 { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 }, 305 {AUD_RATE_THRES_DMD, 0x000000C0},
306 { AUD_DCOC_0_SRC, 0x21 },
307 { AUD_IIR1_0_SEL, 0x0 },
308 { AUD_IIR1_0_SHIFT, 0x7 },
309 { AUD_IIR1_1_SEL, 0x2 },
310 { AUD_IIR1_1_SHIFT, 0x0 },
311 { AUD_DCOC_1_SRC, 0x3 },
312 { AUD_DCOC1_SHIFT, 0x0 },
313 { AUD_DCOC_PASS_IN, 0x0 },
314 { AUD_IIR1_2_SEL, 0x23 },
315 { AUD_IIR1_2_SHIFT, 0x0 },
316 { AUD_IIR1_3_SEL, 0x4 },
317 { AUD_IIR1_3_SHIFT, 0x7 },
318 { AUD_IIR1_4_SEL, 0x5 },
319 { AUD_IIR1_4_SHIFT, 0x7 },
320 { AUD_IIR3_0_SEL, 0x7 },
321 { AUD_IIR3_0_SHIFT, 0x0 },
322 { AUD_DEEMPH0_SRC_SEL, 0x11 },
323 { AUD_DEEMPH0_SHIFT, 0x0 },
324 { AUD_DEEMPH0_G0, 0x7000 },
325 { AUD_DEEMPH0_A0, 0x0 },
326 { AUD_DEEMPH0_B0, 0x0 },
327 { AUD_DEEMPH0_A1, 0x0 },
328 { AUD_DEEMPH0_B1, 0x0 },
329 { AUD_DEEMPH1_SRC_SEL, 0x11 },
330 { AUD_DEEMPH1_SHIFT, 0x0 },
331 { AUD_DEEMPH1_G0, 0x7000 },
332 { AUD_DEEMPH1_A0, 0x0 },
333 { AUD_DEEMPH1_B0, 0x0 },
334 { AUD_DEEMPH1_A1, 0x0 },
335 { AUD_DEEMPH1_B1, 0x0 },
336 { AUD_OUT0_SEL, 0x3F },
337 { AUD_OUT1_SEL, 0x3F },
338 { AUD_DMD_RA_DDS, 0x0F5C285 },
339 { AUD_PLL_INT, 0x1E },
340 { AUD_PLL_DDS, 0x0 },
341 { AUD_PLL_FRAC, 0x0E542 },
342
343 // setup QAM registers
344 { AUD_RATE_ADJ1, 0x00000100 },
345 { AUD_RATE_ADJ2, 0x00000200 },
346 { AUD_RATE_ADJ3, 0x00000300 },
347 { AUD_RATE_ADJ4, 0x00000400 },
348 { AUD_RATE_ADJ5, 0x00000500 },
349 { AUD_RATE_THRES_DMD, 0x000000C0 },
350 { /* end of list */ }, 306 { /* end of list */ },
351 }; 307 };
352 308
353 static const struct rlist nicam_l[] = { 309 static const struct rlist nicam_bgdki_common[] = {
354 // setup QAM registers 310 {AUD_AFE_12DB_EN, 0x00000001},
355 { AUD_RATE_ADJ1, 0x00000060 }, 311 {AUD_RATE_ADJ1, 0x00000010},
356 { AUD_RATE_ADJ2, 0x000000F9 }, 312 {AUD_RATE_ADJ2, 0x00000040},
357 { AUD_RATE_ADJ3, 0x000001CC }, 313 {AUD_RATE_ADJ3, 0x00000100},
358 { AUD_RATE_ADJ4, 0x000002B3 }, 314 {AUD_RATE_ADJ4, 0x00000400},
359 { AUD_RATE_ADJ5, 0x00000726 }, 315 {AUD_RATE_ADJ5, 0x00001000},
360 { AUD_DEEMPHDENOM1_R, 0x0000F3D0 }, 316 //{ AUD_DMD_RA_DDS, 0x00c0d5ce },
361 { AUD_DEEMPHDENOM2_R, 0x00000000 }, 317 {AUD_ERRLOGPERIOD_R, 0x00000fff},
362 { AUD_ERRLOGPERIOD_R, 0x00000064 }, 318 {AUD_ERRINTRPTTHSHLD1_R, 0x000003ff},
363 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, 319 {AUD_ERRINTRPTTHSHLD2_R, 0x000000ff},
364 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, 320 {AUD_ERRINTRPTTHSHLD3_R, 0x0000003f},
365 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, 321 {AUD_POLYPH80SCALEFAC, 0x00000003},
366 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 322 {AUD_DEEMPHGAIN_R, 0x000023c2},
367 { AUD_DMD_RA_DDS, 0x00C00000 }, 323 {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
368 { AUD_PLL_INT, 0x0000001E }, 324 {AUD_DEEMPHNUMER2_R, 0x0003023e},
369 { AUD_PLL_DDS, 0x00000000 }, 325 {AUD_DEEMPHDENOM1_R, 0x0000f3d0},
370 { AUD_PLL_FRAC, 0x0000E542 }, 326 {AUD_DEEMPHDENOM2_R, 0x00000000},
371 { AUD_START_TIMER, 0x00000000 }, 327 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
372 { AUD_DEEMPHNUMER1_R, 0x000353DE }, 328 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
373 { AUD_DEEMPHNUMER2_R, 0x000001B1 }, 329 {AUD_QAM_MODE, 0x05},
374 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
375 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
376 { AUD_QAM_MODE, 0x05 },
377 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
378 { AUD_PHACC_FREQ_8MSB, 0x34 },
379 { AUD_PHACC_FREQ_8LSB, 0x4C },
380 { AUD_DEEMPHGAIN_R, 0x00006680 },
381 { AUD_RATE_THRES_DMD, 0x000000C0 },
382 { /* end of list */ }, 330 { /* end of list */ },
383 } ; 331 };
384 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
385
386 if (!stereo) {
387 /* AM Mono */
388 set_audio_start(core, SEL_A2);
389 set_audio_registers(core, nicam_l_mono);
390 set_audio_finish(core, EN_A2_FORCE_MONO1);
391 } else {
392 /* Nicam Stereo */
393 set_audio_start(core, SEL_NICAM);
394 set_audio_registers(core, nicam_l);
395 set_audio_finish(core, 0x1924); /* FIXME */
396 }
397}
398 332
399static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo) 333 static const struct rlist nicam_i[] = {
400{ 334 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
401 static const struct rlist pal_i_fm_mono[] = { 335 {AUD_PHACC_FREQ_8MSB, 0x3a},
402 {AUD_ERRLOGPERIOD_R, 0x00000064}, 336 {AUD_PHACC_FREQ_8LSB, 0x93},
403 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, 337 { /* end of list */ },
404 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
405 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
406 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
407 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
408 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
409 {AUD_QAM_MODE, 0x05},
410 {AUD_PHACC_FREQ_8MSB, 0x3a},
411 {AUD_PHACC_FREQ_8LSB, 0x93},
412 {AUD_DMD_RA_DDS, 0x002a4f2f},
413 {AUD_PLL_INT, 0x0000001e},
414 {AUD_PLL_DDS, 0x00000004},
415 {AUD_PLL_FRAC, 0x0000e542},
416 {AUD_RATE_ADJ1, 0x00000100},
417 {AUD_RATE_ADJ2, 0x00000200},
418 {AUD_RATE_ADJ3, 0x00000300},
419 {AUD_RATE_ADJ4, 0x00000400},
420 {AUD_RATE_ADJ5, 0x00000500},
421 {AUD_THR_FR, 0x00000000},
422 {AUD_PILOT_BQD_1_K0, 0x0000755b},
423 {AUD_PILOT_BQD_1_K1, 0x00551340},
424 {AUD_PILOT_BQD_1_K2, 0x006d30be},
425 {AUD_PILOT_BQD_1_K3, 0xffd394af},
426 {AUD_PILOT_BQD_1_K4, 0x00400000},
427 {AUD_PILOT_BQD_2_K0, 0x00040000},
428 {AUD_PILOT_BQD_2_K1, 0x002a4841},
429 {AUD_PILOT_BQD_2_K2, 0x00400000},
430 {AUD_PILOT_BQD_2_K3, 0x00000000},
431 {AUD_PILOT_BQD_2_K4, 0x00000000},
432 {AUD_MODE_CHG_TIMER, 0x00000060},
433 {AUD_AFE_12DB_EN, 0x00000001},
434 {AAGC_HYST, 0x0000000a},
435 {AUD_CORDIC_SHIFT_0, 0x00000007},
436 {AUD_CORDIC_SHIFT_1, 0x00000007},
437 {AUD_C1_UP_THR, 0x00007000},
438 {AUD_C1_LO_THR, 0x00005400},
439 {AUD_C2_UP_THR, 0x00005400},
440 {AUD_C2_LO_THR, 0x00003000},
441 {AUD_DCOC_0_SRC, 0x0000001a},
442 {AUD_DCOC0_SHIFT, 0x00000000},
443 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
444 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
445 {AUD_DCOC_PASS_IN, 0x00000003},
446 {AUD_IIR3_0_SEL, 0x00000021},
447 {AUD_DN2_AFC, 0x00000002},
448 {AUD_DCOC_1_SRC, 0x0000001b},
449 {AUD_DCOC1_SHIFT, 0x00000000},
450 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
451 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
452 {AUD_IIR3_1_SEL, 0x00000023},
453 {AUD_DN0_FREQ, 0x000035a3},
454 {AUD_DN2_FREQ, 0x000029c7},
455 {AUD_CRDC0_SRC_SEL, 0x00000511},
456 {AUD_IIR1_0_SEL, 0x00000001},
457 {AUD_IIR1_1_SEL, 0x00000000},
458 {AUD_IIR3_2_SEL, 0x00000003},
459 {AUD_IIR3_2_SHIFT, 0x00000000},
460 {AUD_IIR3_0_SEL, 0x00000002},
461 {AUD_IIR2_0_SEL, 0x00000021},
462 {AUD_IIR2_0_SHIFT, 0x00000002},
463 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
464 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
465 {AUD_POLYPH80SCALEFAC, 0x00000001},
466 {AUD_START_TIMER, 0x00000000},
467 { /* end of list */ },
468 };
469
470 static const struct rlist pal_i_nicam[] = {
471 { AUD_RATE_ADJ1, 0x00000010 },
472 { AUD_RATE_ADJ2, 0x00000040 },
473 { AUD_RATE_ADJ3, 0x00000100 },
474 { AUD_RATE_ADJ4, 0x00000400 },
475 { AUD_RATE_ADJ5, 0x00001000 },
476 // { AUD_DMD_RA_DDS, 0x00c0d5ce },
477 { AUD_DEEMPHGAIN_R, 0x000023c2 },
478 { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
479 { AUD_DEEMPHNUMER2_R, 0x0003023e },
480 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
481 { AUD_DEEMPHDENOM2_R, 0x00000000 },
482 { AUD_DEEMPHDENOM2_R, 0x00000000 },
483 { AUD_ERRLOGPERIOD_R, 0x00000fff },
484 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
485 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
486 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
487 { AUD_POLYPH80SCALEFAC, 0x00000003 },
488 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
489 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
490 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
491 { AUD_QAM_MODE, 0x05 },
492 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
493 { AUD_PHACC_FREQ_8MSB, 0x3a },
494 { AUD_PHACC_FREQ_8LSB, 0x93 },
495 { /* end of list */ },
496 }; 338 };
497 339
498 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo); 340 static const struct rlist nicam_default[] = {
341 {AUD_PDF_DDS_CNST_BYTE0, 0x16},
342 {AUD_PHACC_FREQ_8MSB, 0x34},
343 {AUD_PHACC_FREQ_8LSB, 0x4c},
344 { /* end of list */ },
345 };
499 346
500 if (!stereo) { 347 set_audio_start(core,SEL_NICAM);
501 /* FM Mono */ 348 switch (core->tvaudio) {
502 set_audio_start(core, SEL_A2); 349 case WW_L:
503 set_audio_registers(core, pal_i_fm_mono); 350 dprintk("%s SECAM-L NICAM (status: devel)\n", __FUNCTION__);
504 set_audio_finish(core, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1); 351 set_audio_registers(core, nicam_l);
505 } else { 352 break;
506 /* Nicam Stereo */ 353 case WW_I:
507 set_audio_start(core, SEL_NICAM); 354 dprintk("%s PAL-I NICAM (status: devel)\n", __FUNCTION__);
508 set_audio_registers(core, pal_i_nicam); 355 set_audio_registers(core, nicam_bgdki_common);
509 set_audio_finish(core, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO); 356 set_audio_registers(core, nicam_i);
510 } 357 break;
358 default:
359 dprintk("%s PAL-BGDK NICAM (status: unknown)\n", __FUNCTION__);
360 set_audio_registers(core, nicam_bgdki_common);
361 set_audio_registers(core, nicam_default);
362 break;
363 };
364
365 mode |= EN_DMTRX_LR | EN_DMTRX_BYPASS;
366 set_audio_finish(core, mode);
511} 367}
512 368
513static void set_audio_standard_A2(struct cx88_core *core, u32 mode) 369static void set_audio_standard_A2(struct cx88_core *core, u32 mode)
514{ 370{
515 static const struct rlist a2_common[] = { 371 static const struct rlist a2_bgdk_common[] = {
516 {AUD_ERRLOGPERIOD_R, 0x00000064}, 372 {AUD_ERRLOGPERIOD_R, 0x00000064},
517 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, 373 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
518 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f}, 374 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
519 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f}, 375 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
520 {AUD_PDF_DDS_CNST_BYTE2, 0x06}, 376 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
521 {AUD_PDF_DDS_CNST_BYTE1, 0x82}, 377 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
522 {AUD_PDF_DDS_CNST_BYTE0, 0x12}, 378 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
523 {AUD_QAM_MODE, 0x05}, 379 {AUD_QAM_MODE, 0x05},
524 {AUD_PHACC_FREQ_8MSB, 0x34}, 380 {AUD_PHACC_FREQ_8MSB, 0x34},
525 {AUD_PHACC_FREQ_8LSB, 0x4c}, 381 {AUD_PHACC_FREQ_8LSB, 0x4c},
526 {AUD_RATE_ADJ1, 0x00000100}, 382 {AUD_RATE_ADJ1, 0x00000100},
527 {AUD_RATE_ADJ2, 0x00000200}, 383 {AUD_RATE_ADJ2, 0x00000200},
528 {AUD_RATE_ADJ3, 0x00000300}, 384 {AUD_RATE_ADJ3, 0x00000300},
529 {AUD_RATE_ADJ4, 0x00000400}, 385 {AUD_RATE_ADJ4, 0x00000400},
530 {AUD_RATE_ADJ5, 0x00000500}, 386 {AUD_RATE_ADJ5, 0x00000500},
531 {AUD_THR_FR, 0x00000000}, 387 {AUD_THR_FR, 0x00000000},
532 {AAGC_HYST, 0x0000001a}, 388 {AAGC_HYST, 0x0000001a},
533 {AUD_PILOT_BQD_1_K0, 0x0000755b}, 389 {AUD_PILOT_BQD_1_K0, 0x0000755b},
534 {AUD_PILOT_BQD_1_K1, 0x00551340}, 390 {AUD_PILOT_BQD_1_K1, 0x00551340},
535 {AUD_PILOT_BQD_1_K2, 0x006d30be}, 391 {AUD_PILOT_BQD_1_K2, 0x006d30be},
536 {AUD_PILOT_BQD_1_K3, 0xffd394af}, 392 {AUD_PILOT_BQD_1_K3, 0xffd394af},
537 {AUD_PILOT_BQD_1_K4, 0x00400000}, 393 {AUD_PILOT_BQD_1_K4, 0x00400000},
538 {AUD_PILOT_BQD_2_K0, 0x00040000}, 394 {AUD_PILOT_BQD_2_K0, 0x00040000},
539 {AUD_PILOT_BQD_2_K1, 0x002a4841}, 395 {AUD_PILOT_BQD_2_K1, 0x002a4841},
540 {AUD_PILOT_BQD_2_K2, 0x00400000}, 396 {AUD_PILOT_BQD_2_K2, 0x00400000},
541 {AUD_PILOT_BQD_2_K3, 0x00000000}, 397 {AUD_PILOT_BQD_2_K3, 0x00000000},
542 {AUD_PILOT_BQD_2_K4, 0x00000000}, 398 {AUD_PILOT_BQD_2_K4, 0x00000000},
543 {AUD_MODE_CHG_TIMER, 0x00000040}, 399 {AUD_MODE_CHG_TIMER, 0x00000040},
544 {AUD_AFE_12DB_EN, 0x00000001}, 400 {AUD_AFE_12DB_EN, 0x00000001},
545 {AUD_CORDIC_SHIFT_0, 0x00000007}, 401 {AUD_CORDIC_SHIFT_0, 0x00000007},
546 {AUD_CORDIC_SHIFT_1, 0x00000007}, 402 {AUD_CORDIC_SHIFT_1, 0x00000007},
547 {AUD_DEEMPH0_G0, 0x00000380}, 403 {AUD_DEEMPH0_G0, 0x00000380},
548 {AUD_DEEMPH1_G0, 0x00000380}, 404 {AUD_DEEMPH1_G0, 0x00000380},
549 {AUD_DCOC_0_SRC, 0x0000001a}, 405 {AUD_DCOC_0_SRC, 0x0000001a},
550 {AUD_DCOC0_SHIFT, 0x00000000}, 406 {AUD_DCOC0_SHIFT, 0x00000000},
551 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, 407 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
552 {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, 408 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
553 {AUD_DCOC_PASS_IN, 0x00000003}, 409 {AUD_DCOC_PASS_IN, 0x00000003},
554 {AUD_IIR3_0_SEL, 0x00000021}, 410 {AUD_IIR3_0_SEL, 0x00000021},
555 {AUD_DN2_AFC, 0x00000002}, 411 {AUD_DN2_AFC, 0x00000002},
556 {AUD_DCOC_1_SRC, 0x0000001b}, 412 {AUD_DCOC_1_SRC, 0x0000001b},
557 {AUD_DCOC1_SHIFT, 0x00000000}, 413 {AUD_DCOC1_SHIFT, 0x00000000},
558 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, 414 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
559 {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, 415 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
560 {AUD_IIR3_1_SEL, 0x00000023}, 416 {AUD_IIR3_1_SEL, 0x00000023},
561 {AUD_RDSI_SEL, 0x00000017}, 417 {AUD_RDSI_SEL, 0x00000017},
562 {AUD_RDSI_SHIFT, 0x00000000}, 418 {AUD_RDSI_SHIFT, 0x00000000},
563 {AUD_RDSQ_SEL, 0x00000017}, 419 {AUD_RDSQ_SEL, 0x00000017},
564 {AUD_RDSQ_SHIFT, 0x00000000}, 420 {AUD_RDSQ_SHIFT, 0x00000000},
565 {AUD_PLL_INT, 0x0000001e}, 421 {AUD_PLL_INT, 0x0000001e},
566 {AUD_PLL_DDS, 0x00000000}, 422 {AUD_PLL_DDS, 0x00000000},
567 {AUD_PLL_FRAC, 0x0000e542}, 423 {AUD_PLL_FRAC, 0x0000e542},
568 {AUD_POLYPH80SCALEFAC, 0x00000001}, 424 {AUD_POLYPH80SCALEFAC, 0x00000001},
569 {AUD_START_TIMER, 0x00000000}, 425 {AUD_START_TIMER, 0x00000000},
570 { /* end of list */ }, 426 { /* end of list */ },
571 }; 427 };
572 428
573 static const struct rlist a2_bg[] = { 429 static const struct rlist a2_bg[] = {
574 {AUD_DMD_RA_DDS, 0x002a4f2f}, 430 {AUD_DMD_RA_DDS, 0x002a4f2f},
575 {AUD_C1_UP_THR, 0x00007000}, 431 {AUD_C1_UP_THR, 0x00007000},
576 {AUD_C1_LO_THR, 0x00005400}, 432 {AUD_C1_LO_THR, 0x00005400},
577 {AUD_C2_UP_THR, 0x00005400}, 433 {AUD_C2_UP_THR, 0x00005400},
578 {AUD_C2_LO_THR, 0x00003000}, 434 {AUD_C2_LO_THR, 0x00003000},
579 { /* end of list */ }, 435 { /* end of list */ },
580 }; 436 };
581 437
582 static const struct rlist a2_dk[] = { 438 static const struct rlist a2_dk[] = {
583 {AUD_DMD_RA_DDS, 0x002a4f2f}, 439 {AUD_DMD_RA_DDS, 0x002a4f2f},
584 {AUD_C1_UP_THR, 0x00007000}, 440 {AUD_C1_UP_THR, 0x00007000},
585 {AUD_C1_LO_THR, 0x00005400}, 441 {AUD_C1_LO_THR, 0x00005400},
586 {AUD_C2_UP_THR, 0x00005400}, 442 {AUD_C2_UP_THR, 0x00005400},
587 {AUD_C2_LO_THR, 0x00003000}, 443 {AUD_C2_LO_THR, 0x00003000},
588 {AUD_DN0_FREQ, 0x00003a1c}, 444 {AUD_DN0_FREQ, 0x00003a1c},
589 {AUD_DN2_FREQ, 0x0000d2e0}, 445 {AUD_DN2_FREQ, 0x0000d2e0},
590 { /* end of list */ }, 446 { /* end of list */ },
591 }; 447 };
592/* unknown, probably NTSC-M */ 448
593 static const struct rlist a2_m[] = { 449 static const struct rlist a1_i[] = {
594 {AUD_DMD_RA_DDS, 0x002a0425}, 450 {AUD_ERRLOGPERIOD_R, 0x00000064},
595 {AUD_C1_UP_THR, 0x00003c00}, 451 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
596 {AUD_C1_LO_THR, 0x00003000}, 452 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
597 {AUD_C2_UP_THR, 0x00006000}, 453 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
598 {AUD_C2_LO_THR, 0x00003c00}, 454 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
599 {AUD_DEEMPH0_A0, 0x00007a80}, 455 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
600 {AUD_DEEMPH1_A0, 0x00007a80}, 456 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
601 {AUD_DEEMPH0_G0, 0x00001200}, 457 {AUD_QAM_MODE, 0x05},
602 {AUD_DEEMPH1_G0, 0x00001200}, 458 {AUD_PHACC_FREQ_8MSB, 0x3a},
603 {AUD_DN0_FREQ, 0x0000283b}, 459 {AUD_PHACC_FREQ_8LSB, 0x93},
604 {AUD_DN1_FREQ, 0x00003418}, 460 {AUD_DMD_RA_DDS, 0x002a4f2f},
605 {AUD_DN2_FREQ, 0x000029c7}, 461 {AUD_PLL_INT, 0x0000001e},
606 {AUD_POLY0_DDS_CONSTANT, 0x000a7540}, 462 {AUD_PLL_DDS, 0x00000004},
463 {AUD_PLL_FRAC, 0x0000e542},
464 {AUD_RATE_ADJ1, 0x00000100},
465 {AUD_RATE_ADJ2, 0x00000200},
466 {AUD_RATE_ADJ3, 0x00000300},
467 {AUD_RATE_ADJ4, 0x00000400},
468 {AUD_RATE_ADJ5, 0x00000500},
469 {AUD_THR_FR, 0x00000000},
470 {AUD_PILOT_BQD_1_K0, 0x0000755b},
471 {AUD_PILOT_BQD_1_K1, 0x00551340},
472 {AUD_PILOT_BQD_1_K2, 0x006d30be},
473 {AUD_PILOT_BQD_1_K3, 0xffd394af},
474 {AUD_PILOT_BQD_1_K4, 0x00400000},
475 {AUD_PILOT_BQD_2_K0, 0x00040000},
476 {AUD_PILOT_BQD_2_K1, 0x002a4841},
477 {AUD_PILOT_BQD_2_K2, 0x00400000},
478 {AUD_PILOT_BQD_2_K3, 0x00000000},
479 {AUD_PILOT_BQD_2_K4, 0x00000000},
480 {AUD_MODE_CHG_TIMER, 0x00000060},
481 {AUD_AFE_12DB_EN, 0x00000001},
482 {AAGC_HYST, 0x0000000a},
483 {AUD_CORDIC_SHIFT_0, 0x00000007},
484 {AUD_CORDIC_SHIFT_1, 0x00000007},
485 {AUD_C1_UP_THR, 0x00007000},
486 {AUD_C1_LO_THR, 0x00005400},
487 {AUD_C2_UP_THR, 0x00005400},
488 {AUD_C2_LO_THR, 0x00003000},
489 {AUD_DCOC_0_SRC, 0x0000001a},
490 {AUD_DCOC0_SHIFT, 0x00000000},
491 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
492 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
493 {AUD_DCOC_PASS_IN, 0x00000003},
494 {AUD_IIR3_0_SEL, 0x00000021},
495 {AUD_DN2_AFC, 0x00000002},
496 {AUD_DCOC_1_SRC, 0x0000001b},
497 {AUD_DCOC1_SHIFT, 0x00000000},
498 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
499 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
500 {AUD_IIR3_1_SEL, 0x00000023},
501 {AUD_DN0_FREQ, 0x000035a3},
502 {AUD_DN2_FREQ, 0x000029c7},
503 {AUD_CRDC0_SRC_SEL, 0x00000511},
504 {AUD_IIR1_0_SEL, 0x00000001},
505 {AUD_IIR1_1_SEL, 0x00000000},
506 {AUD_IIR3_2_SEL, 0x00000003},
507 {AUD_IIR3_2_SHIFT, 0x00000000},
508 {AUD_IIR3_0_SEL, 0x00000002},
509 {AUD_IIR2_0_SEL, 0x00000021},
510 {AUD_IIR2_0_SHIFT, 0x00000002},
511 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
512 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
513 {AUD_POLYPH80SCALEFAC, 0x00000001},
514 {AUD_START_TIMER, 0x00000000},
607 { /* end of list */ }, 515 { /* end of list */ },
608 }; 516 };
609 517
610 static const struct rlist a2_deemph50[] = { 518 static const struct rlist am_l[] = {
611 {AUD_DEEMPH0_G0, 0x00000380}, 519 {AUD_ERRLOGPERIOD_R, 0x00000064},
612 {AUD_DEEMPH1_G0, 0x00000380}, 520 {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
613 {AUD_DEEMPHGAIN_R, 0x000011e1}, 521 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
614 {AUD_DEEMPHNUMER1_R, 0x0002a7bc}, 522 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
615 {AUD_DEEMPHNUMER2_R, 0x0003023c}, 523 {AUD_PDF_DDS_CNST_BYTE2, 0x48},
616 { /* end of list */ }, 524 {AUD_PDF_DDS_CNST_BYTE1, 0x3D},
525 {AUD_QAM_MODE, 0x00},
526 {AUD_PDF_DDS_CNST_BYTE0, 0xf5},
527 {AUD_PHACC_FREQ_8MSB, 0x3a},
528 {AUD_PHACC_FREQ_8LSB, 0x4a},
529 {AUD_DEEMPHGAIN_R, 0x00006680},
530 {AUD_DEEMPHNUMER1_R, 0x000353DE},
531 {AUD_DEEMPHNUMER2_R, 0x000001B1},
532 {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
533 {AUD_DEEMPHDENOM2_R, 0x00000000},
534 {AUD_FM_MODE_ENABLE, 0x00000007},
535 {AUD_POLYPH80SCALEFAC, 0x00000003},
536 {AUD_AFE_12DB_EN, 0x00000001},
537 {AAGC_GAIN, 0x00000000},
538 {AAGC_HYST, 0x00000018},
539 {AAGC_DEF, 0x00000020},
540 {AUD_DN0_FREQ, 0x00000000},
541 {AUD_POLY0_DDS_CONSTANT, 0x000E4DB2},
542 {AUD_DCOC_0_SRC, 0x00000021},
543 {AUD_IIR1_0_SEL, 0x00000000},
544 {AUD_IIR1_0_SHIFT, 0x00000007},
545 {AUD_IIR1_1_SEL, 0x00000002},
546 {AUD_IIR1_1_SHIFT, 0x00000000},
547 {AUD_DCOC_1_SRC, 0x00000003},
548 {AUD_DCOC1_SHIFT, 0x00000000},
549 {AUD_DCOC_PASS_IN, 0x00000000},
550 {AUD_IIR1_2_SEL, 0x00000023},
551 {AUD_IIR1_2_SHIFT, 0x00000000},
552 {AUD_IIR1_3_SEL, 0x00000004},
553 {AUD_IIR1_3_SHIFT, 0x00000007},
554 {AUD_IIR1_4_SEL, 0x00000005},
555 {AUD_IIR1_4_SHIFT, 0x00000007},
556 {AUD_IIR3_0_SEL, 0x00000007},
557 {AUD_IIR3_0_SHIFT, 0x00000000},
558 {AUD_DEEMPH0_SRC_SEL, 0x00000011},
559 {AUD_DEEMPH0_SHIFT, 0x00000000},
560 {AUD_DEEMPH0_G0, 0x00007000},
561 {AUD_DEEMPH0_A0, 0x00000000},
562 {AUD_DEEMPH0_B0, 0x00000000},
563 {AUD_DEEMPH0_A1, 0x00000000},
564 {AUD_DEEMPH0_B1, 0x00000000},
565 {AUD_DEEMPH1_SRC_SEL, 0x00000011},
566 {AUD_DEEMPH1_SHIFT, 0x00000000},
567 {AUD_DEEMPH1_G0, 0x00007000},
568 {AUD_DEEMPH1_A0, 0x00000000},
569 {AUD_DEEMPH1_B0, 0x00000000},
570 {AUD_DEEMPH1_A1, 0x00000000},
571 {AUD_DEEMPH1_B1, 0x00000000},
572 {AUD_OUT0_SEL, 0x0000003F},
573 {AUD_OUT1_SEL, 0x0000003F},
574 {AUD_DMD_RA_DDS, 0x00F5C285},
575 {AUD_PLL_INT, 0x0000001E},
576 {AUD_PLL_DDS, 0x00000000},
577 {AUD_PLL_FRAC, 0x0000E542},
578 {AUD_RATE_ADJ1, 0x00000100},
579 {AUD_RATE_ADJ2, 0x00000200},
580 {AUD_RATE_ADJ3, 0x00000300},
581 {AUD_RATE_ADJ4, 0x00000400},
582 {AUD_RATE_ADJ5, 0x00000500},
583 {AUD_RATE_THRES_DMD, 0x000000C0},
584 { /* end of list */ },
617 }; 585 };
618 586
619 static const struct rlist a2_deemph75[] = { 587 static const struct rlist a2_deemph50[] = {
620 {AUD_DEEMPH0_G0, 0x00000480}, 588 {AUD_DEEMPH0_G0, 0x00000380},
621 {AUD_DEEMPH1_G0, 0x00000480}, 589 {AUD_DEEMPH1_G0, 0x00000380},
622 {AUD_DEEMPHGAIN_R, 0x00009000}, 590 {AUD_DEEMPHGAIN_R, 0x000011e1},
623 {AUD_DEEMPHNUMER1_R, 0x000353de}, 591 {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
624 {AUD_DEEMPHNUMER2_R, 0x000001b1}, 592 {AUD_DEEMPHNUMER2_R, 0x0003023c},
625 { /* end of list */ }, 593 { /* end of list */ },
626 }; 594 };
627 595
628 set_audio_start(core, SEL_A2); 596 set_audio_start(core, SEL_A2);
629 set_audio_registers(core, a2_common);
630 switch (core->tvaudio) { 597 switch (core->tvaudio) {
631 case WW_A2_BG: 598 case WW_BG:
632 dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__); 599 dprintk("%s PAL-BG A1/2 (status: known-good)\n", __FUNCTION__);
633 set_audio_registers(core, a2_bg); 600 set_audio_registers(core, a2_bgdk_common);
634 set_audio_registers(core, a2_deemph50); 601 set_audio_registers(core, a2_bg);
602 set_audio_registers(core, a2_deemph50);
635 break; 603 break;
636 case WW_A2_DK: 604 case WW_DK:
637 dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__); 605 dprintk("%s PAL-DK A1/2 (status: known-good)\n", __FUNCTION__);
638 set_audio_registers(core, a2_dk); 606 set_audio_registers(core, a2_bgdk_common);
639 set_audio_registers(core, a2_deemph50); 607 set_audio_registers(core, a2_dk);
608 set_audio_registers(core, a2_deemph50);
640 break; 609 break;
641 case WW_A2_M: 610 case WW_I:
642 dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__); 611 dprintk("%s PAL-I A1 (status: known-good)\n", __FUNCTION__);
643 set_audio_registers(core, a2_m); 612 set_audio_registers(core, a1_i);
644 set_audio_registers(core, a2_deemph75); 613 set_audio_registers(core, a2_deemph50);
614 break;
615 case WW_L:
616 dprintk("%s AM-L (status: devel)\n", __FUNCTION__);
617 set_audio_registers(core, am_l);
618 break;
619 default:
620 dprintk("%s Warning: wrong value\n", __FUNCTION__);
621 return;
645 break; 622 break;
646 }; 623 };
647 624
@@ -656,71 +633,71 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
656 633
657 { /* end of list */ }, 634 { /* end of list */ },
658 }; 635 };
659 dprintk("%s (status: unknown)\n",__FUNCTION__); 636 dprintk("%s (status: unknown)\n", __FUNCTION__);
660 637
661 set_audio_start(core, SEL_EIAJ); 638 set_audio_start(core, SEL_EIAJ);
662 set_audio_registers(core, eiaj); 639 set_audio_registers(core, eiaj);
663 set_audio_finish(core, EN_EIAJ_AUTO_STEREO); 640 set_audio_finish(core, EN_EIAJ_AUTO_STEREO);
664} 641}
665 642
666static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph) 643static void set_audio_standard_FM(struct cx88_core *core,
644 enum cx88_deemph_type deemph)
667{ 645{
668 static const struct rlist fm_deemph_50[] = { 646 static const struct rlist fm_deemph_50[] = {
669 { AUD_DEEMPH0_G0, 0x0C45 }, 647 {AUD_DEEMPH0_G0, 0x0C45},
670 { AUD_DEEMPH0_A0, 0x6262 }, 648 {AUD_DEEMPH0_A0, 0x6262},
671 { AUD_DEEMPH0_B0, 0x1C29 }, 649 {AUD_DEEMPH0_B0, 0x1C29},
672 { AUD_DEEMPH0_A1, 0x3FC66}, 650 {AUD_DEEMPH0_A1, 0x3FC66},
673 { AUD_DEEMPH0_B1, 0x399A }, 651 {AUD_DEEMPH0_B1, 0x399A},
674 652
675 { AUD_DEEMPH1_G0, 0x0D80 }, 653 {AUD_DEEMPH1_G0, 0x0D80},
676 { AUD_DEEMPH1_A0, 0x6262 }, 654 {AUD_DEEMPH1_A0, 0x6262},
677 { AUD_DEEMPH1_B0, 0x1C29 }, 655 {AUD_DEEMPH1_B0, 0x1C29},
678 { AUD_DEEMPH1_A1, 0x3FC66}, 656 {AUD_DEEMPH1_A1, 0x3FC66},
679 { AUD_DEEMPH1_B1, 0x399A}, 657 {AUD_DEEMPH1_B1, 0x399A},
680 658
681 { AUD_POLYPH80SCALEFAC, 0x0003}, 659 {AUD_POLYPH80SCALEFAC, 0x0003},
682 { /* end of list */ }, 660 { /* end of list */ },
683 }; 661 };
684 static const struct rlist fm_deemph_75[] = { 662 static const struct rlist fm_deemph_75[] = {
685 { AUD_DEEMPH0_G0, 0x091B }, 663 {AUD_DEEMPH0_G0, 0x091B},
686 { AUD_DEEMPH0_A0, 0x6B68 }, 664 {AUD_DEEMPH0_A0, 0x6B68},
687 { AUD_DEEMPH0_B0, 0x11EC }, 665 {AUD_DEEMPH0_B0, 0x11EC},
688 { AUD_DEEMPH0_A1, 0x3FC66}, 666 {AUD_DEEMPH0_A1, 0x3FC66},
689 { AUD_DEEMPH0_B1, 0x399A }, 667 {AUD_DEEMPH0_B1, 0x399A},
690 668
691 { AUD_DEEMPH1_G0, 0x0AA0 }, 669 {AUD_DEEMPH1_G0, 0x0AA0},
692 { AUD_DEEMPH1_A0, 0x6B68 }, 670 {AUD_DEEMPH1_A0, 0x6B68},
693 { AUD_DEEMPH1_B0, 0x11EC }, 671 {AUD_DEEMPH1_B0, 0x11EC},
694 { AUD_DEEMPH1_A1, 0x3FC66}, 672 {AUD_DEEMPH1_A1, 0x3FC66},
695 { AUD_DEEMPH1_B1, 0x399A}, 673 {AUD_DEEMPH1_B1, 0x399A},
696 674
697 { AUD_POLYPH80SCALEFAC, 0x0003}, 675 {AUD_POLYPH80SCALEFAC, 0x0003},
698 { /* end of list */ }, 676 { /* end of list */ },
699 }; 677 };
700 678
701 /* It is enough to leave default values? */ 679 /* It is enough to leave default values? */
702 static const struct rlist fm_no_deemph[] = { 680 static const struct rlist fm_no_deemph[] = {
703 681
704 { AUD_POLYPH80SCALEFAC, 0x0003}, 682 {AUD_POLYPH80SCALEFAC, 0x0003},
705 { /* end of list */ }, 683 { /* end of list */ },
706 }; 684 };
707 685
708 dprintk("%s (status: unknown)\n",__FUNCTION__); 686 dprintk("%s (status: unknown)\n", __FUNCTION__);
709 set_audio_start(core, SEL_FMRADIO); 687 set_audio_start(core, SEL_FMRADIO);
710 688
711 switch (deemph) 689 switch (deemph) {
712 { 690 case FM_NO_DEEMPH:
713 case FM_NO_DEEMPH: 691 set_audio_registers(core, fm_no_deemph);
714 set_audio_registers(core, fm_no_deemph); 692 break;
715 break;
716 693
717 case FM_DEEMPH_50: 694 case FM_DEEMPH_50:
718 set_audio_registers(core, fm_deemph_50); 695 set_audio_registers(core, fm_deemph_50);
719 break; 696 break;
720 697
721 case FM_DEEMPH_75: 698 case FM_DEEMPH_75:
722 set_audio_registers(core, fm_deemph_75); 699 set_audio_registers(core, fm_deemph_75);
723 break; 700 break;
724 } 701 }
725 702
726 set_audio_finish(core, EN_FMRADIO_AUTO_STEREO); 703 set_audio_finish(core, EN_FMRADIO_AUTO_STEREO);
@@ -728,36 +705,64 @@ static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type
728 705
729/* ----------------------------------------------------------- */ 706/* ----------------------------------------------------------- */
730 707
708int cx88_detect_nicam(struct cx88_core *core)
709{
710 int i, j = 0;
711
712 dprintk("start nicam autodetect.\n");
713
714 for (i = 0; i < 6; i++) {
715 /* if bit1=1 then nicam is detected */
716 j += ((cx_read(AUD_NICAM_STATUS2) & 0x02) >> 1);
717
718 /* 3x detected: absolutly sure now */
719 if (j == 3) {
720 dprintk("nicam is detected.\n");
721 return 1;
722 }
723
724 /* wait a little bit for next reading status */
725 msleep(10);
726 }
727
728 dprintk("nicam is not detected.\n");
729 return 0;
730}
731
731void cx88_set_tvaudio(struct cx88_core *core) 732void cx88_set_tvaudio(struct cx88_core *core)
732{ 733{
733 switch (core->tvaudio) { 734 switch (core->tvaudio) {
734 case WW_BTSC: 735 case WW_BTSC:
735 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO); 736 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
736 break; 737 break;
737 case WW_NICAM_BGDKL: 738 case WW_BG:
738 set_audio_standard_NICAM_L(core,0); 739 case WW_DK:
739 break; 740 case WW_I:
740 case WW_NICAM_I: 741 case WW_L:
741 set_audio_standard_PAL_I(core,0); 742 /* prepare all dsp registers */
742 break; 743 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
743 case WW_A2_BG: 744
744 case WW_A2_DK: 745 /* set nicam mode - otherwise
745 case WW_A2_M: 746 AUD_NICAM_STATUS2 contains wrong values */
746 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 747 set_audio_standard_NICAM(core, EN_NICAM_AUTO_STEREO);
748 if (0 == cx88_detect_nicam(core)) {
749 /* fall back to fm / am mono */
750 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
751 core->use_nicam = 0;
752 } else {
753 core->use_nicam = 1;
754 }
747 break; 755 break;
748 case WW_EIAJ: 756 case WW_EIAJ:
749 set_audio_standard_EIAJ(core); 757 set_audio_standard_EIAJ(core);
750 break; 758 break;
751 case WW_FM: 759 case WW_FM:
752 set_audio_standard_FM(core,FM_NO_DEEMPH); 760 set_audio_standard_FM(core, FM_NO_DEEMPH);
753 break;
754 case WW_SYSTEM_L_AM:
755 set_audio_standard_NICAM_L(core, 1);
756 break; 761 break;
757 case WW_NONE: 762 case WW_NONE:
758 default: 763 default:
759 printk("%s/0: unknown tv audio mode [%d]\n", 764 printk("%s/0: unknown tv audio mode [%d]\n",
760 core->name, core->tvaudio); 765 core->name, core->tvaudio);
761 break; 766 break;
762 } 767 }
763 return; 768 return;
@@ -766,24 +771,16 @@ void cx88_set_tvaudio(struct cx88_core *core)
766void cx88_newstation(struct cx88_core *core) 771void cx88_newstation(struct cx88_core *core)
767{ 772{
768 core->audiomode_manual = UNSET; 773 core->audiomode_manual = UNSET;
769
770 switch (core->tvaudio) {
771 case WW_SYSTEM_L_AM:
772 /* try nicam ... */
773 core->audiomode_current = V4L2_TUNER_MODE_STEREO;
774 set_audio_standard_NICAM_L(core, 1);
775 break;
776 }
777} 774}
778 775
779void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) 776void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
780{ 777{
781 static char *m[] = {"stereo", "dual mono", "mono", "sap"}; 778 static char *m[] = { "stereo", "dual mono", "mono", "sap" };
782 static char *p[] = {"no pilot", "pilot c1", "pilot c2", "?"}; 779 static char *p[] = { "no pilot", "pilot c1", "pilot c2", "?" };
783 u32 reg,mode,pilot; 780 u32 reg, mode, pilot;
784 781
785 reg = cx_read(AUD_STATUS); 782 reg = cx_read(AUD_STATUS);
786 mode = reg & 0x03; 783 mode = reg & 0x03;
787 pilot = (reg >> 2) & 0x03; 784 pilot = (reg >> 2) & 0x03;
788 785
789 if (core->astat != reg) 786 if (core->astat != reg)
@@ -800,14 +797,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
800 797
801# if 0 798# if 0
802 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | 799 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
803 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; 800 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
804 t->rxsubchans = V4L2_TUNER_SUB_MONO; 801 t->rxsubchans = V4L2_TUNER_SUB_MONO;
805 t->audmode = V4L2_TUNER_MODE_MONO; 802 t->audmode = V4L2_TUNER_MODE_MONO;
806 803
807 switch (core->tvaudio) { 804 switch (core->tvaudio) {
808 case WW_BTSC: 805 case WW_BTSC:
809 t->capability = V4L2_TUNER_CAP_STEREO | 806 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP;
810 V4L2_TUNER_CAP_SAP;
811 t->rxsubchans = V4L2_TUNER_SUB_STEREO; 807 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
812 if (1 == pilot) { 808 if (1 == pilot) {
813 /* SAP */ 809 /* SAP */
@@ -819,13 +815,15 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
819 case WW_A2_M: 815 case WW_A2_M:
820 if (1 == pilot) { 816 if (1 == pilot) {
821 /* stereo */ 817 /* stereo */
822 t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 818 t->rxsubchans =
819 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
823 if (0 == mode) 820 if (0 == mode)
824 t->audmode = V4L2_TUNER_MODE_STEREO; 821 t->audmode = V4L2_TUNER_MODE_STEREO;
825 } 822 }
826 if (2 == pilot) { 823 if (2 == pilot) {
827 /* dual language -- FIXME */ 824 /* dual language -- FIXME */
828 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; 825 t->rxsubchans =
826 V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
829 t->audmode = V4L2_TUNER_MODE_LANG1; 827 t->audmode = V4L2_TUNER_MODE_LANG1;
830 } 828 }
831 break; 829 break;
@@ -840,7 +838,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
840 t->audmode = V4L2_TUNER_MODE_STEREO; 838 t->audmode = V4L2_TUNER_MODE_STEREO;
841 t->rxsubchans |= V4L2_TUNER_SUB_STEREO; 839 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
842 } 840 }
843 break ; 841 break;
844 default: 842 default:
845 /* nothing */ 843 /* nothing */
846 break; 844 break;
@@ -851,7 +849,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
851 849
852void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) 850void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
853{ 851{
854 u32 ctl = UNSET; 852 u32 ctl = UNSET;
855 u32 mask = UNSET; 853 u32 mask = UNSET;
856 854
857 if (manual) { 855 if (manual) {
@@ -879,68 +877,58 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
879 break; 877 break;
880 } 878 }
881 break; 879 break;
882 case WW_A2_BG: 880 case WW_BG:
883 case WW_A2_DK: 881 case WW_DK:
884 case WW_A2_M: 882 case WW_I:
885 switch (mode) { 883 case WW_L:
886 case V4L2_TUNER_MODE_MONO: 884 if (1 == core->use_nicam) {
887 case V4L2_TUNER_MODE_LANG1: 885 switch (mode) {
888 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 886 case V4L2_TUNER_MODE_MONO:
889 break; 887 case V4L2_TUNER_MODE_LANG1:
890 case V4L2_TUNER_MODE_LANG2: 888 set_audio_standard_NICAM(core,
891 set_audio_standard_A2(core, EN_A2_FORCE_MONO2); 889 EN_NICAM_FORCE_MONO1);
892 break; 890 break;
893 case V4L2_TUNER_MODE_STEREO: 891 case V4L2_TUNER_MODE_LANG2:
894 set_audio_standard_A2(core, EN_A2_FORCE_STEREO); 892 set_audio_standard_NICAM(core,
895 break; 893 EN_NICAM_FORCE_MONO2);
896 } 894 break;
897 break; 895 case V4L2_TUNER_MODE_STEREO:
898 case WW_NICAM_BGDKL: 896 set_audio_standard_NICAM(core,
899 switch (mode) { 897 EN_NICAM_FORCE_STEREO);
900 case V4L2_TUNER_MODE_MONO: 898 break;
901 ctl = EN_NICAM_FORCE_MONO1; 899 }
902 mask = 0x3f; 900 } else {
903 break; 901 if ((core->tvaudio == WW_I) || (core->tvaudio == WW_L)) {
904 case V4L2_TUNER_MODE_LANG1: 902 /* fall back to fm / am mono */
905 ctl = EN_NICAM_AUTO_MONO2; 903 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
906 mask = 0x3f; 904 } else {
907 break; 905 /* TODO: Add A2 autodection */
908 case V4L2_TUNER_MODE_STEREO: 906 switch (mode) {
909 ctl = EN_NICAM_FORCE_STEREO | EN_DMTRX_LR; 907 case V4L2_TUNER_MODE_MONO:
910 mask = 0x93f; 908 case V4L2_TUNER_MODE_LANG1:
911 break; 909 set_audio_standard_A2(core,
912 } 910 EN_A2_FORCE_MONO1);
913 break; 911 break;
914 case WW_SYSTEM_L_AM: 912 case V4L2_TUNER_MODE_LANG2:
915 switch (mode) { 913 set_audio_standard_A2(core,
916 case V4L2_TUNER_MODE_MONO: 914 EN_A2_FORCE_MONO2);
917 case V4L2_TUNER_MODE_LANG1: /* FIXME */ 915 break;
918 set_audio_standard_NICAM_L(core, 0); 916 case V4L2_TUNER_MODE_STEREO:
919 break; 917 set_audio_standard_A2(core,
920 case V4L2_TUNER_MODE_STEREO: 918 EN_A2_FORCE_STEREO);
921 set_audio_standard_NICAM_L(core, 1); 919 break;
922 break; 920 }
923 } 921 }
924 break;
925 case WW_NICAM_I:
926 switch (mode) {
927 case V4L2_TUNER_MODE_MONO:
928 case V4L2_TUNER_MODE_LANG1:
929 set_audio_standard_PAL_I(core, 0);
930 break;
931 case V4L2_TUNER_MODE_STEREO:
932 set_audio_standard_PAL_I(core, 1);
933 break;
934 } 922 }
935 break; 923 break;
936 case WW_FM: 924 case WW_FM:
937 switch (mode) { 925 switch (mode) {
938 case V4L2_TUNER_MODE_MONO: 926 case V4L2_TUNER_MODE_MONO:
939 ctl = EN_FMRADIO_FORCE_MONO; 927 ctl = EN_FMRADIO_FORCE_MONO;
940 mask = 0x3f; 928 mask = 0x3f;
941 break; 929 break;
942 case V4L2_TUNER_MODE_STEREO: 930 case V4L2_TUNER_MODE_STEREO:
943 ctl = EN_FMRADIO_AUTO_STEREO; 931 ctl = EN_FMRADIO_AUTO_STEREO;
944 mask = 0x3f; 932 mask = 0x3f;
945 break; 933 break;
946 } 934 }
@@ -970,8 +958,8 @@ int cx88_audio_thread(void *data)
970 break; 958 break;
971 959
972 /* just monitor the audio status for now ... */ 960 /* just monitor the audio status for now ... */
973 memset(&t,0,sizeof(t)); 961 memset(&t, 0, sizeof(t));
974 cx88_get_stereo(core,&t); 962 cx88_get_stereo(core, &t);
975 963
976 if (UNSET != core->audiomode_manual) 964 if (UNSET != core->audiomode_manual)
977 /* manually set, don't do anything. */ 965 /* manually set, don't do anything. */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 3dbc074fb515..24a48f8a48c1 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -34,6 +34,9 @@
34 34
35#include "cx88.h" 35#include "cx88.h"
36 36
37/* Include V4L1 specific functions. Should be removed soon */
38#include <linux/videodev.h>
39
37MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); 40MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 41MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
@@ -100,7 +103,7 @@ static struct cx88_tvnorm tvnorms[] = {
100 .id = V4L2_STD_PAL_I, 103 .id = V4L2_STD_PAL_I,
101 .cxiformat = VideoFormatPAL, 104 .cxiformat = VideoFormatPAL,
102 .cxoformat = 0x181f0008, 105 .cxoformat = 0x181f0008,
103 },{ 106 },{
104 .name = "PAL-M", 107 .name = "PAL-M",
105 .id = V4L2_STD_PAL_M, 108 .id = V4L2_STD_PAL_M,
106 .cxiformat = VideoFormatPALM, 109 .cxiformat = VideoFormatPALM,
@@ -470,7 +473,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
470 struct list_head *item; 473 struct list_head *item;
471 474
472 if (!list_empty(&q->active)) { 475 if (!list_empty(&q->active)) {
473 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); 476 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
474 dprintk(2,"restart_queue [%p/%d]: restart dma\n", 477 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
475 buf, buf->vb.i); 478 buf, buf->vb.i);
476 start_video_dma(dev, q, buf); 479 start_video_dma(dev, q, buf);
@@ -486,7 +489,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
486 for (;;) { 489 for (;;) {
487 if (list_empty(&q->queued)) 490 if (list_empty(&q->queued))
488 return 0; 491 return 0;
489 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); 492 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
490 if (NULL == prev) { 493 if (NULL == prev) {
491 list_del(&buf->vb.queue); 494 list_del(&buf->vb.queue);
492 list_add_tail(&buf->vb.queue,&q->active); 495 list_add_tail(&buf->vb.queue,&q->active);
@@ -783,11 +786,11 @@ static int video_open(struct inode *inode, struct file *file)
783 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); 786 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
784 } 787 }
785 788
786 return 0; 789 return 0;
787} 790}
788 791
789static ssize_t 792static ssize_t
790video_read(struct file *file, char *data, size_t count, loff_t *ppos) 793video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
791{ 794{
792 struct cx8800_fh *fh = file->private_data; 795 struct cx8800_fh *fh = file->private_data;
793 796
@@ -922,7 +925,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
922{ 925{
923 /* struct cx88_core *core = dev->core; */ 926 /* struct cx88_core *core = dev->core; */
924 struct cx88_ctrl *c = NULL; 927 struct cx88_ctrl *c = NULL;
925 u32 v_sat_value; 928 u32 v_sat_value;
926 u32 value; 929 u32 value;
927 int i; 930 int i;
928 931
@@ -1187,7 +1190,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1187 struct v4l2_format *f = arg; 1190 struct v4l2_format *f = arg;
1188 return cx8800_try_fmt(dev,fh,f); 1191 return cx8800_try_fmt(dev,fh,f);
1189 } 1192 }
1190 1193#ifdef HAVE_V4L1
1191 /* --- streaming capture ------------------------------------- */ 1194 /* --- streaming capture ------------------------------------- */
1192 case VIDIOCGMBUF: 1195 case VIDIOCGMBUF:
1193 { 1196 {
@@ -1213,6 +1216,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1213 } 1216 }
1214 return 0; 1217 return 0;
1215 } 1218 }
1219#endif
1216 case VIDIOC_REQBUFS: 1220 case VIDIOC_REQBUFS:
1217 return videobuf_reqbufs(get_queue(fh), arg); 1221 return videobuf_reqbufs(get_queue(fh), arg);
1218 1222
@@ -1244,7 +1248,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1244 res_free(dev,fh,res); 1248 res_free(dev,fh,res);
1245 return 0; 1249 return 0;
1246 } 1250 }
1247
1248 default: 1251 default:
1249 return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl ); 1252 return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl );
1250 } 1253 }
@@ -1252,15 +1255,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1252} 1255}
1253 1256
1254int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, 1257int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1255 struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl) 1258 struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl)
1256{ 1259{
1257 int err; 1260 int err;
1258 1261
1262 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
1259 if (video_debug > 1) 1263 if (video_debug > 1)
1260 cx88_print_ioctl(core->name,cmd); 1264 cx88_print_ioctl(core->name,cmd);
1261 printk( KERN_INFO "CORE IOCTL: 0x%x\n", cmd );
1262 cx88_print_ioctl(core->name,cmd);
1263 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
1264 1265
1265 switch (cmd) { 1266 switch (cmd) {
1266 /* ---------- tv norms ---------- */ 1267 /* ---------- tv norms ---------- */
@@ -1401,7 +1402,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1401 1402
1402 cx88_get_stereo(core ,t); 1403 cx88_get_stereo(core ,t);
1403 reg = cx_read(MO_DEVICE_STATUS); 1404 reg = cx_read(MO_DEVICE_STATUS);
1404 t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; 1405 t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
1405 return 0; 1406 return 0;
1406 } 1407 }
1407 case VIDIOC_S_TUNER: 1408 case VIDIOC_S_TUNER:
@@ -1488,7 +1489,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1488 struct v4l2_capability *cap = arg; 1489 struct v4l2_capability *cap = arg;
1489 1490
1490 memset(cap,0,sizeof(*cap)); 1491 memset(cap,0,sizeof(*cap));
1491 strcpy(cap->driver, "cx8800"); 1492 strcpy(cap->driver, "cx8800");
1492 strlcpy(cap->card, cx88_boards[core->board].name, 1493 strlcpy(cap->card, cx88_boards[core->board].name,
1493 sizeof(cap->card)); 1494 sizeof(cap->card));
1494 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); 1495 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
@@ -1505,6 +1506,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1505 1506
1506 memset(t,0,sizeof(*t)); 1507 memset(t,0,sizeof(*t));
1507 strcpy(t->name, "Radio"); 1508 strcpy(t->name, "Radio");
1509 t->type = V4L2_TUNER_RADIO;
1508 1510
1509 cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t); 1511 cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
1510 return 0; 1512 return 0;
@@ -1539,6 +1541,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1539 *id = 0; 1541 *id = 0;
1540 return 0; 1542 return 0;
1541 } 1543 }
1544#ifdef HAVE_V4L1
1542 case VIDIOCSTUNER: 1545 case VIDIOCSTUNER:
1543 { 1546 {
1544 struct video_tuner *v = arg; 1547 struct video_tuner *v = arg;
@@ -1549,6 +1552,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1549 cx88_call_i2c_clients(core,VIDIOCSTUNER,v); 1552 cx88_call_i2c_clients(core,VIDIOCSTUNER,v);
1550 return 0; 1553 return 0;
1551 } 1554 }
1555#endif
1552 case VIDIOC_S_TUNER: 1556 case VIDIOC_S_TUNER:
1553 { 1557 {
1554 struct v4l2_tuner *t = arg; 1558 struct v4l2_tuner *t = arg;
@@ -1829,8 +1833,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1829 1833
1830 /* print pci info */ 1834 /* print pci info */
1831 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 1835 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
1832 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 1836 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1833 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " 1837 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1834 "latency: %d, mmio: 0x%lx\n", core->name, 1838 "latency: %d, mmio: 0x%lx\n", core->name,
1835 pci_name(pci_dev), dev->pci_rev, pci_dev->irq, 1839 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
1836 dev->pci_lat,pci_resource_start(pci_dev,0)); 1840 dev->pci_lat,pci_resource_start(pci_dev,0));
@@ -1946,7 +1950,7 @@ fail_free:
1946 1950
1947static void __devexit cx8800_finidev(struct pci_dev *pci_dev) 1951static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
1948{ 1952{
1949 struct cx8800_dev *dev = pci_get_drvdata(pci_dev); 1953 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
1950 struct cx88_core *core = dev->core; 1954 struct cx88_core *core = dev->core;
1951 1955
1952 /* stop thread */ 1956 /* stop thread */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index f48dd4353568..b19d3a9e2298 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -22,7 +22,7 @@
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/i2c-algo-bit.h> 24#include <linux/i2c-algo-bit.h>
25#include <linux/videodev.h> 25#include <linux/videodev2.h>
26#include <linux/kdev_t.h> 26#include <linux/kdev_t.h>
27 27
28#include <media/tuner.h> 28#include <media/tuner.h>
@@ -148,7 +148,7 @@ extern struct sram_channel cx88_sram_channels[];
148#define CX88_BOARD_PIXELVIEW 3 148#define CX88_BOARD_PIXELVIEW 3
149#define CX88_BOARD_ATI_WONDER_PRO 4 149#define CX88_BOARD_ATI_WONDER_PRO 4
150#define CX88_BOARD_WINFAST2000XP_EXPERT 5 150#define CX88_BOARD_WINFAST2000XP_EXPERT 5
151#define CX88_BOARD_AVERTV_303 6 151#define CX88_BOARD_AVERTV_STUDIO_303 6
152#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7 152#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7
153#define CX88_BOARD_WINFAST_DV2000 8 153#define CX88_BOARD_WINFAST_DV2000 8
154#define CX88_BOARD_LEADTEK_PVR2000 9 154#define CX88_BOARD_LEADTEK_PVR2000 9
@@ -174,6 +174,11 @@ extern struct sram_channel cx88_sram_channels[];
174#define CX88_BOARD_ADSTECH_DVB_T_PCI 29 174#define CX88_BOARD_ADSTECH_DVB_T_PCI 29
175#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30 175#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30
176#define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31 176#define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31
177#define CX88_BOARD_AVERMEDIA_ULTRATV_MC_550 32
178#define CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD 33
179#define CX88_BOARD_ATI_HDTVWONDER 34
180#define CX88_BOARD_WINFAST_DTV1000 35
181#define CX88_BOARD_AVERTV_303 36
177 182
178enum cx88_itype { 183enum cx88_itype {
179 CX88_VMUX_COMPOSITE1 = 1, 184 CX88_VMUX_COMPOSITE1 = 1,
@@ -203,8 +208,8 @@ struct cx88_board {
203 int tda9887_conf; 208 int tda9887_conf;
204 struct cx88_input input[MAX_CX88_INPUT]; 209 struct cx88_input input[MAX_CX88_INPUT];
205 struct cx88_input radio; 210 struct cx88_input radio;
206 int blackbird:1; 211 unsigned int blackbird:1;
207 int dvb:1; 212 unsigned int dvb:1;
208}; 213};
209 214
210struct cx88_subid { 215struct cx88_subid {
@@ -255,8 +260,8 @@ struct cx88_core {
255 /* pci stuff */ 260 /* pci stuff */
256 int pci_bus; 261 int pci_bus;
257 int pci_slot; 262 int pci_slot;
258 u32 __iomem *lmmio; 263 u32 __iomem *lmmio;
259 u8 __iomem *bmmio; 264 u8 __iomem *bmmio;
260 u32 shadow[SHADOW_MAX]; 265 u32 shadow[SHADOW_MAX];
261 int pci_irqmask; 266 int pci_irqmask;
262 267
@@ -287,6 +292,7 @@ struct cx88_core {
287 u32 audiomode_current; 292 u32 audiomode_current;
288 u32 input; 293 u32 input;
289 u32 astat; 294 u32 astat;
295 u32 use_nicam;
290 296
291 /* IR remote control state */ 297 /* IR remote control state */
292 struct cx88_IR *ir; 298 struct cx88_IR *ir;
@@ -370,6 +376,14 @@ struct cx8802_suspend_state {
370 int disabled; 376 int disabled;
371}; 377};
372 378
379/* TODO: move this to struct v4l2_mpeg_compression ? */
380struct blackbird_dnr {
381 u32 mode;
382 u32 type;
383 u32 spatial;
384 u32 temporal;
385};
386
373struct cx8802_dev { 387struct cx8802_dev {
374 struct cx88_core *core; 388 struct cx88_core *core;
375 spinlock_t slock; 389 spinlock_t slock;
@@ -400,6 +414,10 @@ struct cx8802_dev {
400 414
401 /* for switching modulation types */ 415 /* for switching modulation types */
402 unsigned char ts_gen_cntrl; 416 unsigned char ts_gen_cntrl;
417
418 /* mpeg params */
419 struct v4l2_mpeg_compression params;
420 struct blackbird_dnr dnr_params;
403}; 421};
404 422
405/* ----------------------------------------------------------- */ 423/* ----------------------------------------------------------- */
@@ -514,22 +532,20 @@ extern void cx88_card_setup(struct cx88_core *core);
514 532
515#define WW_NONE 1 533#define WW_NONE 1
516#define WW_BTSC 2 534#define WW_BTSC 2
517#define WW_NICAM_I 3 535#define WW_BG 3
518#define WW_NICAM_BGDKL 4 536#define WW_DK 4
519#define WW_A1 5 537#define WW_I 5
520#define WW_A2_BG 6 538#define WW_L 6
521#define WW_A2_DK 7 539#define WW_EIAJ 7
522#define WW_A2_M 8 540#define WW_I2SPT 8
523#define WW_EIAJ 9 541#define WW_FM 9
524#define WW_SYSTEM_L_AM 10
525#define WW_I2SPT 11
526#define WW_FM 12
527 542
528void cx88_set_tvaudio(struct cx88_core *core); 543void cx88_set_tvaudio(struct cx88_core *core);
529void cx88_newstation(struct cx88_core *core); 544void cx88_newstation(struct cx88_core *core);
530void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t); 545void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
531void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual); 546void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual);
532int cx88_audio_thread(void *data); 547int cx88_audio_thread(void *data);
548int cx88_detect_nicam(struct cx88_core *core);
533 549
534/* ----------------------------------------------------------- */ 550/* ----------------------------------------------------------- */
535/* cx88-input.c */ 551/* cx88-input.c */
@@ -541,7 +557,8 @@ void cx88_ir_irq(struct cx88_core *core);
541/* ----------------------------------------------------------- */ 557/* ----------------------------------------------------------- */
542/* cx88-mpeg.c */ 558/* cx88-mpeg.c */
543 559
544int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf); 560int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
561 enum v4l2_field field);
545void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf); 562void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
546void cx8802_cancel_buffers(struct cx8802_dev *dev); 563void cx8802_cancel_buffers(struct cx8802_dev *dev);
547 564
@@ -562,6 +579,10 @@ extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
562extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, 579extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
563 unsigned int cmd, void *arg); 580 unsigned int cmd, void *arg);
564extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd); 581extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
582void blackbird_set_params(struct cx8802_dev *dev,
583 struct v4l2_mpeg_compression *params);
584void blackbird_set_dnr_params(struct cx8802_dev *dev,
585 struct blackbird_dnr* dnr_params);
565 586
566/* 587/*
567 * Local variables: 588 * Local variables:
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
new file mode 100644
index 000000000000..885fd0170086
--- /dev/null
+++ b/drivers/media/video/em28xx/Kconfig
@@ -0,0 +1,12 @@
1config VIDEO_EM28XX
2 tristate "Empia EM2800/2820/2840 USB video capture support"
3 depends on VIDEO_DEV && USB && I2C
4 select VIDEO_BUF
5 select VIDEO_TUNER
6 select VIDEO_TVEEPROM
7 select VIDEO_IR
8 ---help---
9 This is a video4linux driver for Empia 28xx based TV cards.
10
11 To compile this driver as a module, choose M here: the
12 module will be called em28xx
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
new file mode 100644
index 000000000000..da457a05b0dd
--- /dev/null
+++ b/drivers/media/video/em28xx/Makefile
@@ -0,0 +1,6 @@
1em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
2 em28xx-input.o
3
4obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o
5
6EXTRA_CFLAGS += -I$(src)/..
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
new file mode 100644
index 000000000000..57779e63f35d
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -0,0 +1,292 @@
1/*
2 em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/delay.h>
28#include <linux/i2c.h>
29#include <linux/usb.h>
30#include <media/tuner.h>
31#include <media/audiochip.h>
32#include <media/tveeprom.h>
33#include "msp3400.h"
34
35#include "em28xx.h"
36
37struct em28xx_board em28xx_boards[] = {
38 [EM2800_BOARD_UNKNOWN] = {
39 .name = "Unknown EM2800 video grabber",
40 .is_em2800 = 1,
41 .vchannels = 2,
42 .norm = VIDEO_MODE_PAL,
43 .tda9887_conf = TDA9887_PRESENT,
44 .has_tuner = 1,
45 .decoder = EM28XX_SAA7113,
46 .input = {{
47 .type = EM28XX_VMUX_COMPOSITE1,
48 .vmux = 0,
49 .amux = 1,
50 },{
51 .type = EM28XX_VMUX_SVIDEO,
52 .vmux = 9,
53 .amux = 1,
54 }},
55 },
56 [EM2820_BOARD_UNKNOWN] = {
57 .name = "Unknown EM2820/2840 video grabber",
58 .is_em2800 = 0,
59 .vchannels = 2,
60 .norm = VIDEO_MODE_PAL,
61 .tda9887_conf = TDA9887_PRESENT,
62 .has_tuner = 1,
63 .decoder = EM28XX_SAA7113,
64 .input = {{
65 .type = EM28XX_VMUX_COMPOSITE1,
66 .vmux = 0,
67 .amux = 1,
68 },{
69 .type = EM28XX_VMUX_SVIDEO,
70 .vmux = 9,
71 .amux = 1,
72 }},
73 },
74 [EM2820_BOARD_TERRATEC_CINERGY_250] = {
75 .name = "Terratec Cinergy 250 USB",
76 .vchannels = 3,
77 .norm = VIDEO_MODE_PAL,
78 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
79 .tda9887_conf = TDA9887_PRESENT,
80 .has_tuner = 1,
81 .decoder = EM28XX_SAA7113,
82 .input = {{
83 .type = EM28XX_VMUX_TELEVISION,
84 .vmux = 2,
85 .amux = 0,
86 },{
87 .type = EM28XX_VMUX_COMPOSITE1,
88 .vmux = 0,
89 .amux = 1,
90 },{
91 .type = EM28XX_VMUX_SVIDEO,
92 .vmux = 9,
93 .amux = 1,
94 }},
95 },
96 [EM2820_BOARD_PINNACLE_USB_2] = {
97 .name = "Pinnacle PCTV USB 2",
98 .vchannels = 3,
99 .norm = VIDEO_MODE_PAL,
100 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
101 .tda9887_conf = TDA9887_PRESENT,
102 .has_tuner = 1,
103 .decoder = EM28XX_SAA7113,
104 .input = {{
105 .type = EM28XX_VMUX_TELEVISION,
106 .vmux = 2,
107 .amux = 0,
108 },{
109 .type = EM28XX_VMUX_COMPOSITE1,
110 .vmux = 0,
111 .amux = 1,
112 },{
113 .type = EM28XX_VMUX_SVIDEO,
114 .vmux = 9,
115 .amux = 1,
116 }},
117 },
118 [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
119 .name = "Hauppauge WinTV USB 2",
120 .vchannels = 3,
121 .norm = VIDEO_MODE_NTSC,
122 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
123 .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE,
124 .has_tuner = 1,
125 .decoder = EM28XX_TVP5150,
126 .has_msp34xx = 1,
127 /*FIXME: S-Video not tested */
128 .input = {{
129 .type = EM28XX_VMUX_TELEVISION,
130 .vmux = 0,
131 .amux = 6,
132 },{
133 .type = EM28XX_VMUX_SVIDEO,
134 .vmux = 2,
135 .amux = 1,
136 }},
137 },
138 [EM2820_BOARD_MSI_VOX_USB_2] = {
139 .name = "MSI VOX USB 2.0",
140 .vchannels = 3,
141 .norm = VIDEO_MODE_PAL,
142 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
143 .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE,
144 .has_tuner = 1,
145 .decoder = EM28XX_SAA7114,
146 .input = {{
147 .type = EM28XX_VMUX_TELEVISION,
148 .vmux = 4,
149 .amux = 0,
150 },{
151 .type = EM28XX_VMUX_COMPOSITE1,
152 .vmux = 0,
153 .amux = 1,
154 },{
155 .type = EM28XX_VMUX_SVIDEO,
156 .vmux = 9,
157 .amux = 1,
158 }},
159 },
160 [EM2800_BOARD_TERRATEC_CINERGY_200] = {
161 .name = "Terratec Cinergy 200 USB",
162 .is_em2800 = 1,
163 .vchannels = 3,
164 .norm = VIDEO_MODE_PAL,
165 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
166 .tda9887_conf = TDA9887_PRESENT,
167 .has_tuner = 1,
168 .decoder = EM28XX_SAA7113,
169 .input = {{
170 .type = EM28XX_VMUX_TELEVISION,
171 .vmux = 2,
172 .amux = 0,
173 },{
174 .type = EM28XX_VMUX_COMPOSITE1,
175 .vmux = 0,
176 .amux = 1,
177 },{
178 .type = EM28XX_VMUX_SVIDEO,
179 .vmux = 9,
180 .amux = 1,
181 }},
182 },
183 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
184 .name = "Leadtek Winfast USB II",
185 .is_em2800 = 1,
186 .vchannels = 3,
187 .norm = VIDEO_MODE_PAL,
188 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
189 .tda9887_conf = TDA9887_PRESENT,
190 .has_tuner = 1,
191 .decoder = EM28XX_SAA7113,
192 .input = {{
193 .type = EM28XX_VMUX_TELEVISION,
194 .vmux = 2,
195 .amux = 0,
196 },{
197 .type = EM28XX_VMUX_COMPOSITE1,
198 .vmux = 0,
199 .amux = 1,
200 },{
201 .type = EM28XX_VMUX_SVIDEO,
202 .vmux = 9,
203 .amux = 1,
204 }},
205 },
206 [EM2800_BOARD_KWORLD_USB2800] = {
207 .name = "Kworld USB2800",
208 .is_em2800 = 1,
209 .vchannels = 3,
210 .norm = VIDEO_MODE_PAL,
211 .tuner_type = TUNER_PHILIPS_ATSC,
212 .tda9887_conf = TDA9887_PRESENT,
213 .has_tuner = 1,
214 .decoder = EM28XX_SAA7113,
215 .input = {{
216 .type = EM28XX_VMUX_TELEVISION,
217 .vmux = 2,
218 .amux = 0,
219 },{
220 .type = EM28XX_VMUX_COMPOSITE1,
221 .vmux = 0,
222 .amux = 1,
223 },{
224 .type = EM28XX_VMUX_SVIDEO,
225 .vmux = 9,
226 .amux = 1,
227 }},
228 },
229 [EM2820_BOARD_PINNACLE_DVC_90] = {
230 .name = "Pinnacle Dazzle DVC 90",
231 .vchannels = 3,
232 .norm = VIDEO_MODE_PAL,
233 .has_tuner = 0,
234 .decoder = EM28XX_SAA7113,
235 .input = {{
236 .type = EM28XX_VMUX_COMPOSITE1,
237 .vmux = 0,
238 .amux = 1,
239 },{
240 .type = EM28XX_VMUX_SVIDEO,
241 .vmux = 9,
242 .amux = 1,
243 }},
244 },
245};
246const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
247
248/* table of devices that work with this driver */
249struct usb_device_id em28xx_id_table [] = {
250 { USB_DEVICE(0xeb1a, 0x2800), .driver_info = EM2800_BOARD_UNKNOWN },
251 { USB_DEVICE(0xeb1a, 0x2820), .driver_info = EM2820_BOARD_MSI_VOX_USB_2 },
252 { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
253 { USB_DEVICE(0x2304, 0x0208), .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
254 { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
255 { USB_DEVICE(0x2304, 0x0207), .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
256 { },
257};
258
259void em28xx_card_setup(struct em28xx *dev)
260{
261 /* request some modules */
262 if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) {
263 struct tveeprom tv;
264 struct v4l2_audioout ao;
265#ifdef CONFIG_MODULES
266 request_module("tveeprom");
267 request_module("ir-kbd-i2c");
268 request_module("msp3400");
269#endif
270 /* Call first TVeeprom */
271
272 dev->i2c_client.addr = 0xa0 >> 1;
273 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
274
275 dev->tuner_type= tv.tuner_type;
276 if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
277 dev->has_msp34xx=1;
278 memset (&ao,0,sizeof(ao));
279
280 ao.index=2;
281 ao.mode=V4L2_AUDMODE_32BITS;
282 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao);
283 } else
284 dev->has_msp34xx=0;
285 }
286}
287
288EXPORT_SYMBOL(em28xx_boards);
289EXPORT_SYMBOL(em28xx_bcount);
290EXPORT_SYMBOL(em28xx_id_table);
291
292MODULE_DEVICE_TABLE (usb, em28xx_id_table);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
new file mode 100644
index 000000000000..d54bc0127484
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -0,0 +1,817 @@
1/*
2 em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/usb.h>
29#include <linux/vmalloc.h>
30
31#include "em28xx.h"
32
33/* #define ENABLE_DEBUG_ISOC_FRAMES */
34
35unsigned int core_debug;
36module_param(core_debug,int,0644);
37MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
38
39#define em28xx_coredbg(fmt, arg...) do {\
40 if (core_debug) \
41 printk(KERN_INFO "%s %s :"fmt, \
42 dev->name, __FUNCTION__ , ##arg); } while (0)
43
44unsigned int reg_debug;
45module_param(reg_debug,int,0644);
46MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
47
48#define em28xx_regdbg(fmt, arg...) do {\
49 if (reg_debug) \
50 printk(KERN_INFO "%s %s :"fmt, \
51 dev->name, __FUNCTION__ , ##arg); } while (0)
52
53unsigned int isoc_debug;
54module_param(isoc_debug,int,0644);
55MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]");
56
57#define em28xx_isocdbg(fmt, arg...) do {\
58 if (isoc_debug) \
59 printk(KERN_INFO "%s %s :"fmt, \
60 dev->name, __FUNCTION__ , ##arg); } while (0)
61
62static int alt = EM28XX_PINOUT;
63module_param(alt, int, 0644);
64MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
65
66/* ------------------------------------------------------------------ */
67/* debug help functions */
68
69static const char *v4l1_ioctls[] = {
70 "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
71 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
72 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
73 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
74 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
75#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
76
77static const char *v4l2_ioctls[] = {
78 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
79 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
80 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
81 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
82 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
83 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
84 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
85 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
86 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
87 "S_MODULATOR"
88};
89#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
90
91void em28xx_print_ioctl(char *name, unsigned int cmd)
92{
93 char *dir;
94
95 switch (_IOC_DIR(cmd)) {
96 case _IOC_NONE: dir = "--"; break;
97 case _IOC_READ: dir = "r-"; break;
98 case _IOC_WRITE: dir = "-w"; break;
99 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
100 default: dir = "??"; break;
101 }
102 switch (_IOC_TYPE(cmd)) {
103 case 'v':
104 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
105 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
106 v4l1_ioctls[_IOC_NR(cmd)] : "???");
107 break;
108 case 'V':
109 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
110 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
111 v4l2_ioctls[_IOC_NR(cmd)] : "???");
112 break;
113 default:
114 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
115 name, cmd, dir, _IOC_NR(cmd));
116 }
117}
118
119static void *rvmalloc(size_t size)
120{
121 void *mem;
122 unsigned long adr;
123
124 size = PAGE_ALIGN(size);
125
126 mem = vmalloc_32((unsigned long)size);
127 if (!mem)
128 return NULL;
129
130 memset(mem, 0, size);
131
132 adr = (unsigned long)mem;
133 while (size > 0) {
134 SetPageReserved(vmalloc_to_page((void *)adr));
135 adr += PAGE_SIZE;
136 size -= PAGE_SIZE;
137 }
138
139 return mem;
140}
141
142static void rvfree(void *mem, size_t size)
143{
144 unsigned long adr;
145
146 if (!mem)
147 return;
148
149 size = PAGE_ALIGN(size);
150
151 adr = (unsigned long)mem;
152 while (size > 0) {
153 ClearPageReserved(vmalloc_to_page((void *)adr));
154 adr += PAGE_SIZE;
155 size -= PAGE_SIZE;
156 }
157
158 vfree(mem);
159}
160
161/*
162 * em28xx_request_buffers()
163 * allocate a number of buffers
164 */
165u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
166{
167 const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */
168 void *buff = NULL;
169 u32 i;
170 em28xx_coredbg("requested %i buffers with size %i", count, imagesize);
171 if (count > EM28XX_NUM_FRAMES)
172 count = EM28XX_NUM_FRAMES;
173
174 dev->num_frames = count;
175 while (dev->num_frames > 0) {
176 if ((buff = rvmalloc(dev->num_frames * imagesize)))
177 break;
178 dev->num_frames--;
179 }
180
181 for (i = 0; i < dev->num_frames; i++) {
182 dev->frame[i].bufmem = buff + i * imagesize;
183 dev->frame[i].buf.index = i;
184 dev->frame[i].buf.m.offset = i * imagesize;
185 dev->frame[i].buf.length = dev->frame_size;
186 dev->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
187 dev->frame[i].buf.sequence = 0;
188 dev->frame[i].buf.field = V4L2_FIELD_NONE;
189 dev->frame[i].buf.memory = V4L2_MEMORY_MMAP;
190 dev->frame[i].buf.flags = 0;
191 }
192 return dev->num_frames;
193}
194
195/*
196 * em28xx_queue_unusedframes()
197 * add all frames that are not currently in use to the inbuffer queue
198 */
199void em28xx_queue_unusedframes(struct em28xx *dev)
200{
201 unsigned long lock_flags;
202 u32 i;
203
204 for (i = 0; i < dev->num_frames; i++)
205 if (dev->frame[i].state == F_UNUSED) {
206 dev->frame[i].state = F_QUEUED;
207 spin_lock_irqsave(&dev->queue_lock, lock_flags);
208 list_add_tail(&dev->frame[i].frame, &dev->inqueue);
209 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
210 }
211}
212
213/*
214 * em28xx_release_buffers()
215 * free frame buffers
216 */
217void em28xx_release_buffers(struct em28xx *dev)
218{
219 if (dev->num_frames) {
220 rvfree(dev->frame[0].bufmem,
221 dev->num_frames * PAGE_ALIGN(dev->frame[0].buf.length));
222 dev->num_frames = 0;
223 }
224}
225
226/*
227 * em28xx_read_reg_req()
228 * reads data from the usb device specifying bRequest
229 */
230int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
231 char *buf, int len)
232{
233 int ret, byte;
234
235 em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
236
237 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
238 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
239 0x0000, reg, buf, len, HZ);
240
241 if (reg_debug){
242 printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
243 for (byte = 0; byte < len; byte++) {
244 printk(" %02x", buf[byte]);
245 }
246 printk("\n");
247 }
248
249 return ret;
250}
251
252/*
253 * em28xx_read_reg_req()
254 * reads data from the usb device specifying bRequest
255 */
256int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
257{
258 u8 val;
259 int ret;
260
261 em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
262
263 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
264 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
265 0x0000, reg, &val, 1, HZ);
266
267 if (reg_debug)
268 printk(ret < 0 ? " failed!\n" : "%02x\n", val);
269
270 if (ret < 0)
271 return ret;
272
273 return val;
274}
275
276int em28xx_read_reg(struct em28xx *dev, u16 reg)
277{
278 return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg);
279}
280
281/*
282 * em28xx_write_regs_req()
283 * sends data to the usb device, specifying bRequest
284 */
285int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
286 int len)
287{
288 int ret;
289
290 /*usb_control_msg seems to expect a kmalloced buffer */
291 unsigned char *bufs = kmalloc(len, GFP_KERNEL);
292
293 em28xx_regdbg("req=%02x reg=%02x:", req, reg);
294
295 if (reg_debug) {
296 int i;
297 for (i = 0; i < len; ++i)
298 printk (" %02x", (unsigned char)buf[i]);
299 printk ("\n");
300 }
301
302 if (!bufs)
303 return -ENOMEM;
304 memcpy(bufs, buf, len);
305 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
306 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
307 0x0000, reg, bufs, len, HZ);
308 mdelay(5); /* FIXME: magic number */
309 kfree(bufs);
310 return ret;
311}
312
313int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
314{
315 return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
316}
317
318/*
319 * em28xx_write_reg_bits()
320 * sets only some bits (specified by bitmask) of a register, by first reading
321 * the actual value
322 */
323int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
324 u8 bitmask)
325{
326 int oldval;
327 u8 newval;
328 if ((oldval = em28xx_read_reg(dev, reg)) < 0)
329 return oldval;
330 newval = (((u8) oldval) & ~bitmask) | (val & bitmask);
331 return em28xx_write_regs(dev, reg, &newval, 1);
332}
333
334/*
335 * em28xx_write_ac97()
336 * write a 16 bit value to the specified AC97 address (LSB first!)
337 */
338int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
339{
340 int ret;
341 u8 addr = reg & 0x7f;
342 if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
343 return ret;
344 if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
345 return ret;
346 if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
347 return ret;
348 else if (((u8) ret) & 0x01) {
349 em28xx_warn ("AC97 command still being exectuted: not handled properly!\n");
350 }
351 return 0;
352}
353
354int em28xx_audio_analog_set(struct em28xx *dev)
355{
356 char s[2] = { 0x00, 0x00 };
357 s[0] |= 0x1f - dev->volume;
358 s[1] |= 0x1f - dev->volume;
359 if (dev->mute)
360 s[1] |= 0x80;
361 return em28xx_write_ac97(dev, MASTER_AC97, s);
362}
363
364
365int em28xx_colorlevels_set_default(struct em28xx *dev)
366{
367 em28xx_write_regs(dev, YGAIN_REG, "\x10", 1); /* contrast */
368 em28xx_write_regs(dev, YOFFSET_REG, "\x00", 1); /* brightness */
369 em28xx_write_regs(dev, UVGAIN_REG, "\x10", 1); /* saturation */
370 em28xx_write_regs(dev, UOFFSET_REG, "\x00", 1);
371 em28xx_write_regs(dev, VOFFSET_REG, "\x00", 1);
372 em28xx_write_regs(dev, SHARPNESS_REG, "\x00", 1);
373
374 em28xx_write_regs(dev, GAMMA_REG, "\x20", 1);
375 em28xx_write_regs(dev, RGAIN_REG, "\x20", 1);
376 em28xx_write_regs(dev, GGAIN_REG, "\x20", 1);
377 em28xx_write_regs(dev, BGAIN_REG, "\x20", 1);
378 em28xx_write_regs(dev, ROFFSET_REG, "\x00", 1);
379 em28xx_write_regs(dev, GOFFSET_REG, "\x00", 1);
380 return em28xx_write_regs(dev, BOFFSET_REG, "\x00", 1);
381}
382
383int em28xx_capture_start(struct em28xx *dev, int start)
384{
385 int ret;
386 /* FIXME: which is the best order? */
387 /* video registers are sampled by VREF */
388 if ((ret = em28xx_write_reg_bits(dev, USBSUSP_REG, start ? 0x10 : 0x00,
389 0x10)) < 0)
390 return ret;
391 /* enable video capture */
392 return em28xx_write_regs(dev, VINENABLE_REG, start ? "\x67" : "\x27", 1);
393}
394
395int em28xx_outfmt_set_yuv422(struct em28xx *dev)
396{
397 em28xx_write_regs(dev, OUTFMT_REG, "\x34", 1);
398 em28xx_write_regs(dev, VINMODE_REG, "\x10", 1);
399 return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1);
400}
401
402int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
403 u8 ymax)
404{
405 em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax);
406
407 em28xx_write_regs(dev, XMIN_REG, &xmin, 1);
408 em28xx_write_regs(dev, XMAX_REG, &xmax, 1);
409 em28xx_write_regs(dev, YMIN_REG, &ymin, 1);
410 return em28xx_write_regs(dev, YMAX_REG, &ymax, 1);
411}
412
413int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
414 u16 width, u16 height)
415{
416 u8 cwidth = width;
417 u8 cheight = height;
418 u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01);
419
420 em28xx_coredbg("em28xx Area Set: (%d,%d)\n", (width | (overflow & 2) << 7),
421 (height | (overflow & 1) << 8));
422
423 em28xx_write_regs(dev, HSTART_REG, &hstart, 1);
424 em28xx_write_regs(dev, VSTART_REG, &vstart, 1);
425 em28xx_write_regs(dev, CWIDTH_REG, &cwidth, 1);
426 em28xx_write_regs(dev, CHEIGHT_REG, &cheight, 1);
427 return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1);
428}
429
430int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
431{
432 u8 mode;
433 /* the em2800 scaler only supports scaling down to 50% */
434 if(dev->is_em2800)
435 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
436 else {
437 u8 buf[2];
438 buf[0] = h;
439 buf[1] = h >> 8;
440 em28xx_write_regs(dev, HSCALELOW_REG, (char *)buf, 2);
441 buf[0] = v;
442 buf[1] = v >> 8;
443 em28xx_write_regs(dev, VSCALELOW_REG, (char *)buf, 2);
444 /* it seems that both H and V scalers must be active to work correctly */
445 mode = (h || v)? 0x30: 0x00;
446 }
447 return em28xx_write_reg_bits(dev, COMPR_REG, mode, 0x30);
448}
449
450/* FIXME: this only function read values from dev */
451int em28xx_resolution_set(struct em28xx *dev)
452{
453 int width, height;
454 width = norm_maxw(dev);
455 height = norm_maxh(dev) >> 1;
456
457 em28xx_outfmt_set_yuv422(dev);
458 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
459 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
460 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
461}
462
463
464/******************* isoc transfer handling ****************************/
465
466#ifdef ENABLE_DEBUG_ISOC_FRAMES
467static void em28xx_isoc_dump(struct urb *urb, struct pt_regs *regs)
468{
469 int len = 0;
470 int ntrans = 0;
471 int i;
472
473 printk(KERN_DEBUG "isocIrq: sf=%d np=%d ec=%x\n",
474 urb->start_frame, urb->number_of_packets,
475 urb->error_count);
476 for (i = 0; i < urb->number_of_packets; i++) {
477 unsigned char *buf =
478 urb->transfer_buffer +
479 urb->iso_frame_desc[i].offset;
480 int alen = urb->iso_frame_desc[i].actual_length;
481 if (alen > 0) {
482 if (buf[0] == 0x88) {
483 ntrans++;
484 len += alen;
485 } else if (buf[0] == 0x22) {
486 printk(KERN_DEBUG
487 "= l=%d nt=%d bpp=%d\n",
488 len - 4 * ntrans, ntrans,
489 ntrans == 0 ? 0 : len / ntrans);
490 ntrans = 1;
491 len = alen;
492 } else
493 printk(KERN_DEBUG "!\n");
494 }
495 printk(KERN_DEBUG " n=%d s=%d al=%d %x\n", i,
496 urb->iso_frame_desc[i].status,
497 urb->iso_frame_desc[i].actual_length,
498 (unsigned int)
499 *((unsigned char *)(urb->transfer_buffer +
500 urb->iso_frame_desc[i].
501 offset)));
502 }
503}
504#endif
505
506static inline int em28xx_isoc_video(struct em28xx *dev,struct em28xx_frame_t **f,
507 unsigned long *lock_flags, unsigned char buf)
508{
509 if (!(buf & 0x01)) {
510 if ((*f)->state == F_GRABBING) {
511 /*previous frame is incomplete */
512 if ((*f)->fieldbytesused < dev->field_size) {
513 (*f)->state = F_ERROR;
514 em28xx_isocdbg ("dropping incomplete bottom field (%i missing bytes)",
515 dev->field_size-(*f)->fieldbytesused);
516 } else {
517 (*f)->state = F_DONE;
518 (*f)->buf.bytesused = dev->frame_size;
519 }
520 }
521 if ((*f)->state == F_DONE || (*f)->state == F_ERROR) {
522 /* move current frame to outqueue and get next free buffer from inqueue */
523 spin_lock_irqsave(&dev-> queue_lock, *lock_flags);
524 list_move_tail(&(*f)->frame, &dev->outqueue);
525 if (!list_empty(&dev->inqueue))
526 (*f) = list_entry(dev-> inqueue.next,
527 struct em28xx_frame_t,frame);
528 else
529 (*f) = NULL;
530 spin_unlock_irqrestore(&dev->queue_lock,*lock_flags);
531 }
532 if (!(*f)) {
533 em28xx_isocdbg ("new frame but no buffer is free");
534 return -1;
535 }
536 do_gettimeofday(&(*f)->buf.timestamp);
537 (*f)->buf.sequence = ++dev->frame_count;
538 (*f)->buf.field = V4L2_FIELD_INTERLACED;
539 (*f)->state = F_GRABBING;
540 (*f)->buf.bytesused = 0;
541 (*f)->top_field = 1;
542 (*f)->fieldbytesused = 0;
543 } else {
544 /* acquiring bottom field */
545 if ((*f)->state == F_GRABBING) {
546 if (!(*f)->top_field) {
547 (*f)->state = F_ERROR;
548 em28xx_isocdbg ("unexpected begin of bottom field; discarding it");
549 } else if ((*f)-> fieldbytesused < dev->field_size - 172) {
550 (*f)->state = F_ERROR;
551 em28xx_isocdbg ("dropping incomplete top field (%i missing bytes)",
552 dev->field_size-(*f)->fieldbytesused);
553 } else {
554 (*f)->top_field = 0;
555 (*f)->fieldbytesused = 0;
556 }
557 }
558 }
559 return (0);
560}
561
562static inline void em28xx_isoc_video_copy(struct em28xx *dev,
563 struct em28xx_frame_t **f, unsigned char *buf, int len)
564{
565 void *fieldstart, *startwrite, *startread;
566 int linesdone, currlinedone, offset, lencopy,remain;
567
568 if(dev->frame_size != (*f)->buf.length){
569 em28xx_err("frame_size %i and buf.length %i are different!!!\n",dev->frame_size,(*f)->buf.length);
570 return;
571 }
572
573 if ((*f)->fieldbytesused + len > dev->field_size)
574 len =dev->field_size - (*f)->fieldbytesused;
575
576 if (buf[0] != 0x88 && buf[0] != 0x22) {
577 em28xx_isocdbg("frame is not complete\n");
578 startread = buf;
579 len+=4;
580 } else
581 startread = buf + 4;
582
583 remain = len;
584
585 if ((*f)->top_field)
586 fieldstart = (*f)->bufmem;
587 else
588 fieldstart = (*f)->bufmem + dev->bytesperline;
589
590 linesdone = (*f)->fieldbytesused / dev->bytesperline;
591 currlinedone = (*f)->fieldbytesused % dev->bytesperline;
592 offset = linesdone * dev->bytesperline * 2 + currlinedone;
593 startwrite = fieldstart + offset;
594 lencopy = dev->bytesperline - currlinedone;
595 lencopy = lencopy > remain ? remain : lencopy;
596
597 memcpy(startwrite, startread, lencopy);
598 remain -= lencopy;
599
600 while (remain > 0) {
601 startwrite += lencopy + dev->bytesperline;
602 startread += lencopy;
603 if (dev->bytesperline > remain)
604 lencopy = remain;
605 else
606 lencopy = dev->bytesperline;
607
608 memcpy(startwrite, startread, lencopy);
609 remain -= lencopy;
610 }
611
612 (*f)->fieldbytesused += len;
613}
614
615/*
616 * em28xx_isoIrq()
617 * handles the incoming isoc urbs and fills the frames from our inqueue
618 */
619void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs)
620{
621 struct em28xx *dev = urb->context;
622 int i, status;
623 struct em28xx_frame_t **f;
624 unsigned long lock_flags;
625
626 if (!dev)
627 return;
628#ifdef ENABLE_DEBUG_ISOC_FRAMES
629 if (isoc_debug>1)
630 em28xx_isoc_dump(urb, regs);
631#endif
632
633 if (urb->status == -ENOENT)
634 return;
635
636 f = &dev->frame_current;
637
638 if (dev->stream == STREAM_INTERRUPT) {
639 dev->stream = STREAM_OFF;
640 if ((*f))
641 (*f)->state = F_QUEUED;
642 em28xx_isocdbg("stream interrupted");
643 wake_up_interruptible(&dev->wait_stream);
644 }
645
646 if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
647 return;
648
649 if (dev->stream == STREAM_ON && !list_empty(&dev->inqueue)) {
650 if (!(*f))
651 (*f) = list_entry(dev->inqueue.next,
652 struct em28xx_frame_t, frame);
653
654 for (i = 0; i < urb->number_of_packets; i++) {
655 unsigned char *buf = urb->transfer_buffer +
656 urb->iso_frame_desc[i].offset;
657 int len = urb->iso_frame_desc[i].actual_length - 4;
658
659 if (urb->iso_frame_desc[i].status) {
660 em28xx_isocdbg("data error: [%d] len=%d, status=%d", i,
661 urb->iso_frame_desc[i].actual_length,
662 urb->iso_frame_desc[i].status);
663 if (urb->iso_frame_desc[i].status != -EPROTO)
664 continue;
665 }
666 if (urb->iso_frame_desc[i].actual_length <= 0) {
667 em28xx_isocdbg("packet %d is empty",i);
668 continue;
669 }
670 if (urb->iso_frame_desc[i].actual_length >
671 dev->max_pkt_size) {
672 em28xx_isocdbg("packet bigger than packet size");
673 continue;
674 }
675 /*new frame */
676 if (buf[0] == 0x22 && buf[1] == 0x5a) {
677 em28xx_isocdbg("Video frame, length=%i!",len);
678
679 if (em28xx_isoc_video(dev,f,&lock_flags,buf[2]))
680 break;
681 } else if (buf[0]==0x33 && buf[1]==0x95 && buf[2]==0x00) {
682 em28xx_isocdbg("VBI HEADER!!!");
683 }
684
685 /* actual copying */
686 if ((*f)->state == F_GRABBING) {
687 em28xx_isoc_video_copy(dev,f,buf, len);
688 }
689 }
690 }
691
692 for (i = 0; i < urb->number_of_packets; i++) {
693 urb->iso_frame_desc[i].status = 0;
694 urb->iso_frame_desc[i].actual_length = 0;
695 }
696
697 urb->status = 0;
698 if ((status = usb_submit_urb(urb, GFP_ATOMIC))) {
699 em28xx_errdev("resubmit of urb failed (error=%i)\n", status);
700 dev->state |= DEV_MISCONFIGURED;
701 }
702 wake_up_interruptible(&dev->wait_frame);
703 return;
704}
705
706/*
707 * em28xx_uninit_isoc()
708 * deallocates the buffers and urbs allocated during em28xx_init_iosc()
709 */
710void em28xx_uninit_isoc(struct em28xx *dev)
711{
712 int i;
713
714 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
715 if (dev->urb[i]) {
716 usb_kill_urb(dev->urb[i]);
717 if (dev->transfer_buffer[i]){
718 usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma);
719 }
720 usb_free_urb(dev->urb[i]);
721 }
722 dev->urb[i] = NULL;
723 dev->transfer_buffer[i] = NULL;
724 }
725 em28xx_capture_start(dev, 0);
726}
727
728/*
729 * em28xx_init_isoc()
730 * allocates transfer buffers and submits the urbs for isoc transfer
731 */
732int em28xx_init_isoc(struct em28xx *dev)
733{
734 /* change interface to 3 which allowes the biggest packet sizes */
735 int i, errCode;
736 const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
737
738 /* reset streaming vars */
739 dev->frame_current = NULL;
740 dev->frame_count = 0;
741
742 /* allocate urbs */
743 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
744 struct urb *urb;
745 int j, k;
746 /* allocate transfer buffer */
747 urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL);
748 if (!urb){
749 em28xx_errdev("cannot alloc urb %i\n", i);
750 em28xx_uninit_isoc(dev);
751 return -ENOMEM;
752 }
753 dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma);
754 if (!dev->transfer_buffer[i]) {
755 em28xx_errdev
756 ("unable to allocate %i bytes for transfer buffer %i\n",
757 sb_size, i);
758 em28xx_uninit_isoc(dev);
759 return -ENOMEM;
760 }
761 memset(dev->transfer_buffer[i], 0, sb_size);
762 urb->dev = dev->udev;
763 urb->context = dev;
764 urb->pipe = usb_rcvisocpipe(dev->udev, 0x82);
765 urb->transfer_flags = URB_ISO_ASAP;
766 urb->interval = 1;
767 urb->transfer_buffer = dev->transfer_buffer[i];
768 urb->complete = em28xx_isocIrq;
769 urb->number_of_packets = EM28XX_NUM_PACKETS;
770 urb->transfer_buffer_length = sb_size;
771 for (j = k = 0; j < EM28XX_NUM_PACKETS;
772 j++, k += dev->max_pkt_size) {
773 urb->iso_frame_desc[j].offset = k;
774 urb->iso_frame_desc[j].length =
775 dev->max_pkt_size;
776 }
777 dev->urb[i] = urb;
778 }
779
780 /* submit urbs */
781 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
782 errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL);
783 if (errCode) {
784 em28xx_errdev("submit of urb %i failed (error=%i)\n", i,
785 errCode);
786 em28xx_uninit_isoc(dev);
787 return errCode;
788 }
789 }
790
791 return 0;
792}
793
794int em28xx_set_alternate(struct em28xx *dev)
795{
796 int errCode, prev_alt = dev->alt;
797 dev->alt = alt;
798 if (dev->alt == 0) {
799 int i;
800 for(i=0;i< dev->num_alt; i++)
801 if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
802 dev->alt=i;
803 }
804
805 if (dev->alt != prev_alt) {
806 dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
807 em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt,
808 dev->max_pkt_size);
809 errCode = usb_set_interface(dev->udev, 0, dev->alt);
810 if (errCode < 0) {
811 em28xx_errdev ("cannot change alternate number to %d (error=%i)\n",
812 dev->alt, errCode);
813 return errCode;
814 }
815 }
816 return 0;
817}
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
new file mode 100644
index 000000000000..b32d9852f34c
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -0,0 +1,586 @@
1/*
2 em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/usb.h>
27#include <linux/i2c.h>
28#include <linux/video_decoder.h>
29
30#include "em28xx.h"
31#include <media/tuner.h>
32
33/* ----------------------------------------------------------- */
34
35static unsigned int i2c_scan = 0;
36module_param(i2c_scan, int, 0444);
37MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
38
39static unsigned int i2c_debug = 0;
40module_param(i2c_debug, int, 0644);
41MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
42
43#define dprintk1(lvl,fmt, args...) if (i2c_debug>=lvl) do {\
44 printk(fmt , ##args); } while (0)
45#define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \
46 printk(KERN_DEBUG "%s at %s: " fmt, \
47 dev->name, __FUNCTION__ , ##args); } while (0)
48
49/*
50 * em2800_i2c_send_max4()
51 * send up to 4 bytes to the i2c device
52 */
53static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr,
54 char *buf, int len)
55{
56 int ret;
57 int write_timeout;
58 unsigned char b2[6];
59 BUG_ON(len < 1 || len > 4);
60 b2[5] = 0x80 + len - 1;
61 b2[4] = addr;
62 b2[3] = buf[0];
63 if (len > 1)
64 b2[2] = buf[1];
65 if (len > 2)
66 b2[1] = buf[2];
67 if (len > 3)
68 b2[0] = buf[3];
69
70 ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len);
71 if (ret != 2 + len) {
72 em28xx_warn("writting to i2c device failed (error=%i)\n", ret);
73 return -EIO;
74 }
75 for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
76 write_timeout -= 5) {
77 ret = dev->em28xx_read_reg(dev, 0x05);
78 if (ret == 0x80 + len - 1)
79 return len;
80 mdelay(5);
81 }
82 em28xx_warn("i2c write timed out\n");
83 return -EIO;
84}
85
86/*
87 * em2800_i2c_send_bytes()
88 */
89static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf,
90 short len)
91{
92 char *bufPtr = buf;
93 int ret;
94 int wrcount = 0;
95 int count;
96 int maxLen = 4;
97 struct em28xx *dev = (struct em28xx *)data;
98 while (len > 0) {
99 count = (len > maxLen) ? maxLen : len;
100 ret = em2800_i2c_send_max4(dev, addr, bufPtr, count);
101 if (ret > 0) {
102 len -= count;
103 bufPtr += count;
104 wrcount += count;
105 } else
106 return (ret < 0) ? ret : -EFAULT;
107 }
108 return wrcount;
109}
110
111/*
112 * em2800_i2c_check_for_device()
113 * check if there is a i2c_device at the supplied address
114 */
115static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
116{
117 char msg;
118 int ret;
119 int write_timeout;
120 msg = addr;
121 ret = dev->em28xx_write_regs(dev, 0x04, &msg, 1);
122 if (ret < 0) {
123 em28xx_warn("setting i2c device address failed (error=%i)\n",
124 ret);
125 return ret;
126 }
127 msg = 0x84;
128 ret = dev->em28xx_write_regs(dev, 0x05, &msg, 1);
129 if (ret < 0) {
130 em28xx_warn("preparing i2c read failed (error=%i)\n", ret);
131 return ret;
132 }
133 for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
134 write_timeout -= 5) {
135 unsigned msg = dev->em28xx_read_reg(dev, 0x5);
136 if (msg == 0x94)
137 return -ENODEV;
138 else if (msg == 0x84)
139 return 0;
140 mdelay(5);
141 }
142 return -ENODEV;
143}
144
145/*
146 * em2800_i2c_recv_bytes()
147 * read from the i2c device
148 */
149static int em2800_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
150 char *buf, int len)
151{
152 int ret;
153 /* check for the device and set i2c read address */
154 ret = em2800_i2c_check_for_device(dev, addr);
155 if (ret) {
156 em28xx_warn
157 ("preparing read at i2c address 0x%x failed (error=%i)\n",
158 addr, ret);
159 return ret;
160 }
161 ret = dev->em28xx_read_reg_req_len(dev, 0x0, 0x3, buf, len);
162 if (ret < 0) {
163 em28xx_warn("reading from i2c device at 0x%x failed (error=%i)",
164 addr, ret);
165 return ret;
166 }
167 return ret;
168}
169
170/*
171 * em28xx_i2c_send_bytes()
172 * untested for more than 4 bytes
173 */
174static int em28xx_i2c_send_bytes(void *data, unsigned char addr, char *buf,
175 short len, int stop)
176{
177 int wrcount = 0;
178 struct em28xx *dev = (struct em28xx *)data;
179
180 wrcount = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len);
181
182 return wrcount;
183}
184
185/*
186 * em28xx_i2c_recv_bytes()
187 * read a byte from the i2c device
188 */
189static int em28xx_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
190 char *buf, int len)
191{
192 int ret;
193 ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);
194 if (ret < 0) {
195 em28xx_warn("reading i2c device failed (error=%i)\n", ret);
196 return ret;
197 }
198 if (dev->em28xx_read_reg(dev, 0x5) != 0)
199 return -ENODEV;
200 return ret;
201}
202
203/*
204 * em28xx_i2c_check_for_device()
205 * check if there is a i2c_device at the supplied address
206 */
207static int em28xx_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
208{
209 char msg;
210 int ret;
211 msg = addr;
212
213 ret = dev->em28xx_read_reg_req(dev, 2, addr);
214 if (ret < 0) {
215 em28xx_warn("reading from i2c device failed (error=%i)\n", ret);
216 return ret;
217 }
218 if (dev->em28xx_read_reg(dev, 0x5) != 0)
219 return -ENODEV;
220 return 0;
221}
222
223/*
224 * em28xx_i2c_xfer()
225 * the main i2c transfer function
226 */
227static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
228 struct i2c_msg msgs[], int num)
229{
230 struct em28xx *dev = i2c_adap->algo_data;
231 int addr, rc, i, byte;
232
233 if (num <= 0)
234 return 0;
235 for (i = 0; i < num; i++) {
236 addr = msgs[i].addr << 1;
237 dprintk2(2,"%s %s addr=%x len=%d:",
238 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
239 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
240 if (!msgs[i].len) { /* no len: check only for device presence */
241 if (dev->is_em2800)
242 rc = em2800_i2c_check_for_device(dev, addr);
243 else
244 rc = em28xx_i2c_check_for_device(dev, addr);
245 if (rc < 0) {
246 dprintk2(2," no device\n");
247 return rc;
248 }
249
250 } else if (msgs[i].flags & I2C_M_RD) {
251 /* read bytes */
252 if (dev->is_em2800)
253 rc = em2800_i2c_recv_bytes(dev, addr,
254 msgs[i].buf,
255 msgs[i].len);
256 else
257 rc = em28xx_i2c_recv_bytes(dev, addr,
258 msgs[i].buf,
259 msgs[i].len);
260 if (i2c_debug>=2) {
261 for (byte = 0; byte < msgs[i].len; byte++) {
262 printk(" %02x", msgs[i].buf[byte]);
263 }
264 }
265 } else {
266 /* write bytes */
267 if (i2c_debug>=2) {
268 for (byte = 0; byte < msgs[i].len; byte++)
269 printk(" %02x", msgs[i].buf[byte]);
270 }
271 if (dev->is_em2800)
272 rc = em2800_i2c_send_bytes(dev, addr,
273 msgs[i].buf,
274 msgs[i].len);
275 else
276 rc = em28xx_i2c_send_bytes(dev, addr,
277 msgs[i].buf,
278 msgs[i].len,
279 i == num - 1);
280 if (rc < 0)
281 goto err;
282 }
283 if (i2c_debug>=2)
284 printk("\n");
285 }
286
287 return num;
288 err:
289 dprintk2(2," ERROR: %i\n", rc);
290 return rc;
291}
292
293static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
294{
295 unsigned char buf, *p = eedata;
296 struct em28xx_eeprom *em_eeprom = (void *)eedata;
297 int i, err, size = len, block;
298
299 dev->i2c_client.addr = 0xa0 >> 1;
300
301 /* Check if board has eeprom */
302 err = i2c_master_recv(&dev->i2c_client, &buf, 0);
303 if (err < 0)
304 return -1;
305
306 buf = 0;
307 if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) {
308 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
309 dev->name, err);
310 return -1;
311 }
312 while (size > 0) {
313 if (size > 16)
314 block = 16;
315 else
316 block = size;
317
318 if (block !=
319 (err = i2c_master_recv(&dev->i2c_client, p, block))) {
320 printk(KERN_WARNING
321 "%s: i2c eeprom read error (err=%d)\n",
322 dev->name, err);
323 return -1;
324 }
325 size -= block;
326 p += block;
327 }
328 for (i = 0; i < len; i++) {
329 if (0 == (i % 16))
330 printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
331 printk(" %02x", eedata[i]);
332 if (15 == (i % 16))
333 printk("\n");
334 }
335
336 printk(KERN_INFO "EEPROM ID= 0x%08x\n", em_eeprom->id);
337 printk(KERN_INFO "Vendor/Product ID= %04x:%04x\n", em_eeprom->vendor_ID,
338 em_eeprom->product_ID);
339
340 switch (em_eeprom->chip_conf >> 4 & 0x3) {
341 case 0:
342 printk(KERN_INFO "No audio on board.\n");
343 break;
344 case 1:
345 printk(KERN_INFO "AC97 audio (5 sample rates)\n");
346 break;
347 case 2:
348 printk(KERN_INFO "I2S audio, sample rate=32k\n");
349 break;
350 case 3:
351 printk(KERN_INFO "I2S audio, 3 sample rates\n");
352 break;
353 }
354
355 if (em_eeprom->chip_conf & 1 << 3)
356 printk(KERN_INFO "USB Remote wakeup capable\n");
357
358 if (em_eeprom->chip_conf & 1 << 2)
359 printk(KERN_INFO "USB Self power capable\n");
360
361 switch (em_eeprom->chip_conf & 0x3) {
362 case 0:
363 printk(KERN_INFO "500mA max power\n");
364 break;
365 case 1:
366 printk(KERN_INFO "400mA max power\n");
367 break;
368 case 2:
369 printk(KERN_INFO "300mA max power\n");
370 break;
371 case 3:
372 printk(KERN_INFO "200mA max power\n");
373 break;
374 }
375 printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n",
376 em_eeprom->string_idx_table,em_eeprom->string1,
377 em_eeprom->string2,em_eeprom->string3);
378
379 return 0;
380}
381
382/* ----------------------------------------------------------- */
383
384/*
385 * algo_control()
386 */
387static int algo_control(struct i2c_adapter *adapter,
388 unsigned int cmd, unsigned long arg)
389{
390 return 0;
391}
392
393/*
394 * functionality()
395 */
396static u32 functionality(struct i2c_adapter *adap)
397{
398 return I2C_FUNC_SMBUS_EMUL;
399}
400
401#ifndef I2C_PEC
402static void inc_use(struct i2c_adapter *adap)
403{
404 MOD_INC_USE_COUNT;
405}
406
407static void dec_use(struct i2c_adapter *adap)
408{
409 MOD_DEC_USE_COUNT;
410}
411#endif
412
413static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client)
414{
415 struct em28xx *dev = client->adapter->algo_data;
416 struct tuner_setup tun_setup;
417
418 if (dev->has_tuner) {
419 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
420 tun_setup.type = dev->tuner_type;
421 tun_setup.addr = dev->tuner_addr;
422
423 em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
424 }
425
426 return (0);
427}
428
429/*
430 * attach_inform()
431 * gets called when a device attaches to the i2c bus
432 * does some basic configuration
433 */
434static int attach_inform(struct i2c_client *client)
435{
436 struct em28xx *dev = client->adapter->algo_data;
437
438 switch (client->addr << 1) {
439 case 0x86:
440 em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf);
441 break;
442 case 0x42:
443 dprintk1(1,"attach_inform: saa7114 detected.\n");
444 break;
445 case 0x4a:
446 dprintk1(1,"attach_inform: saa7113 detected.\n");
447 break;
448 case 0xa0:
449 dprintk1(1,"attach_inform: eeprom detected.\n");
450 break;
451 case 0x60:
452 case 0x8e:
453 {
454 struct IR_i2c *ir = i2c_get_clientdata(client);
455 dprintk1(1,"attach_inform: IR detected (%s).\n",ir->phys);
456 em28xx_set_ir(dev,ir);
457 break;
458 }
459 case 0x80:
460 case 0x88:
461 dprintk1(1,"attach_inform: msp34xx detected.\n");
462 break;
463 case 0xb8:
464 case 0xba:
465 dprintk1(1,"attach_inform: tvp5150 detected.\n");
466 break;
467 default:
468 dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1);
469 dev->tuner_addr = client->addr;
470 em28xx_set_tuner(-1, client);
471 }
472
473 return 0;
474}
475
476static struct i2c_algorithm em28xx_algo = {
477 .master_xfer = em28xx_i2c_xfer,
478 .algo_control = algo_control,
479 .functionality = functionality,
480};
481
482static struct i2c_adapter em28xx_adap_template = {
483#ifdef I2C_PEC
484 .owner = THIS_MODULE,
485#else
486 .inc_use = inc_use,
487 .dec_use = dec_use,
488#endif
489#ifdef I2C_CLASS_TV_ANALOG
490 .class = I2C_CLASS_TV_ANALOG,
491#endif
492 .name = "em28xx",
493 .id = I2C_HW_B_EM28XX,
494 .algo = &em28xx_algo,
495 .client_register = attach_inform,
496};
497
498static struct i2c_client em28xx_client_template = {
499 .name = "em28xx internal",
500 .flags = I2C_CLIENT_ALLOW_USE,
501};
502
503/* ----------------------------------------------------------- */
504
505/*
506 * i2c_devs
507 * incomplete list of known devices
508 */
509static char *i2c_devs[128] = {
510 [0x4a >> 1] = "saa7113h",
511 [0x60 >> 1] = "remote IR sensor",
512 [0x8e >> 1] = "remote IR sensor",
513 [0x86 >> 1] = "tda9887",
514 [0x80 >> 1] = "msp34xx",
515 [0x88 >> 1] = "msp34xx",
516 [0xa0 >> 1] = "eeprom",
517 [0xb8 >> 1] = "tvp5150a",
518 [0xba >> 1] = "tvp5150a",
519 [0xc0 >> 1] = "tuner (analog)",
520 [0xc2 >> 1] = "tuner (analog)",
521 [0xc4 >> 1] = "tuner (analog)",
522 [0xc6 >> 1] = "tuner (analog)",
523};
524
525/*
526 * do_i2c_scan()
527 * check i2c address range for devices
528 */
529static void do_i2c_scan(char *name, struct i2c_client *c)
530{
531 unsigned char buf;
532 int i, rc;
533
534 for (i = 0; i < 128; i++) {
535 c->addr = i;
536 rc = i2c_master_recv(c, &buf, 0);
537 if (rc < 0)
538 continue;
539 printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", name,
540 i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
541 }
542}
543
544/*
545 * em28xx_i2c_call_clients()
546 * send commands to all attached i2c devices
547 */
548void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg)
549{
550 BUG_ON(NULL == dev->i2c_adap.algo_data);
551 i2c_clients_command(&dev->i2c_adap, cmd, arg);
552}
553
554/*
555 * em28xx_i2c_register()
556 * register i2c bus
557 */
558int em28xx_i2c_register(struct em28xx *dev)
559{
560 BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg);
561 BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req);
562 dev->i2c_adap = em28xx_adap_template;
563 dev->i2c_adap.dev.parent = &dev->udev->dev;
564 strcpy(dev->i2c_adap.name, dev->name);
565 dev->i2c_adap.algo_data = dev;
566 i2c_add_adapter(&dev->i2c_adap);
567
568 dev->i2c_client = em28xx_client_template;
569 dev->i2c_client.adapter = &dev->i2c_adap;
570
571 em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata));
572
573 if (i2c_scan)
574 do_i2c_scan(dev->name, &dev->i2c_client);
575 return 0;
576}
577
578/*
579 * em28xx_i2c_unregister()
580 * unregister i2c_bus
581 */
582int em28xx_i2c_unregister(struct em28xx *dev)
583{
584 i2c_del_adapter(&dev->i2c_adap);
585 return 0;
586}
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
new file mode 100644
index 000000000000..32c49df58adc
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -0,0 +1,184 @@
1/*
2 handle em28xx IR remotes via linux kernel input layer.
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/sched.h>
29#include <linux/interrupt.h>
30#include <linux/input.h>
31#include <linux/usb.h>
32
33#include "em28xx.h"
34
35static unsigned int disable_ir = 0;
36module_param(disable_ir, int, 0444);
37MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
38
39static unsigned int ir_debug = 0;
40module_param(ir_debug, int, 0644);
41MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
42
43#define dprintk(fmt, arg...) if (ir_debug) \
44 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
45
46/* ---------------------------------------------------------------------- */
47
48static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = {
49 [ 0x01 ] = KEY_CHANNEL,
50 [ 0x02 ] = KEY_SELECT,
51 [ 0x03 ] = KEY_MUTE,
52 [ 0x04 ] = KEY_POWER,
53 [ 0x05 ] = KEY_KP1,
54 [ 0x06 ] = KEY_KP2,
55 [ 0x07 ] = KEY_KP3,
56 [ 0x08 ] = KEY_CHANNELUP,
57 [ 0x09 ] = KEY_KP4,
58 [ 0x0a ] = KEY_KP5,
59 [ 0x0b ] = KEY_KP6,
60 [ 0x0c ] = KEY_CHANNELDOWN,
61 [ 0x0d ] = KEY_KP7,
62 [ 0x0e ] = KEY_KP8,
63 [ 0x0f ] = KEY_KP9,
64 [ 0x10 ] = KEY_VOLUMEUP,
65 [ 0x11 ] = KEY_KP0,
66 [ 0x12 ] = KEY_MENU,
67 [ 0x13 ] = KEY_PRINT,
68 [ 0x14 ] = KEY_VOLUMEDOWN,
69 [ 0x16 ] = KEY_PAUSE,
70 [ 0x18 ] = KEY_RECORD,
71 [ 0x19 ] = KEY_REWIND,
72 [ 0x1a ] = KEY_PLAY,
73 [ 0x1b ] = KEY_FORWARD,
74 [ 0x1c ] = KEY_BACKSPACE,
75 [ 0x1e ] = KEY_STOP,
76 [ 0x40 ] = KEY_ZOOM,
77};
78
79/* ----------------------------------------------------------------------- */
80
81static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
82{
83 unsigned char b;
84
85 /* poll IR chip */
86 if (1 != i2c_master_recv(&ir->c,&b,1)) {
87 dprintk("read error\n");
88 return -EIO;
89 }
90
91 /* it seems that 0xFE indicates that a button is still hold
92 down, while 0xff indicates that no button is hold
93 down. 0xfe sequences are sometimes interrupted by 0xFF */
94
95 dprintk("key %02x\n", b);
96
97 if (b == 0xff)
98 return 0;
99
100 if (b == 0xfe)
101 /* keep old data */
102 return 1;
103
104 *ir_key = b;
105 *ir_raw = b;
106 return 1;
107}
108
109
110static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
111{
112 unsigned char buf[2];
113 unsigned char code;
114
115 /* poll IR chip */
116 if (2 != i2c_master_recv(&ir->c,buf,2))
117 return -EIO;
118
119 /* Does eliminate repeated parity code */
120 if (buf[1]==0xff)
121 return 0;
122
123 /* avoid fast reapeating */
124 if (buf[1]==ir->old)
125 return 0;
126 ir->old=buf[1];
127
128 /* Rearranges bits to the right order */
129 code= ((buf[0]&0x01)<<5) | /* 0010 0000 */
130 ((buf[0]&0x02)<<3) | /* 0001 0000 */
131 ((buf[0]&0x04)<<1) | /* 0000 1000 */
132 ((buf[0]&0x08)>>1) | /* 0000 0100 */
133 ((buf[0]&0x10)>>3) | /* 0000 0010 */
134 ((buf[0]&0x20)>>5); /* 0000 0001 */
135
136 dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",code,buf[0]);
137
138 /* return key */
139 *ir_key = code;
140 *ir_raw = code;
141 return 1;
142}
143
144/* ----------------------------------------------------------------------- */
145void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir)
146{
147 if (disable_ir) {
148 ir->get_key=NULL;
149 return ;
150 }
151
152 /* detect & configure */
153 switch (dev->model) {
154 case (EM2800_BOARD_UNKNOWN):
155 break;
156 case (EM2820_BOARD_UNKNOWN):
157 break;
158 case (EM2800_BOARD_TERRATEC_CINERGY_200):
159 case (EM2820_BOARD_TERRATEC_CINERGY_250):
160 ir->ir_codes = ir_codes_em_terratec;
161 ir->get_key = get_key_terratec;
162 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)");
163 break;
164 case (EM2820_BOARD_PINNACLE_USB_2):
165 break;
166 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
167 ir->ir_codes = ir_codes_hauppauge_new;
168 ir->get_key = get_key_em_haup;
169 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM2840 Hauppauge)");
170 break;
171 case (EM2820_BOARD_MSI_VOX_USB_2):
172 break;
173 case (EM2800_BOARD_LEADTEK_WINFAST_USBII):
174 break;
175 case (EM2800_BOARD_KWORLD_USB2800):
176 break;
177 }
178}
179
180/* ----------------------------------------------------------------------
181 * Local variables:
182 * c-basic-offset: 8
183 * End:
184 */
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
new file mode 100644
index 000000000000..57c1826b928e
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -0,0 +1,1933 @@
1/*
2 em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/usb.h>
29#include <linux/i2c.h>
30#include <linux/version.h>
31#include <linux/video_decoder.h>
32
33#include "em28xx.h"
34#include <media/tuner.h>
35
36#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
37 "Markus Rechberger <mrechberger@gmail.com>, " \
38 "Mauro Carvalho Chehab <mchehab@brturbo.com.br>, " \
39 "Sascha Sommer <saschasommer@freenet.de>"
40
41#define DRIVER_NAME "em28xx"
42#define DRIVER_DESC "Empia em28xx based USB video device driver"
43#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 0, 1)
44
45#define em28xx_videodbg(fmt, arg...) do {\
46 if (video_debug) \
47 printk(KERN_INFO "%s %s :"fmt, \
48 dev->name, __FUNCTION__ , ##arg); } while (0)
49
50MODULE_AUTHOR(DRIVER_AUTHOR);
51MODULE_DESCRIPTION(DRIVER_DESC);
52MODULE_LICENSE("GPL");
53
54static LIST_HEAD(em28xx_devlist);
55
56static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
57module_param_array(card, int, NULL, 0444);
58MODULE_PARM_DESC(card,"card type");
59
60static int tuner = -1;
61module_param(tuner, int, 0444);
62MODULE_PARM_DESC(tuner, "tuner type");
63
64static unsigned int video_debug = 0;
65module_param(video_debug,int,0644);
66MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
67
68/* supported tv norms */
69static struct em28xx_tvnorm tvnorms[] = {
70 {
71 .name = "PAL",
72 .id = V4L2_STD_PAL,
73 .mode = VIDEO_MODE_PAL,
74 }, {
75 .name = "NTSC",
76 .id = V4L2_STD_NTSC,
77 .mode = VIDEO_MODE_NTSC,
78 }, {
79 .name = "SECAM",
80 .id = V4L2_STD_SECAM,
81 .mode = VIDEO_MODE_SECAM,
82 }, {
83 .name = "PAL-M",
84 .id = V4L2_STD_PAL_M,
85 .mode = VIDEO_MODE_PAL,
86 }
87};
88
89static const unsigned char saa7114_i2c_init[] = {
90 0x00,0x00,0x01,0x08,0x02,0xc4,0x03,0x30,0x04,0x90,0x05,0x90,0x06,0xeb,0x07,0xe0,
91 0x08,0x88,0x09,0x40,0x0a,0x80,0x0b,0x44,0x0c,0x40,0x0d,0x00,0x0e,0x81,0x0f,0x2a,
92 0x10,0x06,0x11,0x00,0x12,0xc8,0x13,0x80,0x14,0x00,0x15,0x11,0x16,0x01,0x17,0x42,
93 0x18,0x40,0x19,0x80,0x40,0x00,0x41,0xff,0x42,0xff,0x43,0xff,0x44,0xff,0x45,0xff,
94 0x46,0xff,0x47,0xff,0x48,0xff,0x49,0xff,0x4a,0xff,0x4b,0xff,0x4c,0xff,0x4d,0xff,
95 0x4e,0xff,0x4f,0xff,0x50,0xff,0x51,0xff,0x52,0xff,0x53,0xff,0x54,0x5f,0x55,0xff,
96 0x56,0xff,0x57,0xff,0x58,0x00,0x59,0x47,0x5a,0x03,0x5b,0x03,0x5d,0x3e,0x5e,0x00,
97 0x80,0x1c,0x83,0x01,0x84,0xa5,0x85,0x10,0x86,0x45,0x87,0x41,0x88,0xf0,0x88,0x00,
98 0x88,0xf0,0x90,0x00,0x91,0x08,0x92,0x00,0x93,0x80,0x94,0x08,0x95,0x00,0x96,0xc0,
99 0x97,0x02,0x98,0x13,0x99,0x00,0x9a,0x38,0x9b,0x01,0x9c,0x80,0x9d,0x02,0x9e,0x06,
100 0x9f,0x01,0xa0,0x01,0xa1,0x00,0xa2,0x00,0xa4,0x80,0xa5,0x36,0xa6,0x36,0xa8,0x67,
101 0xa9,0x04,0xaa,0x00,0xac,0x33,0xad,0x02,0xae,0x00,0xb0,0xcd,0xb1,0x04,0xb2,0xcd,
102 0xb3,0x04,0xb4,0x01,0xb8,0x00,0xb9,0x00,0xba,0x00,0xbb,0x00,0xbc,0x00,0xbd,0x00,
103 0xbe,0x00,0xbf,0x00
104};
105
106#define TVNORMS ARRAY_SIZE(tvnorms)
107
108/* supported controls */
109static struct v4l2_queryctrl em28xx_qctrl[] = {
110 {
111 .id = V4L2_CID_BRIGHTNESS,
112 .type = V4L2_CTRL_TYPE_INTEGER,
113 .name = "Brightness",
114 .minimum = -128,
115 .maximum = 127,
116 .step = 1,
117 .default_value = 0,
118 .flags = 0,
119 },{
120 .id = V4L2_CID_CONTRAST,
121 .type = V4L2_CTRL_TYPE_INTEGER,
122 .name = "Contrast",
123 .minimum = 0x0,
124 .maximum = 0x1f,
125 .step = 0x1,
126 .default_value = 0x10,
127 .flags = 0,
128 },{
129 .id = V4L2_CID_SATURATION,
130 .type = V4L2_CTRL_TYPE_INTEGER,
131 .name = "Saturation",
132 .minimum = 0x0,
133 .maximum = 0x1f,
134 .step = 0x1,
135 .default_value = 0x10,
136 .flags = 0,
137 },{
138 .id = V4L2_CID_AUDIO_VOLUME,
139 .type = V4L2_CTRL_TYPE_INTEGER,
140 .name = "Volume",
141 .minimum = 0x0,
142 .maximum = 0x1f,
143 .step = 0x1,
144 .default_value = 0x1f,
145 .flags = 0,
146 },{
147 .id = V4L2_CID_AUDIO_MUTE,
148 .type = V4L2_CTRL_TYPE_BOOLEAN,
149 .name = "Mute",
150 .minimum = 0,
151 .maximum = 1,
152 .step = 1,
153 .default_value = 1,
154 .flags = 0,
155 },{
156 .id = V4L2_CID_RED_BALANCE,
157 .type = V4L2_CTRL_TYPE_INTEGER,
158 .name = "Red chroma balance",
159 .minimum = -128,
160 .maximum = 127,
161 .step = 1,
162 .default_value = 0,
163 .flags = 0,
164 },{
165 .id = V4L2_CID_BLUE_BALANCE,
166 .type = V4L2_CTRL_TYPE_INTEGER,
167 .name = "Blue chroma balance",
168 .minimum = -128,
169 .maximum = 127,
170 .step = 1,
171 .default_value = 0,
172 .flags = 0,
173 },{
174 .id = V4L2_CID_GAMMA,
175 .type = V4L2_CTRL_TYPE_INTEGER,
176 .name = "Gamma",
177 .minimum = 0x0,
178 .maximum = 0x3f,
179 .step = 0x1,
180 .default_value = 0x20,
181 .flags = 0,
182 }
183};
184
185static struct usb_driver em28xx_usb_driver;
186
187static DECLARE_MUTEX(em28xx_sysfs_lock);
188static DECLARE_RWSEM(em28xx_disconnect);
189
190/********************* v4l2 interface ******************************************/
191
192static inline unsigned long kvirt_to_pa(unsigned long adr)
193{
194 unsigned long kva, ret;
195
196 kva = (unsigned long)page_address(vmalloc_to_page((void *)adr));
197 kva |= adr & (PAGE_SIZE - 1);
198 ret = __pa(kva);
199 return ret;
200}
201
202/*
203 * em28xx_config()
204 * inits registers with sane defaults
205 */
206static int em28xx_config(struct em28xx *dev)
207{
208
209 /* Sets I2C speed to 100 KHz */
210 em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1);
211
212 /* enable vbi capturing */
213 em28xx_audio_usb_mute(dev, 1);
214 dev->mute = 1; /* maybe not the right place... */
215 dev->volume = 0x1f;
216 em28xx_audio_analog_set(dev);
217 em28xx_audio_analog_setup(dev);
218 em28xx_outfmt_set_yuv422(dev);
219 em28xx_colorlevels_set_default(dev);
220 em28xx_compression_disable(dev);
221
222 return 0;
223}
224
225/*
226 * em28xx_config_i2c()
227 * configure i2c attached devices
228 */
229void em28xx_config_i2c(struct em28xx *dev)
230{
231 struct v4l2_frequency f;
232 struct video_decoder_init em28xx_vdi = {.data = NULL };
233
234
235 /* configure decoder */
236 if(dev->model == EM2820_BOARD_MSI_VOX_USB_2){
237 em28xx_vdi.data=saa7114_i2c_init;
238 em28xx_vdi.len=sizeof(saa7114_i2c_init);
239 }
240
241
242 em28xx_i2c_call_clients(dev, DECODER_INIT, &em28xx_vdi);
243 em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &dev->ctl_input);
244/* em28xx_i2c_call_clients(dev,DECODER_SET_PICTURE, &dev->vpic); */
245/* em28xx_i2c_call_clients(dev,DECODER_SET_NORM,&dev->tvnorm->id); */
246/* em28xx_i2c_call_clients(dev,DECODER_ENABLE_OUTPUT,&output); */
247/* em28xx_i2c_call_clients(dev,DECODER_DUMP, NULL); */
248
249 /* configure tuner */
250 f.tuner = 0;
251 f.type = V4L2_TUNER_ANALOG_TV;
252 f.frequency = 9076; /* FIXME:remove magic number */
253 dev->ctl_freq = f.frequency;
254 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
255
256 /* configure tda9887 */
257
258
259/* em28xx_i2c_call_clients(dev,VIDIOC_S_STD,&dev->tvnorm->id); */
260}
261
262/*
263 * em28xx_empty_framequeues()
264 * prepare queues for incoming and outgoing frames
265 */
266static void em28xx_empty_framequeues(struct em28xx *dev)
267{
268 u32 i;
269
270 INIT_LIST_HEAD(&dev->inqueue);
271 INIT_LIST_HEAD(&dev->outqueue);
272
273 for (i = 0; i < EM28XX_NUM_FRAMES; i++) {
274 dev->frame[i].state = F_UNUSED;
275 dev->frame[i].buf.bytesused = 0;
276 }
277}
278
279static void video_mux(struct em28xx *dev, int index)
280{
281 int input, ainput;
282
283 input = INPUT(index)->vmux;
284 dev->ctl_input = index;
285 dev->ctl_ainput = INPUT(index)->amux;
286
287 em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input);
288
289
290 em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
291
292 if (dev->has_msp34xx) {
293 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
294 ainput = EM28XX_AUDIO_SRC_TUNER;
295 em28xx_audio_source(dev, ainput);
296 } else {
297 switch (dev->ctl_ainput) {
298 case 0:
299 ainput = EM28XX_AUDIO_SRC_TUNER;
300 break;
301 default:
302 ainput = EM28XX_AUDIO_SRC_LINE;
303 }
304 em28xx_audio_source(dev, ainput);
305 }
306}
307
308/*
309 * em28xx_v4l2_open()
310 * inits the device and starts isoc transfer
311 */
312static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
313{
314 int minor = iminor(inode);
315 int errCode = 0;
316 struct em28xx *h,*dev = NULL;
317 struct list_head *list;
318
319 list_for_each(list,&em28xx_devlist) {
320 h = list_entry(list, struct em28xx, devlist);
321 if (h->vdev->minor == minor) {
322 dev = h;
323 }
324 }
325
326 filp->private_data=dev;
327
328
329 em28xx_videodbg("users=%d\n", dev->users);
330
331 if (!down_read_trylock(&em28xx_disconnect))
332 return -ERESTARTSYS;
333
334 if (dev->users) {
335 em28xx_warn("this driver can be opened only once\n");
336 up_read(&em28xx_disconnect);
337 return -EBUSY;
338 }
339
340/* if(dev->vbi_dev->minor == minor){
341 dev->type=V4L2_BUF_TYPE_VBI_CAPTURE;
342 }*/
343 if (dev->vdev->minor == minor) {
344 dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
345 }
346
347 init_MUTEX(&dev->fileop_lock); /* to 1 == available */
348 spin_lock_init(&dev->queue_lock);
349 init_waitqueue_head(&dev->wait_frame);
350 init_waitqueue_head(&dev->wait_stream);
351
352 down(&dev->lock);
353
354 em28xx_set_alternate(dev);
355
356 dev->width = norm_maxw(dev);
357 dev->height = norm_maxh(dev);
358 dev->frame_size = dev->width * dev->height * 2;
359 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
360 dev->bytesperline = dev->width * 2;
361 dev->hscale = 0;
362 dev->vscale = 0;
363
364 em28xx_capture_start(dev, 1);
365 em28xx_resolution_set(dev);
366
367 /* start the transfer */
368 errCode = em28xx_init_isoc(dev);
369 if (errCode)
370 goto err;
371
372 dev->users++;
373 filp->private_data = dev;
374 dev->io = IO_NONE;
375 dev->stream = STREAM_OFF;
376 dev->num_frames = 0;
377
378 /* prepare queues */
379 em28xx_empty_framequeues(dev);
380
381 dev->state |= DEV_INITIALIZED;
382
383 video_mux(dev, 0);
384
385 err:
386 up(&dev->lock);
387 up_read(&em28xx_disconnect);
388 return errCode;
389}
390
391/*
392 * em28xx_realease_resources()
393 * unregisters the v4l2,i2c and usb devices
394 * called when the device gets disconected or at module unload
395*/
396static void em28xx_release_resources(struct em28xx *dev)
397{
398 down(&em28xx_sysfs_lock);
399
400 em28xx_info("V4L2 device /dev/video%d deregistered\n",
401 dev->vdev->minor);
402 list_del(&dev->devlist);
403 video_unregister_device(dev->vdev);
404/* video_unregister_device(dev->vbi_dev); */
405 em28xx_i2c_unregister(dev);
406 usb_put_dev(dev->udev);
407 up(&em28xx_sysfs_lock);
408}
409
410/*
411 * em28xx_v4l2_close()
412 * stops streaming and deallocates all resources allocated by the v4l2 calls and ioctls
413 */
414static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
415{
416 int errCode;
417 struct em28xx *dev=filp->private_data;
418
419 em28xx_videodbg("users=%d\n", dev->users);
420
421 down(&dev->lock);
422
423 em28xx_uninit_isoc(dev);
424
425 em28xx_release_buffers(dev);
426
427 /* the device is already disconnect, free the remaining resources */
428 if (dev->state & DEV_DISCONNECTED) {
429 em28xx_release_resources(dev);
430 up(&dev->lock);
431 kfree(dev);
432 return 0;
433 }
434
435 /* set alternate 0 */
436 dev->alt = 0;
437 em28xx_videodbg("setting alternate 0\n");
438 errCode = usb_set_interface(dev->udev, 0, 0);
439 if (errCode < 0) {
440 em28xx_errdev ("cannot change alternate number to 0 (error=%i)\n",
441 errCode);
442 }
443
444 dev->users--;
445 wake_up_interruptible_nr(&dev->open, 1);
446 up(&dev->lock);
447 return 0;
448}
449
450/*
451 * em28xx_v4l2_read()
452 * will allocate buffers when called for the first time
453 */
454static ssize_t
455em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
456 loff_t * f_pos)
457{
458 struct em28xx_frame_t *f, *i;
459 unsigned long lock_flags;
460 int ret = 0;
461 struct em28xx *dev = filp->private_data;
462
463 if (down_interruptible(&dev->fileop_lock))
464 return -ERESTARTSYS;
465
466 if (dev->state & DEV_DISCONNECTED) {
467 em28xx_videodbg("device not present\n");
468 up(&dev->fileop_lock);
469 return -ENODEV;
470 }
471
472 if (dev->state & DEV_MISCONFIGURED) {
473 em28xx_videodbg("device misconfigured; close and open it again\n");
474 up(&dev->fileop_lock);
475 return -EIO;
476 }
477
478 if (dev->io == IO_MMAP) {
479 em28xx_videodbg ("IO method is set to mmap; close and open"
480 " the device again to choose the read method\n");
481 up(&dev->fileop_lock);
482 return -EINVAL;
483 }
484
485 if (dev->io == IO_NONE) {
486 if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) {
487 em28xx_errdev("read failed, not enough memory\n");
488 up(&dev->fileop_lock);
489 return -ENOMEM;
490 }
491 dev->io = IO_READ;
492 dev->stream = STREAM_ON;
493 em28xx_queue_unusedframes(dev);
494 }
495
496 if (!count) {
497 up(&dev->fileop_lock);
498 return 0;
499 }
500
501 if (list_empty(&dev->outqueue)) {
502 if (filp->f_flags & O_NONBLOCK) {
503 up(&dev->fileop_lock);
504 return -EAGAIN;
505 }
506 ret = wait_event_interruptible
507 (dev->wait_frame,
508 (!list_empty(&dev->outqueue)) ||
509 (dev->state & DEV_DISCONNECTED));
510 if (ret) {
511 up(&dev->fileop_lock);
512 return ret;
513 }
514 if (dev->state & DEV_DISCONNECTED) {
515 up(&dev->fileop_lock);
516 return -ENODEV;
517 }
518 }
519
520 f = list_entry(dev->outqueue.prev, struct em28xx_frame_t, frame);
521
522 spin_lock_irqsave(&dev->queue_lock, lock_flags);
523 list_for_each_entry(i, &dev->outqueue, frame)
524 i->state = F_UNUSED;
525 INIT_LIST_HEAD(&dev->outqueue);
526 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
527
528 em28xx_queue_unusedframes(dev);
529
530 if (count > f->buf.length)
531 count = f->buf.length;
532
533 if (copy_to_user(buf, f->bufmem, count)) {
534 up(&dev->fileop_lock);
535 return -EFAULT;
536 }
537 *f_pos += count;
538
539 up(&dev->fileop_lock);
540
541 return count;
542}
543
544/*
545 * em28xx_v4l2_poll()
546 * will allocate buffers when called for the first time
547 */
548static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
549{
550 unsigned int mask = 0;
551 struct em28xx *dev = filp->private_data;
552
553 if (down_interruptible(&dev->fileop_lock))
554 return POLLERR;
555
556 if (dev->state & DEV_DISCONNECTED) {
557 em28xx_videodbg("device not present\n");
558 } else if (dev->state & DEV_MISCONFIGURED) {
559 em28xx_videodbg("device is misconfigured; close and open it again\n");
560 } else {
561 if (dev->io == IO_NONE) {
562 if (!em28xx_request_buffers
563 (dev, EM28XX_NUM_READ_FRAMES)) {
564 em28xx_warn
565 ("poll() failed, not enough memory\n");
566 } else {
567 dev->io = IO_READ;
568 dev->stream = STREAM_ON;
569 }
570 }
571
572 if (dev->io == IO_READ) {
573 em28xx_queue_unusedframes(dev);
574 poll_wait(filp, &dev->wait_frame, wait);
575
576 if (!list_empty(&dev->outqueue))
577 mask |= POLLIN | POLLRDNORM;
578
579 up(&dev->fileop_lock);
580
581 return mask;
582 }
583 }
584
585 up(&dev->fileop_lock);
586 return POLLERR;
587}
588
589/*
590 * em28xx_vm_open()
591 */
592static void em28xx_vm_open(struct vm_area_struct *vma)
593{
594 struct em28xx_frame_t *f = vma->vm_private_data;
595 f->vma_use_count++;
596}
597
598/*
599 * em28xx_vm_close()
600 */
601static void em28xx_vm_close(struct vm_area_struct *vma)
602{
603 /* NOTE: buffers are not freed here */
604 struct em28xx_frame_t *f = vma->vm_private_data;
605 f->vma_use_count--;
606}
607
608static struct vm_operations_struct em28xx_vm_ops = {
609 .open = em28xx_vm_open,
610 .close = em28xx_vm_close,
611};
612
613/*
614 * em28xx_v4l2_mmap()
615 */
616static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
617{
618 unsigned long size = vma->vm_end - vma->vm_start,
619 start = vma->vm_start, pos, page;
620 u32 i;
621
622 struct em28xx *dev = filp->private_data;
623
624 if (down_interruptible(&dev->fileop_lock))
625 return -ERESTARTSYS;
626
627 if (dev->state & DEV_DISCONNECTED) {
628 em28xx_videodbg("mmap: device not present\n");
629 up(&dev->fileop_lock);
630 return -ENODEV;
631 }
632
633 if (dev->state & DEV_MISCONFIGURED) {
634 em28xx_videodbg ("mmap: Device is misconfigured; close and "
635 "open it again\n");
636 up(&dev->fileop_lock);
637 return -EIO;
638 }
639
640 if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
641 size != PAGE_ALIGN(dev->frame[0].buf.length)) {
642 up(&dev->fileop_lock);
643 return -EINVAL;
644 }
645
646 for (i = 0; i < dev->num_frames; i++) {
647 if ((dev->frame[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
648 break;
649 }
650 if (i == dev->num_frames) {
651 em28xx_videodbg("mmap: user supplied mapping address is out of range\n");
652 up(&dev->fileop_lock);
653 return -EINVAL;
654 }
655
656 /* VM_IO is eventually going to replace PageReserved altogether */
657 vma->vm_flags |= VM_IO;
658 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
659
660 pos = (unsigned long)dev->frame[i].bufmem;
661 while (size > 0) { /* size is page-aligned */
662 page = vmalloc_to_pfn((void *)pos);
663 if (remap_pfn_range(vma, start, page, PAGE_SIZE,
664 vma->vm_page_prot)) {
665 em28xx_videodbg("mmap: rename page map failed\n");
666 up(&dev->fileop_lock);
667 return -EAGAIN;
668 }
669 start += PAGE_SIZE;
670 pos += PAGE_SIZE;
671 size -= PAGE_SIZE;
672 }
673
674 vma->vm_ops = &em28xx_vm_ops;
675 vma->vm_private_data = &dev->frame[i];
676
677 em28xx_vm_open(vma);
678 up(&dev->fileop_lock);
679 return 0;
680}
681
682/*
683 * em28xx_get_ctrl()
684 * return the current saturation, brightness or contrast, mute state
685 */
686static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
687{
688 s32 tmp;
689 switch (ctrl->id) {
690 case V4L2_CID_AUDIO_MUTE:
691 ctrl->value = dev->mute;
692 return 0;
693 case V4L2_CID_AUDIO_VOLUME:
694 ctrl->value = dev->volume;
695 return 0;
696 case V4L2_CID_BRIGHTNESS:
697 if ((tmp = em28xx_brightness_get(dev)) < 0)
698 return -EIO;
699 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
700 return 0;
701 case V4L2_CID_CONTRAST:
702 if ((ctrl->value = em28xx_contrast_get(dev)) < 0)
703 return -EIO;
704 return 0;
705 case V4L2_CID_SATURATION:
706 if ((ctrl->value = em28xx_saturation_get(dev)) < 0)
707 return -EIO;
708 return 0;
709 case V4L2_CID_RED_BALANCE:
710 if ((tmp = em28xx_v_balance_get(dev)) < 0)
711 return -EIO;
712 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
713 return 0;
714 case V4L2_CID_BLUE_BALANCE:
715 if ((tmp = em28xx_u_balance_get(dev)) < 0)
716 return -EIO;
717 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
718 return 0;
719 case V4L2_CID_GAMMA:
720 if ((ctrl->value = em28xx_gamma_get(dev)) < 0)
721 return -EIO;
722 return 0;
723 default:
724 return -EINVAL;
725 }
726}
727
728/*
729 * em28xx_set_ctrl()
730 * mute or set new saturation, brightness or contrast
731 */
732static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
733{
734 switch (ctrl->id) {
735 case V4L2_CID_AUDIO_MUTE:
736 if (ctrl->value != dev->mute) {
737 dev->mute = ctrl->value;
738 em28xx_audio_usb_mute(dev, ctrl->value);
739 return em28xx_audio_analog_set(dev);
740 }
741 return 0;
742 case V4L2_CID_AUDIO_VOLUME:
743 dev->volume = ctrl->value;
744 return em28xx_audio_analog_set(dev);
745 case V4L2_CID_BRIGHTNESS:
746 return em28xx_brightness_set(dev, ctrl->value);
747 case V4L2_CID_CONTRAST:
748 return em28xx_contrast_set(dev, ctrl->value);
749 case V4L2_CID_SATURATION:
750 return em28xx_saturation_set(dev, ctrl->value);
751 case V4L2_CID_RED_BALANCE:
752 return em28xx_v_balance_set(dev, ctrl->value);
753 case V4L2_CID_BLUE_BALANCE:
754 return em28xx_u_balance_set(dev, ctrl->value);
755 case V4L2_CID_GAMMA:
756 return em28xx_gamma_set(dev, ctrl->value);
757 default:
758 return -EINVAL;
759 }
760}
761
762/*
763 * em28xx_stream_interrupt()
764 * stops streaming
765 */
766static int em28xx_stream_interrupt(struct em28xx *dev)
767{
768 int ret = 0;
769
770 /* stop reading from the device */
771
772 dev->stream = STREAM_INTERRUPT;
773 ret = wait_event_timeout(dev->wait_stream,
774 (dev->stream == STREAM_OFF) ||
775 (dev->state & DEV_DISCONNECTED),
776 EM28XX_URB_TIMEOUT);
777 if (dev->state & DEV_DISCONNECTED)
778 return -ENODEV;
779 else if (ret) {
780 dev->state |= DEV_MISCONFIGURED;
781 em28xx_videodbg("device is misconfigured; close and "
782 "open /dev/video%d again\n", dev->vdev->minor);
783 return ret;
784 }
785
786 return 0;
787}
788
789static int em28xx_set_norm(struct em28xx *dev, int width, int height)
790{
791 unsigned int hscale, vscale;
792 unsigned int maxh, maxw;
793
794 maxw = norm_maxw(dev);
795 maxh = norm_maxh(dev);
796
797 /* width must even because of the YUYV format */
798 /* height must be even because of interlacing */
799 height &= 0xfffe;
800 width &= 0xfffe;
801
802 if (height < 32)
803 height = 32;
804 if (height > maxh)
805 height = maxh;
806 if (width < 48)
807 width = 48;
808 if (width > maxw)
809 width = maxw;
810
811 if ((hscale = (((unsigned long)maxw) << 12) / width - 4096L) >= 0x4000)
812 hscale = 0x3fff;
813 width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
814
815 if ((vscale = (((unsigned long)maxh) << 12) / height - 4096L) >= 0x4000)
816 vscale = 0x3fff;
817 height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
818
819 /* set new image size */
820 dev->width = width;
821 dev->height = height;
822 dev->frame_size = dev->width * dev->height * 2;
823 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
824 dev->bytesperline = dev->width * 2;
825 dev->hscale = hscale;
826 dev->vscale = vscale;
827
828 em28xx_resolution_set(dev);
829
830 return 0;
831}
832
833/*
834 * em28xx_v4l2_do_ioctl()
835 * This function is _not_ called directly, but from
836 * em28xx_v4l2_ioctl. Userspace
837 * copying is done already, arg is a kernel pointer.
838 */
839static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
840 struct em28xx *dev, unsigned int cmd, void *arg,
841 v4l2_kioctl driver_ioctl)
842{
843 int ret;
844
845 switch (cmd) {
846 /* ---------- tv norms ---------- */
847 case VIDIOC_ENUMSTD:
848 {
849 struct v4l2_standard *e = arg;
850 unsigned int i;
851
852 i = e->index;
853 if (i >= TVNORMS)
854 return -EINVAL;
855 ret = v4l2_video_std_construct(e, tvnorms[e->index].id,
856 tvnorms[e->index].name);
857 e->index = i;
858 if (ret < 0)
859 return ret;
860 return 0;
861 }
862 case VIDIOC_G_STD:
863 {
864 v4l2_std_id *id = arg;
865
866 *id = dev->tvnorm->id;
867 return 0;
868 }
869 case VIDIOC_S_STD:
870 {
871 v4l2_std_id *id = arg;
872 unsigned int i;
873
874 for (i = 0; i < TVNORMS; i++)
875 if (*id == tvnorms[i].id)
876 break;
877 if (i == TVNORMS)
878 for (i = 0; i < TVNORMS; i++)
879 if (*id & tvnorms[i].id)
880 break;
881 if (i == TVNORMS)
882 return -EINVAL;
883
884 down(&dev->lock);
885 dev->tvnorm = &tvnorms[i];
886
887 em28xx_set_norm(dev, dev->width, dev->height);
888
889/*
890 dev->width=norm_maxw(dev);
891 dev->height=norm_maxh(dev);
892 dev->frame_size=dev->width*dev->height*2;
893 dev->field_size=dev->frame_size>>1;
894 dev->bytesperline=dev->width*2;
895 dev->hscale=0;
896 dev->vscale=0;
897
898 em28xx_resolution_set(dev);
899*/
900/*
901 em28xx_uninit_isoc(dev);
902 em28xx_set_alternate(dev);
903 em28xx_capture_start(dev, 1);
904 em28xx_resolution_set(dev);
905 em28xx_init_isoc(dev);
906*/
907 em28xx_i2c_call_clients(dev, DECODER_SET_NORM,
908 &tvnorms[i].mode);
909 em28xx_i2c_call_clients(dev, VIDIOC_S_STD,
910 &dev->tvnorm->id);
911
912 up(&dev->lock);
913
914 return 0;
915 }
916
917 /* ------ input switching ---------- */
918 case VIDIOC_ENUMINPUT:
919 {
920 struct v4l2_input *i = arg;
921 unsigned int n;
922 static const char *iname[] = {
923 [EM28XX_VMUX_COMPOSITE1] = "Composite1",
924 [EM28XX_VMUX_COMPOSITE2] = "Composite2",
925 [EM28XX_VMUX_COMPOSITE3] = "Composite3",
926 [EM28XX_VMUX_COMPOSITE4] = "Composite4",
927 [EM28XX_VMUX_SVIDEO] = "S-Video",
928 [EM28XX_VMUX_TELEVISION] = "Television",
929 [EM28XX_VMUX_CABLE] = "Cable TV",
930 [EM28XX_VMUX_DVB] = "DVB",
931 [EM28XX_VMUX_DEBUG] = "for debug only",
932 };
933
934 n = i->index;
935 if (n >= MAX_EM28XX_INPUT)
936 return -EINVAL;
937 if (0 == INPUT(n)->type)
938 return -EINVAL;
939 memset(i, 0, sizeof(*i));
940 i->index = n;
941 i->type = V4L2_INPUT_TYPE_CAMERA;
942 strcpy(i->name, iname[INPUT(n)->type]);
943 if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
944 (EM28XX_VMUX_CABLE == INPUT(n)->type))
945 i->type = V4L2_INPUT_TYPE_TUNER;
946 for (n = 0; n < ARRAY_SIZE(tvnorms); n++)
947 i->std |= tvnorms[n].id;
948 return 0;
949 }
950
951 case VIDIOC_G_INPUT:
952 {
953 int *i = arg;
954 *i = dev->ctl_input;
955
956 return 0;
957 }
958
959 case VIDIOC_S_INPUT:
960 {
961 int *index = arg;
962
963 if (*index >= MAX_EM28XX_INPUT)
964 return -EINVAL;
965 if (0 == INPUT(*index)->type)
966 return -EINVAL;
967
968 down(&dev->lock);
969 video_mux(dev, *index);
970 up(&dev->lock);
971
972 return 0;
973 }
974
975 case VIDIOC_G_AUDIO:
976 {
977 struct v4l2_audio *a = arg;
978 unsigned int index = a->index;
979
980 if (a->index > 1)
981 return -EINVAL;
982 memset(a, 0, sizeof(*a));
983 index = dev->ctl_ainput;
984
985 if (index == 0) {
986 strcpy(a->name, "Television");
987 } else {
988 strcpy(a->name, "Line In");
989 }
990 a->capability = V4L2_AUDCAP_STEREO;
991 a->index = index;
992 return 0;
993 }
994
995 case VIDIOC_S_AUDIO:
996 {
997 struct v4l2_audio *a = arg;
998 if (a->index != dev->ctl_ainput)
999 return -EINVAL;
1000
1001 return 0;
1002 }
1003
1004 /* --- controls ---------------------------------------------- */
1005 case VIDIOC_QUERYCTRL:
1006 {
1007 struct v4l2_queryctrl *qc = arg;
1008 u8 i, n;
1009 n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
1010 for (i = 0; i < n; i++)
1011 if (qc->id && qc->id == em28xx_qctrl[i].id) {
1012 memcpy(qc, &(em28xx_qctrl[i]),
1013 sizeof(*qc));
1014 return 0;
1015 }
1016
1017 return -EINVAL;
1018 }
1019
1020 case VIDIOC_G_CTRL:
1021 {
1022 struct v4l2_control *ctrl = arg;
1023
1024
1025 return em28xx_get_ctrl(dev, ctrl);
1026 }
1027
1028 case VIDIOC_S_CTRL_OLD: /* ??? */
1029 case VIDIOC_S_CTRL:
1030 {
1031 struct v4l2_control *ctrl = arg;
1032 u8 i, n;
1033
1034
1035 n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
1036 for (i = 0; i < n; i++)
1037 if (ctrl->id == em28xx_qctrl[i].id) {
1038 if (ctrl->value <
1039 em28xx_qctrl[i].minimum
1040 || ctrl->value >
1041 em28xx_qctrl[i].maximum)
1042 return -ERANGE;
1043
1044 return em28xx_set_ctrl(dev, ctrl);
1045 }
1046 return -EINVAL;
1047 }
1048
1049 /* --- tuner ioctls ------------------------------------------ */
1050 case VIDIOC_G_TUNER:
1051 {
1052 struct v4l2_tuner *t = arg;
1053 int status = 0;
1054
1055 if (0 != t->index)
1056 return -EINVAL;
1057
1058 memset(t, 0, sizeof(*t));
1059 strcpy(t->name, "Tuner");
1060 t->type = V4L2_TUNER_ANALOG_TV;
1061 t->capability = V4L2_TUNER_CAP_NORM;
1062 t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
1063/* t->signal = 0xffff;*/
1064/* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/
1065 /* No way to get signal strength? */
1066 down(&dev->lock);
1067 em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
1068 &status);
1069 up(&dev->lock);
1070 t->signal =
1071 (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
1072
1073 em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal,
1074 t->afc);
1075 return 0;
1076 }
1077 case VIDIOC_S_TUNER:
1078 {
1079 struct v4l2_tuner *t = arg;
1080 int status = 0;
1081
1082 if (0 != t->index)
1083 return -EINVAL;
1084 memset(t, 0, sizeof(*t));
1085 strcpy(t->name, "Tuner");
1086 t->type = V4L2_TUNER_ANALOG_TV;
1087 t->capability = V4L2_TUNER_CAP_NORM;
1088 t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
1089/* t->signal = 0xffff; */
1090 /* No way to get signal strength? */
1091 down(&dev->lock);
1092 em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
1093 &status);
1094 up(&dev->lock);
1095 t->signal =
1096 (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
1097
1098 em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n",
1099 t->signal, t->afc);
1100 return 0;
1101 }
1102 case VIDIOC_G_FREQUENCY:
1103 {
1104 struct v4l2_frequency *f = arg;
1105
1106 memset(f, 0, sizeof(*f));
1107 f->type = V4L2_TUNER_ANALOG_TV;
1108 f->frequency = dev->ctl_freq;
1109
1110 return 0;
1111 }
1112 case VIDIOC_S_FREQUENCY:
1113 {
1114 struct v4l2_frequency *f = arg;
1115
1116 if (0 != f->tuner)
1117 return -EINVAL;
1118
1119 if (V4L2_TUNER_ANALOG_TV != f->type)
1120 return -EINVAL;
1121
1122 down(&dev->lock);
1123 dev->ctl_freq = f->frequency;
1124 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
1125 up(&dev->lock);
1126 return 0;
1127 }
1128
1129 case VIDIOC_CROPCAP:
1130 {
1131 struct v4l2_cropcap *cc = arg;
1132
1133 if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1134 return -EINVAL;
1135 cc->bounds.left = 0;
1136 cc->bounds.top = 0;
1137 cc->bounds.width = dev->width;
1138 cc->bounds.height = dev->height;
1139 cc->defrect = cc->bounds;
1140 cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */
1141 cc->pixelaspect.denominator = 59;
1142 return 0;
1143 }
1144 case VIDIOC_STREAMON:
1145 {
1146 int *type = arg;
1147
1148 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1149 || dev->io != IO_MMAP)
1150 return -EINVAL;
1151
1152 if (list_empty(&dev->inqueue))
1153 return -EINVAL;
1154
1155 dev->stream = STREAM_ON; /* FIXME: Start video capture here? */
1156
1157 em28xx_videodbg("VIDIOC_STREAMON: starting stream\n");
1158
1159 return 0;
1160 }
1161 case VIDIOC_STREAMOFF:
1162 {
1163 int *type = arg;
1164 int ret;
1165
1166 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1167 || dev->io != IO_MMAP)
1168 return -EINVAL;
1169
1170 if (dev->stream == STREAM_ON) {
1171 em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n");
1172 if ((ret = em28xx_stream_interrupt(dev)))
1173 return ret;
1174 }
1175 em28xx_empty_framequeues(dev);
1176
1177 return 0;
1178 }
1179 default:
1180 return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
1181 driver_ioctl);
1182 }
1183 return 0;
1184}
1185
1186/*
1187 * em28xx_v4l2_do_ioctl()
1188 * This function is _not_ called directly, but from
1189 * em28xx_v4l2_ioctl. Userspace
1190 * copying is done already, arg is a kernel pointer.
1191 */
1192static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1193 unsigned int cmd, void *arg)
1194{
1195 struct em28xx *dev = filp->private_data;
1196
1197 if (!dev)
1198 return -ENODEV;
1199
1200 if (video_debug > 1)
1201 em28xx_print_ioctl(dev->name,cmd);
1202
1203 switch (cmd) {
1204
1205 /* --- capabilities ------------------------------------------ */
1206 case VIDIOC_QUERYCAP:
1207 {
1208 struct v4l2_capability *cap = arg;
1209
1210 memset(cap, 0, sizeof(*cap));
1211 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1212 strlcpy(cap->card, em28xx_boards[dev->model].name,
1213 sizeof(cap->card));
1214 strlcpy(cap->bus_info, dev->udev->dev.bus_id,
1215 sizeof(cap->bus_info));
1216 cap->version = EM28XX_VERSION_CODE;
1217 cap->capabilities =
1218 V4L2_CAP_VIDEO_CAPTURE |
1219 V4L2_CAP_AUDIO |
1220 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1221 if (dev->has_tuner)
1222 cap->capabilities |= V4L2_CAP_TUNER;
1223 return 0;
1224 }
1225
1226 /* --- capture ioctls ---------------------------------------- */
1227 case VIDIOC_ENUM_FMT:
1228 {
1229 struct v4l2_fmtdesc *fmtd = arg;
1230
1231 if (fmtd->index != 0)
1232 return -EINVAL;
1233 memset(fmtd, 0, sizeof(*fmtd));
1234 fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1235 strcpy(fmtd->description, "Packed YUY2");
1236 fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
1237 memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
1238 return 0;
1239 }
1240
1241 case VIDIOC_G_FMT:
1242 {
1243 struct v4l2_format *format = arg;
1244
1245 em28xx_videodbg("VIDIOC_G_FMT: type=%s\n",
1246 format->type ==
1247 V4L2_BUF_TYPE_VIDEO_CAPTURE ?
1248 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
1249 V4L2_BUF_TYPE_VBI_CAPTURE ?
1250 "V4L2_BUF_TYPE_VBI_CAPTURE " :
1251 "not supported");
1252
1253 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1254 return -EINVAL;
1255
1256 format->fmt.pix.width = dev->width;
1257 format->fmt.pix.height = dev->height;
1258 format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1259 format->fmt.pix.bytesperline = dev->bytesperline;
1260 format->fmt.pix.sizeimage = dev->frame_size;
1261 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1262 format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
1263
1264 em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width,
1265 dev->height);
1266 return 0;
1267 }
1268
1269 case VIDIOC_TRY_FMT:
1270 case VIDIOC_S_FMT:
1271 {
1272 struct v4l2_format *format = arg;
1273 u32 i;
1274 int ret = 0;
1275 int width = format->fmt.pix.width;
1276 int height = format->fmt.pix.height;
1277 unsigned int hscale, vscale;
1278 unsigned int maxh, maxw;
1279
1280 maxw = norm_maxw(dev);
1281 maxh = norm_maxh(dev);
1282
1283/* int both_fields; */
1284
1285 em28xx_videodbg("%s: type=%s\n",
1286 cmd ==
1287 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1288 "VIDIOC_S_FMT",
1289 format->type ==
1290 V4L2_BUF_TYPE_VIDEO_CAPTURE ?
1291 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
1292 V4L2_BUF_TYPE_VBI_CAPTURE ?
1293 "V4L2_BUF_TYPE_VBI_CAPTURE " :
1294 "not supported");
1295
1296 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1297 return -EINVAL;
1298
1299 em28xx_videodbg("%s: requested %dx%d\n",
1300 cmd ==
1301 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1302 "VIDIOC_S_FMT", format->fmt.pix.width,
1303 format->fmt.pix.height);
1304
1305 /* FIXME: Move some code away from here */
1306 /* width must even because of the YUYV format */
1307 /* height must be even because of interlacing */
1308 height &= 0xfffe;
1309 width &= 0xfffe;
1310
1311 if (height < 32)
1312 height = 32;
1313 if (height > maxh)
1314 height = maxh;
1315 if (width < 48)
1316 width = 48;
1317 if (width > maxw)
1318 width = maxw;
1319
1320 if(dev->is_em2800){
1321 /* the em2800 can only scale down to 50% */
1322 if(height % (maxh / 2))
1323 height=maxh;
1324 if(width % (maxw / 2))
1325 width=maxw;
1326 /* according to empiatech support */
1327 /* the MaxPacketSize is to small to support */
1328 /* framesizes larger than 640x480 @ 30 fps */
1329 /* or 640x576 @ 25 fps. As this would cut */
1330 /* of a part of the image we prefer */
1331 /* 360x576 or 360x480 for now */
1332 if(width == maxw && height == maxh)
1333 width /= 2;
1334 }
1335
1336 if ((hscale =
1337 (((unsigned long)maxw) << 12) / width - 4096L) >=
1338 0x4000)
1339 hscale = 0x3fff;
1340 width =
1341 (((unsigned long)maxw) << 12) / (hscale + 4096L);
1342
1343 if ((vscale =
1344 (((unsigned long)maxh) << 12) / height - 4096L) >=
1345 0x4000)
1346 vscale = 0x3fff;
1347 height =
1348 (((unsigned long)maxh) << 12) / (vscale + 4096L);
1349
1350 format->fmt.pix.width = width;
1351 format->fmt.pix.height = height;
1352 format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1353 format->fmt.pix.bytesperline = width * 2;
1354 format->fmt.pix.sizeimage = width * 2 * height;
1355 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1356 format->fmt.pix.field = V4L2_FIELD_INTERLACED;
1357
1358 em28xx_videodbg("%s: returned %dx%d (%d, %d)\n",
1359 cmd ==
1360 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1361 "VIDIOC_S_FMT", format->fmt.pix.width,
1362 format->fmt.pix.height, hscale, vscale);
1363
1364 if (cmd == VIDIOC_TRY_FMT)
1365 return 0;
1366
1367 for (i = 0; i < dev->num_frames; i++)
1368 if (dev->frame[i].vma_use_count) {
1369 em28xx_videodbg("VIDIOC_S_FMT failed. "
1370 "Unmap the buffers first.\n");
1371 return -EINVAL;
1372 }
1373
1374 /* stop io in case it is already in progress */
1375 if (dev->stream == STREAM_ON) {
1376 em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
1377 if ((ret = em28xx_stream_interrupt(dev)))
1378 return ret;
1379 }
1380
1381 em28xx_release_buffers(dev);
1382 dev->io = IO_NONE;
1383
1384 /* set new image size */
1385 dev->width = width;
1386 dev->height = height;
1387 dev->frame_size = dev->width * dev->height * 2;
1388 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
1389 dev->bytesperline = dev->width * 2;
1390 dev->hscale = hscale;
1391 dev->vscale = vscale;
1392/* dev->both_fileds = both_fileds; */
1393 em28xx_uninit_isoc(dev);
1394 em28xx_set_alternate(dev);
1395 em28xx_capture_start(dev, 1);
1396 em28xx_resolution_set(dev);
1397 em28xx_init_isoc(dev);
1398
1399 return 0;
1400 }
1401
1402 /* --- streaming capture ------------------------------------- */
1403 case VIDIOC_REQBUFS:
1404 {
1405 struct v4l2_requestbuffers *rb = arg;
1406 u32 i;
1407 int ret;
1408
1409 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1410 rb->memory != V4L2_MEMORY_MMAP)
1411 return -EINVAL;
1412
1413 if (dev->io == IO_READ) {
1414 em28xx_videodbg ("method is set to read;"
1415 " close and open the device again to"
1416 " choose the mmap I/O method\n");
1417 return -EINVAL;
1418 }
1419
1420 for (i = 0; i < dev->num_frames; i++)
1421 if (dev->frame[i].vma_use_count) {
1422 em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n");
1423 return -EINVAL;
1424 }
1425
1426 if (dev->stream == STREAM_ON) {
1427 em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n");
1428 if ((ret = em28xx_stream_interrupt(dev)))
1429 return ret;
1430 }
1431
1432 em28xx_empty_framequeues(dev);
1433
1434 em28xx_release_buffers(dev);
1435 if (rb->count)
1436 rb->count =
1437 em28xx_request_buffers(dev, rb->count);
1438
1439 dev->frame_current = NULL;
1440
1441 em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n",
1442 rb->count);
1443 dev->io = rb->count ? IO_MMAP : IO_NONE;
1444 return 0;
1445 }
1446
1447 case VIDIOC_QUERYBUF:
1448 {
1449 struct v4l2_buffer *b = arg;
1450
1451 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1452 b->index >= dev->num_frames || dev->io != IO_MMAP)
1453 return -EINVAL;
1454
1455 memcpy(b, &dev->frame[b->index].buf, sizeof(*b));
1456
1457 if (dev->frame[b->index].vma_use_count) {
1458 b->flags |= V4L2_BUF_FLAG_MAPPED;
1459 }
1460 if (dev->frame[b->index].state == F_DONE)
1461 b->flags |= V4L2_BUF_FLAG_DONE;
1462 else if (dev->frame[b->index].state != F_UNUSED)
1463 b->flags |= V4L2_BUF_FLAG_QUEUED;
1464 return 0;
1465 }
1466 case VIDIOC_QBUF:
1467 {
1468 struct v4l2_buffer *b = arg;
1469 unsigned long lock_flags;
1470
1471 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1472 b->index >= dev->num_frames || dev->io != IO_MMAP) {
1473 return -EINVAL;
1474 }
1475
1476 if (dev->frame[b->index].state != F_UNUSED) {
1477 return -EAGAIN;
1478 }
1479 dev->frame[b->index].state = F_QUEUED;
1480
1481 /* add frame to fifo */
1482 spin_lock_irqsave(&dev->queue_lock, lock_flags);
1483 list_add_tail(&dev->frame[b->index].frame,
1484 &dev->inqueue);
1485 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
1486
1487 return 0;
1488 }
1489 case VIDIOC_DQBUF:
1490 {
1491 struct v4l2_buffer *b = arg;
1492 struct em28xx_frame_t *f;
1493 unsigned long lock_flags;
1494 int ret = 0;
1495
1496 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1497 || dev->io != IO_MMAP)
1498 return -EINVAL;
1499
1500 if (list_empty(&dev->outqueue)) {
1501 if (dev->stream == STREAM_OFF)
1502 return -EINVAL;
1503 if (filp->f_flags & O_NONBLOCK)
1504 return -EAGAIN;
1505 ret = wait_event_interruptible
1506 (dev->wait_frame,
1507 (!list_empty(&dev->outqueue)) ||
1508 (dev->state & DEV_DISCONNECTED));
1509 if (ret)
1510 return ret;
1511 if (dev->state & DEV_DISCONNECTED)
1512 return -ENODEV;
1513 }
1514
1515 spin_lock_irqsave(&dev->queue_lock, lock_flags);
1516 f = list_entry(dev->outqueue.next,
1517 struct em28xx_frame_t, frame);
1518 list_del(dev->outqueue.next);
1519 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
1520
1521 f->state = F_UNUSED;
1522 memcpy(b, &f->buf, sizeof(*b));
1523
1524 if (f->vma_use_count)
1525 b->flags |= V4L2_BUF_FLAG_MAPPED;
1526
1527 return 0;
1528 }
1529 default:
1530 return em28xx_do_ioctl(inode, filp, dev, cmd, arg,
1531 em28xx_video_do_ioctl);
1532 }
1533 return 0;
1534}
1535
1536/*
1537 * em28xx_v4l2_ioctl()
1538 * handle v4l2 ioctl the main action happens in em28xx_v4l2_do_ioctl()
1539 */
1540static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp,
1541 unsigned int cmd, unsigned long arg)
1542{
1543 int ret = 0;
1544 struct em28xx *dev = filp->private_data;
1545
1546 if (down_interruptible(&dev->fileop_lock))
1547 return -ERESTARTSYS;
1548
1549 if (dev->state & DEV_DISCONNECTED) {
1550 em28xx_errdev("v4l2 ioctl: device not present\n");
1551 up(&dev->fileop_lock);
1552 return -ENODEV;
1553 }
1554
1555 if (dev->state & DEV_MISCONFIGURED) {
1556 em28xx_errdev
1557 ("v4l2 ioctl: device is misconfigured; close and open it again\n");
1558 up(&dev->fileop_lock);
1559 return -EIO;
1560 }
1561
1562 ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl);
1563
1564 up(&dev->fileop_lock);
1565
1566 return ret;
1567}
1568
1569static struct file_operations em28xx_v4l_fops = {
1570 .owner = THIS_MODULE,
1571 .open = em28xx_v4l2_open,
1572 .release = em28xx_v4l2_close,
1573 .ioctl = em28xx_v4l2_ioctl,
1574 .read = em28xx_v4l2_read,
1575 .poll = em28xx_v4l2_poll,
1576 .mmap = em28xx_v4l2_mmap,
1577 .llseek = no_llseek,
1578};
1579
1580/******************************** usb interface *****************************************/
1581
1582/*
1583 * em28xx_init_dev()
1584 * allocates and inits the device structs, registers i2c bus and v4l device
1585 */
1586static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1587 int minor, int model)
1588{
1589 struct em28xx *dev = *devhandle;
1590 int retval = -ENOMEM;
1591 int errCode, i;
1592 unsigned int maxh, maxw;
1593
1594 dev->udev = udev;
1595 dev->model = model;
1596 init_MUTEX(&dev->lock);
1597 init_waitqueue_head(&dev->open);
1598
1599 dev->em28xx_write_regs = em28xx_write_regs;
1600 dev->em28xx_read_reg = em28xx_read_reg;
1601 dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
1602 dev->em28xx_write_regs_req = em28xx_write_regs_req;
1603 dev->em28xx_read_reg_req = em28xx_read_reg_req;
1604 dev->is_em2800 = em28xx_boards[model].is_em2800;
1605 dev->has_tuner = em28xx_boards[model].has_tuner;
1606 dev->has_msp34xx = em28xx_boards[model].has_msp34xx;
1607 dev->tda9887_conf = em28xx_boards[model].tda9887_conf;
1608 dev->decoder = em28xx_boards[model].decoder;
1609
1610 if (tuner >= 0)
1611 dev->tuner_type = tuner;
1612 else
1613 dev->tuner_type = em28xx_boards[model].tuner_type;
1614
1615 dev->video_inputs = em28xx_boards[model].vchannels;
1616
1617 for (i = 0; i < TVNORMS; i++)
1618 if (em28xx_boards[model].norm == tvnorms[i].mode)
1619 break;
1620 if (i == TVNORMS)
1621 i = 0;
1622
1623 dev->tvnorm = &tvnorms[i]; /* set default norm */
1624
1625 em28xx_videodbg("tvnorm=%s\n", dev->tvnorm->name);
1626
1627 maxw = norm_maxw(dev);
1628 maxh = norm_maxh(dev);
1629
1630 /* set default image size */
1631 dev->width = maxw;
1632 dev->height = maxh;
1633 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
1634 dev->field_size = dev->width * dev->height;
1635 dev->frame_size =
1636 dev->interlaced ? dev->field_size << 1 : dev->field_size;
1637 dev->bytesperline = dev->width * 2;
1638 dev->hscale = 0;
1639 dev->vscale = 0;
1640 dev->ctl_input = 2;
1641
1642 /* setup video picture settings for saa7113h */
1643 memset(&dev->vpic, 0, sizeof(dev->vpic));
1644 dev->vpic.colour = 128 << 8;
1645 dev->vpic.hue = 128 << 8;
1646 dev->vpic.brightness = 128 << 8;
1647 dev->vpic.contrast = 192 << 8;
1648 dev->vpic.whiteness = 128 << 8; /* This one isn't used */
1649 dev->vpic.depth = 16;
1650 dev->vpic.palette = VIDEO_PALETTE_YUV422;
1651
1652#ifdef CONFIG_MODULES
1653 /* request some modules */
1654 if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114)
1655 request_module("saa711x");
1656 if (dev->decoder == EM28XX_TVP5150)
1657 request_module("tvp5150");
1658 if (dev->has_tuner)
1659 request_module("tuner");
1660 if (dev->tda9887_conf)
1661 request_module("tda9887");
1662#endif
1663 errCode = em28xx_config(dev);
1664 if (errCode) {
1665 em28xx_errdev("error configuring device\n");
1666 kfree(dev);
1667 return -ENOMEM;
1668 }
1669
1670 down(&dev->lock);
1671 /* register i2c bus */
1672 em28xx_i2c_register(dev);
1673
1674 /* Do board specific init and eeprom reading */
1675 em28xx_card_setup(dev);
1676
1677 /* configure the device */
1678 em28xx_config_i2c(dev);
1679
1680 up(&dev->lock);
1681
1682 errCode = em28xx_config(dev);
1683
1684#ifdef CONFIG_MODULES
1685 if (dev->has_msp34xx)
1686 request_module("msp3400");
1687#endif
1688 /* allocate and fill v4l2 device struct */
1689 dev->vdev = video_device_alloc();
1690 if (NULL == dev->vdev) {
1691 em28xx_errdev("cannot allocate video_device.\n");
1692 kfree(dev);
1693 return -ENOMEM;
1694 }
1695
1696 dev->vdev->type = VID_TYPE_CAPTURE;
1697 if (dev->has_tuner)
1698 dev->vdev->type |= VID_TYPE_TUNER;
1699 dev->vdev->hardware = 0;
1700 dev->vdev->fops = &em28xx_v4l_fops;
1701 dev->vdev->minor = -1;
1702 dev->vdev->dev = &dev->udev->dev;
1703 dev->vdev->release = video_device_release;
1704 snprintf(dev->vdev->name, sizeof(dev->vdev->name), "%s",
1705 "em28xx video");
1706 list_add_tail(&dev->devlist,&em28xx_devlist);
1707
1708 /* register v4l2 device */
1709 down(&dev->lock);
1710 if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1))) {
1711 em28xx_errdev("unable to register video device (error=%i).\n",
1712 retval);
1713 up(&dev->lock);
1714 list_del(&dev->devlist);
1715 video_device_release(dev->vdev);
1716 kfree(dev);
1717 return -ENODEV;
1718 }
1719 if (dev->has_msp34xx) {
1720 /* Send a reset to other chips via gpio */
1721 em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
1722 udelay(2500);
1723 em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1);
1724 udelay(2500);
1725
1726 }
1727 video_mux(dev, 0);
1728
1729 up(&dev->lock);
1730
1731 em28xx_info("V4L2 device registered as /dev/video%d\n",
1732 dev->vdev->minor);
1733
1734 return 0;
1735}
1736
1737/*
1738 * em28xx_usb_probe()
1739 * checks for supported devices
1740 */
1741static int em28xx_usb_probe(struct usb_interface *interface,
1742 const struct usb_device_id *id)
1743{
1744 const struct usb_endpoint_descriptor *endpoint;
1745 struct usb_device *udev;
1746 struct usb_interface *uif;
1747 struct em28xx *dev = NULL;
1748 int retval = -ENODEV;
1749 int model,i,nr,ifnum;
1750
1751 udev = usb_get_dev(interface_to_usbdev(interface));
1752 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
1753
1754
1755 /* Don't register audio interfaces */
1756 if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
1757 em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n",
1758 udev->descriptor.idVendor,udev->descriptor.idProduct,
1759 ifnum,
1760 interface->altsetting[0].desc.bInterfaceClass);
1761 return -ENODEV;
1762 }
1763
1764 em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n",
1765 udev->descriptor.idVendor,udev->descriptor.idProduct,
1766 ifnum,
1767 interface->altsetting[0].desc.bInterfaceClass);
1768
1769 endpoint = &interface->cur_altsetting->endpoint[1].desc;
1770
1771 /* check if the the device has the iso in endpoint at the correct place */
1772 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
1773 USB_ENDPOINT_XFER_ISOC) {
1774 em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n");
1775 return -ENODEV;
1776 }
1777 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
1778 em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n");
1779 return -ENODEV;
1780 }
1781
1782 model=id->driver_info;
1783 nr=interface->minor;
1784
1785 if (nr>EM28XX_MAXBOARDS) {
1786 printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS);
1787 return -ENOMEM;
1788 }
1789
1790 /* allocate memory for our device state and initialize it */
1791 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
1792 if (dev == NULL) {
1793 em28xx_err(DRIVER_NAME ": out of memory!\n");
1794 return -ENOMEM;
1795 }
1796 memset(dev, 0, sizeof(*dev));
1797
1798 /* compute alternate max packet sizes */
1799 uif = udev->actconfig->interface[0];
1800
1801 dev->num_alt=uif->num_altsetting;
1802 printk(DRIVER_NAME ": Alternate settings: %i\n",dev->num_alt);
1803// dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)*
1804 dev->alt_max_pkt_size = kmalloc(32*
1805 dev->num_alt,GFP_KERNEL);
1806 if (dev->alt_max_pkt_size == NULL) {
1807 em28xx_err(DRIVER_NAME ": out of memory!\n");
1808 return -ENOMEM;
1809 }
1810
1811 for (i = 0; i < dev->num_alt ; i++) {
1812 u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
1813 wMaxPacketSize);
1814 dev->alt_max_pkt_size[i] =
1815 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1816 printk(DRIVER_NAME ": Alternate setting %i, max size= %i\n",i,
1817 dev->alt_max_pkt_size[i]);
1818 }
1819
1820 snprintf(dev->name, 29, "em28xx #%d", nr);
1821
1822 if ((card[nr]>=0)&&(card[nr]<em28xx_bcount))
1823 model=card[nr];
1824
1825 if ((model==EM2800_BOARD_UNKNOWN)||(model==EM2820_BOARD_UNKNOWN)) {
1826 printk( "%s: Your board has no eeprom inside it and thus can't\n"
1827 "%s: be autodetected. Please pass card=<n> insmod option to\n"
1828 "%s: workaround that. Redirect complaints to the vendor of\n"
1829 "%s: the TV card. Best regards,\n"
1830 "%s: -- tux\n",
1831 dev->name,dev->name,dev->name,dev->name,dev->name);
1832 printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
1833 dev->name);
1834 for (i = 0; i < em28xx_bcount; i++) {
1835 printk("%s: card=%d -> %s\n",
1836 dev->name, i, em28xx_boards[i].name);
1837 }
1838 }
1839
1840 /* allocate device struct */
1841 retval = em28xx_init_dev(&dev, udev, nr, model);
1842 if (retval)
1843 return retval;
1844
1845 em28xx_info("Found %s\n", em28xx_boards[model].name);
1846
1847 /* save our data pointer in this interface device */
1848 usb_set_intfdata(interface, dev);
1849 return 0;
1850}
1851
1852/*
1853 * em28xx_usb_disconnect()
1854 * called when the device gets diconencted
1855 * video device will be unregistered on v4l2_close in case it is still open
1856 */
1857static void em28xx_usb_disconnect(struct usb_interface *interface)
1858{
1859 struct em28xx *dev = usb_get_intfdata(interface);
1860 usb_set_intfdata(interface, NULL);
1861
1862 if (!dev)
1863 return;
1864
1865 down_write(&em28xx_disconnect);
1866
1867 down(&dev->lock);
1868
1869 em28xx_info("disconnecting %s\n", dev->vdev->name);
1870
1871 wake_up_interruptible_all(&dev->open);
1872
1873 if (dev->users) {
1874 em28xx_warn
1875 ("device /dev/video%d is open! Deregistration and memory "
1876 "deallocation are deferred on close.\n", dev->vdev->minor);
1877 dev->state |= DEV_MISCONFIGURED;
1878 em28xx_uninit_isoc(dev);
1879 dev->state |= DEV_DISCONNECTED;
1880 wake_up_interruptible(&dev->wait_frame);
1881 wake_up_interruptible(&dev->wait_stream);
1882 } else {
1883 dev->state |= DEV_DISCONNECTED;
1884 em28xx_release_resources(dev);
1885 }
1886
1887 up(&dev->lock);
1888
1889 if (!dev->users) {
1890 kfree(dev->alt_max_pkt_size);
1891 kfree(dev);
1892 }
1893
1894 up_write(&em28xx_disconnect);
1895}
1896
1897static struct usb_driver em28xx_usb_driver = {
1898 .owner = THIS_MODULE,
1899 .name = "em28xx",
1900 .probe = em28xx_usb_probe,
1901 .disconnect = em28xx_usb_disconnect,
1902 .id_table = em28xx_id_table,
1903};
1904
1905static int __init em28xx_module_init(void)
1906{
1907 int result;
1908
1909 printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n",
1910 (EM28XX_VERSION_CODE >> 16) & 0xff,
1911 (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
1912#ifdef SNAPSHOT
1913 printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n",
1914 SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100);
1915#endif
1916
1917 /* register this driver with the USB subsystem */
1918 result = usb_register(&em28xx_usb_driver);
1919 if (result)
1920 em28xx_err(DRIVER_NAME
1921 " usb_register failed. Error number %d.\n", result);
1922
1923 return result;
1924}
1925
1926static void __exit em28xx_module_exit(void)
1927{
1928 /* deregister this driver with the USB subsystem */
1929 usb_deregister(&em28xx_usb_driver);
1930}
1931
1932module_init(em28xx_module_init);
1933module_exit(em28xx_module_exit);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
new file mode 100644
index 000000000000..5c7a41ce69f3
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -0,0 +1,513 @@
1/*
2 em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
5 Ludovico Cavedon <cavedon@sssup.it>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7
8 Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de>
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#ifndef _EM28XX_H
26#define _EM28XX_H
27
28#include <linux/videodev.h>
29#include <linux/i2c.h>
30#include <media/ir-kbd-i2c.h>
31
32/* Boards supported by driver */
33
34#define EM2800_BOARD_UNKNOWN 0
35#define EM2820_BOARD_UNKNOWN 1
36#define EM2820_BOARD_TERRATEC_CINERGY_250 2
37#define EM2820_BOARD_PINNACLE_USB_2 3
38#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4
39#define EM2820_BOARD_MSI_VOX_USB_2 5
40#define EM2800_BOARD_TERRATEC_CINERGY_200 6
41#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7
42#define EM2800_BOARD_KWORLD_USB2800 8
43#define EM2820_BOARD_PINNACLE_DVC_90 9
44
45#define UNSET -1
46
47/* maximum number of em28xx boards */
48#define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */
49
50/* maximum number of frames that can be queued */
51#define EM28XX_NUM_FRAMES 5
52/* number of frames that get used for v4l2_read() */
53#define EM28XX_NUM_READ_FRAMES 2
54
55/* number of buffers for isoc transfers */
56#define EM28XX_NUM_BUFS 5
57
58/* number of packets for each buffer
59 windows requests only 40 packets .. so we better do the same
60 this is what I found out for all alternate numbers there!
61 */
62#define EM28XX_NUM_PACKETS 40
63
64/* default alternate; 0 means choose the best */
65#define EM28XX_PINOUT 0
66
67#define EM28XX_INTERLACED_DEFAULT 1
68
69/*
70#define (use usbview if you want to get the other alternate number infos)
71#define
72#define alternate number 2
73#define Endpoint Address: 82
74 Direction: in
75 Attribute: 1
76 Type: Isoc
77 Max Packet Size: 1448
78 Interval: 125us
79
80 alternate number 7
81
82 Endpoint Address: 82
83 Direction: in
84 Attribute: 1
85 Type: Isoc
86 Max Packet Size: 3072
87 Interval: 125us
88*/
89
90/* time to wait when stopping the isoc transfer */
91#define EM28XX_URB_TIMEOUT msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
92
93/* time in msecs to wait for i2c writes to finish */
94#define EM2800_I2C_WRITE_TIMEOUT 20
95
96/* the various frame states */
97enum em28xx_frame_state {
98 F_UNUSED = 0,
99 F_QUEUED,
100 F_GRABBING,
101 F_DONE,
102 F_ERROR,
103};
104
105/* stream states */
106enum em28xx_stream_state {
107 STREAM_OFF,
108 STREAM_INTERRUPT,
109 STREAM_ON,
110};
111
112/* frames */
113struct em28xx_frame_t {
114 void *bufmem;
115 struct v4l2_buffer buf;
116 enum em28xx_frame_state state;
117 struct list_head frame;
118 unsigned long vma_use_count;
119 int top_field;
120 int fieldbytesused;
121};
122
123/* io methods */
124enum em28xx_io_method {
125 IO_NONE,
126 IO_READ,
127 IO_MMAP,
128};
129
130/* inputs */
131
132#define MAX_EM28XX_INPUT 4
133enum enum28xx_itype {
134 EM28XX_VMUX_COMPOSITE1 = 1,
135 EM28XX_VMUX_COMPOSITE2,
136 EM28XX_VMUX_COMPOSITE3,
137 EM28XX_VMUX_COMPOSITE4,
138 EM28XX_VMUX_SVIDEO,
139 EM28XX_VMUX_TELEVISION,
140 EM28XX_VMUX_CABLE,
141 EM28XX_VMUX_DVB,
142 EM28XX_VMUX_DEBUG,
143 EM28XX_RADIO,
144};
145
146struct em28xx_input {
147 enum enum28xx_itype type;
148 unsigned int vmux;
149 unsigned int amux;
150};
151
152#define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
153
154enum em28xx_decoder {
155 EM28XX_TVP5150,
156 EM28XX_SAA7113,
157 EM28XX_SAA7114
158};
159
160struct em28xx_board {
161 char *name;
162 int vchannels;
163 int norm;
164 int tuner_type;
165
166 /* i2c flags */
167 unsigned int is_em2800;
168 unsigned int tda9887_conf;
169
170 unsigned int has_tuner:1;
171 unsigned int has_msp34xx:1;
172
173 enum em28xx_decoder decoder;
174
175 struct em28xx_input input[MAX_EM28XX_INPUT];
176};
177
178struct em28xx_eeprom {
179 u32 id; /* 0x9567eb1a */
180 u16 vendor_ID;
181 u16 product_ID;
182
183 u16 chip_conf;
184
185 u16 board_conf;
186
187 u16 string1, string2, string3;
188
189 u8 string_idx_table;
190};
191
192/* device states */
193enum em28xx_dev_state {
194 DEV_INITIALIZED = 0x01,
195 DEV_DISCONNECTED = 0x02,
196 DEV_MISCONFIGURED = 0x04,
197};
198
199/* tvnorms */
200struct em28xx_tvnorm {
201 char *name;
202 v4l2_std_id id;
203 /* mode for saa7113h */
204 int mode;
205};
206
207/* main device struct */
208struct em28xx {
209 /* generic device properties */
210 char name[30]; /* name (including minor) of the device */
211 int model; /* index in the device_data struct */
212 unsigned int is_em2800;
213 int video_inputs; /* number of video inputs */
214 struct list_head devlist;
215 unsigned int has_tuner:1;
216 unsigned int has_msp34xx:1;
217 unsigned int has_tda9887:1;
218
219 enum em28xx_decoder decoder;
220
221 int tuner_type; /* type of the tuner */
222 int tuner_addr; /* tuner address */
223 int tda9887_conf;
224 /* i2c i/o */
225 struct i2c_adapter i2c_adap;
226 struct i2c_client i2c_client;
227 /* video for linux */
228 int users; /* user count for exclusive use */
229 struct video_device *vdev; /* video for linux device struct */
230 struct video_picture vpic; /* picture settings only used to init saa7113h */
231 struct em28xx_tvnorm *tvnorm; /* selected tv norm */
232 int ctl_freq; /* selected frequency */
233 unsigned int ctl_input; /* selected input */
234 unsigned int ctl_ainput; /* slected audio input */
235 int mute;
236 int volume;
237 /* frame properties */
238 struct em28xx_frame_t frame[EM28XX_NUM_FRAMES]; /* list of frames */
239 int num_frames; /* number of frames currently in use */
240 unsigned int frame_count; /* total number of transfered frames */
241 struct em28xx_frame_t *frame_current; /* the frame that is being filled */
242 int width; /* current frame width */
243 int height; /* current frame height */
244 int frame_size; /* current frame size */
245 int field_size; /* current field size */
246 int bytesperline;
247 int hscale; /* horizontal scale factor (see datasheet) */
248 int vscale; /* vertical scale factor (see datasheet) */
249 int interlaced; /* 1=interlace fileds, 0=just top fileds */
250 int type;
251
252 /* states */
253 enum em28xx_dev_state state;
254 enum em28xx_stream_state stream;
255 enum em28xx_io_method io;
256 /* locks */
257 struct semaphore lock, fileop_lock;
258 spinlock_t queue_lock;
259 struct list_head inqueue, outqueue;
260 wait_queue_head_t open, wait_frame, wait_stream;
261 struct video_device *vbi_dev;
262
263 unsigned char eedata[256];
264
265 /* usb transfer */
266 struct usb_device *udev; /* the usb device */
267 int alt; /* alternate */
268 int max_pkt_size; /* max packet size of isoc transaction */
269 int num_alt; /* Number of alternative settings */
270 unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
271 struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
272 char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */
273 /* helper funcs that call usb_control_msg */
274 int (*em28xx_write_regs) (struct em28xx * dev, u16 reg, char *buf,
275 int len);
276 int (*em28xx_read_reg) (struct em28xx * dev, u16 reg);
277 int (*em28xx_read_reg_req_len) (struct em28xx * dev, u8 req, u16 reg,
278 char *buf, int len);
279 int (*em28xx_write_regs_req) (struct em28xx * dev, u8 req, u16 reg,
280 char *buf, int len);
281 int (*em28xx_read_reg_req) (struct em28xx * dev, u8 req, u16 reg);
282};
283
284/* Provided by em28xx-i2c.c */
285
286void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg);
287int em28xx_i2c_register(struct em28xx *dev);
288int em28xx_i2c_unregister(struct em28xx *dev);
289
290/* Provided by em28xx-input.c */
291
292void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir);
293
294/* Provided by em28xx-core.c */
295
296void em28xx_print_ioctl(char *name, unsigned int cmd);
297
298u32 em28xx_request_buffers(struct em28xx *dev, u32 count);
299void em28xx_queue_unusedframes(struct em28xx *dev);
300void em28xx_release_buffers(struct em28xx *dev);
301
302int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
303 char *buf, int len);
304int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg);
305int em28xx_read_reg(struct em28xx *dev, u16 reg);
306int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
307 int len);
308int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
309int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
310 u8 bitmask);
311int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val);
312int em28xx_audio_analog_set(struct em28xx *dev);
313int em28xx_colorlevels_set_default(struct em28xx *dev);
314int em28xx_capture_start(struct em28xx *dev, int start);
315int em28xx_outfmt_set_yuv422(struct em28xx *dev);
316int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
317 u8 ymax);
318int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
319 u16 width, u16 height);
320int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v);
321int em28xx_resolution_set(struct em28xx *dev);
322void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs);
323int em28xx_init_isoc(struct em28xx *dev);
324void em28xx_uninit_isoc(struct em28xx *dev);
325int em28xx_set_alternate(struct em28xx *dev);
326
327/* Provided by em28xx-cards.c */
328extern int em2800_variant_detect(struct usb_device* udev,int model);
329extern void em28xx_card_setup(struct em28xx *dev);
330extern struct em28xx_board em28xx_boards[];
331extern struct usb_device_id em28xx_id_table[];
332extern const unsigned int em28xx_bcount;
333
334/* em28xx registers */
335#define CHIPID_REG 0x0a
336#define USBSUSP_REG 0x0c /* */
337
338#define AUDIOSRC_REG 0x0e
339#define XCLK_REG 0x0f
340
341#define VINMODE_REG 0x10
342#define VINCTRL_REG 0x11
343#define VINENABLE_REG 0x12 /* */
344
345#define GAMMA_REG 0x14
346#define RGAIN_REG 0x15
347#define GGAIN_REG 0x16
348#define BGAIN_REG 0x17
349#define ROFFSET_REG 0x18
350#define GOFFSET_REG 0x19
351#define BOFFSET_REG 0x1a
352
353#define OFLOW_REG 0x1b
354#define HSTART_REG 0x1c
355#define VSTART_REG 0x1d
356#define CWIDTH_REG 0x1e
357#define CHEIGHT_REG 0x1f
358
359#define YGAIN_REG 0x20
360#define YOFFSET_REG 0x21
361#define UVGAIN_REG 0x22
362#define UOFFSET_REG 0x23
363#define VOFFSET_REG 0x24
364#define SHARPNESS_REG 0x25
365
366#define COMPR_REG 0x26
367#define OUTFMT_REG 0x27
368
369#define XMIN_REG 0x28
370#define XMAX_REG 0x29
371#define YMIN_REG 0x2a
372#define YMAX_REG 0x2b
373
374#define HSCALELOW_REG 0x30
375#define HSCALEHIGH_REG 0x31
376#define VSCALELOW_REG 0x32
377#define VSCALEHIGH_REG 0x33
378
379#define AC97LSB_REG 0x40
380#define AC97MSB_REG 0x41
381#define AC97ADDR_REG 0x42
382#define AC97BUSY_REG 0x43
383
384/* em202 registers */
385#define MASTER_AC97 0x02
386#define VIDEO_AC97 0x14
387
388/* register settings */
389#define EM28XX_AUDIO_SRC_TUNER 0xc0
390#define EM28XX_AUDIO_SRC_LINE 0x80
391
392/* printk macros */
393
394#define em28xx_err(fmt, arg...) do {\
395 printk(KERN_ERR fmt , ##arg); } while (0)
396
397#define em28xx_errdev(fmt, arg...) do {\
398 printk(KERN_ERR "%s: "fmt,\
399 dev->name , ##arg); } while (0)
400
401#define em28xx_info(fmt, arg...) do {\
402 printk(KERN_INFO "%s: "fmt,\
403 dev->name , ##arg); } while (0)
404#define em28xx_warn(fmt, arg...) do {\
405 printk(KERN_WARNING "%s: "fmt,\
406 dev->name , ##arg); } while (0)
407
408inline static int em28xx_audio_source(struct em28xx *dev, int input)
409{
410 return em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
411}
412
413inline static int em28xx_audio_usb_mute(struct em28xx *dev, int mute)
414{
415 return em28xx_write_reg_bits(dev, XCLK_REG, mute ? 0x00 : 0x80, 0x80);
416}
417
418inline static int em28xx_audio_analog_setup(struct em28xx *dev)
419{
420 /* unmute video mixer with default volume level */
421 return em28xx_write_ac97(dev, VIDEO_AC97, "\x08\x08");
422}
423
424inline static int em28xx_compression_disable(struct em28xx *dev)
425{
426 /* side effect of disabling scaler and mixer */
427 return em28xx_write_regs(dev, COMPR_REG, "\x00", 1);
428}
429
430inline static int em28xx_contrast_get(struct em28xx *dev)
431{
432 return em28xx_read_reg(dev, YGAIN_REG) & 0x1f;
433}
434
435inline static int em28xx_brightness_get(struct em28xx *dev)
436{
437 return em28xx_read_reg(dev, YOFFSET_REG);
438}
439
440inline static int em28xx_saturation_get(struct em28xx *dev)
441{
442 return em28xx_read_reg(dev, UVGAIN_REG) & 0x1f;
443}
444
445inline static int em28xx_u_balance_get(struct em28xx *dev)
446{
447 return em28xx_read_reg(dev, UOFFSET_REG);
448}
449
450inline static int em28xx_v_balance_get(struct em28xx *dev)
451{
452 return em28xx_read_reg(dev, VOFFSET_REG);
453}
454
455inline static int em28xx_gamma_get(struct em28xx *dev)
456{
457 return em28xx_read_reg(dev, GAMMA_REG) & 0x3f;
458}
459
460inline static int em28xx_contrast_set(struct em28xx *dev, s32 val)
461{
462 u8 tmp = (u8) val;
463 return em28xx_write_regs(dev, YGAIN_REG, &tmp, 1);
464}
465
466inline static int em28xx_brightness_set(struct em28xx *dev, s32 val)
467{
468 u8 tmp = (u8) val;
469 return em28xx_write_regs(dev, YOFFSET_REG, &tmp, 1);
470}
471
472inline static int em28xx_saturation_set(struct em28xx *dev, s32 val)
473{
474 u8 tmp = (u8) val;
475 return em28xx_write_regs(dev, UVGAIN_REG, &tmp, 1);
476}
477
478inline static int em28xx_u_balance_set(struct em28xx *dev, s32 val)
479{
480 u8 tmp = (u8) val;
481 return em28xx_write_regs(dev, UOFFSET_REG, &tmp, 1);
482}
483
484inline static int em28xx_v_balance_set(struct em28xx *dev, s32 val)
485{
486 u8 tmp = (u8) val;
487 return em28xx_write_regs(dev, VOFFSET_REG, &tmp, 1);
488}
489
490inline static int em28xx_gamma_set(struct em28xx *dev, s32 val)
491{
492 u8 tmp = (u8) val;
493 return em28xx_write_regs(dev, GAMMA_REG, &tmp, 1);
494}
495
496/*FIXME: maxw should be dependent of alt mode */
497inline static unsigned int norm_maxw(struct em28xx *dev)
498{
499 switch(dev->model){
500 case (EM2820_BOARD_MSI_VOX_USB_2): return(640);
501 default: return(720);
502 }
503}
504
505inline static unsigned int norm_maxh(struct em28xx *dev)
506{
507 switch(dev->model){
508 case (EM2820_BOARD_MSI_VOX_USB_2): return(480);
509 default: return (dev->tvnorm->id & V4L2_STD_625_50) ? 576 : 480;
510 }
511}
512
513#endif
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index 234151e48edc..ed81934ef3cd 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -156,6 +156,71 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
156 156
157/* ---------------------------------------------------------------------- */ 157/* ---------------------------------------------------------------------- */
158 158
159/* Ricardo Cerqueira <v4l@cerqueira.org> */
160/* Weird matching, since the remote has "uncommon" keys */
161
162static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
163
164 [ 30 ] = KEY_POWER, // power
165 [ 7 ] = KEY_MEDIA, // source
166 [ 28 ] = KEY_SEARCH, // scan
167
168/* FIXME: duplicate keycodes?
169 *
170 * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
171 * The GPIO values are
172 * 6397fb for both "Scan <" and "CH -",
173 * 639ffb for "Scan >" and "CH+",
174 * 6384fb for "Tune <" and "<<<",
175 * 638cfb for "Tune >" and ">>>", regardless of the mask.
176 *
177 * [ 23 ] = KEY_BACK, // fm scan <<
178 * [ 31 ] = KEY_FORWARD, // fm scan >>
179 *
180 * [ 4 ] = KEY_LEFT, // fm tuning <
181 * [ 12 ] = KEY_RIGHT, // fm tuning >
182 *
183 * For now, these four keys are disabled. Pressing them will generate
184 * the CH+/CH-/<<</>>> events
185 */
186
187 [ 3 ] = KEY_TUNER, // TV/FM
188
189 [ 0 ] = KEY_RECORD,
190 [ 8 ] = KEY_STOP,
191 [ 17 ] = KEY_PLAY,
192
193 [ 26 ] = KEY_PLAYPAUSE, // freeze
194 [ 25 ] = KEY_ZOOM, // zoom
195 [ 15 ] = KEY_TEXT, // min
196
197 [ 1 ] = KEY_KP1,
198 [ 11 ] = KEY_KP2,
199 [ 27 ] = KEY_KP3,
200 [ 5 ] = KEY_KP4,
201 [ 9 ] = KEY_KP5,
202 [ 21 ] = KEY_KP6,
203 [ 6 ] = KEY_KP7,
204 [ 10 ] = KEY_KP8,
205 [ 18 ] = KEY_KP9,
206 [ 2 ] = KEY_KP0,
207 [ 16 ] = KEY_LAST, // +100
208 [ 19 ] = KEY_LIST, // recall
209
210 [ 31 ] = KEY_CHANNELUP, // chn down
211 [ 23 ] = KEY_CHANNELDOWN, // chn up
212 [ 22 ] = KEY_VOLUMEUP, // vol down
213 [ 20 ] = KEY_VOLUMEDOWN, // vol up
214
215 [ 4 ] = KEY_KPMINUS, // <<<
216 [ 14 ] = KEY_SETUP, // function
217 [ 12 ] = KEY_KPPLUS, // >>>
218
219 [ 13 ] = KEY_GOTO, // mts
220 [ 29 ] = KEY_REFRESH, // reset
221 [ 24 ] = KEY_MUTE // mute/unmute
222};
223
159struct IR { 224struct IR {
160 struct bttv_sub_device *sub; 225 struct bttv_sub_device *sub;
161 struct input_dev *input; 226 struct input_dev *input;
@@ -282,53 +347,59 @@ static int ir_probe(struct device *dev)
282 347
283 /* detect & configure */ 348 /* detect & configure */
284 switch (sub->core->type) { 349 switch (sub->core->type) {
285 case BTTV_AVERMEDIA: 350 case BTTV_BOARD_AVERMEDIA:
286 case BTTV_AVPHONE98: 351 case BTTV_BOARD_AVPHONE98:
287 case BTTV_AVERMEDIA98: 352 case BTTV_BOARD_AVERMEDIA98:
288 ir_codes = ir_codes_avermedia; 353 ir_codes = ir_codes_avermedia;
289 ir->mask_keycode = 0xf88000; 354 ir->mask_keycode = 0xf88000;
290 ir->mask_keydown = 0x010000; 355 ir->mask_keydown = 0x010000;
291 ir->polling = 50; // ms 356 ir->polling = 50; // ms
292 break; 357 break;
293 358
294 case BTTV_AVDVBT_761: 359 case BTTV_BOARD_AVDVBT_761:
295 case BTTV_AVDVBT_771: 360 case BTTV_BOARD_AVDVBT_771:
296 ir_codes = ir_codes_avermedia_dvbt; 361 ir_codes = ir_codes_avermedia_dvbt;
297 ir->mask_keycode = 0x0f00c0; 362 ir->mask_keycode = 0x0f00c0;
298 ir->mask_keydown = 0x000020; 363 ir->mask_keydown = 0x000020;
299 ir->polling = 50; // ms 364 ir->polling = 50; // ms
300 break; 365 break;
301 366
302 case BTTV_PXELVWPLTVPAK: 367 case BTTV_BOARD_PXELVWPLTVPAK:
303 ir_codes = ir_codes_pixelview; 368 ir_codes = ir_codes_pixelview;
304 ir->mask_keycode = 0x003e00; 369 ir->mask_keycode = 0x003e00;
305 ir->mask_keyup = 0x010000; 370 ir->mask_keyup = 0x010000;
306 ir->polling = 50; // ms 371 ir->polling = 50; // ms
307 break; 372 break;
308 case BTTV_PV_BT878P_9B: 373 case BTTV_BOARD_PV_BT878P_9B:
309 case BTTV_PV_BT878P_PLUS: 374 case BTTV_BOARD_PV_BT878P_PLUS:
310 ir_codes = ir_codes_pixelview; 375 ir_codes = ir_codes_pixelview;
311 ir->mask_keycode = 0x001f00; 376 ir->mask_keycode = 0x001f00;
312 ir->mask_keyup = 0x008000; 377 ir->mask_keyup = 0x008000;
313 ir->polling = 50; // ms 378 ir->polling = 50; // ms
314 break; 379 break;
315 380
316 case BTTV_WINFAST2000: 381 case BTTV_BOARD_WINFAST2000:
317 ir_codes = ir_codes_winfast; 382 ir_codes = ir_codes_winfast;
318 ir->mask_keycode = 0x1f8; 383 ir->mask_keycode = 0x1f8;
319 break; 384 break;
320 case BTTV_MAGICTVIEW061: 385 case BTTV_BOARD_MAGICTVIEW061:
321 case BTTV_MAGICTVIEW063: 386 case BTTV_BOARD_MAGICTVIEW063:
322 ir_codes = ir_codes_winfast; 387 ir_codes = ir_codes_winfast;
323 ir->mask_keycode = 0x0008e000; 388 ir->mask_keycode = 0x0008e000;
324 ir->mask_keydown = 0x00200000; 389 ir->mask_keydown = 0x00200000;
325 break; 390 break;
326 case BTTV_APAC_VIEWCOMP: 391 case BTTV_BOARD_APAC_VIEWCOMP:
327 ir_codes = ir_codes_apac_viewcomp; 392 ir_codes = ir_codes_apac_viewcomp;
328 ir->mask_keycode = 0x001f00; 393 ir->mask_keycode = 0x001f00;
329 ir->mask_keyup = 0x008000; 394 ir->mask_keyup = 0x008000;
330 ir->polling = 50; // ms 395 ir->polling = 50; // ms
331 break; 396 break;
397 case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
398 ir_codes = ir_codes_conceptronic;
399 ir->mask_keycode = 0x001F00;
400 ir->mask_keyup = 0x006000;
401 ir->polling = 50; // ms
402 break;
332 } 403 }
333 if (NULL == ir_codes) { 404 if (NULL == ir_codes) {
334 kfree(ir); 405 kfree(ir);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 9703d3d351f9..0085567a1421 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -8,6 +8,8 @@
8 * Christoph Bartelmus <lirc@bartelmus.de> 8 * Christoph Bartelmus <lirc@bartelmus.de>
9 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by 9 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
10 * Ulrich Mueller <ulrich.mueller42@web.de> 10 * Ulrich Mueller <ulrich.mueller42@web.de>
11 * modified for em2820 based USB TV tuners by
12 * Markus Rechberger <mrechberger@gmail.com>
11 * 13 *
12 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -37,10 +39,9 @@
37#include <linux/slab.h> 39#include <linux/slab.h>
38#include <linux/i2c.h> 40#include <linux/i2c.h>
39#include <linux/workqueue.h> 41#include <linux/workqueue.h>
40
41#include <asm/semaphore.h> 42#include <asm/semaphore.h>
42
43#include <media/ir-common.h> 43#include <media/ir-common.h>
44#include <media/ir-kbd-i2c.h>
44 45
45/* Mark Phalan <phalanm@o2.ie> */ 46/* Mark Phalan <phalanm@o2.ie> */
46static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { 47static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
@@ -81,57 +82,6 @@ static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
81 [ 28 ] = KEY_MEDIA, /* PC/TV */ 82 [ 28 ] = KEY_MEDIA, /* PC/TV */
82}; 83};
83 84
84static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
85 [ 0x3 ] = KEY_POWER,
86 [ 0x6f ] = KEY_MUTE,
87 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
88
89 [ 0x11 ] = KEY_KP0,
90 [ 0x4 ] = KEY_KP1,
91 [ 0x5 ] = KEY_KP2,
92 [ 0x6 ] = KEY_KP3,
93 [ 0x8 ] = KEY_KP4,
94 [ 0x9 ] = KEY_KP5,
95 [ 0xa ] = KEY_KP6,
96 [ 0xc ] = KEY_KP7,
97 [ 0xd ] = KEY_KP8,
98 [ 0xe ] = KEY_KP9,
99 [ 0x12 ] = KEY_KPDOT, /* 100+ */
100
101 [ 0x7 ] = KEY_VOLUMEUP,
102 [ 0xb ] = KEY_VOLUMEDOWN,
103 [ 0x1a ] = KEY_KPPLUS,
104 [ 0x18 ] = KEY_KPMINUS,
105 [ 0x15 ] = KEY_UP,
106 [ 0x1d ] = KEY_DOWN,
107 [ 0xf ] = KEY_CHANNELUP,
108 [ 0x13 ] = KEY_CHANNELDOWN,
109 [ 0x48 ] = KEY_ZOOM,
110
111 [ 0x1b ] = KEY_VIDEO, /* Video source */
112 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
113 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
114
115 [ 0x4b ] = KEY_RECORD,
116 [ 0x46 ] = KEY_PLAY,
117 [ 0x45 ] = KEY_PAUSE, /* Pause */
118 [ 0x44 ] = KEY_STOP,
119 [ 0x40 ] = KEY_FORWARD, /* Forward ? */
120 [ 0x42 ] = KEY_REWIND, /* Backward ? */
121
122};
123
124struct IR {
125 struct i2c_client c;
126 struct input_dev *input;
127 struct ir_input_state ir;
128
129 struct work_struct work;
130 struct timer_list timer;
131 char phys[32];
132 int (*get_key)(struct IR*, u32*, u32*);
133};
134
135/* ----------------------------------------------------------------------- */ 85/* ----------------------------------------------------------------------- */
136/* insmod parameters */ 86/* insmod parameters */
137 87
@@ -144,7 +94,7 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */
144 94
145/* ----------------------------------------------------------------------- */ 95/* ----------------------------------------------------------------------- */
146 96
147static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw) 97static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
148{ 98{
149 unsigned char buf[3]; 99 unsigned char buf[3];
150 int start, toggle, dev, code; 100 int start, toggle, dev, code;
@@ -171,9 +121,9 @@ static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
171 return 1; 121 return 1;
172} 122}
173 123
174static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw) 124static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
175{ 125{
176 unsigned char b; 126 unsigned char b;
177 127
178 /* poll IR chip */ 128 /* poll IR chip */
179 if (1 != i2c_master_recv(&ir->c,&b,1)) { 129 if (1 != i2c_master_recv(&ir->c,&b,1)) {
@@ -185,9 +135,9 @@ static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
185 return 1; 135 return 1;
186} 136}
187 137
188static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw) 138static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
189{ 139{
190 unsigned char b; 140 unsigned char b;
191 141
192 /* poll IR chip */ 142 /* poll IR chip */
193 if (1 != i2c_master_recv(&ir->c,&b,1)) { 143 if (1 != i2c_master_recv(&ir->c,&b,1)) {
@@ -205,7 +155,7 @@ static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
205 return 1; 155 return 1;
206} 156}
207 157
208static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) 158static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
209{ 159{
210 unsigned char b; 160 unsigned char b;
211 161
@@ -216,15 +166,15 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
216 } 166 }
217 167
218 /* it seems that 0xFE indicates that a button is still hold 168 /* it seems that 0xFE indicates that a button is still hold
219 down, while 0xFF indicates that no button is hold 169 down, while 0xff indicates that no button is hold
220 down. 0xFE sequences are sometimes interrupted by 0xFF */ 170 down. 0xfe sequences are sometimes interrupted by 0xFF */
221 171
222 dprintk(2,"key %02x\n", b); 172 dprintk(2,"key %02x\n", b);
223 173
224 if (b == 0xFF) 174 if (b == 0xff)
225 return 0; 175 return 0;
226 176
227 if (b == 0xFE) 177 if (b == 0xfe)
228 /* keep old data */ 178 /* keep old data */
229 return 1; 179 return 1;
230 180
@@ -233,31 +183,9 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
233 return 1; 183 return 1;
234} 184}
235 185
236static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
237{
238 unsigned char b;
239
240 /* poll IR chip */
241 if (1 != i2c_master_recv(&ir->c,&b,1)) {
242 dprintk(1,"read error\n");
243 return -EIO;
244 }
245
246 /* no button press */
247 if (b==0)
248 return 0;
249
250 /* repeating */
251 if (b & 0x80)
252 return 1;
253
254 *ir_key = b;
255 *ir_raw = b;
256 return 1;
257}
258/* ----------------------------------------------------------------------- */ 186/* ----------------------------------------------------------------------- */
259 187
260static void ir_key_poll(struct IR *ir) 188static void ir_key_poll(struct IR_i2c *ir)
261{ 189{
262 static u32 ir_key, ir_raw; 190 static u32 ir_key, ir_raw;
263 int rc; 191 int rc;
@@ -278,13 +206,13 @@ static void ir_key_poll(struct IR *ir)
278 206
279static void ir_timer(unsigned long data) 207static void ir_timer(unsigned long data)
280{ 208{
281 struct IR *ir = (struct IR*)data; 209 struct IR_i2c *ir = (struct IR_i2c*)data;
282 schedule_work(&ir->work); 210 schedule_work(&ir->work);
283} 211}
284 212
285static void ir_work(void *data) 213static void ir_work(void *data)
286{ 214{
287 struct IR *ir = data; 215 struct IR_i2c *ir = data;
288 ir_key_poll(ir); 216 ir_key_poll(ir);
289 mod_timer(&ir->timer, jiffies+HZ/10); 217 mod_timer(&ir->timer, jiffies+HZ/10);
290} 218}
@@ -297,17 +225,17 @@ static int ir_detach(struct i2c_client *client);
297static int ir_probe(struct i2c_adapter *adap); 225static int ir_probe(struct i2c_adapter *adap);
298 226
299static struct i2c_driver driver = { 227static struct i2c_driver driver = {
300 .name = "ir remote kbd driver", 228 .name = "ir remote kbd driver",
301 .id = I2C_DRIVERID_EXP3, /* FIXME */ 229 .id = I2C_DRIVERID_EXP3, /* FIXME */
302 .flags = I2C_DF_NOTIFY, 230 .flags = I2C_DF_NOTIFY,
303 .attach_adapter = ir_probe, 231 .attach_adapter = ir_probe,
304 .detach_client = ir_detach, 232 .detach_client = ir_detach,
305}; 233};
306 234
307static struct i2c_client client_template = 235static struct i2c_client client_template =
308{ 236{
309 .name = "unset", 237 .name = "unset",
310 .driver = &driver 238 .driver = &driver
311}; 239};
312 240
313static int ir_attach(struct i2c_adapter *adap, int addr, 241static int ir_attach(struct i2c_adapter *adap, int addr,
@@ -316,10 +244,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
316 IR_KEYTAB_TYPE *ir_codes = NULL; 244 IR_KEYTAB_TYPE *ir_codes = NULL;
317 char *name; 245 char *name;
318 int ir_type; 246 int ir_type;
319 struct IR *ir; 247 struct IR_i2c *ir;
320 struct input_dev *input_dev; 248 struct input_dev *input_dev;
321 249
322 ir = kzalloc(sizeof(struct IR), GFP_KERNEL); 250 ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
323 input_dev = input_allocate_device(); 251 input_dev = input_allocate_device();
324 if (!ir || !input_dev) { 252 if (!ir || !input_dev) {
325 kfree(ir); 253 kfree(ir);
@@ -361,10 +289,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
361 ir_codes = ir_codes_empty; 289 ir_codes = ir_codes_empty;
362 break; 290 break;
363 case 0x7a: 291 case 0x7a:
364 name = "Purple TV"; 292 case 0x47:
365 ir->get_key = get_key_purpletv; 293 /* Handled by saa7134-input */
294 name = "SAA713x remote";
366 ir_type = IR_TYPE_OTHER; 295 ir_type = IR_TYPE_OTHER;
367 ir_codes = ir_codes_purpletv;
368 break; 296 break;
369 default: 297 default:
370 /* shouldn't happen */ 298 /* shouldn't happen */
@@ -373,9 +301,24 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
373 return -1; 301 return -1;
374 } 302 }
375 303
376 /* register i2c device */ 304 /* Sets name */
377 i2c_attach_client(&ir->c);
378 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); 305 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
306 ir->ir_codes=ir_codes;
307
308 /* register i2c device
309 * At device register, IR codes may be changed to be
310 * board dependent.
311 */
312 i2c_attach_client(&ir->c);
313
314 /* If IR not supported or disabled, unregisters driver */
315 if (ir->get_key == NULL) {
316 i2c_detach_client(&ir->c);
317 kfree(ir);
318 return -1;
319 }
320
321 /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */
379 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", 322 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
380 ir->c.adapter->dev.bus_id, 323 ir->c.adapter->dev.bus_id,
381 ir->c.dev.bus_id); 324 ir->c.dev.bus_id);
@@ -386,6 +329,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
386 input_dev->name = ir->c.name; 329 input_dev->name = ir->c.name;
387 input_dev->phys = ir->phys; 330 input_dev->phys = ir->phys;
388 331
332 /* register event device */
389 input_register_device(ir->input); 333 input_register_device(ir->input);
390 334
391 /* start polling via eventd */ 335 /* start polling via eventd */
@@ -400,7 +344,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
400 344
401static int ir_detach(struct i2c_client *client) 345static int ir_detach(struct i2c_client *client)
402{ 346{
403 struct IR *ir = i2c_get_clientdata(client); 347 struct IR_i2c *ir = i2c_get_clientdata(client);
404 348
405 /* kill outstanding polls */ 349 /* kill outstanding polls */
406 del_timer(&ir->timer); 350 del_timer(&ir->timer);
@@ -428,9 +372,12 @@ static int ir_probe(struct i2c_adapter *adap)
428 */ 372 */
429 373
430 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; 374 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
431 static const int probe_saa7134[] = { 0x7a, -1 }; 375 static const int probe_saa7134[] = { 0x7a, 0x47, -1 };
376 static const int probe_em28XX[] = { 0x30, 0x47, -1 };
432 const int *probe = NULL; 377 const int *probe = NULL;
433 struct i2c_client c; char buf; int i,rc; 378 struct i2c_client c;
379 unsigned char buf;
380 int i,rc;
434 381
435 switch (adap->id) { 382 switch (adap->id) {
436 case I2C_HW_B_BT848: 383 case I2C_HW_B_BT848:
@@ -439,6 +386,9 @@ static int ir_probe(struct i2c_adapter *adap)
439 case I2C_HW_SAA7134: 386 case I2C_HW_SAA7134:
440 probe = probe_saa7134; 387 probe = probe_saa7134;
441 break; 388 break;
389 case I2C_HW_B_EM28XX:
390 probe = probe_em28XX;
391 break;
442 } 392 }
443 if (NULL == probe) 393 if (NULL == probe)
444 return 0; 394 return 0;
@@ -447,11 +397,11 @@ static int ir_probe(struct i2c_adapter *adap)
447 c.adapter = adap; 397 c.adapter = adap;
448 for (i = 0; -1 != probe[i]; i++) { 398 for (i = 0; -1 != probe[i]; i++) {
449 c.addr = probe[i]; 399 c.addr = probe[i];
450 rc = i2c_master_recv(&c,&buf,1); 400 rc = i2c_master_recv(&c,&buf,0);
451 dprintk(1,"probe 0x%02x @ %s: %s\n", 401 dprintk(1,"probe 0x%02x @ %s: %s\n",
452 probe[i], adap->name, 402 probe[i], adap->name,
453 (1 == rc) ? "yes" : "no"); 403 (0 == rc) ? "yes" : "no");
454 if (1 == rc) { 404 if (0 == rc) {
455 ir_attach(adap,probe[i],0,0); 405 ir_attach(adap,probe[i],0,0);
456 break; 406 break;
457 } 407 }
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index e75e7948fd9d..a23fb0338986 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -54,9 +54,41 @@
54#include <asm/pgtable.h> 54#include <asm/pgtable.h>
55 55
56#include <media/audiochip.h> 56#include <media/audiochip.h>
57#include <media/id.h>
58#include "msp3400.h" 57#include "msp3400.h"
59 58
59#define msp3400_dbg(fmt, arg...) \
60 do { \
61 if (debug) \
62 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
63 i2c_adapter_id(client->adapter), client->addr , ## arg); \
64 } while (0)
65
66/* Medium volume debug. */
67#define msp3400_dbg_mediumvol(fmt, arg...) \
68 do { \
69 if (debug >= 2) \
70 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
71 i2c_adapter_id(client->adapter), client->addr , ## arg); \
72 } while (0)
73
74/* High volume debug. Use with care. */
75#define msp3400_dbg_highvol(fmt, arg...) \
76 do { \
77 if (debug >= 16) \
78 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
79 i2c_adapter_id(client->adapter), client->addr , ## arg); \
80 } while (0)
81
82#define msp3400_err(fmt, arg...) do { \
83 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
84 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
85#define msp3400_warn(fmt, arg...) do { \
86 printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->name, \
87 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
88#define msp3400_info(fmt, arg...) do { \
89 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
90 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
91
60#define OPMODE_AUTO -1 92#define OPMODE_AUTO -1
61#define OPMODE_MANUAL 0 93#define OPMODE_MANUAL 0
62#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */ 94#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */
@@ -73,15 +105,26 @@ static int dolby = 0;
73 105
74static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual 106static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
75 (msp34xxg only) 0x00a0-0x03c0 */ 107 (msp34xxg only) 0x00a0-0x03c0 */
108#define DFP_COUNT 0x41
109static const int bl_dfp[] = {
110 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a,
111 0x0b, 0x0d, 0x0e, 0x10
112};
113
114#define IS_MSP34XX_G(msp) ((msp)->opmode==2)
76 115
77struct msp3400c { 116struct msp3400c {
78 int rev1,rev2; 117 int rev1,rev2;
79 118
80 int opmode; 119 int opmode;
120 int nicam;
81 int mode; 121 int mode;
82 int norm; 122 int norm;
123 int stereo;
83 int nicam_on; 124 int nicam_on;
84 int acb; 125 int acb;
126 int in_scart;
127 int i2s_mode;
85 int main, second; /* sound carrier */ 128 int main, second; /* sound carrier */
86 int input; 129 int input;
87 int source; /* see msp34xxg_set_source */ 130 int source; /* see msp34xxg_set_source */
@@ -91,9 +134,12 @@ struct msp3400c {
91 int rxsubchans; 134 int rxsubchans;
92 135
93 int muted; 136 int muted;
94 int volume, balance; 137 int left, right; /* volume */
95 int bass, treble; 138 int bass, treble;
96 139
140 /* shadow register set */
141 int dfp_regs[DFP_COUNT];
142
97 /* thread */ 143 /* thread */
98 struct task_struct *kthread; 144 struct task_struct *kthread;
99 wait_queue_head_t wq; 145 wait_queue_head_t wq;
@@ -101,6 +147,8 @@ struct msp3400c {
101 int watch_stereo:1; 147 int watch_stereo:1;
102}; 148};
103 149
150#define MIN(a,b) (((a)>(b))?(b):(a))
151#define MAX(a,b) (((a)>(b))?(a):(b))
104#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) 152#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00)
105#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@') 153#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@')
106#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@') 154#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
@@ -110,9 +158,6 @@ struct msp3400c {
110 158
111/* ---------------------------------------------------------------------- */ 159/* ---------------------------------------------------------------------- */
112 160
113#define dprintk if (debug >= 1) printk
114#define d2printk if (debug >= 2) printk
115
116/* read-only */ 161/* read-only */
117module_param(opmode, int, 0444); 162module_param(opmode, int, 0444);
118 163
@@ -132,11 +177,6 @@ MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Defau
132MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); 177MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
133MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); 178MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
134 179
135
136MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
137MODULE_AUTHOR("Gerd Knorr");
138MODULE_LICENSE("Dual BSD/GPL"); /* FreeBSD uses this too */
139
140/* ---------------------------------------------------------------------- */ 180/* ---------------------------------------------------------------------- */
141 181
142#define I2C_MSP3400C 0x80 182#define I2C_MSP3400C 0x80
@@ -153,6 +193,10 @@ static unsigned short normal_i2c[] = {
153}; 193};
154I2C_CLIENT_INSMOD; 194I2C_CLIENT_INSMOD;
155 195
196MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
197MODULE_AUTHOR("Gerd Knorr");
198MODULE_LICENSE("GPL");
199
156/* ----------------------------------------------------------------------- */ 200/* ----------------------------------------------------------------------- */
157/* functions for talking to the MSP3400C Sound processor */ 201/* functions for talking to the MSP3400C Sound processor */
158 202
@@ -172,68 +216,73 @@ static int msp3400c_reset(struct i2c_client *client)
172 { client->addr, I2C_M_RD, 2, read }, 216 { client->addr, I2C_M_RD, 2, read },
173 }; 217 };
174 218
219 msp3400_dbg_highvol("msp3400c_reset\n");
175 if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) || 220 if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) ||
176 (1 != i2c_transfer(client->adapter,&reset[1],1)) || 221 (1 != i2c_transfer(client->adapter,&reset[1],1)) ||
177 (2 != i2c_transfer(client->adapter,test,2)) ) { 222 (2 != i2c_transfer(client->adapter,test,2)) ) {
178 printk(KERN_ERR "msp3400: chip reset failed\n"); 223 msp3400_err("chip reset failed\n");
179 return -1; 224 return -1;
180 } 225 }
181 return 0; 226 return 0;
182} 227}
183 228
184static int 229static int msp3400c_read(struct i2c_client *client, int dev, int addr)
185msp3400c_read(struct i2c_client *client, int dev, int addr)
186{ 230{
187 int err; 231 int err,retval;
232
233 unsigned char write[3];
234 unsigned char read[2];
235 struct i2c_msg msgs[2] = {
236 { client->addr, 0, 3, write },
237 { client->addr, I2C_M_RD, 2, read }
238 };
188 239
189 unsigned char write[3]; 240 write[0] = dev+1;
190 unsigned char read[2]; 241 write[1] = addr >> 8;
191 struct i2c_msg msgs[2] = { 242 write[2] = addr & 0xff;
192 { client->addr, 0, 3, write },
193 { client->addr, I2C_M_RD, 2, read }
194 };
195 write[0] = dev+1;
196 write[1] = addr >> 8;
197 write[2] = addr & 0xff;
198 243
199 for (err = 0; err < 3;) { 244 for (err = 0; err < 3;) {
200 if (2 == i2c_transfer(client->adapter,msgs,2)) 245 if (2 == i2c_transfer(client->adapter,msgs,2))
201 break; 246 break;
202 err++; 247 err++;
203 printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n", 248 msp3400_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err,
204 err, dev, addr); 249 dev, addr);
205 msleep(10); 250 current->state = TASK_INTERRUPTIBLE;
251 schedule_timeout(msecs_to_jiffies(10));
206 } 252 }
207 if (3 == err) { 253 if (3 == err) {
208 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); 254 msp3400_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n");
209 msp3400c_reset(client); 255 msp3400c_reset(client);
210 return -1; 256 return -1;
211 } 257 }
212 return read[0] << 8 | read[1]; 258 retval = read[0] << 8 | read[1];
259 msp3400_dbg_highvol("msp3400c_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval);
260 return retval;
213} 261}
214 262
215static int 263static int msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
216msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
217{ 264{
218 int err; 265 int err;
219 unsigned char buffer[5]; 266 unsigned char buffer[5];
220 267
221 buffer[0] = dev; 268 buffer[0] = dev;
222 buffer[1] = addr >> 8; 269 buffer[1] = addr >> 8;
223 buffer[2] = addr & 0xff; 270 buffer[2] = addr & 0xff;
224 buffer[3] = val >> 8; 271 buffer[3] = val >> 8;
225 buffer[4] = val & 0xff; 272 buffer[4] = val & 0xff;
226 273
274 msp3400_dbg_highvol("msp3400c_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val);
227 for (err = 0; err < 3;) { 275 for (err = 0; err < 3;) {
228 if (5 == i2c_master_send(client, buffer, 5)) 276 if (5 == i2c_master_send(client, buffer, 5))
229 break; 277 break;
230 err++; 278 err++;
231 printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n", 279 msp3400_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err,
232 err, dev, addr); 280 dev, addr);
233 msleep(10); 281 current->state = TASK_INTERRUPTIBLE;
282 schedule_timeout(msecs_to_jiffies(10));
234 } 283 }
235 if (3 == err) { 284 if (3 == err) {
236 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); 285 msp3400_warn("giving up, reseting chip. Sound will go off, sorry folks :-|\n");
237 msp3400c_reset(client); 286 msp3400c_reset(client);
238 return -1; 287 return -1;
239 } 288 }
@@ -266,45 +315,47 @@ static struct MSP_INIT_DATA_DEM {
266 int dfp_src; 315 int dfp_src;
267 int dfp_matrix; 316 int dfp_matrix;
268} msp_init_data[] = { 317} msp_init_data[] = {
269 /* AM (for carrier detect / msp3400) */ 318 { /* AM (for carrier detect / msp3400) */
270 { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 }, 319 {75, 19, 36, 35, 39, 40},
271 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 320 {75, 19, 36, 35, 39, 40},
272 0x00d0, 0x0500, 0x0020, 0x3000}, 321 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
273 322 0x00d0, 0x0500, 0x0020, 0x3000
274 /* AM (for carrier detect / msp3410) */ 323 },{ /* AM (for carrier detect / msp3410) */
275 { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 }, 324 {-1, -1, -8, 2, 59, 126},
276 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 325 {-1, -1, -8, 2, 59, 126},
277 0x00d0, 0x0100, 0x0020, 0x3000}, 326 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
278 327 0x00d0, 0x0100, 0x0020, 0x3000
279 /* FM Radio */ 328 },{ /* FM Radio */
280 { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 }, 329 {-8, -8, 4, 6, 78, 107},
281 MSP_CARRIER(10.7), MSP_CARRIER(10.7), 330 {-8, -8, 4, 6, 78, 107},
282 0x00d0, 0x0480, 0x0020, 0x3000 }, 331 MSP_CARRIER(10.7), MSP_CARRIER(10.7),
283 332 0x00d0, 0x0480, 0x0020, 0x3000
284 /* Terrestial FM-mono + FM-stereo */ 333 },{ /* Terrestial FM-mono + FM-stereo */
285 { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 }, 334 {3, 18, 27, 48, 66, 72},
286 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 335 {3, 18, 27, 48, 66, 72},
287 0x00d0, 0x0480, 0x0030, 0x3000}, 336 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
288 337 0x00d0, 0x0480, 0x0030, 0x3000
289 /* Sat FM-mono */ 338 },{ /* Sat FM-mono */
290 { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 }, 339 { 1, 9, 14, 24, 33, 37},
291 MSP_CARRIER(6.5), MSP_CARRIER(6.5), 340 { 3, 18, 27, 48, 66, 72},
292 0x00c6, 0x0480, 0x0000, 0x3000}, 341 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
293 342 0x00c6, 0x0480, 0x0000, 0x3000
294 /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ 343 },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
295 { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 }, 344 {-2, -8, -10, 10, 50, 86},
296 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 345 {3, 18, 27, 48, 66, 72},
297 0x00d0, 0x0040, 0x0120, 0x3000}, 346 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
298 347 0x00d0, 0x0040, 0x0120, 0x3000
299 /* NICAM/FM -- I (6.0/6.552) */ 348 },{ /* NICAM/FM -- I (6.0/6.552) */
300 { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 }, 349 {2, 4, -6, -4, 40, 94},
301 MSP_CARRIER(6.0), MSP_CARRIER(6.0), 350 {3, 18, 27, 48, 66, 72},
302 0x00d0, 0x0040, 0x0120, 0x3000}, 351 MSP_CARRIER(6.0), MSP_CARRIER(6.0),
303 352 0x00d0, 0x0040, 0x0120, 0x3000
304 /* NICAM/AM -- L (6.5/5.85) */ 353 },{ /* NICAM/AM -- L (6.5/5.85) */
305 { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 }, 354 {-2, -8, -10, 10, 50, 86},
306 MSP_CARRIER(6.5), MSP_CARRIER(6.5), 355 {-4, -12, -9, 23, 79, 126},
307 0x00c6, 0x0140, 0x0120, 0x7c03}, 356 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
357 0x00c6, 0x0140, 0x0120, 0x7c03
358 },
308}; 359};
309 360
310struct CARRIER_DETECT { 361struct CARRIER_DETECT {
@@ -338,32 +389,68 @@ static struct CARRIER_DETECT carrier_detect_65[] = {
338 389
339#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) 390#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
340 391
341/* ----------------------------------------------------------------------- */ 392/* ----------------------------------------------------------------------- *
393 * bits 9 8 5 - SCART DSP input Select:
394 * 0 0 0 - SCART 1 to DSP input (reset position)
395 * 0 1 0 - MONO to DSP input
396 * 1 0 0 - SCART 2 to DSP input
397 * 1 1 1 - Mute DSP input
398 *
399 * bits 11 10 6 - SCART 1 Output Select:
400 * 0 0 0 - undefined (reset position)
401 * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
402 * 1 0 0 - MONO input to SCART 1 Output
403 * 1 1 0 - SCART 1 DA to SCART 1 Output
404 * 0 0 1 - SCART 2 DA to SCART 1 Output
405 * 0 1 1 - SCART 1 Input to SCART 1 Output
406 * 1 1 1 - Mute SCART 1 Output
407 *
408 * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART):
409 * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position)
410 * 0 1 0 - SCART 1 Input to SCART 2 Output
411 * 1 0 0 - MONO input to SCART 2 Output
412 * 0 0 1 - SCART 2 DA to SCART 2 Output
413 * 0 1 1 - SCART 2 Input to SCART 2 Output
414 * 1 1 0 - Mute SCART 2 Output
415 *
416 * Bits 4 to 0 should be zero.
417 * ----------------------------------------------------------------------- */
342 418
343static int scarts[3][9] = { 419static int scarts[3][9] = {
344 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ 420 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
345 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, 421 /* SCART DSP Input select */
346 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, 422 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
347 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, 423 /* SCART1 Output select */
424 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
425 /* SCART2 Output select */
426 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
348}; 427};
349 428
350static char *scart_names[] = { 429static char *scart_names[] = {
351 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" 430 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
352}; 431};
353 432
354static void 433static void msp3400c_set_scart(struct i2c_client *client, int in, int out)
355msp3400c_set_scart(struct i2c_client *client, int in, int out)
356{ 434{
357 struct msp3400c *msp = i2c_get_clientdata(client); 435 struct msp3400c *msp = i2c_get_clientdata(client);
358 436
359 if (-1 == scarts[out][in]) 437 msp->in_scart=in;
360 return; 438
439 if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
440 if (-1 == scarts[out][in])
441 return;
361 442
362 dprintk(KERN_DEBUG 443 msp->acb &= ~scarts[out][SCART_MASK];
363 "msp34xx: scart switch: %s => %d\n",scart_names[in],out); 444 msp->acb |= scarts[out][in];
364 msp->acb &= ~scarts[out][SCART_MASK]; 445 } else
365 msp->acb |= scarts[out][in]; 446 msp->acb = 0xf60; /* Mute Input and SCART 1 Output */
366 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb); 447
448 msp3400_dbg("scart switch: %s => %d (ACB=0x%04x)\n",
449 scart_names[in], out, msp->acb);
450 msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb);
451
452 /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
453 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
367} 454}
368 455
369/* ------------------------------------------------------------------------ */ 456/* ------------------------------------------------------------------------ */
@@ -378,33 +465,34 @@ static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
378} 465}
379 466
380static void msp3400c_setvolume(struct i2c_client *client, 467static void msp3400c_setvolume(struct i2c_client *client,
381 int muted, int volume, int balance) 468 int muted, int left, int right)
382{ 469 {
383 int val = 0, bal = 0; 470 int vol = 0, val = 0, balance = 0;
384 471
385 if (!muted) { 472 if (!muted) {
386 /* 0x7f instead if 0x73 here has sound quality issues, 473 /* 0x7f instead if 0x73 here has sound quality issues,
387 * probably due to overmodulation + clipping ... */ 474 * probably due to overmodulation + clipping ... */
388 val = (volume * 0x73 / 65535) << 8; 475 vol = (left > right) ? left : right;
476 val = (vol * 0x73 / 65535) << 8;
389 } 477 }
390 if (val) { 478 if (vol > 0) {
391 bal = (balance / 256) - 128; 479 balance = ((right - left) * 127) / vol;
392 } 480 }
393 dprintk(KERN_DEBUG 481
394 "msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", 482 msp3400_dbg("setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n",
395 muted ? "on" : "off", volume, balance, val>>8, bal); 483 muted ? "on" : "off", left, right, val >> 8, balance);
396 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ 484 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
397 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ 485 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */
398 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, 486 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007,
399 muted ? 0x01 : (val | 0x01)); 487 muted ? 0x1 : (val | 0x1));
400 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, bal << 8); 488 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0001, balance << 8);
401} 489}
402 490
403static void msp3400c_setbass(struct i2c_client *client, int bass) 491static void msp3400c_setbass(struct i2c_client *client, int bass)
404{ 492{
405 int val = ((bass-32768) * 0x60 / 65535) << 8; 493 int val = ((bass-32768) * 0x60 / 65535) << 8;
406 494
407 dprintk(KERN_DEBUG "msp34xx: setbass: %d 0x%02x\n",bass, val>>8); 495 msp3400_dbg("setbass: %d 0x%02x\n", bass, val >> 8);
408 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ 496 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
409} 497}
410 498
@@ -412,7 +500,7 @@ static void msp3400c_settreble(struct i2c_client *client, int treble)
412{ 500{
413 int val = ((treble-32768) * 0x60 / 65535) << 8; 501 int val = ((treble-32768) * 0x60 / 65535) << 8;
414 502
415 dprintk(KERN_DEBUG "msp34xx: settreble: %d 0x%02x\n",treble, val>>8); 503 msp3400_dbg("settreble: %d 0x%02x\n",treble, val>>8);
416 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ 504 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
417} 505}
418 506
@@ -421,7 +509,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
421 struct msp3400c *msp = i2c_get_clientdata(client); 509 struct msp3400c *msp = i2c_get_clientdata(client);
422 int i; 510 int i;
423 511
424 dprintk(KERN_DEBUG "msp3400: setmode: %d\n",type); 512 msp3400_dbg("setmode: %d\n",type);
425 msp->mode = type; 513 msp->mode = type;
426 msp->audmode = V4L2_TUNER_MODE_MONO; 514 msp->audmode = V4L2_TUNER_MODE_MONO;
427 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 515 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
@@ -474,7 +562,8 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
474 } 562 }
475} 563}
476 564
477static int best_audio_mode(int rxsubchans) 565/* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */
566static int best_video_sound(int rxsubchans)
478{ 567{
479 if (rxsubchans & V4L2_TUNER_SUB_STEREO) 568 if (rxsubchans & V4L2_TUNER_SUB_STEREO)
480 return V4L2_TUNER_MODE_STEREO; 569 return V4L2_TUNER_MODE_STEREO;
@@ -486,31 +575,31 @@ static int best_audio_mode(int rxsubchans)
486} 575}
487 576
488/* turn on/off nicam + stereo */ 577/* turn on/off nicam + stereo */
489static void msp3400c_set_audmode(struct i2c_client *client, int audmode) 578static void msp3400c_setstereo(struct i2c_client *client, int mode)
490{ 579{
491 static char *strmode[16] = { 580 static char *strmode[] = { "0", "mono", "stereo", "3",
492#if __GNUC__ >= 3 581 "lang1", "5", "6", "7", "lang2"
493 [ 0 ... 15 ] = "invalid",
494#endif
495 [ V4L2_TUNER_MODE_MONO ] = "mono",
496 [ V4L2_TUNER_MODE_STEREO ] = "stereo",
497 [ V4L2_TUNER_MODE_LANG1 ] = "lang1",
498 [ V4L2_TUNER_MODE_LANG2 ] = "lang2",
499 }; 582 };
500 struct msp3400c *msp = i2c_get_clientdata(client); 583 struct msp3400c *msp = i2c_get_clientdata(client);
501 int nicam=0; /* channel source: FM/AM or nicam */ 584 int nicam = 0; /* channel source: FM/AM or nicam */
502 int src=0; 585 int src = 0;
503 586
504 BUG_ON(msp->opmode == OPMODE_SIMPLER); 587 if (IS_MSP34XX_G(msp)) {
505 msp->audmode = audmode; 588 /* this method would break everything, let's make sure
589 * it's never called
590 */
591 msp3400_dbg
592 ("DEBUG WARNING setstereo called with mode=%d instead of set_source (ignored)\n",
593 mode);
594 return;
595 }
506 596
507 /* switch demodulator */ 597 /* switch demodulator */
508 switch (msp->mode) { 598 switch (msp->mode) {
509 case MSP_MODE_FM_TERRA: 599 case MSP_MODE_FM_TERRA:
510 dprintk(KERN_DEBUG "msp3400: FM setstereo: %s\n", 600 msp3400_dbg("FM setstereo: %s\n", strmode[mode]);
511 strmode[audmode]);
512 msp3400c_setcarrier(client,msp->second,msp->main); 601 msp3400c_setcarrier(client,msp->second,msp->main);
513 switch (audmode) { 602 switch (mode) {
514 case V4L2_TUNER_MODE_STEREO: 603 case V4L2_TUNER_MODE_STEREO:
515 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); 604 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
516 break; 605 break;
@@ -522,9 +611,8 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
522 } 611 }
523 break; 612 break;
524 case MSP_MODE_FM_SAT: 613 case MSP_MODE_FM_SAT:
525 dprintk(KERN_DEBUG "msp3400: SAT setstereo: %s\n", 614 msp3400_dbg("SAT setstereo: %s\n", strmode[mode]);
526 strmode[audmode]); 615 switch (mode) {
527 switch (audmode) {
528 case V4L2_TUNER_MODE_MONO: 616 case V4L2_TUNER_MODE_MONO:
529 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); 617 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
530 break; 618 break;
@@ -542,39 +630,35 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
542 case MSP_MODE_FM_NICAM1: 630 case MSP_MODE_FM_NICAM1:
543 case MSP_MODE_FM_NICAM2: 631 case MSP_MODE_FM_NICAM2:
544 case MSP_MODE_AM_NICAM: 632 case MSP_MODE_AM_NICAM:
545 dprintk(KERN_DEBUG "msp3400: NICAM setstereo: %s\n", 633 msp3400_dbg("NICAM setstereo: %s\n",strmode[mode]);
546 strmode[audmode]);
547 msp3400c_setcarrier(client,msp->second,msp->main); 634 msp3400c_setcarrier(client,msp->second,msp->main);
548 if (msp->nicam_on) 635 if (msp->nicam_on)
549 nicam=0x0100; 636 nicam=0x0100;
550 break; 637 break;
551 case MSP_MODE_BTSC: 638 case MSP_MODE_BTSC:
552 dprintk(KERN_DEBUG "msp3400: BTSC setstereo: %s\n", 639 msp3400_dbg("BTSC setstereo: %s\n",strmode[mode]);
553 strmode[audmode]);
554 nicam=0x0300; 640 nicam=0x0300;
555 break; 641 break;
556 case MSP_MODE_EXTERN: 642 case MSP_MODE_EXTERN:
557 dprintk(KERN_DEBUG "msp3400: extern setstereo: %s\n", 643 msp3400_dbg("extern setstereo: %s\n",strmode[mode]);
558 strmode[audmode]);
559 nicam = 0x0200; 644 nicam = 0x0200;
560 break; 645 break;
561 case MSP_MODE_FM_RADIO: 646 case MSP_MODE_FM_RADIO:
562 dprintk(KERN_DEBUG "msp3400: FM-Radio setstereo: %s\n", 647 msp3400_dbg("FM-Radio setstereo: %s\n",strmode[mode]);
563 strmode[audmode]);
564 break; 648 break;
565 default: 649 default:
566 dprintk(KERN_DEBUG "msp3400: mono setstereo\n"); 650 msp3400_dbg("mono setstereo\n");
567 return; 651 return;
568 } 652 }
569 653
570 /* switch audio */ 654 /* switch audio */
571 switch (audmode) { 655 switch (best_video_sound(mode)) {
572 case V4L2_TUNER_MODE_STEREO: 656 case V4L2_TUNER_MODE_STEREO:
573 src = 0x0020 | nicam; 657 src = 0x0020 | nicam;
574 break; 658 break;
575 case V4L2_TUNER_MODE_MONO: 659 case V4L2_TUNER_MODE_MONO:
576 if (msp->mode == MSP_MODE_AM_NICAM) { 660 if (msp->mode == MSP_MODE_AM_NICAM) {
577 dprintk("msp3400: switching to AM mono\n"); 661 msp3400_dbg("switching to AM mono\n");
578 /* AM mono decoding is handled by tuner, not MSP chip */ 662 /* AM mono decoding is handled by tuner, not MSP chip */
579 /* SCART switching control register */ 663 /* SCART switching control register */
580 msp3400c_set_scart(client,SCART_MONO,0); 664 msp3400c_set_scart(client,SCART_MONO,0);
@@ -588,8 +672,7 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
588 src = 0x0010 | nicam; 672 src = 0x0010 | nicam;
589 break; 673 break;
590 } 674 }
591 dprintk(KERN_DEBUG 675 msp3400_dbg("setstereo final source/matrix = 0x%x\n", src);
592 "msp3400: setstereo final source/matrix = 0x%x\n", src);
593 676
594 if (dolby) { 677 if (dolby) {
595 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); 678 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
@@ -605,29 +688,55 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
605} 688}
606 689
607static void 690static void
608msp3400c_print_mode(struct msp3400c *msp) 691msp3400c_print_mode(struct i2c_client *client)
609{ 692{
693 struct msp3400c *msp = i2c_get_clientdata(client);
694
610 if (msp->main == msp->second) { 695 if (msp->main == msp->second) {
611 printk(KERN_DEBUG "msp3400: mono sound carrier: %d.%03d MHz\n", 696 msp3400_dbg("mono sound carrier: %d.%03d MHz\n",
612 msp->main/910000,(msp->main/910)%1000); 697 msp->main/910000,(msp->main/910)%1000);
613 } else { 698 } else {
614 printk(KERN_DEBUG "msp3400: main sound carrier: %d.%03d MHz\n", 699 msp3400_dbg("main sound carrier: %d.%03d MHz\n",
615 msp->main/910000,(msp->main/910)%1000); 700 msp->main/910000,(msp->main/910)%1000);
616 } 701 }
617 if (msp->mode == MSP_MODE_FM_NICAM1 || 702 if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2)
618 msp->mode == MSP_MODE_FM_NICAM2) 703 msp3400_dbg("NICAM/FM carrier : %d.%03d MHz\n",
619 printk(KERN_DEBUG "msp3400: NICAM/FM carrier : %d.%03d MHz\n",
620 msp->second/910000,(msp->second/910)%1000); 704 msp->second/910000,(msp->second/910)%1000);
621 if (msp->mode == MSP_MODE_AM_NICAM) 705 if (msp->mode == MSP_MODE_AM_NICAM)
622 printk(KERN_DEBUG "msp3400: NICAM/AM carrier : %d.%03d MHz\n", 706 msp3400_dbg("NICAM/AM carrier : %d.%03d MHz\n",
623 msp->second/910000,(msp->second/910)%1000); 707 msp->second/910000,(msp->second/910)%1000);
624 if (msp->mode == MSP_MODE_FM_TERRA && 708 if (msp->mode == MSP_MODE_FM_TERRA &&
625 msp->main != msp->second) { 709 msp->main != msp->second) {
626 printk(KERN_DEBUG "msp3400: FM-stereo carrier : %d.%03d MHz\n", 710 msp3400_dbg("FM-stereo carrier : %d.%03d MHz\n",
627 msp->second/910000,(msp->second/910)%1000); 711 msp->second/910000,(msp->second/910)%1000);
628 } 712 }
629} 713}
630 714
715#define MSP3400_MAX 4
716static struct i2c_client *msps[MSP3400_MAX];
717static void msp3400c_restore_dfp(struct i2c_client *client)
718{
719 struct msp3400c *msp = i2c_get_clientdata(client);
720 int i;
721
722 for (i = 0; i < DFP_COUNT; i++) {
723 if (-1 == msp->dfp_regs[i])
724 continue;
725 msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]);
726 }
727}
728
729/* if the dfp_regs is set, set what's in there. Otherwise, set the default value */
730static int msp3400c_write_dfp_with_default(struct i2c_client *client,
731 int addr, int default_value)
732{
733 struct msp3400c *msp = i2c_get_clientdata(client);
734 int value = default_value;
735 if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr])
736 value = msp->dfp_regs[addr];
737 return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value);
738}
739
631/* ----------------------------------------------------------------------- */ 740/* ----------------------------------------------------------------------- */
632 741
633struct REGISTER_DUMP { 742struct REGISTER_DUMP {
@@ -635,8 +744,15 @@ struct REGISTER_DUMP {
635 char *name; 744 char *name;
636}; 745};
637 746
638static int 747struct REGISTER_DUMP d1[] = {
639autodetect_stereo(struct i2c_client *client) 748 {0x007e, "autodetect"},
749 {0x0023, "C_AD_BITS "},
750 {0x0038, "ADD_BITS "},
751 {0x003e, "CIB_BITS "},
752 {0x0057, "ERROR_RATE"},
753};
754
755static int autodetect_stereo(struct i2c_client *client)
640{ 756{
641 struct msp3400c *msp = i2c_get_clientdata(client); 757 struct msp3400c *msp = i2c_get_clientdata(client);
642 int val; 758 int val;
@@ -649,8 +765,7 @@ autodetect_stereo(struct i2c_client *client)
649 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); 765 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
650 if (val > 32767) 766 if (val > 32767)
651 val -= 65536; 767 val -= 65536;
652 dprintk(KERN_DEBUG 768 msp3400_dbg("stereo detect register: %d\n",val);
653 "msp34xx: stereo detect register: %d\n",val);
654 if (val > 4096) { 769 if (val > 4096) {
655 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; 770 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
656 } else if (val < -4096) { 771 } else if (val < -4096) {
@@ -664,8 +779,7 @@ autodetect_stereo(struct i2c_client *client)
664 case MSP_MODE_FM_NICAM2: 779 case MSP_MODE_FM_NICAM2:
665 case MSP_MODE_AM_NICAM: 780 case MSP_MODE_AM_NICAM:
666 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); 781 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
667 dprintk(KERN_DEBUG 782 msp3400_dbg("nicam sync=%d, mode=%d\n",
668 "msp34xx: nicam sync=%d, mode=%d\n",
669 val & 1, (val & 0x1e) >> 1); 783 val & 1, (val & 0x1e) >> 1);
670 784
671 if (val & 1) { 785 if (val & 1) {
@@ -698,8 +812,7 @@ autodetect_stereo(struct i2c_client *client)
698 break; 812 break;
699 case MSP_MODE_BTSC: 813 case MSP_MODE_BTSC:
700 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); 814 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
701 dprintk(KERN_DEBUG 815 msp3400_dbg("status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
702 "msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
703 val, 816 val,
704 (val & 0x0002) ? "no" : "yes", 817 (val & 0x0002) ? "no" : "yes",
705 (val & 0x0004) ? "no" : "yes", 818 (val & 0x0004) ? "no" : "yes",
@@ -713,13 +826,13 @@ autodetect_stereo(struct i2c_client *client)
713 } 826 }
714 if (rxsubchans != msp->rxsubchans) { 827 if (rxsubchans != msp->rxsubchans) {
715 update = 1; 828 update = 1;
716 dprintk(KERN_DEBUG "msp34xx: watch: rxsubchans %d => %d\n", 829 msp3400_dbg("watch: rxsubchans %d => %d\n",
717 msp->rxsubchans,rxsubchans); 830 msp->rxsubchans,rxsubchans);
718 msp->rxsubchans = rxsubchans; 831 msp->rxsubchans = rxsubchans;
719 } 832 }
720 if (newnicam != msp->nicam_on) { 833 if (newnicam != msp->nicam_on) {
721 update = 1; 834 update = 1;
722 dprintk(KERN_DEBUG "msp34xx: watch: nicam %d => %d\n", 835 msp3400_dbg("watch: nicam %d => %d\n",
723 msp->nicam_on,newnicam); 836 msp->nicam_on,newnicam);
724 msp->nicam_on = newnicam; 837 msp->nicam_on = newnicam;
725 } 838 }
@@ -756,8 +869,15 @@ static void watch_stereo(struct i2c_client *client)
756{ 869{
757 struct msp3400c *msp = i2c_get_clientdata(client); 870 struct msp3400c *msp = i2c_get_clientdata(client);
758 871
759 if (autodetect_stereo(client)) 872 if (autodetect_stereo(client)) {
760 msp3400c_set_audmode(client,best_audio_mode(msp->rxsubchans)); 873 if (msp->stereo & V4L2_TUNER_MODE_STEREO)
874 msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
875 else if (msp->stereo & VIDEO_SOUND_LANG1)
876 msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
877 else
878 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
879 }
880
761 if (once) 881 if (once)
762 msp->watch_stereo = 0; 882 msp->watch_stereo = 0;
763} 883}
@@ -769,14 +889,14 @@ static int msp3400c_thread(void *data)
769 struct CARRIER_DETECT *cd; 889 struct CARRIER_DETECT *cd;
770 int count, max1,max2,val1,val2, val,this; 890 int count, max1,max2,val1,val2, val,this;
771 891
772 printk("msp3400: kthread started\n"); 892 msp3400_info("msp3400 daemon started\n");
773 for (;;) { 893 for (;;) {
774 d2printk("msp3400: thread: sleep\n"); 894 msp3400_dbg_mediumvol("msp3400 thread: sleep\n");
775 msp34xx_sleep(msp,-1); 895 msp34xx_sleep(msp,-1);
776 d2printk("msp3400: thread: wakeup\n"); 896 msp3400_dbg_mediumvol("msp3400 thread: wakeup\n");
777 897
778 restart: 898 restart:
779 dprintk("msp3410: thread: restart scan\n"); 899 msp3400_dbg("thread: restart scan\n");
780 msp->restart = 0; 900 msp->restart = 0;
781 if (kthread_should_stop()) 901 if (kthread_should_stop())
782 break; 902 break;
@@ -784,9 +904,8 @@ static int msp3400c_thread(void *data)
784 if (VIDEO_MODE_RADIO == msp->norm || 904 if (VIDEO_MODE_RADIO == msp->norm ||
785 MSP_MODE_EXTERN == msp->mode) { 905 MSP_MODE_EXTERN == msp->mode) {
786 /* no carrier scan, just unmute */ 906 /* no carrier scan, just unmute */
787 printk("msp3400: thread: no carrier scan\n"); 907 msp3400_info("thread: no carrier scan\n");
788 msp3400c_setvolume(client, msp->muted, 908 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
789 msp->volume, msp->balance);
790 continue; 909 continue;
791 } 910 }
792 911
@@ -802,13 +921,14 @@ static int msp3400c_thread(void *data)
802 goto restart; 921 goto restart;
803 922
804 /* carrier detect pass #1 -- main carrier */ 923 /* carrier detect pass #1 -- main carrier */
805 cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main); 924 cd = carrier_detect_main;
925 count = CARRIER_COUNT(carrier_detect_main);
806 926
807 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { 927 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
808 /* autodetect doesn't work well with AM ... */ 928 /* autodetect doesn't work well with AM ... */
809 max1 = 3; 929 max1 = 3;
810 count = 0; 930 count = 0;
811 dprintk("msp3400: AM sound override\n"); 931 msp3400_dbg("AM sound override\n");
812 } 932 }
813 933
814 for (this = 0; this < count; this++) { 934 for (this = 0; this < count; this++) {
@@ -820,7 +940,7 @@ static int msp3400c_thread(void *data)
820 val -= 65536; 940 val -= 65536;
821 if (val1 < val) 941 if (val1 < val)
822 val1 = val, max1 = this; 942 val1 = val, max1 = this;
823 dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name); 943 msp3400_dbg("carrier1 val: %5d / %s\n", val,cd[this].name);
824 } 944 }
825 945
826 /* carrier detect pass #2 -- second (stereo) carrier */ 946 /* carrier detect pass #2 -- second (stereo) carrier */
@@ -836,13 +956,16 @@ static int msp3400c_thread(void *data)
836 case 0: /* 4.5 */ 956 case 0: /* 4.5 */
837 case 2: /* 6.0 */ 957 case 2: /* 6.0 */
838 default: 958 default:
839 cd = NULL; count = 0; 959 cd = NULL;
960 count = 0;
840 break; 961 break;
841 } 962 }
842 963
843 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { 964 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
844 /* autodetect doesn't work well with AM ... */ 965 /* autodetect doesn't work well with AM ... */
845 cd = NULL; count = 0; max2 = 0; 966 cd = NULL;
967 count = 0;
968 max2 = 0;
846 } 969 }
847 for (this = 0; this < count; this++) { 970 for (this = 0; this < count; this++) {
848 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); 971 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
@@ -853,7 +976,7 @@ static int msp3400c_thread(void *data)
853 val -= 65536; 976 val -= 65536;
854 if (val2 < val) 977 if (val2 < val)
855 val2 = val, max2 = this; 978 val2 = val, max2 = this;
856 dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name); 979 msp3400_dbg("carrier2 val: %5d / %s\n", val,cd[this].name);
857 } 980 }
858 981
859 /* programm the msp3400 according to the results */ 982 /* programm the msp3400 according to the results */
@@ -865,7 +988,7 @@ static int msp3400c_thread(void *data)
865 msp->second = carrier_detect_55[max2].cdo; 988 msp->second = carrier_detect_55[max2].cdo;
866 msp3400c_setmode(client, MSP_MODE_FM_TERRA); 989 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
867 msp->nicam_on = 0; 990 msp->nicam_on = 0;
868 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 991 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
869 msp->watch_stereo = 1; 992 msp->watch_stereo = 1;
870 } else if (max2 == 1 && HAVE_NICAM(msp)) { 993 } else if (max2 == 1 && HAVE_NICAM(msp)) {
871 /* B/G NICAM */ 994 /* B/G NICAM */
@@ -892,7 +1015,7 @@ static int msp3400c_thread(void *data)
892 msp->second = carrier_detect_65[max2].cdo; 1015 msp->second = carrier_detect_65[max2].cdo;
893 msp3400c_setmode(client, MSP_MODE_FM_TERRA); 1016 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
894 msp->nicam_on = 0; 1017 msp->nicam_on = 0;
895 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1018 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
896 msp->watch_stereo = 1; 1019 msp->watch_stereo = 1;
897 } else if (max2 == 0 && 1020 } else if (max2 == 0 &&
898 msp->norm == VIDEO_MODE_SECAM) { 1021 msp->norm == VIDEO_MODE_SECAM) {
@@ -900,7 +1023,7 @@ static int msp3400c_thread(void *data)
900 msp->second = carrier_detect_65[max2].cdo; 1023 msp->second = carrier_detect_65[max2].cdo;
901 msp3400c_setmode(client, MSP_MODE_AM_NICAM); 1024 msp3400c_setmode(client, MSP_MODE_AM_NICAM);
902 msp->nicam_on = 0; 1025 msp->nicam_on = 0;
903 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1026 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
904 msp3400c_setcarrier(client, msp->second, msp->main); 1027 msp3400c_setcarrier(client, msp->second, msp->main);
905 /* volume prescale for SCART (AM mono input) */ 1028 /* volume prescale for SCART (AM mono input) */
906 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); 1029 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
@@ -924,15 +1047,16 @@ static int msp3400c_thread(void *data)
924 msp->nicam_on = 0; 1047 msp->nicam_on = 0;
925 msp3400c_setcarrier(client, msp->second, msp->main); 1048 msp3400c_setcarrier(client, msp->second, msp->main);
926 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 1049 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
927 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1050 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
928 break; 1051 break;
929 } 1052 }
930 1053
931 /* unmute */ 1054 /* unmute */
932 msp3400c_setvolume(client, msp->muted, 1055 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
933 msp->volume, msp->balance); 1056 msp3400c_restore_dfp(client);
1057
934 if (debug) 1058 if (debug)
935 msp3400c_print_mode(msp); 1059 msp3400c_print_mode(client);
936 1060
937 /* monitor tv audio mode */ 1061 /* monitor tv audio mode */
938 while (msp->watch_stereo) { 1062 while (msp->watch_stereo) {
@@ -941,7 +1065,7 @@ static int msp3400c_thread(void *data)
941 watch_stereo(client); 1065 watch_stereo(client);
942 } 1066 }
943 } 1067 }
944 dprintk(KERN_DEBUG "msp3400: thread: exit\n"); 1068 msp3400_dbg("thread: exit\n");
945 return 0; 1069 return 0;
946} 1070}
947 1071
@@ -985,10 +1109,12 @@ static inline const char *msp34xx_standard_mode_name(int mode)
985 return "unknown"; 1109 return "unknown";
986} 1110}
987 1111
988static int msp34xx_modus(int norm) 1112static int msp34xx_modus(struct i2c_client *client, int norm)
989{ 1113{
990 switch (norm) { 1114 switch (norm) {
991 case VIDEO_MODE_PAL: 1115 case VIDEO_MODE_PAL:
1116 msp3400_dbg("video mode selected to PAL\n");
1117
992#if 1 1118#if 1
993 /* experimental: not sure this works with all chip versions */ 1119 /* experimental: not sure this works with all chip versions */
994 return 0x7003; 1120 return 0x7003;
@@ -997,12 +1123,16 @@ static int msp34xx_modus(int norm)
997 return 0x1003; 1123 return 0x1003;
998#endif 1124#endif
999 case VIDEO_MODE_NTSC: /* BTSC */ 1125 case VIDEO_MODE_NTSC: /* BTSC */
1126 msp3400_dbg("video mode selected to NTSC\n");
1000 return 0x2003; 1127 return 0x2003;
1001 case VIDEO_MODE_SECAM: 1128 case VIDEO_MODE_SECAM:
1129 msp3400_dbg("video mode selected to SECAM\n");
1002 return 0x0003; 1130 return 0x0003;
1003 case VIDEO_MODE_RADIO: 1131 case VIDEO_MODE_RADIO:
1132 msp3400_dbg("video mode selected to Radio\n");
1004 return 0x0003; 1133 return 0x0003;
1005 case VIDEO_MODE_AUTO: 1134 case VIDEO_MODE_AUTO:
1135 msp3400_dbg("video mode selected to Auto\n");
1006 return 0x2003; 1136 return 0x2003;
1007 default: 1137 default:
1008 return 0x0003; 1138 return 0x0003;
@@ -1031,23 +1161,22 @@ static int msp3410d_thread(void *data)
1031 struct msp3400c *msp = i2c_get_clientdata(client); 1161 struct msp3400c *msp = i2c_get_clientdata(client);
1032 int mode,val,i,std; 1162 int mode,val,i,std;
1033 1163
1034 printk("msp3410: daemon started\n"); 1164 msp3400_info("msp3410 daemon started\n");
1035 for (;;) { 1165 for (;;) {
1036 d2printk(KERN_DEBUG "msp3410: thread: sleep\n"); 1166 msp3400_dbg_mediumvol("msp3410 thread: sleep\n");
1037 msp34xx_sleep(msp,-1); 1167 msp34xx_sleep(msp,-1);
1038 d2printk(KERN_DEBUG "msp3410: thread: wakeup\n"); 1168 msp3400_dbg_mediumvol("msp3410 thread: wakeup\n");
1039 1169
1040 restart: 1170 restart:
1041 dprintk("msp3410: thread: restart scan\n"); 1171 msp3400_dbg("thread: restart scan\n");
1042 msp->restart = 0; 1172 msp->restart = 0;
1043 if (kthread_should_stop()) 1173 if (kthread_should_stop())
1044 break; 1174 break;
1045 1175
1046 if (msp->mode == MSP_MODE_EXTERN) { 1176 if (msp->mode == MSP_MODE_EXTERN) {
1047 /* no carrier scan needed, just unmute */ 1177 /* no carrier scan needed, just unmute */
1048 dprintk(KERN_DEBUG "msp3410: thread: no carrier scan\n"); 1178 msp3400_dbg("thread: no carrier scan\n");
1049 msp3400c_setvolume(client, msp->muted, 1179 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1050 msp->volume, msp->balance);
1051 continue; 1180 continue;
1052 } 1181 }
1053 1182
@@ -1059,14 +1188,14 @@ static int msp3410d_thread(void *data)
1059 goto restart; 1188 goto restart;
1060 1189
1061 /* start autodetect */ 1190 /* start autodetect */
1062 mode = msp34xx_modus(msp->norm); 1191 mode = msp34xx_modus(client, msp->norm);
1063 std = msp34xx_standard(msp->norm); 1192 std = msp34xx_standard(msp->norm);
1064 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode); 1193 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
1065 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std); 1194 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
1066 msp->watch_stereo = 0; 1195 msp->watch_stereo = 0;
1067 1196
1068 if (debug) 1197 if (debug)
1069 printk(KERN_DEBUG "msp3410: setting mode: %s (0x%04x)\n", 1198 msp3400_dbg("setting mode: %s (0x%04x)\n",
1070 msp34xx_standard_mode_name(std) ,std); 1199 msp34xx_standard_mode_name(std) ,std);
1071 1200
1072 if (std != 1) { 1201 if (std != 1) {
@@ -1082,13 +1211,13 @@ static int msp3410d_thread(void *data)
1082 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); 1211 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
1083 if (val < 0x07ff) 1212 if (val < 0x07ff)
1084 break; 1213 break;
1085 dprintk(KERN_DEBUG "msp3410: detection still in progress\n"); 1214 msp3400_dbg("detection still in progress\n");
1086 } 1215 }
1087 } 1216 }
1088 for (i = 0; modelist[i].name != NULL; i++) 1217 for (i = 0; modelist[i].name != NULL; i++)
1089 if (modelist[i].retval == val) 1218 if (modelist[i].retval == val)
1090 break; 1219 break;
1091 dprintk(KERN_DEBUG "msp3410: current mode: %s (0x%04x)\n", 1220 msp3400_dbg("current mode: %s (0x%04x)\n",
1092 modelist[i].name ? modelist[i].name : "unknown", 1221 modelist[i].name ? modelist[i].name : "unknown",
1093 val); 1222 val);
1094 msp->main = modelist[i].main; 1223 msp->main = modelist[i].main;
@@ -1096,7 +1225,7 @@ static int msp3410d_thread(void *data)
1096 1225
1097 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { 1226 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
1098 /* autodetection has failed, let backup */ 1227 /* autodetection has failed, let backup */
1099 dprintk(KERN_DEBUG "msp3410: autodetection failed," 1228 msp3400_dbg("autodetection failed,"
1100 " switching to backup mode: %s (0x%04x)\n", 1229 " switching to backup mode: %s (0x%04x)\n",
1101 modelist[8].name ? modelist[8].name : "unknown",val); 1230 modelist[8].name ? modelist[8].name : "unknown",val);
1102 val = 0x0009; 1231 val = 0x0009;
@@ -1120,13 +1249,13 @@ static int msp3410d_thread(void *data)
1120 msp->rxsubchans = V4L2_TUNER_SUB_STEREO; 1249 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1121 msp->nicam_on = 1; 1250 msp->nicam_on = 1;
1122 msp->watch_stereo = 1; 1251 msp->watch_stereo = 1;
1123 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); 1252 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
1124 break; 1253 break;
1125 case 0x0009: 1254 case 0x0009:
1126 msp->mode = MSP_MODE_AM_NICAM; 1255 msp->mode = MSP_MODE_AM_NICAM;
1127 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 1256 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
1128 msp->nicam_on = 1; 1257 msp->nicam_on = 1;
1129 msp3400c_set_audmode(client,V4L2_TUNER_MODE_MONO); 1258 msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
1130 msp->watch_stereo = 1; 1259 msp->watch_stereo = 1;
1131 break; 1260 break;
1132 case 0x0020: /* BTSC */ 1261 case 0x0020: /* BTSC */
@@ -1135,7 +1264,7 @@ static int msp3410d_thread(void *data)
1135 msp->rxsubchans = V4L2_TUNER_SUB_STEREO; 1264 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1136 msp->nicam_on = 0; 1265 msp->nicam_on = 0;
1137 msp->watch_stereo = 1; 1266 msp->watch_stereo = 1;
1138 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); 1267 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
1139 break; 1268 break;
1140 case 0x0040: /* FM radio */ 1269 case 0x0040: /* FM radio */
1141 msp->mode = MSP_MODE_FM_RADIO; 1270 msp->mode = MSP_MODE_FM_RADIO;
@@ -1169,9 +1298,10 @@ static int msp3410d_thread(void *data)
1169 /* unmute, restore misc registers */ 1298 /* unmute, restore misc registers */
1170 msp3400c_setbass(client, msp->bass); 1299 msp3400c_setbass(client, msp->bass);
1171 msp3400c_settreble(client, msp->treble); 1300 msp3400c_settreble(client, msp->treble);
1172 msp3400c_setvolume(client, msp->muted, 1301 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1173 msp->volume, msp->balance); 1302 msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb);
1174 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb); 1303 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1304 msp3400c_restore_dfp(client);
1175 1305
1176 /* monitor tv audio mode */ 1306 /* monitor tv audio mode */
1177 while (msp->watch_stereo) { 1307 while (msp->watch_stereo) {
@@ -1180,7 +1310,7 @@ static int msp3410d_thread(void *data)
1180 watch_stereo(client); 1310 watch_stereo(client);
1181 } 1311 }
1182 } 1312 }
1183 dprintk(KERN_DEBUG "msp3410: thread: exit\n"); 1313 msp3400_dbg("thread: exit\n");
1184 return 0; 1314 return 0;
1185} 1315}
1186 1316
@@ -1195,7 +1325,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source);
1195/* (re-)initialize the msp34xxg, according to the current norm in msp->norm 1325/* (re-)initialize the msp34xxg, according to the current norm in msp->norm
1196 * return 0 if it worked, -1 if it failed 1326 * return 0 if it worked, -1 if it failed
1197 */ 1327 */
1198static int msp34xxg_init(struct i2c_client *client) 1328static int msp34xxg_reset(struct i2c_client *client)
1199{ 1329{
1200 struct msp3400c *msp = i2c_get_clientdata(client); 1330 struct msp3400c *msp = i2c_get_clientdata(client);
1201 int modus,std; 1331 int modus,std;
@@ -1210,8 +1340,10 @@ static int msp34xxg_init(struct i2c_client *client)
1210 0x0f20 /* mute DSP input, mute SCART 1 */)) 1340 0x0f20 /* mute DSP input, mute SCART 1 */))
1211 return -1; 1341 return -1;
1212 1342
1343 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1344
1213 /* step-by-step initialisation, as described in the manual */ 1345 /* step-by-step initialisation, as described in the manual */
1214 modus = msp34xx_modus(msp->norm); 1346 modus = msp34xx_modus(client, msp->norm);
1215 std = msp34xx_standard(msp->norm); 1347 std = msp34xx_standard(msp->norm);
1216 modus &= ~0x03; /* STATUS_CHANGE=0 */ 1348 modus &= ~0x03; /* STATUS_CHANGE=0 */
1217 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */ 1349 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */
@@ -1222,7 +1354,7 @@ static int msp34xxg_init(struct i2c_client *client)
1222 return -1; 1354 return -1;
1223 if (msp3400c_write(client, 1355 if (msp3400c_write(client,
1224 I2C_MSP3400C_DEM, 1356 I2C_MSP3400C_DEM,
1225 0x20/*stanard*/, 1357 0x20/*standard*/,
1226 std)) 1358 std))
1227 return -1; 1359 return -1;
1228 1360
@@ -1230,21 +1362,18 @@ static int msp34xxg_init(struct i2c_client *client)
1230 standard/audio autodetection right now */ 1362 standard/audio autodetection right now */
1231 msp34xxg_set_source(client, msp->source); 1363 msp34xxg_set_source(client, msp->source);
1232 1364
1233 if (msp3400c_write(client, I2C_MSP3400C_DFP, 1365 if (msp3400c_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */
1234 0x0e, /* AM/FM Prescale */ 1366 0x3000
1235 0x3000 /* default: [15:8] 75khz deviation */)) 1367 /* default: [15:8] 75khz deviation */
1368 ))
1236 return -1; 1369 return -1;
1237 1370
1238 if (msp3400c_write(client, I2C_MSP3400C_DFP, 1371 if (msp3400c_write_dfp_with_default(client, 0x10, /* NICAM Prescale */
1239 0x10, /* NICAM Prescale */ 1372 0x5a00
1240 0x5a00 /* default: 9db gain (as recommended) */)) 1373 /* default: 9db gain (as recommended) */
1374 ))
1241 return -1; 1375 return -1;
1242 1376
1243 if (msp3400c_write(client,
1244 I2C_MSP3400C_DEM,
1245 0x20, /* STANDARD SELECT */
1246 standard /* default: 0x01 for automatic standard select*/))
1247 return -1;
1248 return 0; 1377 return 0;
1249} 1378}
1250 1379
@@ -1254,27 +1383,27 @@ static int msp34xxg_thread(void *data)
1254 struct msp3400c *msp = i2c_get_clientdata(client); 1383 struct msp3400c *msp = i2c_get_clientdata(client);
1255 int val, std, i; 1384 int val, std, i;
1256 1385
1257 printk("msp34xxg: daemon started\n"); 1386 msp3400_info("msp34xxg daemon started\n");
1258 msp->source = 1; /* default */ 1387 msp->source = 1; /* default */
1259 for (;;) { 1388 for (;;) {
1260 d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n"); 1389 msp3400_dbg_mediumvol("msp34xxg thread: sleep\n");
1261 msp34xx_sleep(msp,-1); 1390 msp34xx_sleep(msp,-1);
1262 d2printk(KERN_DEBUG "msp34xxg: thread: wakeup\n"); 1391 msp3400_dbg_mediumvol("msp34xxg thread: wakeup\n");
1263 1392
1264 restart: 1393 restart:
1265 dprintk("msp34xxg: thread: restart scan\n"); 1394 msp3400_dbg("thread: restart scan\n");
1266 msp->restart = 0; 1395 msp->restart = 0;
1267 if (kthread_should_stop()) 1396 if (kthread_should_stop())
1268 break; 1397 break;
1269 1398
1270 /* setup the chip*/ 1399 /* setup the chip*/
1271 msp34xxg_init(client); 1400 msp34xxg_reset(client);
1272 std = standard; 1401 std = standard;
1273 if (std != 0x01) 1402 if (std != 0x01)
1274 goto unmute; 1403 goto unmute;
1275 1404
1276 /* watch autodetect */ 1405 /* watch autodetect */
1277 dprintk("msp34xxg: triggered autodetect, waiting for result\n"); 1406 msp3400_dbg("triggered autodetect, waiting for result\n");
1278 for (i = 0; i < 10; i++) { 1407 for (i = 0; i < 10; i++) {
1279 if (msp34xx_sleep(msp,100)) 1408 if (msp34xx_sleep(msp,100))
1280 goto restart; 1409 goto restart;
@@ -1285,23 +1414,23 @@ static int msp34xxg_thread(void *data)
1285 std = val; 1414 std = val;
1286 break; 1415 break;
1287 } 1416 }
1288 dprintk("msp34xxg: detection still in progress\n"); 1417 msp3400_dbg("detection still in progress\n");
1289 } 1418 }
1290 if (0x01 == std) { 1419 if (0x01 == std) {
1291 dprintk("msp34xxg: detection still in progress after 10 tries. giving up.\n"); 1420 msp3400_dbg("detection still in progress after 10 tries. giving up.\n");
1292 continue; 1421 continue;
1293 } 1422 }
1294 1423
1295 unmute: 1424 unmute:
1296 dprintk("msp34xxg: current mode: %s (0x%04x)\n", 1425 msp3400_dbg("current mode: %s (0x%04x)\n",
1297 msp34xx_standard_mode_name(std), std); 1426 msp34xx_standard_mode_name(std), std);
1298 1427
1299 /* unmute: dispatch sound to scart output, set scart volume */ 1428 /* unmute: dispatch sound to scart output, set scart volume */
1300 dprintk("msp34xxg: unmute\n"); 1429 msp3400_dbg("unmute\n");
1301 1430
1302 msp3400c_setbass(client, msp->bass); 1431 msp3400c_setbass(client, msp->bass);
1303 msp3400c_settreble(client, msp->treble); 1432 msp3400c_settreble(client, msp->treble);
1304 msp3400c_setvolume(client, msp->muted, msp->volume, msp->balance); 1433 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1305 1434
1306 /* restore ACB */ 1435 /* restore ACB */
1307 if (msp3400c_write(client, 1436 if (msp3400c_write(client,
@@ -1309,8 +1438,10 @@ static int msp34xxg_thread(void *data)
1309 0x13, /* ACB */ 1438 0x13, /* ACB */
1310 msp->acb)) 1439 msp->acb))
1311 return -1; 1440 return -1;
1441
1442 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1312 } 1443 }
1313 dprintk(KERN_DEBUG "msp34xxg: thread: exit\n"); 1444 msp3400_dbg("thread: exit\n");
1314 return 0; 1445 return 0;
1315} 1446}
1316 1447
@@ -1329,7 +1460,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source)
1329 * for MONO (source==0) downmixing set bit[7:0] to 0x30 1460 * for MONO (source==0) downmixing set bit[7:0] to 0x30
1330 */ 1461 */
1331 int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); 1462 int value = (source&0x07)<<8|(source==0 ? 0x30:0x20);
1332 dprintk("msp34xxg: set source to %d (0x%x)\n", source, value); 1463 msp3400_dbg("set source to %d (0x%x)\n", source, value);
1333 msp3400c_write(client, 1464 msp3400c_write(client,
1334 I2C_MSP3400C_DFP, 1465 I2C_MSP3400C_DFP,
1335 0x08, /* Loudspeaker Output */ 1466 0x08, /* Loudspeaker Output */
@@ -1380,7 +1511,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client)
1380 * this is a problem, I'll handle SAP just like lang1/lang2. 1511 * this is a problem, I'll handle SAP just like lang1/lang2.
1381 */ 1512 */
1382 } 1513 }
1383 dprintk("msp34xxg: status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", 1514 msp3400_dbg("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
1384 status, is_stereo, is_bilingual, msp->rxsubchans); 1515 status, is_stereo, is_bilingual, msp->rxsubchans);
1385} 1516}
1386 1517
@@ -1427,7 +1558,7 @@ static void msp_wake_thread(struct i2c_client *client);
1427 1558
1428static struct i2c_driver driver = { 1559static struct i2c_driver driver = {
1429 .owner = THIS_MODULE, 1560 .owner = THIS_MODULE,
1430 .name = "i2c msp3400 driver", 1561 .name = "msp3400",
1431 .id = I2C_DRIVERID_MSP3400, 1562 .id = I2C_DRIVERID_MSP3400,
1432 .flags = I2C_DF_NOTIFY, 1563 .flags = I2C_DF_NOTIFY,
1433 .attach_adapter = msp_probe, 1564 .attach_adapter = msp_probe,
@@ -1449,57 +1580,64 @@ static struct i2c_client client_template =
1449static int msp_attach(struct i2c_adapter *adap, int addr, int kind) 1580static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1450{ 1581{
1451 struct msp3400c *msp; 1582 struct msp3400c *msp;
1452 struct i2c_client *c; 1583 struct i2c_client *client = &client_template;
1453 int (*thread_func)(void *data) = NULL; 1584 int (*thread_func)(void *data) = NULL;
1585 int i;
1454 1586
1455 client_template.adapter = adap; 1587 client_template.adapter = adap;
1456 client_template.addr = addr; 1588 client_template.addr = addr;
1457 1589
1458 if (-1 == msp3400c_reset(&client_template)) { 1590 if (-1 == msp3400c_reset(&client_template)) {
1459 dprintk("msp34xx: no chip found\n"); 1591 msp3400_dbg("no chip found\n");
1460 return -1; 1592 return -1;
1461 } 1593 }
1462 1594
1463 if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) 1595 if (NULL == (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
1464 return -ENOMEM; 1596 return -ENOMEM;
1465 memcpy(c,&client_template,sizeof(struct i2c_client)); 1597 memcpy(client,&client_template,sizeof(struct i2c_client));
1466 if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) { 1598 if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
1467 kfree(c); 1599 kfree(client);
1468 return -ENOMEM; 1600 return -ENOMEM;
1469 } 1601 }
1470 1602
1471 memset(msp,0,sizeof(struct msp3400c)); 1603 memset(msp,0,sizeof(struct msp3400c));
1472 msp->volume = 58880; /* 0db gain */ 1604 msp->norm = VIDEO_MODE_NTSC;
1473 msp->balance = 32768; 1605 msp->left = 58880; /* 0db gain */
1474 msp->bass = 32768; 1606 msp->right = 58880; /* 0db gain */
1475 msp->treble = 32768; 1607 msp->bass = 32768;
1476 msp->input = -1; 1608 msp->treble = 32768;
1477 msp->muted = 1; 1609 msp->input = -1;
1478 1610 msp->muted = 0;
1479 i2c_set_clientdata(c, msp); 1611 msp->i2s_mode = 0;
1612 for (i = 0; i < DFP_COUNT; i++)
1613 msp->dfp_regs[i] = -1;
1614
1615 i2c_set_clientdata(client, msp);
1480 init_waitqueue_head(&msp->wq); 1616 init_waitqueue_head(&msp->wq);
1481 1617
1482 if (-1 == msp3400c_reset(c)) { 1618 if (-1 == msp3400c_reset(client)) {
1483 kfree(msp); 1619 kfree(msp);
1484 kfree(c); 1620 kfree(client);
1485 dprintk("msp34xx: no chip found\n"); 1621 msp3400_dbg("no chip found\n");
1486 return -1; 1622 return -1;
1487 } 1623 }
1488 1624
1489 msp->rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e); 1625 msp->rev1 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1e);
1490 if (-1 != msp->rev1) 1626 if (-1 != msp->rev1)
1491 msp->rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f); 1627 msp->rev2 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1f);
1492 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) { 1628 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
1493 kfree(msp); 1629 kfree(msp);
1494 kfree(c); 1630 kfree(client);
1495 dprintk("msp34xx: error while reading chip version\n"); 1631 msp3400_dbg("error while reading chip version\n");
1496 return -1; 1632 return -1;
1497 } 1633 }
1634 msp3400_dbg("rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2);
1498 1635
1499 msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance); 1636 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1500 1637
1501 snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d", 1638 snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d",
1502 (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@', 1639 ((msp->rev1>>4)&0x0f) + '3',
1640 (msp->rev2>>8)&0xff, (msp->rev1&0x0f)+'@',
1503 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f); 1641 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
1504 1642
1505 msp->opmode = opmode; 1643 msp->opmode = opmode;
@@ -1513,7 +1651,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1513 } 1651 }
1514 1652
1515 /* hello world :-) */ 1653 /* hello world :-) */
1516 printk(KERN_INFO "msp34xx: init: chip=%s", c->name); 1654 msp3400_info("chip=%s", client->name);
1517 if (HAVE_NICAM(msp)) 1655 if (HAVE_NICAM(msp))
1518 printk(" +nicam"); 1656 printk(" +nicam");
1519 if (HAVE_SIMPLE(msp)) 1657 if (HAVE_SIMPLE(msp))
@@ -1542,29 +1680,49 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1542 1680
1543 /* startup control thread if needed */ 1681 /* startup control thread if needed */
1544 if (thread_func) { 1682 if (thread_func) {
1545 msp->kthread = kthread_run(thread_func, c, "msp34xx"); 1683 msp->kthread = kthread_run(thread_func, client, "msp34xx");
1684
1546 if (NULL == msp->kthread) 1685 if (NULL == msp->kthread)
1547 printk(KERN_WARNING "msp34xx: kernel_thread() failed\n"); 1686 msp3400_warn("kernel_thread() failed\n");
1548 msp_wake_thread(c); 1687 msp_wake_thread(client);
1549 } 1688 }
1550 1689
1551 /* done */ 1690 /* done */
1552 i2c_attach_client(c); 1691 i2c_attach_client(client);
1692
1693 /* update our own array */
1694 for (i = 0; i < MSP3400_MAX; i++) {
1695 if (NULL == msps[i]) {
1696 msps[i] = client;
1697 break;
1698 }
1699 }
1700
1553 return 0; 1701 return 0;
1554} 1702}
1555 1703
1556static int msp_detach(struct i2c_client *client) 1704static int msp_detach(struct i2c_client *client)
1557{ 1705{
1558 struct msp3400c *msp = i2c_get_clientdata(client); 1706 struct msp3400c *msp = i2c_get_clientdata(client);
1707 int i;
1559 1708
1560 /* shutdown control thread */ 1709 /* shutdown control thread */
1561 if (msp->kthread >= 0) { 1710 if (msp->kthread) {
1562 msp->restart = 1; 1711 msp->restart = 1;
1563 kthread_stop(msp->kthread); 1712 kthread_stop(msp->kthread);
1564 } 1713 }
1565 msp3400c_reset(client); 1714 msp3400c_reset(client);
1715
1716 /* update our own array */
1717 for (i = 0; i < MSP3400_MAX; i++) {
1718 if (client == msps[i]) {
1719 msps[i] = NULL;
1720 break;
1721 }
1722 }
1566 1723
1567 i2c_detach_client(client); 1724 i2c_detach_client(client);
1725
1568 kfree(msp); 1726 kfree(msp);
1569 kfree(client); 1727 kfree(client);
1570 return 0; 1728 return 0;
@@ -1640,7 +1798,7 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1640 case OPMODE_MANUAL: 1798 case OPMODE_MANUAL:
1641 case OPMODE_SIMPLE: 1799 case OPMODE_SIMPLE:
1642 msp->watch_stereo = 0; 1800 msp->watch_stereo = 0;
1643 msp3400c_set_audmode(client, audmode); 1801 msp3400c_setstereo(client, audmode);
1644 break; 1802 break;
1645 case OPMODE_SIMPLER: 1803 case OPMODE_SIMPLER:
1646 msp34xxg_set_audmode(client, audmode); 1804 msp34xxg_set_audmode(client, audmode);
@@ -1648,16 +1806,18 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1648 } 1806 }
1649} 1807}
1650 1808
1809
1651static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) 1810static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1652{ 1811{
1653 struct msp3400c *msp = i2c_get_clientdata(client); 1812 struct msp3400c *msp = i2c_get_clientdata(client);
1654 __u16 *sarg = arg; 1813 __u16 *sarg = arg;
1655 int scart = 0; 1814 int scart = 0;
1656 1815
1657 switch (cmd) { 1816 switch (cmd) {
1658 1817
1659 case AUDC_SET_INPUT: 1818 case AUDC_SET_INPUT:
1660 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg); 1819 msp3400_dbg("AUDC_SET_INPUT(%d)\n",*sarg);
1820
1661 if (*sarg == msp->input) 1821 if (*sarg == msp->input)
1662 break; 1822 break;
1663 msp->input = *sarg; 1823 msp->input = *sarg;
@@ -1691,15 +1851,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1691 msp3400c_set_scart(client,scart,0); 1851 msp3400c_set_scart(client,scart,0);
1692 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); 1852 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
1693 if (msp->opmode != OPMODE_SIMPLER) 1853 if (msp->opmode != OPMODE_SIMPLER)
1694 msp3400c_set_audmode(client, msp->audmode); 1854 msp3400c_setstereo(client, msp->audmode);
1695 } 1855 }
1696 msp_wake_thread(client); 1856 msp_wake_thread(client);
1697 break; 1857 break;
1698 1858
1699 case AUDC_SET_RADIO: 1859 case AUDC_SET_RADIO:
1700 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_RADIO\n"); 1860 msp3400_dbg("AUDC_SET_RADIO\n");
1701 msp->norm = VIDEO_MODE_RADIO; 1861 msp->norm = VIDEO_MODE_RADIO;
1702 dprintk(KERN_DEBUG "msp34xx: switching to radio mode\n"); 1862 msp3400_dbg("switching to radio mode\n");
1703 msp->watch_stereo = 0; 1863 msp->watch_stereo = 0;
1704 switch (msp->opmode) { 1864 switch (msp->opmode) {
1705 case OPMODE_MANUAL: 1865 case OPMODE_MANUAL:
@@ -1707,8 +1867,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1707 msp3400c_setmode(client,MSP_MODE_FM_RADIO); 1867 msp3400c_setmode(client,MSP_MODE_FM_RADIO);
1708 msp3400c_setcarrier(client, MSP_CARRIER(10.7), 1868 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
1709 MSP_CARRIER(10.7)); 1869 MSP_CARRIER(10.7));
1710 msp3400c_setvolume(client, msp->muted, 1870 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1711 msp->volume, msp->balance);
1712 break; 1871 break;
1713 case OPMODE_SIMPLE: 1872 case OPMODE_SIMPLE:
1714 case OPMODE_SIMPLER: 1873 case OPMODE_SIMPLER:
@@ -1717,6 +1876,30 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1717 break; 1876 break;
1718 } 1877 }
1719 break; 1878 break;
1879 /* work-in-progress: hook to control the DFP registers */
1880 case MSP_SET_DFPREG:
1881 {
1882 struct msp_dfpreg *r = arg;
1883 int i;
1884
1885 if (r->reg < 0 || r->reg >= DFP_COUNT)
1886 return -EINVAL;
1887 for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++)
1888 if (r->reg == bl_dfp[i])
1889 return -EINVAL;
1890 msp->dfp_regs[r->reg] = r->value;
1891 msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value);
1892 return 0;
1893 }
1894 case MSP_GET_DFPREG:
1895 {
1896 struct msp_dfpreg *r = arg;
1897
1898 if (r->reg < 0 || r->reg >= DFP_COUNT)
1899 return -EINVAL;
1900 r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg);
1901 return 0;
1902 }
1720 1903
1721 /* --- v4l ioctls --- */ 1904 /* --- v4l ioctls --- */
1722 /* take care: bttv does userspace copying, we'll get a 1905 /* take care: bttv does userspace copying, we'll get a
@@ -1725,7 +1908,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1725 { 1908 {
1726 struct video_audio *va = arg; 1909 struct video_audio *va = arg;
1727 1910
1728 dprintk(KERN_DEBUG "msp34xx: VIDIOCGAUDIO\n"); 1911 msp3400_dbg("VIDIOCGAUDIO\n");
1729 va->flags |= VIDEO_AUDIO_VOLUME | 1912 va->flags |= VIDEO_AUDIO_VOLUME |
1730 VIDEO_AUDIO_BASS | 1913 VIDEO_AUDIO_BASS |
1731 VIDEO_AUDIO_TREBLE | 1914 VIDEO_AUDIO_TREBLE |
@@ -1733,8 +1916,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1733 if (msp->muted) 1916 if (msp->muted)
1734 va->flags |= VIDEO_AUDIO_MUTE; 1917 va->flags |= VIDEO_AUDIO_MUTE;
1735 1918
1736 va->volume = msp->volume; 1919 if (msp->muted)
1737 va->balance = (va->volume) ? msp->balance : 32768; 1920 va->flags |= VIDEO_AUDIO_MUTE;
1921 va->volume = MAX(msp->left, msp->right);
1922 va->balance = (32768 * MIN(msp->left, msp->right)) /
1923 (va->volume ? va->volume : 1);
1924 va->balance = (msp->left < msp->right) ?
1925 (65535 - va->balance) : va->balance;
1926 if (0 == va->volume)
1927 va->balance = 32768;
1738 va->bass = msp->bass; 1928 va->bass = msp->bass;
1739 va->treble = msp->treble; 1929 va->treble = msp->treble;
1740 1930
@@ -1746,27 +1936,43 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1746 { 1936 {
1747 struct video_audio *va = arg; 1937 struct video_audio *va = arg;
1748 1938
1749 dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n"); 1939 msp3400_dbg("VIDIOCSAUDIO\n");
1750 msp->muted = (va->flags & VIDEO_AUDIO_MUTE); 1940 msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
1751 msp->volume = va->volume; 1941 msp->left = (MIN(65536 - va->balance, 32768) *
1752 msp->balance = va->balance; 1942 va->volume) / 32768;
1943 msp->right = (MIN(va->balance, 32768) * va->volume) / 32768;
1753 msp->bass = va->bass; 1944 msp->bass = va->bass;
1754 msp->treble = va->treble; 1945 msp->treble = va->treble;
1755 1946 msp3400_dbg("VIDIOCSAUDIO setting va->volume to %d\n",
1756 msp3400c_setvolume(client, msp->muted, 1947 va->volume);
1757 msp->volume, msp->balance); 1948 msp3400_dbg("VIDIOCSAUDIO setting va->balance to %d\n",
1758 msp3400c_setbass(client,msp->bass); 1949 va->balance);
1759 msp3400c_settreble(client,msp->treble); 1950 msp3400_dbg("VIDIOCSAUDIO setting va->flags to %d\n",
1951 va->flags);
1952 msp3400_dbg("VIDIOCSAUDIO setting msp->left to %d\n",
1953 msp->left);
1954 msp3400_dbg("VIDIOCSAUDIO setting msp->right to %d\n",
1955 msp->right);
1956 msp3400_dbg("VIDIOCSAUDIO setting msp->bass to %d\n",
1957 msp->bass);
1958 msp3400_dbg("VIDIOCSAUDIO setting msp->treble to %d\n",
1959 msp->treble);
1960 msp3400_dbg("VIDIOCSAUDIO setting msp->mode to %d\n",
1961 msp->mode);
1962 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1963 msp3400c_setbass(client, msp->bass);
1964 msp3400c_settreble(client, msp->treble);
1760 1965
1761 if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) 1966 if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO)
1762 msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); 1967 msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode));
1763 break; 1968 break;
1764 } 1969 }
1970
1765 case VIDIOCSCHAN: 1971 case VIDIOCSCHAN:
1766 { 1972 {
1767 struct video_channel *vc = arg; 1973 struct video_channel *vc = arg;
1768 1974
1769 dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN (norm=%d)\n",vc->norm); 1975 msp3400_dbg("VIDIOCSCHAN (norm=%d)\n",vc->norm);
1770 msp->norm = vc->norm; 1976 msp->norm = vc->norm;
1771 msp_wake_thread(client); 1977 msp_wake_thread(client);
1772 break; 1978 break;
@@ -1776,12 +1982,135 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1776 case VIDIOC_S_FREQUENCY: 1982 case VIDIOC_S_FREQUENCY:
1777 { 1983 {
1778 /* new channel -- kick audio carrier scan */ 1984 /* new channel -- kick audio carrier scan */
1779 dprintk(KERN_DEBUG "msp34xx: VIDIOCSFREQ\n"); 1985 msp3400_dbg("VIDIOCSFREQ\n");
1780 msp_wake_thread(client); 1986 msp_wake_thread(client);
1781 break; 1987 break;
1782 } 1988 }
1783 1989
1990 /* msp34xx specific */
1991 case MSP_SET_MATRIX:
1992 {
1993 struct msp_matrix *mspm = arg;
1994
1995 msp3400_dbg("MSP_SET_MATRIX\n");
1996 msp3400c_set_scart(client, mspm->input, mspm->output);
1997 break;
1998 }
1999
1784 /* --- v4l2 ioctls --- */ 2000 /* --- v4l2 ioctls --- */
2001 case VIDIOC_S_STD:
2002 {
2003 v4l2_std_id *id = arg;
2004
2005 /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/
2006 if (*id & V4L2_STD_PAL) {
2007 msp->norm=VIDEO_MODE_PAL;
2008 } else if (*id & V4L2_STD_SECAM) {
2009 msp->norm=VIDEO_MODE_SECAM;
2010 } else {
2011 msp->norm=VIDEO_MODE_NTSC;
2012 }
2013
2014 msp_wake_thread(client);
2015 return 0;
2016 }
2017
2018 case VIDIOC_ENUMINPUT:
2019 {
2020 struct v4l2_input *i = arg;
2021
2022 if (i->index != 0)
2023 return -EINVAL;
2024
2025 i->type = V4L2_INPUT_TYPE_TUNER;
2026 switch (i->index) {
2027 case AUDIO_RADIO:
2028 strcpy(i->name,"Radio");
2029 break;
2030 case AUDIO_EXTERN_1:
2031 strcpy(i->name,"Extern 1");
2032 break;
2033 case AUDIO_EXTERN_2:
2034 strcpy(i->name,"Extern 2");
2035 break;
2036 case AUDIO_TUNER:
2037 strcpy(i->name,"Television");
2038 break;
2039 default:
2040 return -EINVAL;
2041 }
2042 return 0;
2043 }
2044
2045 case VIDIOC_G_AUDIO:
2046 {
2047 struct v4l2_audio *a = arg;
2048
2049 memset(a,0,sizeof(*a));
2050
2051 switch (a->index) {
2052 case AUDIO_RADIO:
2053 strcpy(a->name,"Radio");
2054 break;
2055 case AUDIO_EXTERN_1:
2056 strcpy(a->name,"Extern 1");
2057 break;
2058 case AUDIO_EXTERN_2:
2059 strcpy(a->name,"Extern 2");
2060 break;
2061 case AUDIO_TUNER:
2062 strcpy(a->name,"Television");
2063 break;
2064 default:
2065 return -EINVAL;
2066 }
2067
2068 msp_any_detect_stereo(client);
2069 if (msp->audmode == V4L2_TUNER_MODE_STEREO) {
2070 a->capability=V4L2_AUDCAP_STEREO;
2071 }
2072
2073 break;
2074 }
2075 case VIDIOC_S_AUDIO:
2076 {
2077 struct v4l2_audio *sarg = arg;
2078
2079 switch (sarg->index) {
2080 case AUDIO_RADIO:
2081 /* Hauppauge uses IN2 for the radio */
2082 msp->mode = MSP_MODE_FM_RADIO;
2083 scart = SCART_IN2;
2084 break;
2085 case AUDIO_EXTERN_1:
2086 /* IN1 is often used for external input ... */
2087 msp->mode = MSP_MODE_EXTERN;
2088 scart = SCART_IN1;
2089 break;
2090 case AUDIO_EXTERN_2:
2091 /* ... sometimes it is IN2 through ;) */
2092 msp->mode = MSP_MODE_EXTERN;
2093 scart = SCART_IN2;
2094 break;
2095 case AUDIO_TUNER:
2096 msp->mode = -1;
2097 break;
2098 }
2099 if (scart) {
2100 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
2101 msp->audmode = V4L2_TUNER_MODE_STEREO;
2102 msp3400c_set_scart(client,scart,0);
2103 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
2104 }
2105 if (sarg->capability==V4L2_AUDCAP_STEREO) {
2106 msp->audmode = V4L2_TUNER_MODE_STEREO;
2107 } else {
2108 msp->audmode &= ~V4L2_TUNER_MODE_STEREO;
2109 }
2110 msp_any_set_audmode(client, msp->audmode);
2111 msp_wake_thread(client);
2112 break;
2113 }
1785 case VIDIOC_G_TUNER: 2114 case VIDIOC_G_TUNER:
1786 { 2115 {
1787 struct v4l2_tuner *vt = arg; 2116 struct v4l2_tuner *vt = arg;
@@ -1804,13 +2133,46 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1804 break; 2133 break;
1805 } 2134 }
1806 2135
1807 /* msp34xx specific */ 2136 case VIDIOC_G_AUDOUT:
1808 case MSP_SET_MATRIX:
1809 { 2137 {
1810 struct msp_matrix *mspm = arg; 2138 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2139 int idx=a->index;
2140
2141 memset(a,0,sizeof(*a));
2142
2143 switch (idx) {
2144 case 0:
2145 strcpy(a->name,"Scart1 Out");
2146 break;
2147 case 1:
2148 strcpy(a->name,"Scart2 Out");
2149 break;
2150 case 2:
2151 strcpy(a->name,"I2S Out");
2152 break;
2153 default:
2154 return -EINVAL;
2155 }
2156 break;
2157
2158 }
2159 case VIDIOC_S_AUDOUT:
2160 {
2161 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2162
2163 if (a->index<0||a->index>2)
2164 return -EINVAL;
2165
2166 if (a->index==2) {
2167 if (a->mode == V4L2_AUDMODE_32BITS)
2168 msp->i2s_mode=1;
2169 else
2170 msp->i2s_mode=0;
2171 }
2172 msp3400_dbg("Setting audio out on msp34xx to input %i, mode %i\n",
2173 a->index,msp->i2s_mode);
2174 msp3400c_set_scart(client,msp->in_scart,a->index+1);
1811 2175
1812 dprintk(KERN_DEBUG "msp34xx: MSP_SET_MATRIX\n");
1813 msp3400c_set_scart(client, mspm->input, mspm->output);
1814 break; 2176 break;
1815 } 2177 }
1816 2178
@@ -1823,19 +2185,19 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1823 2185
1824static int msp_suspend(struct device * dev, pm_message_t state) 2186static int msp_suspend(struct device * dev, pm_message_t state)
1825{ 2187{
1826 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 2188 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1827 2189
1828 dprintk("msp34xx: suspend\n"); 2190 msp3400_dbg("msp34xx: suspend\n");
1829 msp3400c_reset(c); 2191 msp3400c_reset(client);
1830 return 0; 2192 return 0;
1831} 2193}
1832 2194
1833static int msp_resume(struct device * dev) 2195static int msp_resume(struct device * dev)
1834{ 2196{
1835 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 2197 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1836 2198
1837 dprintk("msp34xx: resume\n"); 2199 msp3400_dbg("msp34xx: resume\n");
1838 msp_wake_thread(c); 2200 msp_wake_thread(client);
1839 return 0; 2201 return 0;
1840} 2202}
1841 2203
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 972aa5e0aeef..2180018f06de 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -76,17 +76,17 @@ static int mt2032_compute_freq(struct i2c_client *c,
76 unsigned int xogc) //all in Hz 76 unsigned int xogc) //all in Hz
77{ 77{
78 struct tuner *t = i2c_get_clientdata(c); 78 struct tuner *t = i2c_get_clientdata(c);
79 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1, 79 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
80 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq; 80 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
81 81
82 fref= 5250 *1000; //5.25MHz 82 fref= 5250 *1000; //5.25MHz
83 desired_lo1=rfin+if1; 83 desired_lo1=rfin+if1;
84 84
85 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000); 85 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
86 lo1n=lo1/8; 86 lo1n=lo1/8;
87 lo1a=lo1-(lo1n*8); 87 lo1a=lo1-(lo1n*8);
88 88
89 s=rfin/1000/1000+1090; 89 s=rfin/1000/1000+1090;
90 90
91 if(optimize_vco) { 91 if(optimize_vco) {
92 if(s>1890) sel=0; 92 if(s>1890) sel=0;
@@ -96,34 +96,34 @@ static int mt2032_compute_freq(struct i2c_client *c,
96 else sel=4; // >1090 96 else sel=4; // >1090
97 } 97 }
98 else { 98 else {
99 if(s>1790) sel=0; // <1958 99 if(s>1790) sel=0; // <1958
100 else if(s>1617) sel=1; 100 else if(s>1617) sel=1;
101 else if(s>1449) sel=2; 101 else if(s>1449) sel=2;
102 else if(s>1291) sel=3; 102 else if(s>1291) sel=3;
103 else sel=4; // >1090 103 else sel=4; // >1090
104 } 104 }
105 *ret_sel=sel; 105 *ret_sel=sel;
106 106
107 lo1freq=(lo1a+8*lo1n)*fref; 107 lo1freq=(lo1a+8*lo1n)*fref;
108 108
109 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n", 109 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
110 rfin,lo1,lo1n,lo1a,sel,lo1freq); 110 rfin,lo1,lo1n,lo1a,sel,lo1freq);
111 111
112 desired_lo2=lo1freq-rfin-if2; 112 desired_lo2=lo1freq-rfin-if2;
113 lo2=(desired_lo2)/fref; 113 lo2=(desired_lo2)/fref;
114 lo2n=lo2/8; 114 lo2n=lo2/8;
115 lo2a=lo2-(lo2n*8); 115 lo2a=lo2-(lo2n*8);
116 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith 116 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
117 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000; 117 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
118 118
119 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n", 119 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
120 rfin,lo2,lo2n,lo2a,lo2num,lo2freq); 120 rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
121 121
122 if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) { 122 if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
123 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n", 123 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
124 lo1a, lo1n, lo2a,lo2n); 124 lo1a, lo1n, lo2a,lo2n);
125 return(-1); 125 return(-1);
126 } 126 }
127 127
128 mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to); 128 mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to);
129 // should recalculate lo1 (one step up/down) 129 // should recalculate lo1 (one step up/down)
@@ -135,10 +135,10 @@ static int mt2032_compute_freq(struct i2c_client *c,
135 buf[3]=0x0f; //reserved 135 buf[3]=0x0f; //reserved
136 buf[4]=0x1f; 136 buf[4]=0x1f;
137 buf[5]=(lo2n-1) | (lo2a<<5); 137 buf[5]=(lo2n-1) | (lo2a<<5);
138 if(rfin >400*1000*1000) 138 if(rfin >400*1000*1000)
139 buf[6]=0xe4; 139 buf[6]=0xe4;
140 else 140 else
141 buf[6]=0xf4; // set PKEN per rev 1.2 141 buf[6]=0xf4; // set PKEN per rev 1.2
142 buf[7]=8+xogc; 142 buf[7]=8+xogc;
143 buf[8]=0xc3; //reserved 143 buf[8]=0xc3; //reserved
144 buf[9]=0x4e; //reserved 144 buf[9]=0x4e; //reserved
@@ -168,7 +168,7 @@ static int mt2032_check_lo_lock(struct i2c_client *c)
168 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]); 168 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
169 udelay(1000); 169 udelay(1000);
170 } 170 }
171 return lock; 171 return lock;
172} 172}
173 173
174static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock) 174static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
@@ -202,7 +202,7 @@ static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
202 202
203 buf[0]=0x0f; 203 buf[0]=0x0f;
204 buf[1]=sel; 204 buf[1]=sel;
205 i2c_master_send(c,buf,2); 205 i2c_master_send(c,buf,2);
206 lock=mt2032_check_lo_lock(c); 206 lock=mt2032_check_lo_lock(c);
207 return lock; 207 return lock;
208} 208}
@@ -219,23 +219,23 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
219 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", 219 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
220 rfin,if1,if2,from,to); 220 rfin,if1,if2,from,to);
221 221
222 buf[0]=0; 222 buf[0]=0;
223 ret=i2c_master_send(c,buf,1); 223 ret=i2c_master_send(c,buf,1);
224 i2c_master_recv(c,buf,21); 224 i2c_master_recv(c,buf,21);
225 225
226 buf[0]=0; 226 buf[0]=0;
227 ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc); 227 ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc);
228 if (ret<0) 228 if (ret<0)
229 return; 229 return;
230 230
231 // send only the relevant registers per Rev. 1.2 231 // send only the relevant registers per Rev. 1.2
232 buf[0]=0; 232 buf[0]=0;
233 ret=i2c_master_send(c,buf,4); 233 ret=i2c_master_send(c,buf,4);
234 buf[5]=5; 234 buf[5]=5;
235 ret=i2c_master_send(c,buf+5,4); 235 ret=i2c_master_send(c,buf+5,4);
236 buf[11]=11; 236 buf[11]=11;
237 ret=i2c_master_send(c,buf+11,3); 237 ret=i2c_master_send(c,buf+11,3);
238 if(ret!=3) 238 if(ret!=3)
239 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret); 239 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
240 240
241 // wait for PLLs to lock (per manual), retry LINT if not. 241 // wait for PLLs to lock (per manual), retry LINT if not.
@@ -253,7 +253,7 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
253 mdelay(10); 253 mdelay(10);
254 buf[1]=8+t->xogc; 254 buf[1]=8+t->xogc;
255 i2c_master_send(c,buf,2); 255 i2c_master_send(c,buf,2);
256 } 256 }
257 257
258 if (lock!=6) 258 if (lock!=6)
259 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n"); 259 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
@@ -284,7 +284,7 @@ static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
284 if2 = 38900*1000; 284 if2 = 38900*1000;
285 } 285 }
286 286
287 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, 287 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
288 1090*1000*1000, if2, from, to); 288 1090*1000*1000, if2, from, to);
289} 289}
290 290
@@ -294,7 +294,7 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
294 int if2 = t->radio_if2; 294 int if2 = t->radio_if2;
295 295
296 // per Manual for FM tuning: first if center freq. 1085 MHz 296 // per Manual for FM tuning: first if center freq. 1085 MHz
297 mt2032_set_if_freq(c, freq * 1000 / 16, 297 mt2032_set_if_freq(c, freq * 1000 / 16,
298 1085*1000*1000,if2,if2,if2); 298 1085*1000*1000,if2,if2,if2);
299} 299}
300 300
@@ -302,57 +302,57 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
302static int mt2032_init(struct i2c_client *c) 302static int mt2032_init(struct i2c_client *c)
303{ 303{
304 struct tuner *t = i2c_get_clientdata(c); 304 struct tuner *t = i2c_get_clientdata(c);
305 unsigned char buf[21]; 305 unsigned char buf[21];
306 int ret,xogc,xok=0; 306 int ret,xogc,xok=0;
307 307
308 // Initialize Registers per spec. 308 // Initialize Registers per spec.
309 buf[1]=2; // Index to register 2 309 buf[1]=2; // Index to register 2
310 buf[2]=0xff; 310 buf[2]=0xff;
311 buf[3]=0x0f; 311 buf[3]=0x0f;
312 buf[4]=0x1f; 312 buf[4]=0x1f;
313 ret=i2c_master_send(c,buf+1,4); 313 ret=i2c_master_send(c,buf+1,4);
314 314
315 buf[5]=6; // Index register 6 315 buf[5]=6; // Index register 6
316 buf[6]=0xe4; 316 buf[6]=0xe4;
317 buf[7]=0x8f; 317 buf[7]=0x8f;
318 buf[8]=0xc3; 318 buf[8]=0xc3;
319 buf[9]=0x4e; 319 buf[9]=0x4e;
320 buf[10]=0xec; 320 buf[10]=0xec;
321 ret=i2c_master_send(c,buf+5,6); 321 ret=i2c_master_send(c,buf+5,6);
322 322
323 buf[12]=13; // Index register 13 323 buf[12]=13; // Index register 13
324 buf[13]=0x32; 324 buf[13]=0x32;
325 ret=i2c_master_send(c,buf+12,2); 325 ret=i2c_master_send(c,buf+12,2);
326 326
327 // Adjust XOGC (register 7), wait for XOK 327 // Adjust XOGC (register 7), wait for XOK
328 xogc=7; 328 xogc=7;
329 do { 329 do {
330 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); 330 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
331 mdelay(10); 331 mdelay(10);
332 buf[0]=0x0e; 332 buf[0]=0x0e;
333 i2c_master_send(c,buf,1); 333 i2c_master_send(c,buf,1);
334 i2c_master_recv(c,buf,1); 334 i2c_master_recv(c,buf,1);
335 xok=buf[0]&0x01; 335 xok=buf[0]&0x01;
336 tuner_dbg("mt2032: xok = 0x%02x\n",xok); 336 tuner_dbg("mt2032: xok = 0x%02x\n",xok);
337 if (xok == 1) break; 337 if (xok == 1) break;
338 338
339 xogc--; 339 xogc--;
340 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); 340 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
341 if (xogc == 3) { 341 if (xogc == 3) {
342 xogc=4; // min. 4 per spec 342 xogc=4; // min. 4 per spec
343 break; 343 break;
344 } 344 }
345 buf[0]=0x07; 345 buf[0]=0x07;
346 buf[1]=0x88 + xogc; 346 buf[1]=0x88 + xogc;
347 ret=i2c_master_send(c,buf,2); 347 ret=i2c_master_send(c,buf,2);
348 if (ret!=2) 348 if (ret!=2)
349 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); 349 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
350 } while (xok != 1 ); 350 } while (xok != 1 );
351 t->xogc=xogc; 351 t->xogc=xogc;
352 352
353 t->tv_freq = mt2032_set_tv_freq; 353 t->tv_freq = mt2032_set_tv_freq;
354 t->radio_freq = mt2032_set_radio_freq; 354 t->radio_freq = mt2032_set_radio_freq;
355 return(1); 355 return(1);
356} 356}
357 357
358static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna) 358static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna)
@@ -426,7 +426,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
426 } 426 }
427 427
428 ret=i2c_master_send(c,buf,6); 428 ret=i2c_master_send(c,buf,6);
429 if (ret!=6) 429 if (ret!=6)
430 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret); 430 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
431} 431}
432 432
@@ -437,11 +437,11 @@ static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
437 437
438 if (t->std & V4L2_STD_525_60) { 438 if (t->std & V4L2_STD_525_60) {
439 // NTSC 439 // NTSC
440 if2 = 45750*1000; 440 if2 = 45750*1000;
441 } else { 441 } else {
442 // PAL 442 // PAL
443 if2 = 38900*1000; 443 if2 = 38900*1000;
444 } 444 }
445 if (V4L2_TUNER_DIGITAL_TV == t->mode) { 445 if (V4L2_TUNER_DIGITAL_TV == t->mode) {
446 // DVB (pinnacle 300i) 446 // DVB (pinnacle 300i)
447 if2 = 36150*1000; 447 if2 = 36150*1000;
@@ -455,7 +455,7 @@ static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq)
455 struct tuner *t = i2c_get_clientdata(c); 455 struct tuner *t = i2c_get_clientdata(c);
456 int if2 = t->radio_if2; 456 int if2 = t->radio_if2;
457 457
458 mt2050_set_if_freq(c, freq*62500, if2); 458 mt2050_set_if_freq(c, freq * 1000 / 16, if2);
459 mt2050_set_antenna(c, radio_antenna); 459 mt2050_set_antenna(c, radio_antenna);
460} 460}
461 461
@@ -487,7 +487,7 @@ int microtune_init(struct i2c_client *c)
487{ 487{
488 struct tuner *t = i2c_get_clientdata(c); 488 struct tuner *t = i2c_get_clientdata(c);
489 char *name; 489 char *name;
490 unsigned char buf[21]; 490 unsigned char buf[21];
491 int company_code; 491 int company_code;
492 492
493 memset(buf,0,sizeof(buf)); 493 memset(buf,0,sizeof(buf));
@@ -496,17 +496,17 @@ int microtune_init(struct i2c_client *c)
496 t->standby = NULL; 496 t->standby = NULL;
497 name = "unknown"; 497 name = "unknown";
498 498
499 i2c_master_send(c,buf,1); 499 i2c_master_send(c,buf,1);
500 i2c_master_recv(c,buf,21); 500 i2c_master_recv(c,buf,21);
501 if (tuner_debug) { 501 if (tuner_debug) {
502 int i; 502 int i;
503 tuner_dbg("MT20xx hexdump:"); 503 tuner_dbg("MT20xx hexdump:");
504 for(i=0;i<21;i++) { 504 for(i=0;i<21;i++) {
505 printk(" %02x",buf[i]); 505 printk(" %02x",buf[i]);
506 if(((i+1)%8)==0) printk(" "); 506 if(((i+1)%8)==0) printk(" ");
507 } 507 }
508 printk("\n"); 508 printk("\n");
509 } 509 }
510 company_code = buf[0x11] << 8 | buf[0x12]; 510 company_code = buf[0x11] << 8 | buf[0x12];
511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n", 511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
512 company_code,buf[0x13],buf[0x14]); 512 company_code,buf[0x13],buf[0x14]);
@@ -525,8 +525,8 @@ int microtune_init(struct i2c_client *c)
525 default: 525 default:
526 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n", 526 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
527 name); 527 name);
528 return 0; 528 return 0;
529 } 529 }
530 530
531 strlcpy(c->name, name, sizeof(c->name)); 531 strlcpy(c->name, name, sizeof(c->name));
532 tuner_info("microtune %s found, OK\n",name); 532 tuner_info("microtune %s found, OK\n",name);
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index 72b70eb5da1d..dca3ddfd510f 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -31,7 +31,6 @@
31#include <linux/wait.h> 31#include <linux/wait.h>
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33 33
34#include <media/id.h>
35 34
36#include "rds.h" 35#include "rds.h"
37 36
@@ -246,7 +245,7 @@ static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf)
246 s->wr_index = 0; 245 s->wr_index = 0;
247 246
248 if (s->wr_index == s->rd_index) { 247 if (s->wr_index == s->rd_index) {
249 s->rd_index++; 248 s->rd_index += 3;
250 if (s->rd_index >= s->buf_size) 249 if (s->rd_index >= s->buf_size)
251 s->rd_index = 0; 250 s->rd_index = 0;
252 } else 251 } else
@@ -328,7 +327,7 @@ static void saa6588_work(void *data)
328 struct saa6588 *s = (struct saa6588 *)data; 327 struct saa6588 *s = (struct saa6588 *)data;
329 328
330 saa6588_i2c_poll(s); 329 saa6588_i2c_poll(s);
331 mod_timer(&s->timer, jiffies + HZ / 50); /* 20 msec */ 330 mod_timer(&s->timer, jiffies + msecs_to_jiffies(20));
332} 331}
333 332
334static int saa6588_configure(struct saa6588 *s) 333static int saa6588_configure(struct saa6588 *s)
@@ -434,9 +433,9 @@ static int saa6588_probe(struct i2c_adapter *adap)
434 return i2c_probe(adap, &addr_data, saa6588_attach); 433 return i2c_probe(adap, &addr_data, saa6588_attach);
435#else 434#else
436 switch (adap->id) { 435 switch (adap->id) {
437 case I2C_ALGO_BIT | I2C_HW_B_BT848: 436 case I2C_HW_B_BT848:
438 case I2C_ALGO_BIT | I2C_HW_B_RIVA: 437 case I2C_HW_B_RIVA:
439 case I2C_ALGO_SAA7134: 438 case I2C_HW_SAA7134:
440 return i2c_probe(adap, &addr_data, saa6588_attach); 439 return i2c_probe(adap, &addr_data, saa6588_attach);
441 break; 440 break;
442 } 441 }
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c
new file mode 100644
index 000000000000..9aa8827de2c3
--- /dev/null
+++ b/drivers/media/video/saa711x.c
@@ -0,0 +1,593 @@
1/*
2 * saa711x - Philips SAA711x video decoder driver version 0.0.1
3 *
4 * To do: Now, it handles only saa7113/7114. Should be improved to
5 * handle all Philips saa711x devices.
6 *
7 * Based on saa7113 driver from Dave Perks <dperks@ibm.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/fs.h>
29#include <linux/kernel.h>
30#include <linux/major.h>
31#include <linux/slab.h>
32#include <linux/mm.h>
33#include <linux/pci.h>
34#include <linux/signal.h>
35#include <asm/io.h>
36#include <asm/pgtable.h>
37#include <asm/page.h>
38#include <linux/sched.h>
39#include <asm/segment.h>
40#include <linux/types.h>
41#include <asm/uaccess.h>
42#include <linux/videodev.h>
43
44MODULE_DESCRIPTION("Philips SAA711x video decoder driver");
45MODULE_AUTHOR("Dave Perks, Jose Ignacio Gijon, Joerg Heckenbach, Mark McClelland, Dwaine Garden");
46MODULE_LICENSE("GPL");
47
48#include <linux/i2c.h>
49#include <linux/i2c-dev.h>
50
51#define I2C_NAME(s) (s)->name
52
53#include <linux/video_decoder.h>
54
55static int debug = 0;
56MODULE_PARM(debug, "i");
57MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)");
58
59
60#define dprintk(num, format, args...) \
61 do { \
62 if (debug >= num) \
63 printk(format , ##args); \
64 } while (0)
65
66/* ----------------------------------------------------------------------- */
67
68struct saa711x {
69 unsigned char reg[32];
70
71 int norm;
72 int input;
73 int enable;
74 int bright;
75 int contrast;
76 int hue;
77 int sat;
78};
79
80#define I2C_SAA7113 0x4A
81#define I2C_SAA7114 0x42
82
83/* ----------------------------------------------------------------------- */
84
85static inline int
86saa711x_write (struct i2c_client *client,
87 u8 reg,
88 u8 value)
89{
90 struct saa711x *decoder = i2c_get_clientdata(client);
91
92 decoder->reg[reg] = value;
93 return i2c_smbus_write_byte_data(client, reg, value);
94}
95
96static int
97saa711x_write_block (struct i2c_client *client,
98 const u8 *data,
99 unsigned int len)
100{
101 int ret = -1;
102 u8 reg;
103
104 /* the saa711x has an autoincrement function, use it if
105 * the adapter understands raw I2C */
106 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
107 /* do raw I2C, not smbus compatible */
108 struct saa711x *decoder = i2c_get_clientdata(client);
109 struct i2c_msg msg;
110 u8 block_data[32];
111
112 msg.addr = client->addr;
113 msg.flags = 0;
114 while (len >= 2) {
115 msg.buf = (char *) block_data;
116 msg.len = 0;
117 block_data[msg.len++] = reg = data[0];
118 do {
119 block_data[msg.len++] =
120 decoder->reg[reg++] = data[1];
121 len -= 2;
122 data += 2;
123 } while (len >= 2 && data[0] == reg &&
124 msg.len < 32);
125 if ((ret = i2c_transfer(client->adapter,
126 &msg, 1)) < 0)
127 break;
128 }
129 } else {
130 /* do some slow I2C emulation kind of thing */
131 while (len >= 2) {
132 reg = *data++;
133 if ((ret = saa711x_write(client, reg,
134 *data++)) < 0)
135 break;
136 len -= 2;
137 }
138 }
139
140 return ret;
141}
142
143static int
144saa711x_init_decoder (struct i2c_client *client,
145 struct video_decoder_init *init)
146{
147 return saa711x_write_block(client, init->data, init->len);
148}
149
150static inline int
151saa711x_read (struct i2c_client *client,
152 u8 reg)
153{
154 return i2c_smbus_read_byte_data(client, reg);
155}
156
157/* ----------------------------------------------------------------------- */
158
159static const unsigned char saa711x_i2c_init[] = {
160 0x00, 0x00, /* PH711x_CHIP_VERSION 00 - ID byte */
161 0x01, 0x08, /* PH711x_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */
162 0x02, 0xc0, /* PH711x_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */
163 0x03, 0x23, /* PH711x_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */
164 0x04, 0x00, /* PH711x_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */
165 0x05, 0x00, /* PH711x_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */
166 0x06, 0xeb, /* PH711x_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */
167 0x07, 0xe0, /* PH711x_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */
168 0x08, 0x88, /* PH711x_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */
169 0x09, 0x00, /* PH711x_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */
170 0x0a, 0x80, /* PH711x_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */
171 0x0b, 0x47, /* PH711x_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */
172 0x0c, 0x40, /* PH711x_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */
173 0x0d, 0x00, /* PH711x_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */
174 0x0e, 0x01, /* PH711x_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */
175 0x0f, 0xaa, /* PH711x_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */
176 0x10, 0x00, /* PH711x_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */
177 0x11, 0x1C, /* PH711x_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */
178 0x12, 0x01, /* PH711x_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */
179 0x13, 0x00, /* PH711x_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */
180 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */
181 0x15, 0x00, /* PH711x_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */
182 0x16, 0x00, /* PH711x_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */
183 0x17, 0x00, /* PH711x_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */
184};
185
186static int
187saa711x_command (struct i2c_client *client,
188 unsigned int cmd,
189 void *arg)
190{
191 struct saa711x *decoder = i2c_get_clientdata(client);
192
193 switch (cmd) {
194
195 case 0:
196 case DECODER_INIT:
197 {
198 struct video_decoder_init *init = arg;
199 if (NULL != init)
200 return saa711x_init_decoder(client, init);
201 else {
202 struct video_decoder_init vdi;
203 vdi.data = saa711x_i2c_init;
204 vdi.len = sizeof(saa711x_i2c_init);
205 return saa711x_init_decoder(client, &vdi);
206 }
207 }
208
209 case DECODER_DUMP:
210 {
211 int i;
212
213 for (i = 0; i < 32; i += 16) {
214 int j;
215
216 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
217 for (j = 0; j < 16; ++j) {
218 printk(" %02x",
219 saa711x_read(client, i + j));
220 }
221 printk("\n");
222 }
223 }
224 break;
225
226 case DECODER_GET_CAPABILITIES:
227 {
228 struct video_decoder_capability *cap = arg;
229
230 cap->flags = VIDEO_DECODER_PAL |
231 VIDEO_DECODER_NTSC |
232 VIDEO_DECODER_SECAM |
233 VIDEO_DECODER_AUTO |
234 VIDEO_DECODER_CCIR;
235 cap->inputs = 8;
236 cap->outputs = 1;
237 }
238 break;
239
240 case DECODER_GET_STATUS:
241 {
242 int *iarg = arg;
243 int status;
244 int res;
245
246 status = saa711x_read(client, 0x1f);
247 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
248 status);
249 res = 0;
250 if ((status & (1 << 6)) == 0) {
251 res |= DECODER_STATUS_GOOD;
252 }
253 switch (decoder->norm) {
254 case VIDEO_MODE_NTSC:
255 res |= DECODER_STATUS_NTSC;
256 break;
257 case VIDEO_MODE_PAL:
258 res |= DECODER_STATUS_PAL;
259 break;
260 case VIDEO_MODE_SECAM:
261 res |= DECODER_STATUS_SECAM;
262 break;
263 default:
264 case VIDEO_MODE_AUTO:
265 if ((status & (1 << 5)) != 0) {
266 res |= DECODER_STATUS_NTSC;
267 } else {
268 res |= DECODER_STATUS_PAL;
269 }
270 break;
271 }
272 if ((status & (1 << 0)) != 0) {
273 res |= DECODER_STATUS_COLOR;
274 }
275 *iarg = res;
276 }
277 break;
278
279 case DECODER_SET_GPIO:
280 {
281 int *iarg = arg;
282 if (0 != *iarg) {
283 saa711x_write(client, 0x11,
284 (decoder->reg[0x11] | 0x80));
285 } else {
286 saa711x_write(client, 0x11,
287 (decoder->reg[0x11] & 0x7f));
288 }
289 break;
290 }
291
292 case DECODER_SET_VBI_BYPASS:
293 {
294 int *iarg = arg;
295 if (0 != *iarg) {
296 saa711x_write(client, 0x13,
297 (decoder->reg[0x13] & 0xf0) | 0x0a);
298 } else {
299 saa711x_write(client, 0x13,
300 (decoder->reg[0x13] & 0xf0));
301 }
302 break;
303 }
304
305 case DECODER_SET_NORM:
306 {
307 int *iarg = arg;
308
309 switch (*iarg) {
310
311 case VIDEO_MODE_NTSC:
312 saa711x_write(client, 0x08,
313 (decoder->reg[0x08] & 0x3f) | 0x40);
314 saa711x_write(client, 0x0e,
315 (decoder->reg[0x0e] & 0x8f));
316 break;
317
318 case VIDEO_MODE_PAL:
319 saa711x_write(client, 0x08,
320 (decoder->reg[0x08] & 0x3f) | 0x00);
321 saa711x_write(client, 0x0e,
322 (decoder->reg[0x0e] & 0x8f));
323 break;
324
325 case VIDEO_MODE_SECAM:
326 saa711x_write(client, 0x08,
327 (decoder->reg[0x0e] & 0x3f) | 0x00);
328 saa711x_write(client, 0x0e,
329 (decoder->reg[0x0e] & 0x8f) | 0x50);
330 break;
331
332 case VIDEO_MODE_AUTO:
333 saa711x_write(client, 0x08,
334 (decoder->reg[0x08] & 0x3f) | 0x80);
335 saa711x_write(client, 0x0e,
336 (decoder->reg[0x0e] & 0x8f));
337 break;
338
339 default:
340 return -EINVAL;
341
342 }
343 decoder->norm = *iarg;
344 }
345 break;
346
347 case DECODER_SET_INPUT:
348 {
349 int *iarg = arg;
350 if (*iarg < 0 || *iarg > 9) {
351 return -EINVAL;
352 }
353 if (decoder->input != *iarg) {
354 decoder->input = *iarg;
355 /* select mode */
356 saa711x_write(client, 0x02,
357 (decoder->reg[0x02] & 0xf0) | decoder->input);
358 /* bypass chrominance trap for modes 4..7 */
359 saa711x_write(client, 0x09,
360 (decoder->reg[0x09] & 0x7f) | ((decoder->input > 3) ? 0x80 : 0));
361 }
362 }
363 break;
364
365 case DECODER_SET_OUTPUT:
366 {
367 int *iarg = arg;
368
369 /* not much choice of outputs */
370 if (*iarg != 0) {
371 return -EINVAL;
372 }
373 }
374 break;
375
376 case DECODER_ENABLE_OUTPUT:
377 {
378 int *iarg = arg;
379 int enable = (*iarg != 0);
380
381 if (decoder->enable != enable) {
382 decoder->enable = enable;
383
384 /* RJ: If output should be disabled (for
385 * playing videos), we also need a open PLL.
386 * The input is set to 0 (where no input
387 * source is connected), although this
388 * is not necessary.
389 *
390 * If output should be enabled, we have to
391 * reverse the above.
392 */
393
394 if (decoder->enable) {
395 saa711x_write(client, 0x02,
396 (decoder->
397 reg[0x02] & 0xf8) |
398 decoder->input);
399 saa711x_write(client, 0x08,
400 (decoder->reg[0x08] & 0xfb));
401 saa711x_write(client, 0x11,
402 (decoder->
403 reg[0x11] & 0xf3) | 0x0c);
404 } else {
405 saa711x_write(client, 0x02,
406 (decoder->reg[0x02] & 0xf8));
407 saa711x_write(client, 0x08,
408 (decoder->
409 reg[0x08] & 0xfb) | 0x04);
410 saa711x_write(client, 0x11,
411 (decoder->reg[0x11] & 0xf3));
412 }
413 }
414 }
415 break;
416
417 case DECODER_SET_PICTURE:
418 {
419 struct video_picture *pic = arg;
420
421 if (decoder->bright != pic->brightness) {
422 /* We want 0 to 255 we get 0-65535 */
423 decoder->bright = pic->brightness;
424 saa711x_write(client, 0x0a, decoder->bright >> 8);
425 }
426 if (decoder->contrast != pic->contrast) {
427 /* We want 0 to 127 we get 0-65535 */
428 decoder->contrast = pic->contrast;
429 saa711x_write(client, 0x0b,
430 decoder->contrast >> 9);
431 }
432 if (decoder->sat != pic->colour) {
433 /* We want 0 to 127 we get 0-65535 */
434 decoder->sat = pic->colour;
435 saa711x_write(client, 0x0c, decoder->sat >> 9);
436 }
437 if (decoder->hue != pic->hue) {
438 /* We want -128 to 127 we get 0-65535 */
439 decoder->hue = pic->hue;
440 saa711x_write(client, 0x0d,
441 (decoder->hue - 32768) >> 8);
442 }
443 }
444 break;
445
446 default:
447 return -EINVAL;
448 }
449
450 return 0;
451}
452
453/* ----------------------------------------------------------------------- */
454
455/*
456 * Generic i2c probe
457 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
458 */
459
460/* standard i2c insmod options */
461static unsigned short normal_i2c[] = {
462 I2C_SAA7113>>1, /* saa7113 */
463 I2C_SAA7114>>1, /* saa7114 */
464 I2C_CLIENT_END
465};
466
467I2C_CLIENT_INSMOD;
468
469
470static struct i2c_driver i2c_driver_saa711x;
471
472static int
473saa711x_detect_client (struct i2c_adapter *adapter,
474 int address,
475 int kind)
476{
477 int i;
478 struct i2c_client *client;
479 struct saa711x *decoder;
480 struct video_decoder_init vdi;
481
482 dprintk(1,
483 KERN_INFO
484 "saa711x.c: detecting saa711x client on address 0x%x\n",
485 address << 1);
486
487 /* Check if the adapter supports the needed features */
488 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
489 return 0;
490
491 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
492 if (client == 0)
493 return -ENOMEM;
494 memset(client, 0, sizeof(struct i2c_client));
495 client->addr = address;
496 client->adapter = adapter;
497 client->driver = &i2c_driver_saa711x;
498 client->flags = I2C_CLIENT_ALLOW_USE;
499 strlcpy(I2C_NAME(client), "saa711x", sizeof(I2C_NAME(client)));
500 decoder = kmalloc(sizeof(struct saa711x), GFP_KERNEL);
501 if (decoder == NULL) {
502 kfree(client);
503 return -ENOMEM;
504 }
505 memset(decoder, 0, sizeof(struct saa711x));
506 decoder->norm = VIDEO_MODE_NTSC;
507 decoder->input = 0;
508 decoder->enable = 1;
509 decoder->bright = 32768;
510 decoder->contrast = 32768;
511 decoder->hue = 32768;
512 decoder->sat = 32768;
513 i2c_set_clientdata(client, decoder);
514
515 i = i2c_attach_client(client);
516 if (i) {
517 kfree(client);
518 kfree(decoder);
519 return i;
520 }
521
522 vdi.data = saa711x_i2c_init;
523 vdi.len = sizeof(saa711x_i2c_init);
524 i = saa711x_init_decoder(client, &vdi);
525 if (i < 0) {
526 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
527 I2C_NAME(client), i);
528 } else {
529 dprintk(1,
530 KERN_INFO
531 "%s_attach: chip version %x at address 0x%x\n",
532 I2C_NAME(client), saa711x_read(client, 0x00) >> 4,
533 client->addr << 1);
534 }
535
536 return 0;
537}
538
539static int
540saa711x_attach_adapter (struct i2c_adapter *adapter)
541{
542 dprintk(1,
543 KERN_INFO
544 "saa711x.c: starting probe for adapter %s (0x%x)\n",
545 I2C_NAME(adapter), adapter->id);
546 return i2c_probe(adapter, &addr_data, &saa711x_detect_client);
547}
548
549static int
550saa711x_detach_client (struct i2c_client *client)
551{
552 struct saa711x *decoder = i2c_get_clientdata(client);
553 int err;
554
555 err = i2c_detach_client(client);
556 if (err) {
557 return err;
558 }
559
560 kfree(decoder);
561 kfree(client);
562
563 return 0;
564}
565
566/* ----------------------------------------------------------------------- */
567
568static struct i2c_driver i2c_driver_saa711x = {
569 .owner = THIS_MODULE,
570 .name = "saa711x",
571
572 .id = I2C_DRIVERID_SAA711X,
573 .flags = I2C_DF_NOTIFY,
574
575 .attach_adapter = saa711x_attach_adapter,
576 .detach_client = saa711x_detach_client,
577 .command = saa711x_command,
578};
579
580static int __init
581saa711x_init (void)
582{
583 return i2c_add_driver(&i2c_driver_saa711x);
584}
585
586static void __exit
587saa711x_exit (void)
588{
589 i2c_del_driver(&i2c_driver_saa711x);
590}
591
592module_init(saa711x_init);
593module_exit(saa711x_exit);
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
new file mode 100644
index 000000000000..624e8808a517
--- /dev/null
+++ b/drivers/media/video/saa7134/Kconfig
@@ -0,0 +1,68 @@
1config VIDEO_SAA7134
2 tristate "Philips SAA7134 support"
3 depends on VIDEO_DEV && PCI && I2C && SOUND
4 select VIDEO_BUF
5 select VIDEO_IR
6 select VIDEO_TUNER
7 select CRC32
8 ---help---
9 This is a video4linux driver for Philips SAA713x based
10 TV cards.
11
12 To compile this driver as a module, choose M here: the
13 module will be called saa7134.
14
15config VIDEO_SAA7134_DVB
16 tristate "DVB/ATSC Support for saa7134 based TV cards"
17 depends on VIDEO_SAA7134 && DVB_CORE
18 select VIDEO_BUF_DVB
19 ---help---
20 This adds support for DVB cards based on the
21 Philips saa7134 chip.
22
23 To compile this driver as a module, choose M here: the
24 module will be called saa7134-dvb.
25
26 You must also select one or more DVB demodulators.
27 If you are unsure which you need, choose all of them.
28
29config VIDEO_SAA7134_DVB_ALL_FRONTENDS
30 bool "Build all supported frontends for saa7134 based TV cards"
31 default y
32 depends on VIDEO_SAA7134_DVB
33 select DVB_MT352
34 select DVB_TDA1004X
35 select DVB_NXT200X
36 ---help---
37 This builds saa7134-dvb with all currently supported frontend
38 demodulators. If you wish to tweak your configuration, and
39 only include support for the hardware that you need, choose N here.
40
41 If you are unsure, choose Y.
42
43config VIDEO_SAA7134_DVB_MT352
44 tristate "Zarlink MT352 DVB-T Support"
45 default m
46 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
47 select DVB_MT352
48 ---help---
49 This adds DVB-T support for cards based on the
50 Philips saa7134 chip and the MT352 demodulator.
51
52config VIDEO_SAA7134_DVB_TDA1004X
53 tristate "Phillips TDA10045H/TDA10046H DVB-T Support"
54 default m
55 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
56 select DVB_TDA1004X
57 ---help---
58 This adds DVB-T support for cards based on the
59 Philips saa7134 chip and the TDA10045H/TDA10046H demodulator.
60
61config VIDEO_SAA7134_DVB_NXT200X
62 tristate "NXT2002/NXT2004 ATSC Support"
63 default m
64 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
65 select DVB_NXT200X
66 ---help---
67 This adds ATSC 8VSB and QAM64/256 support for cards based on the
68 Philips saa7134 chip and the NXT2002/NXT2004 demodulator.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index b778ffd94e65..e0b28f0533af 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -3,15 +3,22 @@ saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \
3 saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \ 3 saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \
4 saa7134-vbi.o saa7134-video.o saa7134-input.o 4 saa7134-vbi.o saa7134-video.o saa7134-input.o
5 5
6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o saa6752hs.o 6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \
7 saa6752hs.o saa7134-alsa.o
7obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o 8obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
8 9
9EXTRA_CFLAGS += -I$(src)/.. 10EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core 11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends 12EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
13ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
14 EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
15endif
12ifneq ($(CONFIG_DVB_MT352),n) 16ifneq ($(CONFIG_DVB_MT352),n)
13 EXTRA_CFLAGS += -DHAVE_MT352=1 17 EXTRA_CFLAGS += -DHAVE_MT352=1
14endif 18endif
15ifneq ($(CONFIG_DVB_TDA1004X),n) 19ifneq ($(CONFIG_DVB_TDA1004X),n)
16 EXTRA_CFLAGS += -DHAVE_TDA1004X=1 20 EXTRA_CFLAGS += -DHAVE_TDA1004X=1
17endif 21endif
22ifneq ($(CONFIG_DVB_NXT200X),n)
23 EXTRA_CFLAGS += -DHAVE_NXT200X=1
24endif
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 382911c6ef22..cdd1ed9c8065 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -13,7 +13,6 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/crc32.h> 14#include <linux/crc32.h>
15 15
16#include <media/id.h>
17 16
18#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000 17#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
19#define MPEG_VIDEO_MAX_BITRATE_MAX 27000 18#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
@@ -57,6 +56,7 @@ struct saa6752hs_state {
57 struct i2c_client client; 56 struct i2c_client client;
58 struct v4l2_mpeg_compression params; 57 struct v4l2_mpeg_compression params;
59 enum saa6752hs_videoformat video_format; 58 enum saa6752hs_videoformat video_format;
59 v4l2_std_id standard;
60}; 60};
61 61
62enum saa6752hs_command { 62enum saa6752hs_command {
@@ -74,58 +74,58 @@ enum saa6752hs_command {
74/* ---------------------------------------------------------------------- */ 74/* ---------------------------------------------------------------------- */
75 75
76static u8 PAT[] = { 76static u8 PAT[] = {
77 0xc2, // i2c register 77 0xc2, /* i2c register */
78 0x00, // table number for encoder 78 0x00, /* table number for encoder */
79 79
80 0x47, // sync 80 0x47, /* sync */
81 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) 81 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) */
82 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) 82 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
83 83
84 0x00, // PSI pointer to start of table 84 0x00, /* PSI pointer to start of table */
85 85
86 0x00, // tid(0) 86 0x00, /* tid(0) */
87 0xb0, 0x0d, // section_syntax_indicator(1), section_length(13) 87 0xb0, 0x0d, /* section_syntax_indicator(1), section_length(13) */
88 88
89 0x00, 0x01, // transport_stream_id(1) 89 0x00, 0x01, /* transport_stream_id(1) */
90 90
91 0xc1, // version_number(0), current_next_indicator(1) 91 0xc1, /* version_number(0), current_next_indicator(1) */
92 92
93 0x00, 0x00, // section_number(0), last_section_number(0) 93 0x00, 0x00, /* section_number(0), last_section_number(0) */
94 94
95 0x00, 0x01, // program_number(1) 95 0x00, 0x01, /* program_number(1) */
96 96
97 0xe0, 0x00, // PMT PID 97 0xe0, 0x00, /* PMT PID */
98 98
99 0x00, 0x00, 0x00, 0x00 // CRC32 99 0x00, 0x00, 0x00, 0x00 /* CRC32 */
100}; 100};
101 101
102static u8 PMT[] = { 102static u8 PMT[] = {
103 0xc2, // i2c register 103 0xc2, /* i2c register */
104 0x01, // table number for encoder 104 0x01, /* table number for encoder */
105 105
106 0x47, // sync 106 0x47, /* sync */
107 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid 107 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid */
108 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) 108 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
109 109
110 0x00, // PSI pointer to start of table 110 0x00, /* PSI pointer to start of table */
111 111
112 0x02, // tid(2) 112 0x02, /* tid(2) */
113 0xb0, 0x17, // section_syntax_indicator(1), section_length(23) 113 0xb0, 0x17, /* section_syntax_indicator(1), section_length(23) */
114 114
115 0x00, 0x01, // program_number(1) 115 0x00, 0x01, /* program_number(1) */
116 116
117 0xc1, // version_number(0), current_next_indicator(1) 117 0xc1, /* version_number(0), current_next_indicator(1) */
118 118
119 0x00, 0x00, // section_number(0), last_section_number(0) 119 0x00, 0x00, /* section_number(0), last_section_number(0) */
120 120
121 0xe0, 0x00, // PCR_PID 121 0xe0, 0x00, /* PCR_PID */
122 122
123 0xf0, 0x00, // program_info_length(0) 123 0xf0, 0x00, /* program_info_length(0) */
124 124
125 0x02, 0xe0, 0x00, 0xf0, 0x00, // video stream type(2), pid 125 0x02, 0xe0, 0x00, 0xf0, 0x00, /* video stream type(2), pid */
126 0x04, 0xe0, 0x00, 0xf0, 0x00, // audio stream type(4), pid 126 0x04, 0xe0, 0x00, 0xf0, 0x00, /* audio stream type(4), pid */
127 127
128 0x00, 0x00, 0x00, 0x00 // CRC32 128 0x00, 0x00, 0x00, 0x00 /* CRC32 */
129}; 129};
130 130
131static struct v4l2_mpeg_compression param_defaults = 131static struct v4l2_mpeg_compression param_defaults =
@@ -166,33 +166,33 @@ static int saa6752hs_chip_command(struct i2c_client* client,
166 unsigned long timeout; 166 unsigned long timeout;
167 int status = 0; 167 int status = 0;
168 168
169 // execute the command 169 /* execute the command */
170 switch(command) { 170 switch(command) {
171 case SAA6752HS_COMMAND_RESET: 171 case SAA6752HS_COMMAND_RESET:
172 buf[0] = 0x00; 172 buf[0] = 0x00;
173 break; 173 break;
174 174
175 case SAA6752HS_COMMAND_STOP: 175 case SAA6752HS_COMMAND_STOP:
176 buf[0] = 0x03; 176 buf[0] = 0x03;
177 break; 177 break;
178 178
179 case SAA6752HS_COMMAND_START: 179 case SAA6752HS_COMMAND_START:
180 buf[0] = 0x02; 180 buf[0] = 0x02;
181 break; 181 break;
182 182
183 case SAA6752HS_COMMAND_PAUSE: 183 case SAA6752HS_COMMAND_PAUSE:
184 buf[0] = 0x04; 184 buf[0] = 0x04;
185 break; 185 break;
186 186
187 case SAA6752HS_COMMAND_RECONFIGURE: 187 case SAA6752HS_COMMAND_RECONFIGURE:
188 buf[0] = 0x05; 188 buf[0] = 0x05;
189 break; 189 break;
190 190
191 case SAA6752HS_COMMAND_SLEEP: 191 case SAA6752HS_COMMAND_SLEEP:
192 buf[0] = 0x06; 192 buf[0] = 0x06;
193 break; 193 break;
194 194
195 case SAA6752HS_COMMAND_RECONFIGURE_FORCE: 195 case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
196 buf[0] = 0x07; 196 buf[0] = 0x07;
197 break; 197 break;
198 198
@@ -200,13 +200,13 @@ static int saa6752hs_chip_command(struct i2c_client* client,
200 return -EINVAL; 200 return -EINVAL;
201 } 201 }
202 202
203 // set it and wait for it to be so 203 /* set it and wait for it to be so */
204 i2c_master_send(client, buf, 1); 204 i2c_master_send(client, buf, 1);
205 timeout = jiffies + HZ * 3; 205 timeout = jiffies + HZ * 3;
206 for (;;) { 206 for (;;) {
207 // get the current status 207 /* get the current status */
208 buf[0] = 0x10; 208 buf[0] = 0x10;
209 i2c_master_send(client, buf, 1); 209 i2c_master_send(client, buf, 1);
210 i2c_master_recv(client, buf, 1); 210 i2c_master_recv(client, buf, 1);
211 211
212 if (!(buf[0] & 0x20)) 212 if (!(buf[0] & 0x20))
@@ -216,61 +216,58 @@ static int saa6752hs_chip_command(struct i2c_client* client,
216 break; 216 break;
217 } 217 }
218 218
219 // wait a bit
220 msleep(10); 219 msleep(10);
221 } 220 }
222 221
223 // delay a bit to let encoder settle 222 /* delay a bit to let encoder settle */
224 msleep(50); 223 msleep(50);
225 224
226 // done 225 return status;
227 return status;
228} 226}
229 227
230 228
231static int saa6752hs_set_bitrate(struct i2c_client* client, 229static int saa6752hs_set_bitrate(struct i2c_client* client,
232 struct v4l2_mpeg_compression* params) 230 struct v4l2_mpeg_compression* params)
233{ 231{
234 u8 buf[3]; 232 u8 buf[3];
235 233
236 // set the bitrate mode 234 /* set the bitrate mode */
237 buf[0] = 0x71; 235 buf[0] = 0x71;
238 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1; 236 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1;
239 i2c_master_send(client, buf, 2); 237 i2c_master_send(client, buf, 2);
240 238
241 // set the video bitrate 239 /* set the video bitrate */
242 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) { 240 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) {
243 // set the target bitrate 241 /* set the target bitrate */
244 buf[0] = 0x80; 242 buf[0] = 0x80;
245 buf[1] = params->vi_bitrate.target >> 8; 243 buf[1] = params->vi_bitrate.target >> 8;
246 buf[2] = params->vi_bitrate.target & 0xff; 244 buf[2] = params->vi_bitrate.target & 0xff;
247 i2c_master_send(client, buf, 3); 245 i2c_master_send(client, buf, 3);
248 246
249 // set the max bitrate 247 /* set the max bitrate */
250 buf[0] = 0x81; 248 buf[0] = 0x81;
251 buf[1] = params->vi_bitrate.max >> 8; 249 buf[1] = params->vi_bitrate.max >> 8;
252 buf[2] = params->vi_bitrate.max & 0xff; 250 buf[2] = params->vi_bitrate.max & 0xff;
253 i2c_master_send(client, buf, 3); 251 i2c_master_send(client, buf, 3);
254 } else { 252 } else {
255 // set the target bitrate (no max bitrate for CBR) 253 /* set the target bitrate (no max bitrate for CBR) */
256 buf[0] = 0x81; 254 buf[0] = 0x81;
257 buf[1] = params->vi_bitrate.target >> 8; 255 buf[1] = params->vi_bitrate.target >> 8;
258 buf[2] = params->vi_bitrate.target & 0xff; 256 buf[2] = params->vi_bitrate.target & 0xff;
259 i2c_master_send(client, buf, 3); 257 i2c_master_send(client, buf, 3);
260 } 258 }
261 259
262 // set the audio bitrate 260 /* set the audio bitrate */
263 buf[0] = 0x94; 261 buf[0] = 0x94;
264 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1; 262 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1;
265 i2c_master_send(client, buf, 2); 263 i2c_master_send(client, buf, 2);
266 264
267 // set the total bitrate 265 /* set the total bitrate */
268 buf[0] = 0xb1; 266 buf[0] = 0xb1;
269 buf[1] = params->st_bitrate.target >> 8; 267 buf[1] = params->st_bitrate.target >> 8;
270 buf[2] = params->st_bitrate.target & 0xff; 268 buf[2] = params->st_bitrate.target & 0xff;
271 i2c_master_send(client, buf, 3); 269 i2c_master_send(client, buf, 3);
272 270
273 // return success
274 return 0; 271 return 0;
275} 272}
276 273
@@ -376,36 +373,43 @@ static int saa6752hs_init(struct i2c_client* client)
376 373
377 h = i2c_get_clientdata(client); 374 h = i2c_get_clientdata(client);
378 375
379 // Set video format - must be done first as it resets other settings 376 /* Set video format - must be done first as it resets other settings */
380 buf[0] = 0x41; 377 buf[0] = 0x41;
381 buf[1] = h->video_format; 378 buf[1] = h->video_format;
382 i2c_master_send(client, buf, 2); 379 i2c_master_send(client, buf, 2);
383 380
384 // set bitrate 381 /* Set number of lines in input signal */
385 saa6752hs_set_bitrate(client, &h->params); 382 buf[0] = 0x40;
383 buf[1] = 0x00;
384 if (h->standard & V4L2_STD_525_60)
385 buf[1] = 0x01;
386 i2c_master_send(client, buf, 2);
387
388 /* set bitrate */
389 saa6752hs_set_bitrate(client, &h->params);
386 390
387 // Set GOP structure {3, 13} 391 /* Set GOP structure {3, 13} */
388 buf[0] = 0x72; 392 buf[0] = 0x72;
389 buf[1] = 0x03; 393 buf[1] = 0x03;
390 buf[2] = 0x0D; 394 buf[2] = 0x0D;
391 i2c_master_send(client,buf,3); 395 i2c_master_send(client,buf,3);
392 396
393 // Set minimum Q-scale {4} 397 /* Set minimum Q-scale {4} */
394 buf[0] = 0x82; 398 buf[0] = 0x82;
395 buf[1] = 0x04; 399 buf[1] = 0x04;
396 i2c_master_send(client,buf,2); 400 i2c_master_send(client,buf,2);
397 401
398 // Set maximum Q-scale {12} 402 /* Set maximum Q-scale {12} */
399 buf[0] = 0x83; 403 buf[0] = 0x83;
400 buf[1] = 0x0C; 404 buf[1] = 0x0C;
401 i2c_master_send(client,buf,2); 405 i2c_master_send(client,buf,2);
402 406
403 // Set Output Protocol 407 /* Set Output Protocol */
404 buf[0] = 0xD0; 408 buf[0] = 0xD0;
405 buf[1] = 0x81; 409 buf[1] = 0x81;
406 i2c_master_send(client,buf,2); 410 i2c_master_send(client,buf,2);
407 411
408 // Set video output stream format {TS} 412 /* Set video output stream format {TS} */
409 buf[0] = 0xB0; 413 buf[0] = 0xB0;
410 buf[1] = 0x05; 414 buf[1] = 0x05;
411 i2c_master_send(client,buf,2); 415 i2c_master_send(client,buf,2);
@@ -421,9 +425,9 @@ static int saa6752hs_init(struct i2c_client* client)
421 localPAT[sizeof(PAT) - 1] = crc & 0xFF; 425 localPAT[sizeof(PAT) - 1] = crc & 0xFF;
422 426
423 /* compute PMT */ 427 /* compute PMT */
424 memcpy(localPMT, PMT, sizeof(PMT)); 428 memcpy(localPMT, PMT, sizeof(PMT));
425 localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f); 429 localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
426 localPMT[4] = h->params.ts_pid_pmt & 0xff; 430 localPMT[4] = h->params.ts_pid_pmt & 0xff;
427 localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F); 431 localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F);
428 localPMT[16] = h->params.ts_pid_pcr & 0xFF; 432 localPMT[16] = h->params.ts_pid_pcr & 0xFF;
429 localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F); 433 localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F);
@@ -436,39 +440,39 @@ static int saa6752hs_init(struct i2c_client* client)
436 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; 440 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF;
437 localPMT[sizeof(PMT) - 1] = crc & 0xFF; 441 localPMT[sizeof(PMT) - 1] = crc & 0xFF;
438 442
439 // Set Audio PID 443 /* Set Audio PID */
440 buf[0] = 0xC1; 444 buf[0] = 0xC1;
441 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; 445 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF;
442 buf[2] = h->params.ts_pid_audio & 0xFF; 446 buf[2] = h->params.ts_pid_audio & 0xFF;
443 i2c_master_send(client,buf,3); 447 i2c_master_send(client,buf,3);
444 448
445 // Set Video PID 449 /* Set Video PID */
446 buf[0] = 0xC0; 450 buf[0] = 0xC0;
447 buf[1] = (h->params.ts_pid_video >> 8) & 0xFF; 451 buf[1] = (h->params.ts_pid_video >> 8) & 0xFF;
448 buf[2] = h->params.ts_pid_video & 0xFF; 452 buf[2] = h->params.ts_pid_video & 0xFF;
449 i2c_master_send(client,buf,3); 453 i2c_master_send(client,buf,3);
450 454
451 // Set PCR PID 455 /* Set PCR PID */
452 buf[0] = 0xC4; 456 buf[0] = 0xC4;
453 buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF; 457 buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF;
454 buf[2] = h->params.ts_pid_pcr & 0xFF; 458 buf[2] = h->params.ts_pid_pcr & 0xFF;
455 i2c_master_send(client,buf,3); 459 i2c_master_send(client,buf,3);
456 460
457 // Send SI tables 461 /* Send SI tables */
458 i2c_master_send(client,localPAT,sizeof(PAT)); 462 i2c_master_send(client,localPAT,sizeof(PAT));
459 i2c_master_send(client,localPMT,sizeof(PMT)); 463 i2c_master_send(client,localPMT,sizeof(PMT));
460 464
461 // mute then unmute audio. This removes buzzing artefacts 465 /* mute then unmute audio. This removes buzzing artefacts */
462 buf[0] = 0xa4; 466 buf[0] = 0xa4;
463 buf[1] = 1; 467 buf[1] = 1;
464 i2c_master_send(client, buf, 2); 468 i2c_master_send(client, buf, 2);
465 buf[1] = 0; 469 buf[1] = 0;
466 i2c_master_send(client, buf, 2); 470 i2c_master_send(client, buf, 2);
467 471
468 // start it going 472 /* start it going */
469 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); 473 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START);
470 474
471 // readout current state 475 /* readout current state */
472 buf[0] = 0xE1; 476 buf[0] = 0xE1;
473 buf[1] = 0xA7; 477 buf[1] = 0xA7;
474 buf[2] = 0xFE; 478 buf[2] = 0xFE;
@@ -477,7 +481,7 @@ static int saa6752hs_init(struct i2c_client* client)
477 i2c_master_send(client, buf, 5); 481 i2c_master_send(client, buf, 5);
478 i2c_master_recv(client, buf2, 4); 482 i2c_master_recv(client, buf2, 4);
479 483
480 // change aspect ratio 484 /* change aspect ratio */
481 buf[0] = 0xE0; 485 buf[0] = 0xE0;
482 buf[1] = 0xA7; 486 buf[1] = 0xA7;
483 buf[2] = 0xFE; 487 buf[2] = 0xFE;
@@ -498,7 +502,6 @@ static int saa6752hs_init(struct i2c_client* client)
498 buf[8] = buf2[3]; 502 buf[8] = buf2[3];
499 i2c_master_send(client, buf, 9); 503 i2c_master_send(client, buf, 9);
500 504
501 // return success
502 return 0; 505 return 0;
503} 506}
504 507
@@ -506,16 +509,19 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
506{ 509{
507 struct saa6752hs_state *h; 510 struct saa6752hs_state *h;
508 511
509 printk("saa6752hs: chip found @ 0x%x\n", addr<<1); 512 printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
510 513
511 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL))) 514 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
512 return -ENOMEM; 515 return -ENOMEM;
513 memset(h,0,sizeof(*h)); 516 memset(h,0,sizeof(*h));
514 h->client = client_template; 517 h->client = client_template;
515 h->params = param_defaults; 518 h->params = param_defaults;
516 h->client.adapter = adap; 519 h->client.adapter = adap;
517 h->client.addr = addr; 520 h->client.addr = addr;
518 521
522 /* Assume 625 input lines */
523 h->standard = 0;
524
519 i2c_set_clientdata(&h->client, h); 525 i2c_set_clientdata(&h->client, h);
520 i2c_attach_client(&h->client); 526 i2c_attach_client(&h->client);
521 return 0; 527 return 0;
@@ -545,7 +551,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
545 struct v4l2_mpeg_compression *params = arg; 551 struct v4l2_mpeg_compression *params = arg;
546 int err = 0; 552 int err = 0;
547 553
548 switch (cmd) { 554 switch (cmd) {
549 case VIDIOC_S_MPEGCOMP: 555 case VIDIOC_S_MPEGCOMP:
550 if (NULL == params) { 556 if (NULL == params) {
551 /* apply settings and start encoder */ 557 /* apply settings and start encoder */
@@ -559,7 +565,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
559 break; 565 break;
560 case VIDIOC_G_FMT: 566 case VIDIOC_G_FMT:
561 { 567 {
562 struct v4l2_format *f = arg; 568 struct v4l2_format *f = arg;
563 569
564 if (h->video_format == SAA6752HS_VF_UNKNOWN) 570 if (h->video_format == SAA6752HS_VF_UNKNOWN)
565 h->video_format = SAA6752HS_VF_D1; 571 h->video_format = SAA6752HS_VF_D1;
@@ -576,6 +582,9 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
576 saa6752hs_set_subsampling(client, f); 582 saa6752hs_set_subsampling(client, f);
577 break; 583 break;
578 } 584 }
585 case VIDIOC_S_STD:
586 h->standard = *((v4l2_std_id *) arg);
587 break;
579 default: 588 default:
580 /* nothing */ 589 /* nothing */
581 break; 590 break;
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
new file mode 100644
index 000000000000..4f3c42354329
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -0,0 +1,1047 @@
1/*
2 * SAA713x ALSA support for V4L
3 *
4 *
5 * Caveats:
6 * - Volume doesn't work (it's always at max)
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, version 2
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <sound/driver.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/time.h>
27#include <linux/wait.h>
28#include <linux/moduleparam.h>
29#include <linux/module.h>
30#include <sound/core.h>
31#include <sound/control.h>
32#include <sound/pcm.h>
33#include <sound/initval.h>
34
35#include "saa7134.h"
36#include "saa7134-reg.h"
37
38static unsigned int debug = 0;
39module_param(debug, int, 0644);
40MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
41
42/*
43 * Configuration macros
44 */
45
46/* defaults */
47#define MIXER_ADDR_TVTUNER 0
48#define MIXER_ADDR_LINE1 1
49#define MIXER_ADDR_LINE2 2
50#define MIXER_ADDR_LAST 2
51
52static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
53static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
54static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
55
56module_param_array(index, int, NULL, 0444);
57MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
58
59#define dprintk(fmt, arg...) if (debug) \
60 printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
61
62/*
63 * Main chip structure
64 */
65typedef struct snd_card_saa7134 {
66 snd_card_t *card;
67 spinlock_t mixer_lock;
68 int mixer_volume[MIXER_ADDR_LAST+1][2];
69 int capture_source[MIXER_ADDR_LAST+1][2];
70 struct pci_dev *pci;
71 struct saa7134_dev *saadev;
72
73 unsigned long iobase;
74 int irq;
75
76 spinlock_t lock;
77} snd_card_saa7134_t;
78
79
80
81/*
82 * PCM structure
83 */
84
85typedef struct snd_card_saa7134_pcm {
86 struct saa7134_dev *saadev;
87
88 spinlock_t lock;
89 unsigned int pcm_size; /* buffer size */
90 unsigned int pcm_count; /* bytes per period */
91 unsigned int pcm_bps; /* bytes per second */
92 snd_pcm_substream_t *substream;
93} snd_card_saa7134_pcm_t;
94
95static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
96
97
98/*
99 * saa7134 DMA audio stop
100 *
101 * Called when the capture device is released or the buffer overflows
102 *
103 * - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped
104 * if we just share dsp_dma_stop and use it here
105 *
106 */
107
108static void saa7134_dma_stop(struct saa7134_dev *dev)
109
110{
111 dev->dmasound.dma_blk = -1;
112 dev->dmasound.dma_running = 0;
113 saa7134_set_dmabits(dev);
114}
115
116/*
117 * saa7134 DMA audio start
118 *
119 * Called when preparing the capture device for use
120 *
121 * - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped
122 * if we just share dsp_dma_start and use it here
123 *
124 */
125
126static void saa7134_dma_start(struct saa7134_dev *dev)
127{
128 dev->dmasound.dma_blk = 0;
129 dev->dmasound.dma_running = 1;
130 saa7134_set_dmabits(dev);
131}
132
133/*
134 * saa7134 audio DMA IRQ handler
135 *
136 * Called whenever we get an SAA7134_IRQ_REPORT_DONE_RA3 interrupt
137 * Handles shifting between the 2 buffers, manages the read counters,
138 * and notifies ALSA when periods elapse
139 *
140 * - Mostly copied from saa7134-oss's saa7134_irq_oss_done.
141 *
142 */
143
144void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
145{
146 int next_blk, reg = 0;
147
148 spin_lock(&dev->slock);
149 if (UNSET == dev->dmasound.dma_blk) {
150 dprintk("irq: recording stopped\n");
151 goto done;
152 }
153 if (0 != (status & 0x0f000000))
154 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
155 if (0 == (status & 0x10000000)) {
156 /* odd */
157 if (0 == (dev->dmasound.dma_blk & 0x01))
158 reg = SAA7134_RS_BA1(6);
159 } else {
160 /* even */
161 if (1 == (dev->dmasound.dma_blk & 0x01))
162 reg = SAA7134_RS_BA2(6);
163 }
164 if (0 == reg) {
165 dprintk("irq: field oops [%s]\n",
166 (status & 0x10000000) ? "even" : "odd");
167 goto done;
168 }
169
170 if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
171 dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
172 dev->dmasound.bufsize, dev->dmasound.blocks);
173 snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
174 saa7134_dma_stop(dev);
175 goto done;
176 }
177
178 /* next block addr */
179 next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
180 saa_writel(reg,next_blk * dev->dmasound.blksize);
181 if (debug > 2)
182 dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n",
183 (status & 0x10000000) ? "even" : "odd ", next_blk,
184 next_blk * dev->dmasound.blksize, dev->dmasound.blocks, dev->dmasound.blksize, dev->dmasound.read_count);
185
186 /* update status & wake waiting readers */
187 dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
188 dev->dmasound.read_count += dev->dmasound.blksize;
189
190 dev->dmasound.recording_on = reg;
191
192 if (dev->dmasound.read_count >= snd_pcm_lib_period_bytes(dev->dmasound.substream)) {
193 spin_unlock(&dev->slock);
194 snd_pcm_period_elapsed(dev->dmasound.substream);
195 spin_lock(&dev->slock);
196 }
197 done:
198 spin_unlock(&dev->slock);
199
200}
201
202/*
203 * IRQ request handler
204 *
205 * Runs along with saa7134's IRQ handler, discards anything that isn't
206 * DMA sound
207 *
208 */
209
210static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
211{
212 struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
213 unsigned long report, status;
214 int loop, handled = 0;
215
216 for (loop = 0; loop < 10; loop++) {
217 report = saa_readl(SAA7134_IRQ_REPORT);
218 status = saa_readl(SAA7134_IRQ_STATUS);
219
220 if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
221 handled = 1;
222 saa_writel(SAA7134_IRQ_REPORT,report);
223 saa7134_irq_alsa_done(dev, status);
224 } else {
225 goto out;
226 }
227 }
228
229 if (loop == 10) {
230 dprintk("error! looping IRQ!");
231 }
232
233out:
234 return IRQ_RETVAL(handled);
235}
236
237/*
238 * ALSA capture trigger
239 *
240 * - One of the ALSA capture callbacks.
241 *
242 * Called whenever a capture is started or stopped. Must be defined,
243 * but there's nothing we want to do here
244 *
245 */
246
247static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
248 int cmd)
249{
250 snd_pcm_runtime_t *runtime = substream->runtime;
251 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
252 struct saa7134_dev *dev=saapcm->saadev;
253 int err = 0;
254
255 spin_lock_irq(&dev->slock);
256 if (cmd == SNDRV_PCM_TRIGGER_START) {
257 /* start dma */
258 saa7134_dma_start(dev);
259 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
260 /* stop dma */
261 saa7134_dma_stop(dev);
262 } else {
263 err = -EINVAL;
264 }
265 spin_unlock_irq(&dev->slock);
266
267 return err;
268}
269
270/*
271 * DMA buffer config
272 *
273 * Sets the values that will later be used as the size of the buffer,
274 * size of the fragments, and total number of fragments.
275 * Must be called during the preparation stage, before memory is
276 * allocated
277 *
278 * - Copied verbatim from saa7134-oss. Can be dropped
279 * if we just share dsp_buffer_conf from OSS.
280 */
281
282static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
283{
284 if (blksize < 0x100)
285 blksize = 0x100;
286 if (blksize > 0x10000)
287 blksize = 0x10000;
288
289 if (blocks < 2)
290 blocks = 2;
291 if ((blksize * blocks) > 1024*1024)
292 blocks = 1024*1024 / blksize;
293
294 dev->dmasound.blocks = blocks;
295 dev->dmasound.blksize = blksize;
296 dev->dmasound.bufsize = blksize * blocks;
297
298 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
299 blocks,blksize,blksize * blocks / 1024);
300 return 0;
301}
302
303/*
304 * DMA buffer initialization
305 *
306 * Uses V4L functions to initialize the DMA. Shouldn't be necessary in
307 * ALSA, but I was unable to use ALSA's own DMA, and had to force the
308 * usage of V4L's
309 *
310 * - Copied verbatim from saa7134-oss. Can be dropped
311 * if we just share dsp_buffer_init from OSS.
312 */
313
314static int dsp_buffer_init(struct saa7134_dev *dev)
315{
316 int err;
317
318 if (!dev->dmasound.bufsize)
319 BUG();
320 videobuf_dma_init(&dev->dmasound.dma);
321 err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
322 (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
323 if (0 != err)
324 return err;
325 return 0;
326}
327
328/*
329 * ALSA PCM preparation
330 *
331 * - One of the ALSA capture callbacks.
332 *
333 * Called right after the capture device is opened, this function configures
334 * the buffer using the previously defined functions, allocates the memory,
335 * sets up the hardware registers, and then starts the DMA. When this function
336 * returns, the audio should be flowing.
337 *
338 */
339
340static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
341{
342 snd_pcm_runtime_t *runtime = substream->runtime;
343 int err, bswap, sign;
344 u32 fmt, control;
345 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
346 struct saa7134_dev *dev;
347 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
348 unsigned int bps;
349 unsigned long size;
350 unsigned count;
351
352 size = snd_pcm_lib_buffer_bytes(substream);
353 count = snd_pcm_lib_period_bytes(substream);
354
355 saapcm->saadev->dmasound.substream = substream;
356 bps = runtime->rate * runtime->channels;
357 bps *= snd_pcm_format_width(runtime->format);
358 bps /= 8;
359 if (bps <= 0)
360 return -EINVAL;
361 saapcm->pcm_bps = bps;
362 saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream);
363 saapcm->pcm_count = snd_pcm_lib_period_bytes(substream);
364
365
366 dev=saa7134->saadev;
367
368 dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count));
369
370 err = dsp_buffer_init(dev);
371 if (0 != err)
372 goto fail2;
373
374 /* prepare buffer */
375 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
376 return err;
377 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
378 goto fail1;
379 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
380 dev->dmasound.dma.sglist,
381 dev->dmasound.dma.sglen,
382 0)))
383 goto fail2;
384
385
386
387 switch (runtime->format) {
388 case SNDRV_PCM_FORMAT_U8:
389 case SNDRV_PCM_FORMAT_S8:
390 fmt = 0x00;
391 break;
392 case SNDRV_PCM_FORMAT_U16_LE:
393 case SNDRV_PCM_FORMAT_U16_BE:
394 case SNDRV_PCM_FORMAT_S16_LE:
395 case SNDRV_PCM_FORMAT_S16_BE:
396 fmt = 0x01;
397 break;
398 default:
399 err = -EINVAL;
400 return 1;
401 }
402
403 switch (runtime->format) {
404 case SNDRV_PCM_FORMAT_S8:
405 case SNDRV_PCM_FORMAT_S16_LE:
406 case SNDRV_PCM_FORMAT_S16_BE:
407 sign = 1;
408 break;
409 default:
410 sign = 0;
411 break;
412 }
413
414 switch (runtime->format) {
415 case SNDRV_PCM_FORMAT_U16_BE:
416 case SNDRV_PCM_FORMAT_S16_BE:
417 bswap = 1; break;
418 default:
419 bswap = 0; break;
420 }
421
422 switch (dev->pci->device) {
423 case PCI_DEVICE_ID_PHILIPS_SAA7134:
424 if (1 == runtime->channels)
425 fmt |= (1 << 3);
426 if (2 == runtime->channels)
427 fmt |= (3 << 3);
428 if (sign)
429 fmt |= 0x04;
430
431 fmt |= (MIXER_ADDR_TVTUNER == dev->dmasound.input) ? 0xc0 : 0x80;
432 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
433 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8);
434 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
435 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
436
437 break;
438 case PCI_DEVICE_ID_PHILIPS_SAA7133:
439 case PCI_DEVICE_ID_PHILIPS_SAA7135:
440 if (1 == runtime->channels)
441 fmt |= (1 << 4);
442 if (2 == runtime->channels)
443 fmt |= (2 << 4);
444 if (!sign)
445 fmt |= 0x04;
446 saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1);
447 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
448 //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210);
449 break;
450 }
451
452 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
453 runtime->format, runtime->channels, fmt,
454 bswap ? 'b' : '-');
455 /* dma: setup channel 6 (= AUDIO) */
456 control = SAA7134_RS_CONTROL_BURST_16 |
457 SAA7134_RS_CONTROL_ME |
458 (dev->dmasound.pt.dma >> 12);
459 if (bswap)
460 control |= SAA7134_RS_CONTROL_BSWAP;
461
462 /* I should be able to use runtime->dma_addr in the control
463 byte, but it doesn't work. So I allocate the DMA using the
464 V4L functions, and force ALSA to use that as the DMA area */
465
466 runtime->dma_area = dev->dmasound.dma.vmalloc;
467
468 saa_writel(SAA7134_RS_BA1(6),0);
469 saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
470 saa_writel(SAA7134_RS_PITCH(6),0);
471 saa_writel(SAA7134_RS_CONTROL(6),control);
472
473 dev->dmasound.rate = runtime->rate;
474
475 return 0;
476 fail2:
477 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
478 fail1:
479 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
480 return err;
481
482
483}
484
485/*
486 * ALSA pointer fetching
487 *
488 * - One of the ALSA capture callbacks.
489 *
490 * Called whenever a period elapses, it must return the current hardware
491 * position of the buffer.
492 * Also resets the read counter used to prevent overruns
493 *
494 */
495
496static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
497{
498 snd_pcm_runtime_t *runtime = substream->runtime;
499 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
500 struct saa7134_dev *dev=saapcm->saadev;
501
502
503
504 if (dev->dmasound.read_count) {
505 dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream);
506 dev->dmasound.read_offset += snd_pcm_lib_period_bytes(substream);
507 if (dev->dmasound.read_offset == dev->dmasound.bufsize)
508 dev->dmasound.read_offset = 0;
509 }
510
511 return bytes_to_frames(runtime, dev->dmasound.read_offset);
512}
513
514/*
515 * ALSA hardware capabilities definition
516 */
517
518static snd_pcm_hardware_t snd_card_saa7134_capture =
519{
520 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
521 SNDRV_PCM_INFO_BLOCK_TRANSFER |
522 SNDRV_PCM_INFO_MMAP_VALID),
523 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
524 SNDRV_PCM_FMTBIT_S16_BE | \
525 SNDRV_PCM_FMTBIT_S8 | \
526 SNDRV_PCM_FMTBIT_U8 | \
527 SNDRV_PCM_FMTBIT_U16_LE | \
528 SNDRV_PCM_FMTBIT_U16_BE,
529 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
530 .rate_min = 32000,
531 .rate_max = 48000,
532 .channels_min = 1,
533 .channels_max = 2,
534 .buffer_bytes_max = (256*1024),
535 .period_bytes_min = 64,
536 .period_bytes_max = (256*1024),
537 .periods_min = 2,
538 .periods_max = 1024,
539};
540
541static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
542{
543 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
544
545 kfree(saapcm);
546}
547
548
549/*
550 * ALSA hardware params
551 *
552 * - One of the ALSA capture callbacks.
553 *
554 * Called on initialization, right before the PCM preparation
555 * Usually used in ALSA to allocate the DMA, but since we don't use the
556 * ALSA DMA it does nothing
557 *
558 */
559
560static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
561 snd_pcm_hw_params_t * hw_params)
562{
563
564 return 0;
565
566
567}
568
569/*
570 * ALSA hardware release
571 *
572 * - One of the ALSA capture callbacks.
573 *
574 * Called after closing the device, but before snd_card_saa7134_capture_close
575 * Usually used in ALSA to free the DMA, but since we don't use the
576 * ALSA DMA I'm almost sure this isn't necessary.
577 *
578 */
579
580static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
581{
582 return 0;
583}
584
585/*
586 * DMA buffer release
587 *
588 * Called after closing the device, during snd_card_saa7134_capture_close
589 *
590 */
591
592static int dsp_buffer_free(struct saa7134_dev *dev)
593{
594 if (!dev->dmasound.blksize)
595 BUG();
596
597 videobuf_dma_free(&dev->dmasound.dma);
598
599 dev->dmasound.blocks = 0;
600 dev->dmasound.blksize = 0;
601 dev->dmasound.bufsize = 0;
602
603 return 0;
604}
605
606/*
607 * ALSA capture finish
608 *
609 * - One of the ALSA capture callbacks.
610 *
611 * Called after closing the device. It stops the DMA audio and releases
612 * the buffers
613 *
614 */
615
616static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
617{
618 snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream);
619 struct saa7134_dev *dev = chip->saadev;
620
621 /* unlock buffer */
622 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
623 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
624
625 dsp_buffer_free(dev);
626 return 0;
627}
628
629/*
630 * ALSA capture start
631 *
632 * - One of the ALSA capture callbacks.
633 *
634 * Called when opening the device. It creates and populates the PCM
635 * structure
636 *
637 */
638
639static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
640{
641 snd_pcm_runtime_t *runtime = substream->runtime;
642 snd_card_saa7134_pcm_t *saapcm;
643 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
644 struct saa7134_dev *dev = saa7134->saadev;
645 int err;
646
647 down(&dev->dmasound.lock);
648
649 dev->dmasound.afmt = SNDRV_PCM_FORMAT_U8;
650 dev->dmasound.channels = 2;
651 dev->dmasound.read_count = 0;
652 dev->dmasound.read_offset = 0;
653
654 up(&dev->dmasound.lock);
655
656 saapcm = kzalloc(sizeof(*saapcm), GFP_KERNEL);
657 if (saapcm == NULL)
658 return -ENOMEM;
659 saapcm->saadev=saa7134->saadev;
660
661 spin_lock_init(&saapcm->lock);
662
663 saapcm->substream = substream;
664 runtime->private_data = saapcm;
665 runtime->private_free = snd_card_saa7134_runtime_free;
666 runtime->hw = snd_card_saa7134_capture;
667
668 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
669 return err;
670
671 return 0;
672}
673
674/*
675 * ALSA capture callbacks definition
676 */
677
678static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
679 .open = snd_card_saa7134_capture_open,
680 .close = snd_card_saa7134_capture_close,
681 .ioctl = snd_pcm_lib_ioctl,
682 .hw_params = snd_card_saa7134_hw_params,
683 .hw_free = snd_card_saa7134_hw_free,
684 .prepare = snd_card_saa7134_capture_prepare,
685 .trigger = snd_card_saa7134_capture_trigger,
686 .pointer = snd_card_saa7134_capture_pointer,
687};
688
689/*
690 * ALSA PCM setup
691 *
692 * Called when initializing the board. Sets up the name and hooks up
693 * the callbacks
694 *
695 */
696
697static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
698{
699 snd_pcm_t *pcm;
700 int err;
701
702 if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
703 return err;
704 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_saa7134_capture_ops);
705 pcm->private_data = saa7134;
706 pcm->info_flags = 0;
707 strcpy(pcm->name, "SAA7134 PCM");
708 return 0;
709}
710
711#define SAA713x_VOLUME(xname, xindex, addr) \
712{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
713 .info = snd_saa7134_volume_info, \
714 .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
715 .private_value = addr }
716
717static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
718{
719 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
720 uinfo->count = 2;
721 uinfo->value.integer.min = 0;
722 uinfo->value.integer.max = 20;
723 return 0;
724}
725
726static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
727{
728 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
729 int addr = kcontrol->private_value;
730
731 ucontrol->value.integer.value[0] = chip->mixer_volume[addr][0];
732 ucontrol->value.integer.value[1] = chip->mixer_volume[addr][1];
733 return 0;
734}
735
736static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
737{
738 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
739 unsigned long flags;
740 int change, addr = kcontrol->private_value;
741 int left, right;
742
743 left = ucontrol->value.integer.value[0];
744 if (left < 0)
745 left = 0;
746 if (left > 20)
747 left = 20;
748 right = ucontrol->value.integer.value[1];
749 if (right < 0)
750 right = 0;
751 if (right > 20)
752 right = 20;
753 spin_lock_irqsave(&chip->mixer_lock, flags);
754 change = chip->mixer_volume[addr][0] != left ||
755 chip->mixer_volume[addr][1] != right;
756 chip->mixer_volume[addr][0] = left;
757 chip->mixer_volume[addr][1] = right;
758 spin_unlock_irqrestore(&chip->mixer_lock, flags);
759 return change;
760}
761
762#define SAA713x_CAPSRC(xname, xindex, addr) \
763{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
764 .info = snd_saa7134_capsrc_info, \
765 .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
766 .private_value = addr }
767
768static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
769{
770 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
771 uinfo->count = 2;
772 uinfo->value.integer.min = 0;
773 uinfo->value.integer.max = 1;
774 return 0;
775}
776
777static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
778{
779 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
780 unsigned long flags;
781 int addr = kcontrol->private_value;
782
783 spin_lock_irqsave(&chip->mixer_lock, flags);
784 ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
785 ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
786 spin_unlock_irqrestore(&chip->mixer_lock, flags);
787 return 0;
788}
789
790static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
791{
792 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
793 unsigned long flags;
794 int change, addr = kcontrol->private_value;
795 int left, right;
796 u32 anabar, xbarin;
797 int analog_io, rate;
798 struct saa7134_dev *dev;
799
800 dev = chip->saadev;
801
802 left = ucontrol->value.integer.value[0] & 1;
803 right = ucontrol->value.integer.value[1] & 1;
804 spin_lock_irqsave(&chip->mixer_lock, flags);
805
806 change = chip->capture_source[addr][0] != left ||
807 chip->capture_source[addr][1] != right;
808 chip->capture_source[addr][0] = left;
809 chip->capture_source[addr][1] = right;
810 dev->dmasound.input=addr;
811 spin_unlock_irqrestore(&chip->mixer_lock, flags);
812
813
814 if (change) {
815 switch (dev->pci->device) {
816
817 case PCI_DEVICE_ID_PHILIPS_SAA7134:
818 switch (addr) {
819 case MIXER_ADDR_TVTUNER:
820 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
821 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
822 break;
823 case MIXER_ADDR_LINE1:
824 case MIXER_ADDR_LINE2:
825 analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08;
826 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
827 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
828 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
829 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
830 break;
831 }
832
833 break;
834 case PCI_DEVICE_ID_PHILIPS_SAA7133:
835 case PCI_DEVICE_ID_PHILIPS_SAA7135:
836 xbarin = 0x03; // adc
837 anabar = 0;
838 switch (addr) {
839 case MIXER_ADDR_TVTUNER:
840 xbarin = 0; // Demodulator
841 anabar = 2; // DACs
842 break;
843 case MIXER_ADDR_LINE1:
844 anabar = 0; // aux1, aux1
845 break;
846 case MIXER_ADDR_LINE2:
847 anabar = 9; // aux2, aux2
848 break;
849 }
850
851 /* output xbar always main channel */
852 saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
853
854 if (left || right) { // We've got data, turn the input on
855 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
856 saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
857 } else {
858 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
859 saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
860 }
861 break;
862 }
863 }
864
865 return change;
866}
867
868static snd_kcontrol_new_t snd_saa7134_controls[] = {
869SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
870SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
871SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
872SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
873SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
874SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
875};
876
877/*
878 * ALSA mixer setup
879 *
880 * Called when initializing the board. Sets up the name and hooks up
881 * the callbacks
882 *
883 */
884
885static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
886{
887 snd_card_t *card = chip->card;
888 unsigned int idx;
889 int err;
890
891 snd_assert(chip != NULL, return -EINVAL);
892 strcpy(card->mixername, "SAA7134 Mixer");
893
894 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) {
895 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0)
896 return err;
897 }
898 return 0;
899}
900
901static int snd_saa7134_free(snd_card_saa7134_t *chip)
902{
903 return 0;
904}
905
906static int snd_saa7134_dev_free(snd_device_t *device)
907{
908 snd_card_saa7134_t *chip = device->device_data;
909 return snd_saa7134_free(chip);
910}
911
912/*
913 * ALSA initialization
914 *
915 * Called by saa7134-core, it creates the basic structures and registers
916 * the ALSA devices
917 *
918 */
919
920int alsa_card_saa7134_create (struct saa7134_dev *saadev)
921{
922 static int dev;
923
924 snd_card_t *card;
925 snd_card_saa7134_t *chip;
926 int err;
927 static snd_device_ops_t ops = {
928 .dev_free = snd_saa7134_dev_free,
929 };
930
931
932 if (dev >= SNDRV_CARDS)
933 return -ENODEV;
934 if (!enable[dev])
935 return -ENODEV;
936
937 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
938
939 if (card == NULL)
940 return -ENOMEM;
941
942 strcpy(card->driver, "SAA7134");
943
944 /* Card "creation" */
945
946 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
947 if (chip == NULL) {
948 return -ENOMEM;
949 }
950
951 spin_lock_init(&chip->lock);
952 spin_lock_init(&chip->mixer_lock);
953
954 chip->saadev = saadev;
955
956 chip->card = card;
957
958 chip->pci = saadev->pci;
959 chip->irq = saadev->pci->irq;
960 chip->iobase = pci_resource_start(saadev->pci, 0);
961
962 err = request_irq(saadev->pci->irq, saa7134_alsa_irq,
963 SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev);
964
965 if (err < 0) {
966 printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n",
967 saadev->name, saadev->pci->irq);
968 goto __nodev;
969 }
970
971 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
972 goto __nodev;
973 }
974
975 if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
976 goto __nodev;
977
978 if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)
979 goto __nodev;
980
981 snd_card_set_dev(card, &chip->pci->dev);
982
983 /* End of "creation" */
984
985 strcpy(card->shortname, "SAA7134");
986 sprintf(card->longname, "%s at 0x%lx irq %d",
987 chip->saadev->name, chip->iobase, chip->irq);
988
989 if ((err = snd_card_register(card)) == 0) {
990 snd_saa7134_cards[dev] = card;
991 return 0;
992 }
993
994__nodev:
995 snd_card_free(card);
996 kfree(chip);
997 return err;
998}
999
1000/*
1001 * Module initializer
1002 *
1003 * Loops through present saa7134 cards, and assigns an ALSA device
1004 * to each one
1005 *
1006 */
1007
1008static int saa7134_alsa_init(void)
1009{
1010 struct saa7134_dev *saadev = NULL;
1011 struct list_head *list;
1012
1013 printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
1014
1015 list_for_each(list,&saa7134_devlist) {
1016 saadev = list_entry(list, struct saa7134_dev, devlist);
1017 alsa_card_saa7134_create(saadev);
1018 }
1019
1020 if (saadev == NULL)
1021 printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
1022
1023 return 0;
1024
1025}
1026
1027/*
1028 * Module destructor
1029 */
1030
1031void saa7134_alsa_exit(void)
1032{
1033 int idx;
1034
1035 for (idx = 0; idx < SNDRV_CARDS; idx++) {
1036 snd_card_free(snd_saa7134_cards[idx]);
1037 }
1038
1039 printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n");
1040
1041 return;
1042}
1043
1044module_init(saa7134_alsa_init);
1045module_exit(saa7134_alsa_exit);
1046MODULE_LICENSE("GPL");
1047MODULE_AUTHOR("Ricardo Cerqueira");
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index acc7a4335e23..663d03e5bc67 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -191,10 +191,14 @@ struct saa7134_board saa7134_boards[] = {
191 .amux = TV, 191 .amux = TV,
192 .tv = 1, 192 .tv = 1,
193 },{ 193 },{
194 .name = name_comp1, 194 .name = name_comp1, /* Composite signal on S-Video input */
195 .vmux = 0, 195 .vmux = 0,
196 .amux = LINE2, 196 .amux = LINE2,
197 },{ 197 },{
198 .name = name_comp2, /* Composite input */
199 .vmux = 3,
200 .amux = LINE2,
201 },{
198 .name = name_svideo, 202 .name = name_svideo,
199 .vmux = 8, 203 .vmux = 8,
200 .amux = LINE2, 204 .amux = LINE2,
@@ -2109,8 +2113,423 @@ struct saa7134_board saa7134_boards[] = {
2109 .gpio = 0x01, 2113 .gpio = 0x01,
2110 }, 2114 },
2111 }, 2115 },
2112}; 2116 [SAA7134_BOARD_BEHOLD_409FM] = {
2117 /* <http://tuner.beholder.ru>, Sergey <skiv@orel.ru> */
2118 .name = "Beholder BeholdTV 409 FM",
2119 .audio_clock = 0x00187de7,
2120 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
2121 .radio_type = UNSET,
2122 .tuner_addr = ADDR_UNSET,
2123 .radio_addr = ADDR_UNSET,
2124 .tda9887_conf = TDA9887_PRESENT,
2125 .inputs = {{
2126 .name = name_tv,
2127 .vmux = 3,
2128 .amux = TV,
2129 .tv = 1,
2130 },{
2131 .name = name_comp1,
2132 .vmux = 1,
2133 .amux = LINE1,
2134 },{
2135 .name = name_svideo,
2136 .vmux = 8,
2137 .amux = LINE1,
2138 }},
2139 .radio = {
2140 .name = name_radio,
2141 .amux = LINE2,
2142 },
2143 },
2144 [SAA7134_BOARD_GOTVIEW_7135] = {
2145 /* Mike Baikov <mike@baikov.com> */
2146 /* Andrey Cvetcov <ays14@yandex.ru> */
2147 .name = "GoTView 7135 PCI",
2148 .audio_clock = 0x00187de7,
2149 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
2150 .radio_type = UNSET,
2151 .tuner_addr = ADDR_UNSET,
2152 .radio_addr = ADDR_UNSET,
2153 .tda9887_conf = TDA9887_PRESENT,
2154 .gpiomask = 0x00200003,
2155 .inputs = {{
2156 .name = name_tv,
2157 .vmux = 1,
2158 .amux = TV,
2159 .tv = 1,
2160 .gpio = 0x00200003,
2161 },{
2162 .name = name_tv_mono,
2163 .vmux = 1,
2164 .amux = LINE2,
2165 .gpio = 0x00200003,
2166 },{
2167 .name = name_comp1,
2168 .vmux = 3,
2169 .amux = LINE1,
2170 .gpio = 0x00200003,
2171 },{
2172 .name = name_svideo,
2173 .vmux = 8,
2174 .amux = LINE1,
2175 .gpio = 0x00200003,
2176 }},
2177 .radio = {
2178 .name = name_radio,
2179 .amux = LINE2,
2180 .gpio = 0x00200003,
2181 },
2182 .mute = {
2183 .name = name_mute,
2184 .amux = TV,
2185 .gpio = 0x00200003,
2186 },
2187 },
2188 [SAA7134_BOARD_PHILIPS_EUROPA] = {
2189 .name = "Philips EUROPA V3 reference design",
2190 .audio_clock = 0x00187de7,
2191 .tuner_type = TUNER_PHILIPS_TD1316,
2192 .radio_type = UNSET,
2193 .tuner_addr = 0x61,
2194 .radio_addr = ADDR_UNSET,
2195 .tda9887_conf = TDA9887_PRESENT,
2196 .mpeg = SAA7134_MPEG_DVB,
2197 .inputs = {{
2198 .name = name_tv,
2199 .vmux = 3,
2200 .amux = TV,
2201 .tv = 1,
2202 },{
2203 .name = name_comp1,
2204 .vmux = 0,
2205 .amux = LINE2,
2206 },{
2207 .name = name_svideo,
2208 .vmux = 8,
2209 .amux = LINE2,
2210 }},
2211 },
2212 [SAA7134_BOARD_VIDEOMATE_DVBT_300] = {
2213 .name = "Compro Videomate DVB-T300",
2214 .audio_clock = 0x00187de7,
2215 .tuner_type = TUNER_PHILIPS_TD1316,
2216 .radio_type = UNSET,
2217 .tuner_addr = 0x61,
2218 .radio_addr = ADDR_UNSET,
2219 .tda9887_conf = TDA9887_PRESENT,
2220 .mpeg = SAA7134_MPEG_DVB,
2221 .inputs = {{
2222 .name = name_tv,
2223 .vmux = 3,
2224 .amux = TV,
2225 .tv = 1,
2226 },{
2227 .name = name_comp1,
2228 .vmux = 1,
2229 .amux = LINE2,
2230 },{
2231 .name = name_svideo,
2232 .vmux = 8,
2233 .amux = LINE2,
2234 }},
2235 },
2236 [SAA7134_BOARD_VIDEOMATE_DVBT_200] = {
2237 .name = "Compro Videomate DVB-T200",
2238 .tuner_type = TUNER_ABSENT,
2239 .audio_clock = 0x00187de7,
2240 .radio_type = UNSET,
2241 .tuner_addr = ADDR_UNSET,
2242 .radio_addr = ADDR_UNSET,
2243 .mpeg = SAA7134_MPEG_DVB,
2244 .inputs = {{
2245 .name = name_comp1,
2246 .vmux = 0,
2247 .amux = LINE1,
2248 },{
2249 .name = name_svideo,
2250 .vmux = 8,
2251 .amux = LINE1,
2252 }},
2253 },
2254 [SAA7134_BOARD_RTD_VFG7350] = {
2255 .name = "RTD Embedded Technologies VFG7350",
2256 .audio_clock = 0x00200000,
2257 .tuner_type = TUNER_ABSENT,
2258 .radio_type = UNSET,
2259 .tuner_addr = ADDR_UNSET,
2260 .radio_addr = ADDR_UNSET,
2261 .inputs = {{
2262 .name = "Composite 0",
2263 .vmux = 0,
2264 .amux = LINE1,
2265 },{
2266 .name = "Composite 1",
2267 .vmux = 1,
2268 .amux = LINE2,
2269 },{
2270 .name = "Composite 2",
2271 .vmux = 2,
2272 .amux = LINE1,
2273 },{
2274 .name = "Composite 3",
2275 .vmux = 3,
2276 .amux = LINE2,
2277 },{
2278 .name = "S-Video 0",
2279 .vmux = 8,
2280 .amux = LINE1,
2281 },{
2282 .name = "S-Video 1",
2283 .vmux = 9,
2284 .amux = LINE2,
2285 }},
2286 .mpeg = SAA7134_MPEG_EMPRESS,
2287 .video_out = CCIR656,
2288 .vid_port_opts = ( SET_T_CODE_POLARITY_NON_INVERTED |
2289 SET_CLOCK_NOT_DELAYED |
2290 SET_CLOCK_INVERTED |
2291 SET_VSYNC_OFF ),
2292 },
2293 [SAA7134_BOARD_RTD_VFG7330] = {
2294 .name = "RTD Embedded Technologies VFG7330",
2295 .audio_clock = 0x00200000,
2296 .tuner_type = TUNER_ABSENT,
2297 .radio_type = UNSET,
2298 .tuner_addr = ADDR_UNSET,
2299 .radio_addr = ADDR_UNSET,
2300 .inputs = {{
2301 .name = "Composite 0",
2302 .vmux = 0,
2303 .amux = LINE1,
2304 },{
2305 .name = "Composite 1",
2306 .vmux = 1,
2307 .amux = LINE2,
2308 },{
2309 .name = "Composite 2",
2310 .vmux = 2,
2311 .amux = LINE1,
2312 },{
2313 .name = "Composite 3",
2314 .vmux = 3,
2315 .amux = LINE2,
2316 },{
2317 .name = "S-Video 0",
2318 .vmux = 8,
2319 .amux = LINE1,
2320 },{
2321 .name = "S-Video 1",
2322 .vmux = 9,
2323 .amux = LINE2,
2324 }},
2325 },
2326 [SAA7134_BOARD_FLYTVPLATINUM_MINI2] = {
2327 .name = "LifeView FlyTV Platinum Mini2",
2328 .audio_clock = 0x00200000,
2329 .tuner_type = TUNER_PHILIPS_TDA8290,
2330 .radio_type = UNSET,
2331 .tuner_addr = ADDR_UNSET,
2332 .radio_addr = ADDR_UNSET,
2113 2333
2334 .inputs = {{
2335 .name = name_tv,
2336 .vmux = 1,
2337 .amux = TV,
2338 .tv = 1,
2339 },{
2340 .name = name_comp1, /* Composite signal on S-Video input */
2341 .vmux = 0,
2342 .amux = LINE2,
2343 },{
2344 .name = name_comp2, /* Composite input */
2345 .vmux = 3,
2346 .amux = LINE2,
2347 },{
2348 .name = name_svideo,
2349 .vmux = 8,
2350 .amux = LINE2,
2351 }},
2352 },
2353 [SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = {
2354 /* Michael Krufky <mkrufky@m1k.net>
2355 * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder
2356 * AFAIK, there is no analog demod, thus,
2357 * no support for analog television.
2358 */
2359 .name = "AVerMedia AVerTVHD MCE A180",
2360 .audio_clock = 0x00187de7,
2361 .tuner_type = TUNER_ABSENT,
2362 .radio_type = UNSET,
2363 .tuner_addr = ADDR_UNSET,
2364 .radio_addr = ADDR_UNSET,
2365 .mpeg = SAA7134_MPEG_DVB,
2366 .inputs = {{
2367 .name = name_comp1,
2368 .vmux = 3,
2369 .amux = LINE2,
2370 },{
2371 .name = name_svideo,
2372 .vmux = 8,
2373 .amux = LINE2,
2374 }},
2375 },
2376 [SAA7134_BOARD_MONSTERTV_MOBILE] = {
2377 .name = "SKNet MonsterTV Mobile",
2378 .audio_clock = 0x00187de7,
2379 .tuner_type = TUNER_PHILIPS_TDA8290,
2380 .radio_type = UNSET,
2381 .tuner_addr = ADDR_UNSET,
2382 .radio_addr = ADDR_UNSET,
2383
2384 .inputs = {{
2385 .name = name_tv,
2386 .vmux = 1,
2387 .amux = TV,
2388 .tv = 1,
2389 },{
2390 .name = name_comp1,
2391 .vmux = 3,
2392 .amux = LINE1,
2393 },{
2394 .name = name_svideo,
2395 .vmux = 6,
2396 .amux = LINE1,
2397 }},
2398 },
2399 [SAA7134_BOARD_PINNACLE_PCTV_110i] = {
2400 .name = "Pinnacle PCTV 110i (saa7133)",
2401 .audio_clock = 0x00187de7,
2402 .tuner_type = TUNER_PHILIPS_TDA8290,
2403 .radio_type = UNSET,
2404 .tuner_addr = ADDR_UNSET,
2405 .radio_addr = ADDR_UNSET,
2406 .gpiomask = 0x080200000,
2407 .inputs = {{
2408 .name = name_tv,
2409 .vmux = 4,
2410 .amux = TV,
2411 .tv = 1,
2412 },{
2413 .name = name_comp1,
2414 .vmux = 1,
2415 .amux = LINE2,
2416 },{
2417 .name = name_svideo,
2418 .vmux = 8,
2419 .amux = LINE2,
2420 }},
2421 .radio = {
2422 .name = name_radio,
2423 .amux = LINE1,
2424 },
2425 },
2426 [SAA7134_BOARD_ASUSTeK_P7131_DUAL] = {
2427 .name = "ASUSTeK P7131 Dual",
2428 .audio_clock = 0x00187de7,
2429 .tuner_type = TUNER_PHILIPS_TDA8290,
2430 .radio_type = UNSET,
2431 .tuner_addr = ADDR_UNSET,
2432 .radio_addr = ADDR_UNSET,
2433 .gpiomask = 1 << 21,
2434 .mpeg = SAA7134_MPEG_DVB,
2435 .inputs = {{
2436 .name = name_tv,
2437 .vmux = 1,
2438 .amux = TV,
2439 .tv = 1,
2440 },{
2441 .name = name_comp1,
2442 .vmux = 3,
2443 .amux = LINE2,
2444 },{
2445 .name = name_svideo,
2446 .vmux = 8,
2447 .amux = LINE2,
2448 }},
2449 .radio = {
2450 .name = name_radio,
2451 .amux = TV,
2452 .gpio = 0x0200000,
2453 },
2454 },
2455 [SAA7134_BOARD_SEDNA_PC_TV_CARDBUS] = {
2456 /* Paul Tom Zalac <pzalac@gmail.com> */
2457 /* Pavel Mihaylov <bin@bash.info> */
2458 .name = "Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)",
2459 /* Sedna/MuchTV (OEM) Cardbus TV Tuner */
2460 .audio_clock = 0x00187de7,
2461 .tuner_type = TUNER_PHILIPS_TDA8290,
2462 .radio_type = UNSET,
2463 .tuner_addr = ADDR_UNSET,
2464 .radio_addr = ADDR_UNSET,
2465 .gpiomask = 0xe880c0,
2466 .inputs = {{
2467 .name = name_tv,
2468 .vmux = 3,
2469 .amux = TV,
2470 .tv = 1,
2471 },{
2472 .name = name_comp1,
2473 .vmux = 1,
2474 .amux = LINE1,
2475 },{
2476 .name = name_svideo,
2477 .vmux = 6,
2478 .amux = LINE1,
2479 }},
2480 .radio = {
2481 .name = name_radio,
2482 .amux = LINE2,
2483 },
2484 },
2485 [SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV] = {
2486 /* "Cyril Lacoux (Yack)" <clacoux@ifeelgood.org> */
2487 .name = "ASUS Digimatrix TV",
2488 .audio_clock = 0x00200000,
2489 .tuner_type = TUNER_PHILIPS_FQ1216ME,
2490 .tda9887_conf = TDA9887_PRESENT,
2491 .radio_type = UNSET,
2492 .tuner_addr = ADDR_UNSET,
2493 .radio_addr = ADDR_UNSET,
2494 .inputs = {{
2495 .name = name_tv,
2496 .vmux = 1,
2497 .amux = TV,
2498 .tv = 1,
2499 },{
2500 .name = name_comp1,
2501 .vmux = 3,
2502 .amux = LINE1,
2503 },{
2504 .name = name_svideo,
2505 .vmux = 8,
2506 .amux = LINE1,
2507 }},
2508 },
2509 [SAA7134_BOARD_PHILIPS_TIGER] = {
2510 .name = "Philips Tiger reference design",
2511 .audio_clock = 0x00187de7,
2512 .tuner_type = TUNER_PHILIPS_TDA8290,
2513 .radio_type = UNSET,
2514 .tuner_addr = ADDR_UNSET,
2515 .radio_addr = ADDR_UNSET,
2516 .mpeg = SAA7134_MPEG_DVB,
2517 .inputs = {{
2518 .name = name_tv,
2519 .vmux = 1,
2520 .amux = TV,
2521 .tv = 1,
2522 },{
2523 .name = name_comp1,
2524 .vmux = 3,
2525 .amux = LINE1,
2526 },{
2527 .name = name_svideo,
2528 .vmux = 8,
2529 .amux = LINE1,
2530 }},
2531 },
2532};
2114 2533
2115const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 2534const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
2116 2535
@@ -2145,19 +2564,19 @@ struct pci_device_id saa7134_pci_tbl[] = {
2145 },{ 2564 },{
2146 .vendor = PCI_VENDOR_ID_PHILIPS, 2565 .vendor = PCI_VENDOR_ID_PHILIPS,
2147 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2566 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2148 .subvendor = 0x153B, 2567 .subvendor = 0x153b,
2149 .subdevice = 0x1142, 2568 .subdevice = 0x1142,
2150 .driver_data = SAA7134_BOARD_CINERGY400, 2569 .driver_data = SAA7134_BOARD_CINERGY400,
2151 },{ 2570 },{
2152 .vendor = PCI_VENDOR_ID_PHILIPS, 2571 .vendor = PCI_VENDOR_ID_PHILIPS,
2153 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2572 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2154 .subvendor = 0x153B, 2573 .subvendor = 0x153b,
2155 .subdevice = 0x1143, 2574 .subdevice = 0x1143,
2156 .driver_data = SAA7134_BOARD_CINERGY600, 2575 .driver_data = SAA7134_BOARD_CINERGY600,
2157 },{ 2576 },{
2158 .vendor = PCI_VENDOR_ID_PHILIPS, 2577 .vendor = PCI_VENDOR_ID_PHILIPS,
2159 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2578 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2160 .subvendor = 0x153B, 2579 .subvendor = 0x153b,
2161 .subdevice = 0x1158, 2580 .subdevice = 0x1158,
2162 .driver_data = SAA7134_BOARD_CINERGY600_MK3, 2581 .driver_data = SAA7134_BOARD_CINERGY600_MK3,
2163 },{ 2582 },{
@@ -2193,6 +2612,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
2193 },{ 2612 },{
2194 .vendor = PCI_VENDOR_ID_PHILIPS, 2613 .vendor = PCI_VENDOR_ID_PHILIPS,
2195 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 2614 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2615 .subvendor = 0x14c0,
2616 .subdevice = 0x1212, /* minipci, LR1212 */
2617 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI2,
2618 },{
2619 .vendor = PCI_VENDOR_ID_PHILIPS,
2620 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2621 .subvendor = 0x4e42,
2622 .subdevice = 0x0212, /* OEM minipci, LR212 */
2623 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
2624 },{
2625 .vendor = PCI_VENDOR_ID_PHILIPS,
2626 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2196 .subvendor = 0x5168, /* Animation Technologies (LifeView) */ 2627 .subvendor = 0x5168, /* Animation Technologies (LifeView) */
2197 .subdevice = 0x0214, /* Standard PCI, LR214WF */ 2628 .subdevice = 0x0214, /* Standard PCI, LR214WF */
2198 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, 2629 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
@@ -2369,7 +2800,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
2369 },{ 2800 },{
2370 .vendor = PCI_VENDOR_ID_PHILIPS, 2801 .vendor = PCI_VENDOR_ID_PHILIPS,
2371 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 2802 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
2372 .subvendor = 0x153B, 2803 .subvendor = 0x153b,
2373 .subdevice = 0x1152, 2804 .subdevice = 0x1152,
2374 .driver_data = SAA7134_BOARD_CINERGY200, 2805 .driver_data = SAA7134_BOARD_CINERGY200,
2375 },{ 2806 },{
@@ -2434,13 +2865,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
2434 .subvendor = 0x1421, 2865 .subvendor = 0x1421,
2435 .subdevice = 0x0350, /* PCI version */ 2866 .subdevice = 0x0350, /* PCI version */
2436 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, 2867 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2437
2438 },{ 2868 },{
2439 .vendor = PCI_VENDOR_ID_PHILIPS, 2869 .vendor = PCI_VENDOR_ID_PHILIPS,
2440 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 2870 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2441 .subvendor = 0x1421, 2871 .subvendor = 0x1421,
2442 .subdevice = 0x0370, /* cardbus version */ 2872 .subdevice = 0x0370, /* cardbus version */
2443 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, 2873 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2874 },{
2875 .vendor = PCI_VENDOR_ID_PHILIPS,
2876 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2877 .subvendor = 0x1421,
2878 .subdevice = 0x1370, /* cardbus version */
2879 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2444 2880
2445 },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */ 2881 },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */
2446 .vendor = PCI_VENDOR_ID_PHILIPS, 2882 .vendor = PCI_VENDOR_ID_PHILIPS,
@@ -2459,9 +2895,81 @@ struct pci_device_id saa7134_pci_tbl[] = {
2459 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2895 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2460 .subvendor = 0x1043, 2896 .subvendor = 0x1043,
2461 .subdevice = 0x0210, /* mini pci PAL/SECAM version */ 2897 .subdevice = 0x0210, /* mini pci PAL/SECAM version */
2462 .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX, 2898 .driver_data = SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV,
2463 2899
2464 },{ 2900 },{
2901 .vendor = PCI_VENDOR_ID_PHILIPS,
2902 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2903 .subvendor = 0x0000, /* It shouldn't break anything, since subdevice id seems unique */
2904 .subdevice = 0x4091,
2905 .driver_data = SAA7134_BOARD_BEHOLD_409FM,
2906 },{
2907 .vendor = PCI_VENDOR_ID_PHILIPS,
2908 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2909 .subvendor = 0x5456, /* GoTView */
2910 .subdevice = 0x7135,
2911 .driver_data = SAA7134_BOARD_GOTVIEW_7135,
2912 },{
2913 .vendor = PCI_VENDOR_ID_PHILIPS,
2914 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2915 .subvendor = PCI_VENDOR_ID_PHILIPS,
2916 .subdevice = 0x2004,
2917 .driver_data = SAA7134_BOARD_PHILIPS_EUROPA,
2918 },{
2919 .vendor = PCI_VENDOR_ID_PHILIPS,
2920 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2921 .subvendor = 0x185b,
2922 .subdevice = 0xc900,
2923 .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_300,
2924 },{
2925 .vendor = PCI_VENDOR_ID_PHILIPS,
2926 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
2927 .subvendor = 0x185b,
2928 .subdevice = 0xc901,
2929 .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_200,
2930 },{
2931 .vendor = PCI_VENDOR_ID_PHILIPS,
2932 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2933 .subvendor = 0x1435,
2934 .subdevice = 0x7350,
2935 .driver_data = SAA7134_BOARD_RTD_VFG7350,
2936 },{
2937 .vendor = PCI_VENDOR_ID_PHILIPS,
2938 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2939 .subvendor = 0x1435,
2940 .subdevice = 0x7330,
2941 .driver_data = SAA7134_BOARD_RTD_VFG7330,
2942 },{
2943 .vendor = PCI_VENDOR_ID_PHILIPS,
2944 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2945 .subvendor = 0x1461,
2946 .subdevice = 0x1044,
2947 .driver_data = SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180,
2948 },{
2949 .vendor = PCI_VENDOR_ID_PHILIPS,
2950 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2951 .subvendor = 0x1131,
2952 .subdevice = 0x4ee9,
2953 .driver_data = SAA7134_BOARD_MONSTERTV_MOBILE,
2954 },{
2955 .vendor = PCI_VENDOR_ID_PHILIPS,
2956 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2957 .subvendor = 0x11bd,
2958 .subdevice = 0x002e,
2959 .driver_data = SAA7134_BOARD_PINNACLE_PCTV_110i,
2960 },{
2961 .vendor = PCI_VENDOR_ID_PHILIPS,
2962 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2963 .subvendor = 0x1043,
2964 .subdevice = 0x4862,
2965 .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
2966 },{
2967 .vendor = PCI_VENDOR_ID_PHILIPS,
2968 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2969 .subvendor = PCI_VENDOR_ID_PHILIPS,
2970 .subdevice = 0x2018,
2971 .driver_data = SAA7134_BOARD_PHILIPS_TIGER,
2972 },{
2465 /* --- boards without eeprom + subsystem ID --- */ 2973 /* --- boards without eeprom + subsystem ID --- */
2466 .vendor = PCI_VENDOR_ID_PHILIPS, 2974 .vendor = PCI_VENDOR_ID_PHILIPS,
2467 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2975 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -2530,9 +3038,10 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2530 switch (dev->board) { 3038 switch (dev->board) {
2531 case SAA7134_BOARD_FLYVIDEO2000: 3039 case SAA7134_BOARD_FLYVIDEO2000:
2532 case SAA7134_BOARD_FLYVIDEO3000: 3040 case SAA7134_BOARD_FLYVIDEO3000:
2533 dev->has_remote = 1; 3041 dev->has_remote = SAA7134_REMOTE_GPIO;
2534 board_flyvideo(dev); 3042 board_flyvideo(dev);
2535 break; 3043 break;
3044 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
2536 case SAA7134_BOARD_FLYTVPLATINUM_FM: 3045 case SAA7134_BOARD_FLYTVPLATINUM_FM:
2537 case SAA7134_BOARD_CINERGY400: 3046 case SAA7134_BOARD_CINERGY400:
2538 case SAA7134_BOARD_CINERGY600: 3047 case SAA7134_BOARD_CINERGY600:
@@ -2550,10 +3059,16 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2550/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ 3059/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */
2551 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 3060 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
2552 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 3061 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
3062 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
3063 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
2553 case SAA7134_BOARD_MANLI_MTV001: 3064 case SAA7134_BOARD_MANLI_MTV001:
2554 case SAA7134_BOARD_MANLI_MTV002: 3065 case SAA7134_BOARD_MANLI_MTV002:
3066 case SAA7134_BOARD_BEHOLD_409FM:
2555 case SAA7134_BOARD_AVACSSMARTTV: 3067 case SAA7134_BOARD_AVACSSMARTTV:
2556 dev->has_remote = 1; 3068 case SAA7134_BOARD_GOTVIEW_7135:
3069 case SAA7134_BOARD_KWORLD_TERMINATOR:
3070 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
3071 dev->has_remote = SAA7134_REMOTE_GPIO;
2557 break; 3072 break;
2558 case SAA7134_BOARD_MD5044: 3073 case SAA7134_BOARD_MD5044:
2559 printk("%s: seems there are two different versions of the MD5044\n" 3074 printk("%s: seems there are two different versions of the MD5044\n"
@@ -2565,11 +3080,14 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2565 /* power-up tuner chip */ 3080 /* power-up tuner chip */
2566 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); 3081 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
2567 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000); 3082 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
2568 msleep(1); 3083 case SAA7134_BOARD_MONSTERTV_MOBILE:
3084 /* power-up tuner chip */
3085 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
3086 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004);
2569 break; 3087 break;
2570 case SAA7134_BOARD_FLYDVBTDUO: 3088 case SAA7134_BOARD_FLYDVBTDUO:
2571 case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS: 3089 case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
2572 /* turn the fan on Hac: static for the time being */ 3090 /* turn the fan on */
2573 saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); 3091 saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
2574 saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); 3092 saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
2575 break; 3093 break;
@@ -2579,6 +3097,22 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2579 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); 3097 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
2580 msleep(1); 3098 msleep(1);
2581 break; 3099 break;
3100 case SAA7134_BOARD_RTD_VFG7350:
3101
3102 /*
3103 * Make sure Production Test Register at offset 0x1D1 is cleared
3104 * to take chip out of test mode. Clearing bit 4 (TST_EN_AOUT)
3105 * prevents pin 105 from remaining low; keeping pin 105 low
3106 * continually resets the SAA6752 chip.
3107 */
3108
3109 saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
3110 break;
3111 /* i2c remotes */
3112 case SAA7134_BOARD_PINNACLE_PCTV_110i:
3113 case SAA7134_BOARD_UPMOST_PURPLE_TV:
3114 dev->has_remote = SAA7134_REMOTE_I2C;
3115 break;
2582 } 3116 }
2583 return 0; 3117 return 0;
2584} 3118}
@@ -2613,7 +3147,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
2613 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup); 3147 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup);
2614 } 3148 }
2615 break; 3149 break;
2616case SAA7134_BOARD_MD7134: 3150 case SAA7134_BOARD_MD7134:
2617 { 3151 {
2618 struct tuner_setup tun_setup; 3152 struct tuner_setup tun_setup;
2619 u8 subaddr; 3153 u8 subaddr;
@@ -2680,6 +3214,33 @@ case SAA7134_BOARD_MD7134:
2680 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup); 3214 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
2681 } 3215 }
2682 break; 3216 break;
3217 case SAA7134_BOARD_PHILIPS_EUROPA:
3218 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
3219 /* The Philips EUROPA based hybrid boards have the tuner connected through
3220 * the channel decoder. We have to make it transparent to find it
3221 */
3222 {
3223 struct tuner_setup tun_setup;
3224 u8 data[] = { 0x07, 0x02};
3225 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
3226 i2c_transfer(&dev->i2c_adap, &msg, 1);
3227
3228 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
3229 tun_setup.type = dev->tuner_type;
3230 tun_setup.addr = dev->tuner_addr;
3231
3232 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
3233 }
3234 break;
3235 case SAA7134_BOARD_PHILIPS_TIGER:
3236 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
3237 /* this is a hybrid board, initialize to analog mode */
3238 {
3239 u8 data[] = { 0x3c, 0x33, 0x68};
3240 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
3241 i2c_transfer(&dev->i2c_adap, &msg, 1);
3242 }
3243 break;
2683 } 3244 }
2684 return 0; 3245 return 0;
2685} 3246}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index e5e36f3c6250..19b88744fb31 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -57,6 +57,10 @@ static unsigned int oss = 0;
57module_param(oss, int, 0444); 57module_param(oss, int, 0444);
58MODULE_PARM_DESC(oss,"register oss devices (default: no)"); 58MODULE_PARM_DESC(oss,"register oss devices (default: no)");
59 59
60static unsigned int alsa = 0;
61module_param(alsa, int, 0444);
62MODULE_PARM_DESC(alsa,"register alsa devices (default: no)");
63
60static unsigned int latency = UNSET; 64static unsigned int latency = UNSET;
61module_param(latency, int, 0444); 65module_param(latency, int, 0444);
62MODULE_PARM_DESC(latency,"pci latency timer"); 66MODULE_PARM_DESC(latency,"pci latency timer");
@@ -190,6 +194,7 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
190 194
191static int need_empress; 195static int need_empress;
192static int need_dvb; 196static int need_dvb;
197static int need_alsa;
193 198
194static int pending_call(struct notifier_block *self, unsigned long state, 199static int pending_call(struct notifier_block *self, unsigned long state,
195 void *module) 200 void *module)
@@ -197,10 +202,12 @@ static int pending_call(struct notifier_block *self, unsigned long state,
197 if (module != THIS_MODULE || state != MODULE_STATE_LIVE) 202 if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
198 return NOTIFY_DONE; 203 return NOTIFY_DONE;
199 204
200 if (need_empress) 205 if (need_empress)
201 request_module("saa7134-empress"); 206 request_module("saa7134-empress");
202 if (need_dvb) 207 if (need_dvb)
203 request_module("saa7134-dvb"); 208 request_module("saa7134-dvb");
209 if (need_alsa)
210 request_module("saa7134-alsa");
204 return NOTIFY_DONE; 211 return NOTIFY_DONE;
205} 212}
206 213
@@ -275,8 +282,8 @@ unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
275 282
276int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt) 283int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
277{ 284{
278 __le32 *cpu; 285 __le32 *cpu;
279 dma_addr_t dma_addr; 286 dma_addr_t dma_addr;
280 287
281 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr); 288 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
282 if (NULL == cpu) 289 if (NULL == cpu)
@@ -436,7 +443,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
436 ctrl |= SAA7134_MAIN_CTRL_TE0; 443 ctrl |= SAA7134_MAIN_CTRL_TE0;
437 irq |= SAA7134_IRQ1_INTE_RA0_1 | 444 irq |= SAA7134_IRQ1_INTE_RA0_1 |
438 SAA7134_IRQ1_INTE_RA0_0; 445 SAA7134_IRQ1_INTE_RA0_0;
439 cap = dev->video_q.curr->vb.field; 446 cap = dev->video_q.curr->vb.field;
440 } 447 }
441 448
442 /* video capture -- dma 1+2 (planar modes) */ 449 /* video capture -- dma 1+2 (planar modes) */
@@ -465,7 +472,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
465 } 472 }
466 473
467 /* audio capture -- dma 3 */ 474 /* audio capture -- dma 3 */
468 if (dev->oss.dma_running) { 475 if (dev->dmasound.dma_running) {
469 ctrl |= SAA7134_MAIN_CTRL_TE6; 476 ctrl |= SAA7134_MAIN_CTRL_TE6;
470 irq |= SAA7134_IRQ1_INTE_RA3_1 | 477 irq |= SAA7134_IRQ1_INTE_RA3_1 |
471 SAA7134_IRQ1_INTE_RA3_0; 478 SAA7134_IRQ1_INTE_RA3_0;
@@ -570,6 +577,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
570 dev->name); 577 dev->name);
571 goto out; 578 goto out;
572 } 579 }
580
581 /* If alsa support is active and we get a sound report, exit
582 and let the saa7134-alsa module deal with it */
583
584 if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && alsa) {
585 if (irq_debug > 1)
586 printk(KERN_DEBUG "%s/irq: ignoring interrupt for ALSA\n",
587 dev->name);
588 goto out;
589 }
590
573 handled = 1; 591 handled = 1;
574 saa_writel(SAA7134_IRQ_REPORT,report); 592 saa_writel(SAA7134_IRQ_REPORT,report);
575 if (irq_debug) 593 if (irq_debug)
@@ -591,13 +609,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
591 card_has_mpeg(dev)) 609 card_has_mpeg(dev))
592 saa7134_irq_ts_done(dev,status); 610 saa7134_irq_ts_done(dev,status);
593 611
594 if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) 612 if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) {
595 saa7134_irq_oss_done(dev,status); 613 if (oss) {
614 saa7134_irq_oss_done(dev,status);
615 }
616 }
596 617
597 if ((report & (SAA7134_IRQ_REPORT_GPIO16 | 618 if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
598 SAA7134_IRQ_REPORT_GPIO18)) && 619 SAA7134_IRQ_REPORT_GPIO18)) &&
599 dev->remote) 620 dev->remote)
600 saa7134_input_irq(dev); 621 saa7134_input_irq(dev);
622
601 } 623 }
602 624
603 if (10 == loop) { 625 if (10 == loop) {
@@ -636,7 +658,7 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
636 658
637 saa_writel(SAA7134_IRQ1, 0); 659 saa_writel(SAA7134_IRQ1, 0);
638 saa_writel(SAA7134_IRQ2, 0); 660 saa_writel(SAA7134_IRQ2, 0);
639 init_MUTEX(&dev->lock); 661 init_MUTEX(&dev->lock);
640 spin_lock_init(&dev->slock); 662 spin_lock_init(&dev->slock);
641 663
642 saa7134_track_gpio(dev,"pre-init"); 664 saa7134_track_gpio(dev,"pre-init");
@@ -646,14 +668,6 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
646 saa7134_ts_init1(dev); 668 saa7134_ts_init1(dev);
647 saa7134_input_init1(dev); 669 saa7134_input_init1(dev);
648 670
649 switch (dev->pci->device) {
650 case PCI_DEVICE_ID_PHILIPS_SAA7134:
651 case PCI_DEVICE_ID_PHILIPS_SAA7133:
652 case PCI_DEVICE_ID_PHILIPS_SAA7135:
653 saa7134_oss_init1(dev);
654 break;
655 }
656
657 /* RAM FIFO config */ 671 /* RAM FIFO config */
658 saa_writel(SAA7134_FIFO_SIZE, 0x08070503); 672 saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
659 saa_writel(SAA7134_THRESHOULD,0x02020202); 673 saa_writel(SAA7134_THRESHOULD,0x02020202);
@@ -668,6 +682,21 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
668 SAA7134_MAIN_CTRL_ESFE | 682 SAA7134_MAIN_CTRL_ESFE |
669 SAA7134_MAIN_CTRL_EBDAC); 683 SAA7134_MAIN_CTRL_EBDAC);
670 684
685 /*
686 * Initialize OSS _after_ enabling audio clock PLL and audio processing.
687 * OSS initialization writes to registers via the audio DSP; these
688 * writes will fail unless the audio clock has been started. At worst,
689 * audio will not work.
690 */
691
692 switch (dev->pci->device) {
693 case PCI_DEVICE_ID_PHILIPS_SAA7134:
694 case PCI_DEVICE_ID_PHILIPS_SAA7133:
695 case PCI_DEVICE_ID_PHILIPS_SAA7135:
696 saa7134_oss_init1(dev);
697 break;
698 }
699
671 /* enable peripheral devices */ 700 /* enable peripheral devices */
672 saa_writeb(SAA7134_SPECIAL_MODE, 0x01); 701 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
673 702
@@ -687,7 +716,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
687 saa7134_tvaudio_init2(dev); 716 saa7134_tvaudio_init2(dev);
688 717
689 /* enable IRQ's */ 718 /* enable IRQ's */
690 irq2_mask = 719 irq2_mask =
691 SAA7134_IRQ2_INTE_DEC3 | 720 SAA7134_IRQ2_INTE_DEC3 |
692 SAA7134_IRQ2_INTE_DEC2 | 721 SAA7134_IRQ2_INTE_DEC2 |
693 SAA7134_IRQ2_INTE_DEC1 | 722 SAA7134_IRQ2_INTE_DEC1 |
@@ -695,10 +724,12 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
695 SAA7134_IRQ2_INTE_PE | 724 SAA7134_IRQ2_INTE_PE |
696 SAA7134_IRQ2_INTE_AR; 725 SAA7134_IRQ2_INTE_AR;
697 726
698 if (dev->has_remote) 727 if (dev->has_remote == SAA7134_REMOTE_GPIO)
699 irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 | 728 irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
700 SAA7134_IRQ2_INTE_GPIO18A | 729 SAA7134_IRQ2_INTE_GPIO18A |
701 SAA7134_IRQ2_INTE_GPIO16 ); 730 SAA7134_IRQ2_INTE_GPIO16 );
731 else if (dev->has_remote == SAA7134_REMOTE_I2C)
732 request_module("ir-kbd-i2c");
702 733
703 saa_writel(SAA7134_IRQ1, 0); 734 saa_writel(SAA7134_IRQ1, 0);
704 saa_writel(SAA7134_IRQ2, irq2_mask); 735 saa_writel(SAA7134_IRQ2, irq2_mask);
@@ -872,8 +903,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
872 903
873 /* print pci info */ 904 /* print pci info */
874 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 905 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
875 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 906 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
876 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " 907 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
877 "latency: %d, mmio: 0x%lx\n", dev->name, 908 "latency: %d, mmio: 0x%lx\n", dev->name,
878 pci_name(pci_dev), dev->pci_rev, pci_dev->irq, 909 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
879 dev->pci_lat,pci_resource_start(pci_dev,0)); 910 dev->pci_lat,pci_resource_start(pci_dev,0));
@@ -897,7 +928,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
897 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; 928 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
898 if (UNSET != tuner[dev->nr]) 929 if (UNSET != tuner[dev->nr])
899 dev->tuner_type = tuner[dev->nr]; 930 dev->tuner_type = tuner[dev->nr];
900 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", 931 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
901 dev->name,pci_dev->subsystem_vendor, 932 dev->name,pci_dev->subsystem_vendor,
902 pci_dev->subsystem_device,saa7134_boards[dev->board].name, 933 pci_dev->subsystem_device,saa7134_boards[dev->board].name,
903 dev->board, card[dev->nr] == dev->board ? 934 dev->board, card[dev->nr] == dev->board ?
@@ -947,14 +978,20 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
947 request_module("tuner"); 978 request_module("tuner");
948 if (dev->tda9887_conf) 979 if (dev->tda9887_conf)
949 request_module("tda9887"); 980 request_module("tda9887");
950 if (card_is_empress(dev)) { 981 if (card_is_empress(dev)) {
951 request_module("saa6752hs"); 982 request_module("saa6752hs");
952 request_module_depend("saa7134-empress",&need_empress); 983 request_module_depend("saa7134-empress",&need_empress);
953 } 984 }
954 985
955 if (card_is_dvb(dev)) 986 if (card_is_dvb(dev))
956 request_module_depend("saa7134-dvb",&need_dvb); 987 request_module_depend("saa7134-dvb",&need_dvb);
957 988
989 if (!oss && alsa) {
990 dprintk("Requesting ALSA module\n");
991 request_module_depend("saa7134-alsa",&need_alsa);
992 }
993
994
958 v4l2_prio_init(&dev->prio); 995 v4l2_prio_init(&dev->prio);
959 996
960 /* register v4l devices */ 997 /* register v4l devices */
@@ -993,22 +1030,22 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
993 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1030 case PCI_DEVICE_ID_PHILIPS_SAA7133:
994 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1031 case PCI_DEVICE_ID_PHILIPS_SAA7135:
995 if (oss) { 1032 if (oss) {
996 err = dev->oss.minor_dsp = 1033 err = dev->dmasound.minor_dsp =
997 register_sound_dsp(&saa7134_dsp_fops, 1034 register_sound_dsp(&saa7134_dsp_fops,
998 dsp_nr[dev->nr]); 1035 dsp_nr[dev->nr]);
999 if (err < 0) { 1036 if (err < 0) {
1000 goto fail4; 1037 goto fail4;
1001 } 1038 }
1002 printk(KERN_INFO "%s: registered device dsp%d\n", 1039 printk(KERN_INFO "%s: registered device dsp%d\n",
1003 dev->name,dev->oss.minor_dsp >> 4); 1040 dev->name,dev->dmasound.minor_dsp >> 4);
1004 1041
1005 err = dev->oss.minor_mixer = 1042 err = dev->dmasound.minor_mixer =
1006 register_sound_mixer(&saa7134_mixer_fops, 1043 register_sound_mixer(&saa7134_mixer_fops,
1007 mixer_nr[dev->nr]); 1044 mixer_nr[dev->nr]);
1008 if (err < 0) 1045 if (err < 0)
1009 goto fail5; 1046 goto fail5;
1010 printk(KERN_INFO "%s: registered device mixer%d\n", 1047 printk(KERN_INFO "%s: registered device mixer%d\n",
1011 dev->name,dev->oss.minor_mixer >> 4); 1048 dev->name,dev->dmasound.minor_mixer >> 4);
1012 } 1049 }
1013 break; 1050 break;
1014 } 1051 }
@@ -1035,7 +1072,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1035 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1072 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1036 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1073 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1037 if (oss) 1074 if (oss)
1038 unregister_sound_dsp(dev->oss.minor_dsp); 1075 unregister_sound_dsp(dev->dmasound.minor_dsp);
1039 break; 1076 break;
1040 } 1077 }
1041 fail4: 1078 fail4:
@@ -1055,7 +1092,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1055 1092
1056static void __devexit saa7134_finidev(struct pci_dev *pci_dev) 1093static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1057{ 1094{
1058 struct saa7134_dev *dev = pci_get_drvdata(pci_dev); 1095 struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
1059 struct list_head *item; 1096 struct list_head *item;
1060 struct saa7134_mpeg_ops *mops; 1097 struct saa7134_mpeg_ops *mops;
1061 1098
@@ -1093,8 +1130,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1093 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1130 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1094 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1131 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1095 if (oss) { 1132 if (oss) {
1096 unregister_sound_mixer(dev->oss.minor_mixer); 1133 unregister_sound_mixer(dev->dmasound.minor_mixer);
1097 unregister_sound_dsp(dev->oss.minor_dsp); 1134 unregister_sound_dsp(dev->dmasound.minor_dsp);
1098 } 1135 }
1099 break; 1136 break;
1100 } 1137 }
@@ -1149,10 +1186,10 @@ EXPORT_SYMBOL(saa7134_ts_unregister);
1149/* ----------------------------------------------------------- */ 1186/* ----------------------------------------------------------- */
1150 1187
1151static struct pci_driver saa7134_pci_driver = { 1188static struct pci_driver saa7134_pci_driver = {
1152 .name = "saa7134", 1189 .name = "saa7134",
1153 .id_table = saa7134_pci_tbl, 1190 .id_table = saa7134_pci_tbl,
1154 .probe = saa7134_initdev, 1191 .probe = saa7134_initdev,
1155 .remove = __devexit_p(saa7134_finidev), 1192 .remove = __devexit_p(saa7134_finidev),
1156}; 1193};
1157 1194
1158static int saa7134_init(void) 1195static int saa7134_init(void)
@@ -1188,6 +1225,13 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients);
1188EXPORT_SYMBOL(saa7134_devlist); 1225EXPORT_SYMBOL(saa7134_devlist);
1189EXPORT_SYMBOL(saa7134_boards); 1226EXPORT_SYMBOL(saa7134_boards);
1190 1227
1228/* ----------------- For ALSA -------------------------------- */
1229
1230EXPORT_SYMBOL(saa7134_pgtable_free);
1231EXPORT_SYMBOL(saa7134_pgtable_build);
1232EXPORT_SYMBOL(saa7134_pgtable_alloc);
1233EXPORT_SYMBOL(saa7134_set_dmabits);
1234
1191/* ----------------------------------------------------------- */ 1235/* ----------------------------------------------------------- */
1192/* 1236/*
1193 * Local variables: 1237 * Local variables:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 639ae51a052d..e016480c3468 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -29,7 +29,6 @@
29#include <linux/kthread.h> 29#include <linux/kthread.h>
30#include <linux/suspend.h> 30#include <linux/suspend.h>
31 31
32
33#include "saa7134-reg.h" 32#include "saa7134-reg.h"
34#include "saa7134.h" 33#include "saa7134.h"
35 34
@@ -40,6 +39,10 @@
40#ifdef HAVE_TDA1004X 39#ifdef HAVE_TDA1004X
41# include "tda1004x.h" 40# include "tda1004x.h"
42#endif 41#endif
42#ifdef HAVE_NXT200X
43# include "nxt200x.h"
44# include "dvb-pll.h"
45#endif
43 46
44MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 47MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
45MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
@@ -151,25 +154,12 @@ static struct mt352_config pinnacle_300i = {
151/* ------------------------------------------------------------------ */ 154/* ------------------------------------------------------------------ */
152 155
153#ifdef HAVE_TDA1004X 156#ifdef HAVE_TDA1004X
154static int philips_tu1216_pll_init(struct dvb_frontend *fe)
155{
156 struct saa7134_dev *dev = fe->dvb->priv;
157 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
158 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
159
160 /* setup PLL configuration */
161 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
162 return -EIO;
163 msleep(1);
164 157
165 return 0; 158static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
166}
167
168static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
169{ 159{
170 struct saa7134_dev *dev = fe->dvb->priv; 160 struct saa7134_dev *dev = fe->dvb->priv;
171 u8 tuner_buf[4]; 161 u8 tuner_buf[4];
172 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = 162 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len =
173 sizeof(tuner_buf) }; 163 sizeof(tuner_buf) };
174 int tuner_frequency = 0; 164 int tuner_frequency = 0;
175 u8 band, cp, filter; 165 u8 band, cp, filter;
@@ -242,11 +232,36 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
242 232
243 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) 233 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
244 return -EIO; 234 return -EIO;
235 msleep(1);
236 return 0;
237}
245 238
239static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe)
240{
241 struct saa7134_dev *dev = fe->dvb->priv;
242 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
243 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
244
245 /* setup PLL configuration */
246 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
247 return -EIO;
246 msleep(1); 248 msleep(1);
249
247 return 0; 250 return 0;
248} 251}
249 252
253/* ------------------------------------------------------------------ */
254
255static int philips_tu1216_pll_60_init(struct dvb_frontend *fe)
256{
257 return philips_tda6651_pll_init(0x60, fe);
258}
259
260static int philips_tu1216_pll_60_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
261{
262 return philips_tda6651_pll_set(0x60, fe, params);
263}
264
250static int philips_tu1216_request_firmware(struct dvb_frontend *fe, 265static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
251 const struct firmware **fw, char *name) 266 const struct firmware **fw, char *name)
252{ 267{
@@ -254,22 +269,108 @@ static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
254 return request_firmware(fw, name, &dev->pci->dev); 269 return request_firmware(fw, name, &dev->pci->dev);
255} 270}
256 271
257static struct tda1004x_config philips_tu1216_config = { 272static struct tda1004x_config philips_tu1216_60_config = {
273
274 .demod_address = 0x8,
275 .invert = 1,
276 .invert_oclk = 0,
277 .xtal_freq = TDA10046_XTAL_4M,
278 .agc_config = TDA10046_AGC_DEFAULT,
279 .if_freq = TDA10046_FREQ_3617,
280 .pll_init = philips_tu1216_pll_60_init,
281 .pll_set = philips_tu1216_pll_60_set,
282 .pll_sleep = NULL,
283 .request_firmware = philips_tu1216_request_firmware,
284};
285
286/* ------------------------------------------------------------------ */
287
288static int philips_tu1216_pll_61_init(struct dvb_frontend *fe)
289{
290 return philips_tda6651_pll_init(0x61, fe);
291}
292
293static int philips_tu1216_pll_61_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
294{
295 return philips_tda6651_pll_set(0x61, fe, params);
296}
297
298static struct tda1004x_config philips_tu1216_61_config = {
258 299
259 .demod_address = 0x8, 300 .demod_address = 0x8,
260 .invert = 1, 301 .invert = 1,
261 .invert_oclk = 1, 302 .invert_oclk = 0,
262 .xtal_freq = TDA10046_XTAL_4M, 303 .xtal_freq = TDA10046_XTAL_4M,
263 .agc_config = TDA10046_AGC_DEFAULT, 304 .agc_config = TDA10046_AGC_DEFAULT,
264 .if_freq = TDA10046_FREQ_3617, 305 .if_freq = TDA10046_FREQ_3617,
265 .pll_init = philips_tu1216_pll_init, 306 .pll_init = philips_tu1216_pll_61_init,
266 .pll_set = philips_tu1216_pll_set, 307 .pll_set = philips_tu1216_pll_61_set,
267 .pll_sleep = NULL, 308 .pll_sleep = NULL,
268 .request_firmware = philips_tu1216_request_firmware, 309 .request_firmware = philips_tu1216_request_firmware,
269}; 310};
270 311
271/* ------------------------------------------------------------------ */ 312/* ------------------------------------------------------------------ */
272 313
314static int philips_europa_pll_init(struct dvb_frontend *fe)
315{
316 struct saa7134_dev *dev = fe->dvb->priv;
317 static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab };
318 struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
319
320 /* setup PLL configuration */
321 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
322 return -EIO;
323 msleep(1);
324
325 /* switch the board to dvb mode */
326 init_msg.addr = 0x43;
327 init_msg.len = 0x02;
328 msg[0] = 0x00;
329 msg[1] = 0x40;
330 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
331 return -EIO;
332
333 return 0;
334}
335
336static int philips_td1316_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
337{
338 return philips_tda6651_pll_set(0x61, fe, params);
339}
340
341static void philips_europa_analog(struct dvb_frontend *fe)
342{
343 struct saa7134_dev *dev = fe->dvb->priv;
344 /* this message actually turns the tuner back to analog mode */
345 static u8 msg[] = { 0x0b, 0xdc, 0x86, 0xa4 };
346 struct i2c_msg analog_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
347
348 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
349 msleep(1);
350
351 /* switch the board to analog mode */
352 analog_msg.addr = 0x43;
353 analog_msg.len = 0x02;
354 msg[0] = 0x00;
355 msg[1] = 0x14;
356 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
357}
358
359static struct tda1004x_config philips_europa_config = {
360
361 .demod_address = 0x8,
362 .invert = 0,
363 .invert_oclk = 0,
364 .xtal_freq = TDA10046_XTAL_4M,
365 .agc_config = TDA10046_AGC_IFO_AUTO_POS,
366 .if_freq = TDA10046_FREQ_052,
367 .pll_init = philips_europa_pll_init,
368 .pll_set = philips_td1316_pll_set,
369 .pll_sleep = philips_europa_analog,
370 .request_firmware = NULL,
371};
372
373/* ------------------------------------------------------------------ */
273 374
274static int philips_fmd1216_pll_init(struct dvb_frontend *fe) 375static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
275{ 376{
@@ -382,7 +483,6 @@ static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
382 return 0; 483 return 0;
383} 484}
384 485
385#ifdef HAVE_TDA1004X
386static struct tda1004x_config medion_cardbus = { 486static struct tda1004x_config medion_cardbus = {
387 .demod_address = 0x08, 487 .demod_address = 0x08,
388 .invert = 1, 488 .invert = 1,
@@ -395,7 +495,6 @@ static struct tda1004x_config medion_cardbus = {
395 .pll_sleep = philips_fmd1216_analog, 495 .pll_sleep = philips_fmd1216_analog,
396 .request_firmware = NULL, 496 .request_firmware = NULL,
397}; 497};
398#endif
399 498
400/* ------------------------------------------------------------------ */ 499/* ------------------------------------------------------------------ */
401 500
@@ -452,7 +551,7 @@ static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
452 u8 tuner_buf[14]; 551 u8 tuner_buf[14];
453 552
454 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf, 553 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,
455 .len = sizeof(tuner_buf) }; 554 .len = sizeof(tuner_buf) };
456 int i, tuner_freq, if_freq; 555 int i, tuner_freq, if_freq;
457 u32 N; 556 u32 N;
458 switch (params->u.ofdm.bandwidth) { 557 switch (params->u.ofdm.bandwidth) {
@@ -511,7 +610,7 @@ static void philips_tda827x_pll_sleep(struct dvb_frontend *fe)
511 struct saa7134_dev *dev = fe->dvb->priv; 610 struct saa7134_dev *dev = fe->dvb->priv;
512 static u8 tda827x_sleep[] = { 0x30, 0xd0}; 611 static u8 tda827x_sleep[] = { 0x30, 0xd0};
513 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep, 612 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep,
514 .len = sizeof(tda827x_sleep) }; 613 .len = sizeof(tda827x_sleep) };
515 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); 614 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
516} 615}
517 616
@@ -527,6 +626,202 @@ static struct tda1004x_config tda827x_lifeview_config = {
527 .pll_sleep = philips_tda827x_pll_sleep, 626 .pll_sleep = philips_tda827x_pll_sleep,
528 .request_firmware = NULL, 627 .request_firmware = NULL,
529}; 628};
629
630/* ------------------------------------------------------------------ */
631
632struct tda827xa_data {
633 u32 lomax;
634 u8 svco;
635 u8 spd;
636 u8 scr;
637 u8 sbs;
638 u8 gc3;
639};
640
641static struct tda827xa_data tda827xa_dvbt[] = {
642 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
643 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
644 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
645 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
646 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
647 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
648 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
649 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
650 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
651 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
652 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
653 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
654 { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
655 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
656 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
657 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
658 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
659 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
660 { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
661 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
662 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
663 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
664 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
665 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
666 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
667 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
668 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}};
669
670
671static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
672{
673 struct saa7134_dev *dev = fe->dvb->priv;
674 u8 tuner_buf[14];
675 unsigned char reg2[2];
676
677 struct i2c_msg msg = {.addr = addr,.flags = 0,.buf = tuner_buf};
678 int i, tuner_freq, if_freq;
679 u32 N;
680
681 switch (params->u.ofdm.bandwidth) {
682 case BANDWIDTH_6_MHZ:
683 if_freq = 4000000;
684 break;
685 case BANDWIDTH_7_MHZ:
686 if_freq = 4500000;
687 break;
688 default: /* 8 MHz or Auto */
689 if_freq = 5000000;
690 break;
691 }
692 tuner_freq = params->frequency + if_freq;
693
694 i = 0;
695 while (tda827xa_dvbt[i].lomax < tuner_freq) {
696 if(tda827xa_dvbt[i + 1].lomax == 0)
697 break;
698 i++;
699 }
700
701 N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
702 tuner_buf[0] = 0; // subaddress
703 tuner_buf[1] = N >> 8;
704 tuner_buf[2] = N & 0xff;
705 tuner_buf[3] = 0;
706 tuner_buf[4] = 0x16;
707 tuner_buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
708 tda827xa_dvbt[i].sbs;
709 tuner_buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
710 tuner_buf[7] = 0x0c;
711 tuner_buf[8] = 0x06;
712 tuner_buf[9] = 0x24;
713 tuner_buf[10] = 0xff;
714 tuner_buf[11] = 0x60;
715 tuner_buf[12] = 0x00;
716 tuner_buf[13] = 0x39; // lpsel
717 msg.len = 14;
718 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
719 return -EIO;
720
721 msg.buf= reg2;
722 msg.len = 2;
723 reg2[0] = 0x60;
724 reg2[1] = 0x3c;
725 i2c_transfer(&dev->i2c_adap, &msg, 1);
726
727 reg2[0] = 0xa0;
728 reg2[1] = 0x40;
729 i2c_transfer(&dev->i2c_adap, &msg, 1);
730
731 msleep(2);
732 /* correct CP value */
733 reg2[0] = 0x30;
734 reg2[1] = 0x10 + tda827xa_dvbt[i].scr;
735 msg.len = 2;
736 i2c_transfer(&dev->i2c_adap, &msg, 1);
737
738 msleep(550);
739 reg2[0] = 0x50;
740 reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
741 i2c_transfer(&dev->i2c_adap, &msg, 1);
742
743 return 0;
744
745}
746
747static void philips_tda827xa_pll_sleep(u8 addr, struct dvb_frontend *fe)
748{
749 struct saa7134_dev *dev = fe->dvb->priv;
750 static u8 tda827xa_sleep[] = { 0x30, 0x90};
751 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep,
752 .len = sizeof(tda827xa_sleep) };
753 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
754
755}
756
757/* ------------------------------------------------------------------ */
758
759static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
760{
761 int ret;
762 struct saa7134_dev *dev = fe->dvb->priv;
763 static u8 tda8290_close[] = { 0x21, 0xc0};
764 static u8 tda8290_open[] = { 0x21, 0x80};
765 struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2};
766 /* close tda8290 i2c bridge */
767 tda8290_msg.buf = tda8290_close;
768 ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
769 if (ret != 1)
770 return -EIO;
771 msleep(20);
772 ret = philips_tda827xa_pll_set(0x61, fe, params);
773 if (ret != 0)
774 return ret;
775 /* open tda8290 i2c bridge */
776 tda8290_msg.buf = tda8290_open;
777 i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
778 return ret;
779};
780
781static int philips_tiger_dvb_mode(struct dvb_frontend *fe)
782{
783 struct saa7134_dev *dev = fe->dvb->priv;
784 static u8 data[] = { 0x3c, 0x33, 0x6a};
785 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
786
787 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
788 return -EIO;
789 return 0;
790}
791
792static void philips_tiger_analog_mode(struct dvb_frontend *fe)
793{
794 struct saa7134_dev *dev = fe->dvb->priv;
795 static u8 data[] = { 0x3c, 0x33, 0x68};
796 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
797
798 i2c_transfer(&dev->i2c_adap, &msg, 1);
799 philips_tda827xa_pll_sleep( 0x61, fe);
800}
801
802static struct tda1004x_config philips_tiger_config = {
803 .demod_address = 0x08,
804 .invert = 1,
805 .invert_oclk = 0,
806 .xtal_freq = TDA10046_XTAL_16M,
807 .agc_config = TDA10046_AGC_TDA827X,
808 .if_freq = TDA10046_FREQ_045,
809 .pll_init = philips_tiger_dvb_mode,
810 .pll_set = philips_tiger_pll_set,
811 .pll_sleep = philips_tiger_analog_mode,
812 .request_firmware = NULL,
813};
814
815#endif
816
817/* ------------------------------------------------------------------ */
818
819#ifdef HAVE_NXT200X
820static struct nxt200x_config avertvhda180 = {
821 .demod_address = 0x0a,
822 .pll_address = 0x61,
823 .pll_desc = &dvb_pll_tdhu2,
824};
530#endif 825#endif
531 826
532/* ------------------------------------------------------------------ */ 827/* ------------------------------------------------------------------ */
@@ -558,7 +853,7 @@ static int dvb_init(struct saa7134_dev *dev)
558 &dev->i2c_adap); 853 &dev->i2c_adap);
559 break; 854 break;
560 case SAA7134_BOARD_PHILIPS_TOUGH: 855 case SAA7134_BOARD_PHILIPS_TOUGH:
561 dev->dvb.frontend = tda10046_attach(&philips_tu1216_config, 856 dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config,
562 &dev->i2c_adap); 857 &dev->i2c_adap);
563 break; 858 break;
564 case SAA7134_BOARD_FLYDVBTDUO: 859 case SAA7134_BOARD_FLYDVBTDUO:
@@ -569,6 +864,31 @@ static int dvb_init(struct saa7134_dev *dev)
569 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, 864 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
570 &dev->i2c_adap); 865 &dev->i2c_adap);
571 break; 866 break;
867 case SAA7134_BOARD_PHILIPS_EUROPA:
868 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
869 &dev->i2c_adap);
870 break;
871 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
872 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
873 &dev->i2c_adap);
874 break;
875 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
876 dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config,
877 &dev->i2c_adap);
878 break;
879 case SAA7134_BOARD_PHILIPS_TIGER:
880 dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
881 &dev->i2c_adap);
882 break;
883 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
884 dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
885 &dev->i2c_adap);
886 break;
887#endif
888#ifdef HAVE_NXT200X
889 case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
890 dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap);
891 break;
572#endif 892#endif
573 default: 893 default:
574 printk("%s: Huh? unknown DVB card?\n",dev->name); 894 printk("%s: Huh? unknown DVB card?\n",dev->name);
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 77b627eb6483..e9ec69efb4c9 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -55,7 +55,7 @@ static void ts_reset_encoder(struct saa7134_dev* dev)
55 55
56 saa_writeb(SAA7134_SPECIAL_MODE, 0x00); 56 saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
57 msleep(10); 57 msleep(10);
58 saa_writeb(SAA7134_SPECIAL_MODE, 0x01); 58 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
59 msleep(100); 59 msleep(100);
60 dev->empress_started = 0; 60 dev->empress_started = 0;
61} 61}
@@ -65,7 +65,7 @@ static int ts_init_encoder(struct saa7134_dev* dev)
65 ts_reset_encoder(dev); 65 ts_reset_encoder(dev);
66 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL); 66 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL);
67 dev->empress_started = 1; 67 dev->empress_started = 1;
68 return 0; 68 return 0;
69} 69}
70 70
71/* ------------------------------------------------------------------ */ 71/* ------------------------------------------------------------------ */
@@ -169,7 +169,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
169 struct v4l2_capability *cap = arg; 169 struct v4l2_capability *cap = arg;
170 170
171 memset(cap,0,sizeof(*cap)); 171 memset(cap,0,sizeof(*cap));
172 strcpy(cap->driver, "saa7134"); 172 strcpy(cap->driver, "saa7134");
173 strlcpy(cap->card, saa7134_boards[dev->board].name, 173 strlcpy(cap->card, saa7134_boards[dev->board].name,
174 sizeof(cap->card)); 174 sizeof(cap->card));
175 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 175 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 711aa8e85fac..7575043f0874 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -239,7 +239,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
239 unsigned char data; 239 unsigned char data;
240 int addr,rc,i,byte; 240 int addr,rc,i,byte;
241 241
242 status = i2c_get_status(dev); 242 status = i2c_get_status(dev);
243 if (!i2c_is_idle(status)) 243 if (!i2c_is_idle(status))
244 if (!i2c_reset(dev)) 244 if (!i2c_reset(dev))
245 return -EIO; 245 return -EIO;
@@ -296,7 +296,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
296 rc = -EIO; 296 rc = -EIO;
297 if (!i2c_is_busy_wait(dev)) 297 if (!i2c_is_busy_wait(dev))
298 goto err; 298 goto err;
299 status = i2c_get_status(dev); 299 status = i2c_get_status(dev);
300 if (i2c_is_error(status)) 300 if (i2c_is_error(status))
301 goto err; 301 goto err;
302 /* ensure that the bus is idle for at least one bit slot */ 302 /* ensure that the bus is idle for at least one bit slot */
@@ -335,6 +335,20 @@ static int attach_inform(struct i2c_client *client)
335 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", 335 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
336 client->driver->name, client->addr, client->name); 336 client->driver->name, client->addr, client->name);
337 337
338 /* Am I an i2c remote control? */
339
340 switch (client->addr) {
341 case 0x7a:
342 case 0x47:
343 {
344 struct IR_i2c *ir = i2c_get_clientdata(client);
345 d1printk("%s i2c IR detected (%s).\n",
346 client->driver->name,ir->phys);
347 saa7134_set_i2c_ir(dev,ir);
348 break;
349 }
350 }
351
338 if (!client->driver->command) 352 if (!client->driver->command)
339 return 0; 353 return 0;
340 354
@@ -348,12 +362,12 @@ static int attach_inform(struct i2c_client *client)
348 362
349 client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup); 363 client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup);
350 } 364 }
351 } 365 }
352 366
353 if (tuner != UNSET) { 367 if (tuner != UNSET) {
354 368
355 tun_setup.type = tuner; 369 tun_setup.type = tuner;
356 tun_setup.addr = saa7134_boards[dev->board].tuner_addr; 370 tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
357 371
358 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) { 372 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) {
359 373
@@ -361,11 +375,11 @@ static int attach_inform(struct i2c_client *client)
361 375
362 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup); 376 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup);
363 } 377 }
364 } 378 }
365 379
366 client->driver->command(client, TDA9887_SET_CONFIG, &conf); 380 client->driver->command(client, TDA9887_SET_CONFIG, &conf);
367 381
368 return 0; 382 return 0;
369} 383}
370 384
371static struct i2c_algorithm saa7134_algo = { 385static struct i2c_algorithm saa7134_algo = {
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 242cb235cf92..329accda6d45 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -39,6 +39,8 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
39 39
40#define dprintk(fmt, arg...) if (ir_debug) \ 40#define dprintk(fmt, arg...) if (ir_debug) \
41 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) 41 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
42#define i2cdprintk(fmt, arg...) if (ir_debug) \
43 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
42 44
43/* ---------------------------------------------------------------------- */ 45/* ---------------------------------------------------------------------- */
44 46
@@ -114,24 +116,24 @@ static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
114/* Alfons Geser <a.geser@cox.net> 116/* Alfons Geser <a.geser@cox.net>
115 * updates from Job D. R. Borges <jobdrb@ig.com.br> */ 117 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
116static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = { 118static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
117 [ 18 ] = KEY_POWER, 119 [ 18 ] = KEY_POWER,
118 [ 1 ] = KEY_TV, // DVR 120 [ 1 ] = KEY_TV, // DVR
119 [ 21 ] = KEY_DVD, // DVD 121 [ 21 ] = KEY_DVD, // DVD
120 [ 23 ] = KEY_AUDIO, // music 122 [ 23 ] = KEY_AUDIO, // music
121 // DVR mode / DVD mode / music mode 123 // DVR mode / DVD mode / music mode
122 124
123 [ 27 ] = KEY_MUTE, // mute 125 [ 27 ] = KEY_MUTE, // mute
124 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek 126 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
125 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek 127 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
126 [ 22 ] = KEY_ZOOM, // full screen 128 [ 22 ] = KEY_ZOOM, // full screen
127 [ 28 ] = KEY_VIDEO, // video source / eject / delall 129 [ 28 ] = KEY_VIDEO, // video source / eject / delall
128 [ 29 ] = KEY_RESTART, // playback / angle / del 130 [ 29 ] = KEY_RESTART, // playback / angle / del
129 [ 47 ] = KEY_SEARCH, // scan / menu / playlist 131 [ 47 ] = KEY_SEARCH, // scan / menu / playlist
130 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo 132 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
131 133
132 [ 49 ] = KEY_HELP, // help 134 [ 49 ] = KEY_HELP, // help
133 [ 50 ] = KEY_MODE, // num/memo 135 [ 50 ] = KEY_MODE, // num/memo
134 [ 51 ] = KEY_ESC, // cancel 136 [ 51 ] = KEY_ESC, // cancel
135 137
136 [ 12 ] = KEY_UP, // up 138 [ 12 ] = KEY_UP, // up
137 [ 16 ] = KEY_DOWN, // down 139 [ 16 ] = KEY_DOWN, // down
@@ -148,24 +150,24 @@ static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
148 [ 45 ] = KEY_PLAY, // play 150 [ 45 ] = KEY_PLAY, // play
149 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle 151 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle
150 152
151 [ 0 ] = KEY_KP0, 153 [ 0 ] = KEY_KP0,
152 [ 5 ] = KEY_KP1, 154 [ 5 ] = KEY_KP1,
153 [ 6 ] = KEY_KP2, 155 [ 6 ] = KEY_KP2,
154 [ 7 ] = KEY_KP3, 156 [ 7 ] = KEY_KP3,
155 [ 9 ] = KEY_KP4, 157 [ 9 ] = KEY_KP4,
156 [ 10 ] = KEY_KP5, 158 [ 10 ] = KEY_KP5,
157 [ 11 ] = KEY_KP6, 159 [ 11 ] = KEY_KP6,
158 [ 13 ] = KEY_KP7, 160 [ 13 ] = KEY_KP7,
159 [ 14 ] = KEY_KP8, 161 [ 14 ] = KEY_KP8,
160 [ 15 ] = KEY_KP9, 162 [ 15 ] = KEY_KP9,
161 163
162 [ 42 ] = KEY_VOLUMEUP, 164 [ 42 ] = KEY_VOLUMEUP,
163 [ 17 ] = KEY_VOLUMEDOWN, 165 [ 17 ] = KEY_VOLUMEDOWN,
164 [ 24 ] = KEY_CHANNELUP, // CH.tracking up 166 [ 24 ] = KEY_CHANNELUP, // CH.tracking up
165 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down 167 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
166 168
167 [ 19 ] = KEY_KPENTER, // enter 169 [ 19 ] = KEY_KPENTER, // enter
168 [ 33 ] = KEY_KPDOT, // . (decimal dot) 170 [ 33 ] = KEY_KPDOT, // . (decimal dot)
169}; 171};
170 172
171static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = { 173static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
@@ -401,7 +403,183 @@ static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
401 403
402 // 0x1d unused ? 404 // 0x1d unused ?
403}; 405};
404/* ---------------------------------------------------------------------- */ 406
407
408/* Mike Baikov <mike@baikov.com> */
409static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = {
410
411 [ 33 ] = KEY_POWER,
412 [ 105] = KEY_TV,
413 [ 51 ] = KEY_KP0,
414 [ 81 ] = KEY_KP1,
415 [ 49 ] = KEY_KP2,
416 [ 113] = KEY_KP3,
417 [ 59 ] = KEY_KP4,
418 [ 88 ] = KEY_KP5,
419 [ 65 ] = KEY_KP6,
420 [ 72 ] = KEY_KP7,
421 [ 48 ] = KEY_KP8,
422 [ 83 ] = KEY_KP9,
423 [ 115] = KEY_AGAIN, /* LOOP */
424 [ 10 ] = KEY_AUDIO,
425 [ 97 ] = KEY_PRINT, /* PREVIEW */
426 [ 122] = KEY_VIDEO,
427 [ 32 ] = KEY_CHANNELUP,
428 [ 64 ] = KEY_CHANNELDOWN,
429 [ 24 ] = KEY_VOLUMEDOWN,
430 [ 80 ] = KEY_VOLUMEUP,
431 [ 16 ] = KEY_MUTE,
432 [ 74 ] = KEY_SEARCH,
433 [ 123] = KEY_SHUFFLE, /* SNAPSHOT */
434 [ 34 ] = KEY_RECORD,
435 [ 98 ] = KEY_STOP,
436 [ 120] = KEY_PLAY,
437 [ 57 ] = KEY_REWIND,
438 [ 89 ] = KEY_PAUSE,
439 [ 25 ] = KEY_FORWARD,
440 [ 9 ] = KEY_ZOOM,
441
442 [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */
443 [ 26 ] = KEY_F22, /* MIN TIMESHIFT */
444 [ 58 ] = KEY_F23, /* TIMESHIFT */
445 [ 112] = KEY_F24, /* NORMAL TIMESHIFT */
446};
447
448static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
449 [ 0x3 ] = KEY_POWER,
450 [ 0x6f ] = KEY_MUTE,
451 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
452
453 [ 0x11 ] = KEY_KP0,
454 [ 0x4 ] = KEY_KP1,
455 [ 0x5 ] = KEY_KP2,
456 [ 0x6 ] = KEY_KP3,
457 [ 0x8 ] = KEY_KP4,
458 [ 0x9 ] = KEY_KP5,
459 [ 0xa ] = KEY_KP6,
460 [ 0xc ] = KEY_KP7,
461 [ 0xd ] = KEY_KP8,
462 [ 0xe ] = KEY_KP9,
463 [ 0x12 ] = KEY_KPDOT, /* 100+ */
464
465 [ 0x7 ] = KEY_VOLUMEUP,
466 [ 0xb ] = KEY_VOLUMEDOWN,
467 [ 0x1a ] = KEY_KPPLUS,
468 [ 0x18 ] = KEY_KPMINUS,
469 [ 0x15 ] = KEY_UP,
470 [ 0x1d ] = KEY_DOWN,
471 [ 0xf ] = KEY_CHANNELUP,
472 [ 0x13 ] = KEY_CHANNELDOWN,
473 [ 0x48 ] = KEY_ZOOM,
474
475 [ 0x1b ] = KEY_VIDEO, /* Video source */
476 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
477 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
478
479 [ 0x4b ] = KEY_RECORD,
480 [ 0x46 ] = KEY_PLAY,
481 [ 0x45 ] = KEY_PAUSE, /* Pause */
482 [ 0x44 ] = KEY_STOP,
483 [ 0x40 ] = KEY_FORWARD, /* Forward ? */
484 [ 0x42 ] = KEY_REWIND, /* Backward ? */
485
486};
487
488static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
489 [ 0x59 ] = KEY_MUTE,
490 [ 0x4a ] = KEY_POWER,
491
492 [ 0x18 ] = KEY_TEXT,
493 [ 0x26 ] = KEY_TV,
494 [ 0x3d ] = KEY_PRINT,
495
496 [ 0x48 ] = KEY_RED,
497 [ 0x04 ] = KEY_GREEN,
498 [ 0x11 ] = KEY_YELLOW,
499 [ 0x00 ] = KEY_BLUE,
500
501 [ 0x2d ] = KEY_VOLUMEUP,
502 [ 0x1e ] = KEY_VOLUMEDOWN,
503
504 [ 0x49 ] = KEY_MENU,
505
506 [ 0x16 ] = KEY_CHANNELUP,
507 [ 0x17 ] = KEY_CHANNELDOWN,
508
509 [ 0x20 ] = KEY_UP,
510 [ 0x21 ] = KEY_DOWN,
511 [ 0x22 ] = KEY_LEFT,
512 [ 0x23 ] = KEY_RIGHT,
513 [ 0x0d ] = KEY_SELECT,
514
515
516
517 [ 0x08 ] = KEY_BACK,
518 [ 0x07 ] = KEY_REFRESH,
519
520 [ 0x2f ] = KEY_ZOOM,
521 [ 0x29 ] = KEY_RECORD,
522
523 [ 0x4b ] = KEY_PAUSE,
524 [ 0x4d ] = KEY_REWIND,
525 [ 0x2e ] = KEY_PLAY,
526 [ 0x4e ] = KEY_FORWARD,
527 [ 0x53 ] = KEY_PREVIOUS,
528 [ 0x4c ] = KEY_STOP,
529 [ 0x54 ] = KEY_NEXT,
530
531 [ 0x69 ] = KEY_KP0,
532 [ 0x6a ] = KEY_KP1,
533 [ 0x6b ] = KEY_KP2,
534 [ 0x6c ] = KEY_KP3,
535 [ 0x6d ] = KEY_KP4,
536 [ 0x6e ] = KEY_KP5,
537 [ 0x6f ] = KEY_KP6,
538 [ 0x70 ] = KEY_KP7,
539 [ 0x71 ] = KEY_KP8,
540 [ 0x72 ] = KEY_KP9,
541
542 [ 0x74 ] = KEY_CHANNEL,
543 [ 0x0a ] = KEY_BACKSPACE,
544};
545
546/* Mapping for the 28 key remote control as seen at
547 http://www.sednacomputer.com/photo/cardbus-tv.jpg
548 Pavel Mihaylov <bin@bash.info> */
549static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = {
550 [ 0 ] = KEY_KP0,
551 [ 1 ] = KEY_KP1,
552 [ 2 ] = KEY_KP2,
553 [ 3 ] = KEY_KP3,
554 [ 4 ] = KEY_KP4,
555 [ 5 ] = KEY_KP5,
556 [ 6 ] = KEY_KP6,
557 [ 7 ] = KEY_KP7,
558 [ 8 ] = KEY_KP8,
559 [ 9 ] = KEY_KP9,
560
561 [ 0x0a ] = KEY_AGAIN, /* Recall */
562 [ 0x0b ] = KEY_CHANNELUP,
563 [ 0x0c ] = KEY_VOLUMEUP,
564 [ 0x0d ] = KEY_MODE, /* Stereo */
565 [ 0x0e ] = KEY_STOP,
566 [ 0x0f ] = KEY_PREVIOUSSONG,
567 [ 0x10 ] = KEY_ZOOM,
568 [ 0x11 ] = KEY_TUNER, /* Source */
569 [ 0x12 ] = KEY_POWER,
570 [ 0x13 ] = KEY_MUTE,
571 [ 0x15 ] = KEY_CHANNELDOWN,
572 [ 0x18 ] = KEY_VOLUMEDOWN,
573 [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */
574 [ 0x1a ] = KEY_NEXTSONG,
575 [ 0x1b ] = KEY_TEXT, /* Time Shift */
576 [ 0x1c ] = KEY_RADIO, /* FM Radio */
577 [ 0x1d ] = KEY_RECORD,
578 [ 0x1e ] = KEY_PAUSE,
579};
580
581
582/* -------------------- GPIO generic keycode builder -------------------- */
405 583
406static int build_key(struct saa7134_dev *dev) 584static int build_key(struct saa7134_dev *dev)
407{ 585{
@@ -413,13 +591,13 @@ static int build_key(struct saa7134_dev *dev)
413 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN); 591 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
414 592
415 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); 593 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
416 if (ir->polling) { 594 if (ir->polling) {
417 if (ir->last_gpio == gpio) 595 if (ir->last_gpio == gpio)
418 return 0; 596 return 0;
419 ir->last_gpio = gpio; 597 ir->last_gpio = gpio;
420 } 598 }
421 599
422 data = ir_extract_bits(gpio, ir->mask_keycode); 600 data = ir_extract_bits(gpio, ir->mask_keycode);
423 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", 601 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
424 gpio, ir->mask_keycode, data); 602 gpio, ir->mask_keycode, data);
425 603
@@ -432,13 +610,87 @@ static int build_key(struct saa7134_dev *dev)
432 return 0; 610 return 0;
433} 611}
434 612
435/* ---------------------------------------------------------------------- */ 613/* --------------------- Chip specific I2C key builders ----------------- */
614
615static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
616{
617 unsigned char b;
618
619 /* poll IR chip */
620 if (1 != i2c_master_recv(&ir->c,&b,1)) {
621 i2cdprintk("read error\n");
622 return -EIO;
623 }
624
625 /* no button press */
626 if (b==0)
627 return 0;
628
629 /* repeating */
630 if (b & 0x80)
631 return 1;
632
633 *ir_key = b;
634 *ir_raw = b;
635 return 1;
636}
637
638/* The new pinnacle PCTV remote (with the colored buttons)
639 *
640 * Ricardo Cerqueira <v4l@cerqueira.org>
641 */
642
643static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
644{
645 unsigned char b[4];
646 unsigned int start = 0,parity = 0,code = 0;
647
648 /* poll IR chip */
649 if (4 != i2c_master_recv(&ir->c,b,4)) {
650 i2cdprintk("read error\n");
651 return -EIO;
652 }
653
654 for (start = 0; start<4; start++) {
655 if (b[start] == 0x80) {
656 code=b[(start+3)%4];
657 parity=b[(start+2)%4];
658 }
659 }
660
661 /* Empty Request */
662 if (parity==0)
663 return 0;
664
665 /* Repeating... */
666 if (ir->old == parity)
667 return 0;
668
669
670 ir->old = parity;
671
672 /* Reduce code value to fit inside IR_KEYTAB_SIZE
673 *
674 * this is the only value that results in 42 unique
675 * codes < 128
676 */
677
678 code %= 0x88;
679
680 *ir_raw = code;
681 *ir_key = code;
682
683 i2cdprintk("Pinnacle PCTV key %02x\n", code);
684
685 return 1;
686}
687
436 688
437void saa7134_input_irq(struct saa7134_dev *dev) 689void saa7134_input_irq(struct saa7134_dev *dev)
438{ 690{
439 struct saa7134_ir *ir = dev->remote; 691 struct saa7134_ir *ir = dev->remote;
440 692
441 if (!ir->polling) 693 if (!ir->polling)
442 build_key(dev); 694 build_key(dev);
443} 695}
444 696
@@ -464,7 +716,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
464 int polling = 0; 716 int polling = 0;
465 int ir_type = IR_TYPE_OTHER; 717 int ir_type = IR_TYPE_OTHER;
466 718
467 if (!dev->has_remote) 719 if (dev->has_remote != SAA7134_REMOTE_GPIO)
468 return -ENODEV; 720 return -ENODEV;
469 if (disable_ir) 721 if (disable_ir)
470 return -ENODEV; 722 return -ENODEV;
@@ -473,7 +725,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
473 switch (dev->board) { 725 switch (dev->board) {
474 case SAA7134_BOARD_FLYVIDEO2000: 726 case SAA7134_BOARD_FLYVIDEO2000:
475 case SAA7134_BOARD_FLYVIDEO3000: 727 case SAA7134_BOARD_FLYVIDEO3000:
476 case SAA7134_BOARD_FLYTVPLATINUM_FM: 728 case SAA7134_BOARD_FLYTVPLATINUM_FM:
729 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
477 ir_codes = flyvideo_codes; 730 ir_codes = flyvideo_codes;
478 mask_keycode = 0xEC00000; 731 mask_keycode = 0xEC00000;
479 mask_keydown = 0x0040000; 732 mask_keydown = 0x0040000;
@@ -514,14 +767,33 @@ int saa7134_input_init1(struct saa7134_dev *dev)
514 saa_setb(SAA7134_GPIO_GPMODE0, 0x4); 767 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
515 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); 768 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
516 break; 769 break;
770 case SAA7134_BOARD_KWORLD_TERMINATOR:
771 ir_codes = avacssmart_codes;
772 mask_keycode = 0x00001f;
773 mask_keyup = 0x000060;
774 polling = 50; // ms
775 break;
517 case SAA7134_BOARD_MANLI_MTV001: 776 case SAA7134_BOARD_MANLI_MTV001:
518 case SAA7134_BOARD_MANLI_MTV002: 777 case SAA7134_BOARD_MANLI_MTV002:
778 case SAA7134_BOARD_BEHOLD_409FM:
519 ir_codes = manli_codes; 779 ir_codes = manli_codes;
520 mask_keycode = 0x001f00; 780 mask_keycode = 0x001f00;
521 mask_keyup = 0x004000; 781 mask_keyup = 0x004000;
522 mask_keydown = 0x002000;
523 polling = 50; // ms 782 polling = 50; // ms
524 break; 783 break;
784 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
785 ir_codes = pctv_sedna_codes;
786 mask_keycode = 0x001f00;
787 mask_keyup = 0x004000;
788 polling = 50; // ms
789 break;
790 case SAA7134_BOARD_GOTVIEW_7135:
791 ir_codes = gotview7135_codes;
792 mask_keycode = 0x0003EC;
793 mask_keyup = 0x008000;
794 mask_keydown = 0x000010;
795 polling = 50; // ms
796 break;
525 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 797 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
526 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 798 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
527 ir_codes = videomate_tv_pvr_codes; 799 ir_codes = videomate_tv_pvr_codes;
@@ -529,6 +801,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
529 mask_keyup = 0x400000; 801 mask_keyup = 0x400000;
530 polling = 50; // ms 802 polling = 50; // ms
531 break; 803 break;
804 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
805 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
806 ir_codes = videomate_tv_pvr_codes;
807 mask_keycode = 0x003F00;
808 mask_keyup = 0x040000;
809 break;
532 } 810 }
533 if (NULL == ir_codes) { 811 if (NULL == ir_codes) {
534 printk("%s: Oops: IR config error [card=%d]\n", 812 printk("%s: Oops: IR config error [card=%d]\n",
@@ -548,7 +826,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
548 ir->mask_keycode = mask_keycode; 826 ir->mask_keycode = mask_keycode;
549 ir->mask_keydown = mask_keydown; 827 ir->mask_keydown = mask_keydown;
550 ir->mask_keyup = mask_keyup; 828 ir->mask_keyup = mask_keyup;
551 ir->polling = polling; 829 ir->polling = polling;
552 830
553 /* init input device */ 831 /* init input device */
554 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", 832 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
@@ -596,6 +874,31 @@ void saa7134_input_fini(struct saa7134_dev *dev)
596 dev->remote = NULL; 874 dev->remote = NULL;
597} 875}
598 876
877void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
878{
879 if (disable_ir) {
880 dprintk("Found supported i2c remote, but IR has been disabled\n");
881 ir->get_key=NULL;
882 return;
883 }
884
885 switch (dev->board) {
886 case SAA7134_BOARD_PINNACLE_PCTV_110i:
887 snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
888 ir->get_key = get_key_pinnacle;
889 ir->ir_codes = ir_codes_pinnacle;
890 break;
891 case SAA7134_BOARD_UPMOST_PURPLE_TV:
892 snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
893 ir->get_key = get_key_purpletv;
894 ir->ir_codes = ir_codes_purpletv;
895 break;
896 default:
897 dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
898 break;
899 }
900
901}
599/* ---------------------------------------------------------------------- 902/* ----------------------------------------------------------------------
600 * Local variables: 903 * Local variables:
601 * c-basic-offset: 8 904 * c-basic-offset: 8
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index c20630c82f1c..fd53dfcc1644 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -44,6 +44,7 @@ MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
44#define dprintk(fmt, arg...) if (oss_debug) \ 44#define dprintk(fmt, arg...) if (oss_debug) \
45 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg) 45 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
46 46
47
47/* ------------------------------------------------------------------ */ 48/* ------------------------------------------------------------------ */
48 49
49static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) 50static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
@@ -58,12 +59,12 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
58 if ((blksize * blocks) > 1024*1024) 59 if ((blksize * blocks) > 1024*1024)
59 blocks = 1024*1024 / blksize; 60 blocks = 1024*1024 / blksize;
60 61
61 dev->oss.blocks = blocks; 62 dev->dmasound.blocks = blocks;
62 dev->oss.blksize = blksize; 63 dev->dmasound.blksize = blksize;
63 dev->oss.bufsize = blksize * blocks; 64 dev->dmasound.bufsize = blksize * blocks;
64 65
65 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n", 66 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
66 blocks,blksize,blksize * blocks / 1024); 67 blocks,blksize,blksize * blocks / 1024);
67 return 0; 68 return 0;
68} 69}
69 70
@@ -71,11 +72,11 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
71{ 72{
72 int err; 73 int err;
73 74
74 if (!dev->oss.bufsize) 75 if (!dev->dmasound.bufsize)
75 BUG(); 76 BUG();
76 videobuf_dma_init(&dev->oss.dma); 77 videobuf_dma_init(&dev->dmasound.dma);
77 err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE, 78 err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
78 (dev->oss.bufsize + PAGE_SIZE) >> PAGE_SHIFT); 79 (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
79 if (0 != err) 80 if (0 != err)
80 return err; 81 return err;
81 return 0; 82 return 0;
@@ -83,26 +84,26 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
83 84
84static int dsp_buffer_free(struct saa7134_dev *dev) 85static int dsp_buffer_free(struct saa7134_dev *dev)
85{ 86{
86 if (!dev->oss.blksize) 87 if (!dev->dmasound.blksize)
87 BUG(); 88 BUG();
88 videobuf_dma_free(&dev->oss.dma); 89 videobuf_dma_free(&dev->dmasound.dma);
89 dev->oss.blocks = 0; 90 dev->dmasound.blocks = 0;
90 dev->oss.blksize = 0; 91 dev->dmasound.blksize = 0;
91 dev->oss.bufsize = 0; 92 dev->dmasound.bufsize = 0;
92 return 0; 93 return 0;
93} 94}
94 95
95static void dsp_dma_start(struct saa7134_dev *dev) 96static void dsp_dma_start(struct saa7134_dev *dev)
96{ 97{
97 dev->oss.dma_blk = 0; 98 dev->dmasound.dma_blk = 0;
98 dev->oss.dma_running = 1; 99 dev->dmasound.dma_running = 1;
99 saa7134_set_dmabits(dev); 100 saa7134_set_dmabits(dev);
100} 101}
101 102
102static void dsp_dma_stop(struct saa7134_dev *dev) 103static void dsp_dma_stop(struct saa7134_dev *dev)
103{ 104{
104 dev->oss.dma_blk = -1; 105 dev->dmasound.dma_blk = -1;
105 dev->oss.dma_running = 0; 106 dev->dmasound.dma_running = 0;
106 saa7134_set_dmabits(dev); 107 saa7134_set_dmabits(dev);
107} 108}
108 109
@@ -113,18 +114,18 @@ static int dsp_rec_start(struct saa7134_dev *dev)
113 unsigned long flags; 114 unsigned long flags;
114 115
115 /* prepare buffer */ 116 /* prepare buffer */
116 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma))) 117 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
117 return err; 118 return err;
118 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->oss.pt))) 119 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
119 goto fail1; 120 goto fail1;
120 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->oss.pt, 121 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
121 dev->oss.dma.sglist, 122 dev->dmasound.dma.sglist,
122 dev->oss.dma.sglen, 123 dev->dmasound.dma.sglen,
123 0))) 124 0)))
124 goto fail2; 125 goto fail2;
125 126
126 /* sample format */ 127 /* sample format */
127 switch (dev->oss.afmt) { 128 switch (dev->dmasound.afmt) {
128 case AFMT_U8: 129 case AFMT_U8:
129 case AFMT_S8: fmt = 0x00; break; 130 case AFMT_S8: fmt = 0x00; break;
130 case AFMT_U16_LE: 131 case AFMT_U16_LE:
@@ -136,14 +137,14 @@ static int dsp_rec_start(struct saa7134_dev *dev)
136 goto fail2; 137 goto fail2;
137 } 138 }
138 139
139 switch (dev->oss.afmt) { 140 switch (dev->dmasound.afmt) {
140 case AFMT_S8: 141 case AFMT_S8:
141 case AFMT_S16_LE: 142 case AFMT_S16_LE:
142 case AFMT_S16_BE: sign = 1; break; 143 case AFMT_S16_BE: sign = 1; break;
143 default: sign = 0; break; 144 default: sign = 0; break;
144 } 145 }
145 146
146 switch (dev->oss.afmt) { 147 switch (dev->dmasound.afmt) {
147 case AFMT_U16_BE: 148 case AFMT_U16_BE:
148 case AFMT_S16_BE: bswap = 1; break; 149 case AFMT_S16_BE: bswap = 1; break;
149 default: bswap = 0; break; 150 default: bswap = 0; break;
@@ -151,58 +152,58 @@ static int dsp_rec_start(struct saa7134_dev *dev)
151 152
152 switch (dev->pci->device) { 153 switch (dev->pci->device) {
153 case PCI_DEVICE_ID_PHILIPS_SAA7134: 154 case PCI_DEVICE_ID_PHILIPS_SAA7134:
154 if (1 == dev->oss.channels) 155 if (1 == dev->dmasound.channels)
155 fmt |= (1 << 3); 156 fmt |= (1 << 3);
156 if (2 == dev->oss.channels) 157 if (2 == dev->dmasound.channels)
157 fmt |= (3 << 3); 158 fmt |= (3 << 3);
158 if (sign) 159 if (sign)
159 fmt |= 0x04; 160 fmt |= 0x04;
160 fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80; 161 fmt |= (TV == dev->dmasound.input) ? 0xc0 : 0x80;
161 162
162 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->oss.blksize - 1) & 0x0000ff)); 163 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
163 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->oss.blksize - 1) & 0x00ff00) >> 8); 164 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8);
164 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->oss.blksize - 1) & 0xff0000) >> 16); 165 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
165 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt); 166 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
166 167
167 break; 168 break;
168 case PCI_DEVICE_ID_PHILIPS_SAA7133: 169 case PCI_DEVICE_ID_PHILIPS_SAA7133:
169 case PCI_DEVICE_ID_PHILIPS_SAA7135: 170 case PCI_DEVICE_ID_PHILIPS_SAA7135:
170 if (1 == dev->oss.channels) 171 if (1 == dev->dmasound.channels)
171 fmt |= (1 << 4); 172 fmt |= (1 << 4);
172 if (2 == dev->oss.channels) 173 if (2 == dev->dmasound.channels)
173 fmt |= (2 << 4); 174 fmt |= (2 << 4);
174 if (!sign) 175 if (!sign)
175 fmt |= 0x04; 176 fmt |= 0x04;
176 saa_writel(0x588 >> 2, dev->oss.blksize -4); 177 saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -4);
177 saa_writel(0x58c >> 2, 0x543210 | (fmt << 24)); 178 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
178 break; 179 break;
179 } 180 }
180 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n", 181 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
181 dev->oss.afmt, dev->oss.channels, fmt, 182 dev->dmasound.afmt, dev->dmasound.channels, fmt,
182 bswap ? 'b' : '-'); 183 bswap ? 'b' : '-');
183 184
184 /* dma: setup channel 6 (= AUDIO) */ 185 /* dma: setup channel 6 (= AUDIO) */
185 control = SAA7134_RS_CONTROL_BURST_16 | 186 control = SAA7134_RS_CONTROL_BURST_16 |
186 SAA7134_RS_CONTROL_ME | 187 SAA7134_RS_CONTROL_ME |
187 (dev->oss.pt.dma >> 12); 188 (dev->dmasound.pt.dma >> 12);
188 if (bswap) 189 if (bswap)
189 control |= SAA7134_RS_CONTROL_BSWAP; 190 control |= SAA7134_RS_CONTROL_BSWAP;
190 saa_writel(SAA7134_RS_BA1(6),0); 191 saa_writel(SAA7134_RS_BA1(6),0);
191 saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize); 192 saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
192 saa_writel(SAA7134_RS_PITCH(6),0); 193 saa_writel(SAA7134_RS_PITCH(6),0);
193 saa_writel(SAA7134_RS_CONTROL(6),control); 194 saa_writel(SAA7134_RS_CONTROL(6),control);
194 195
195 /* start dma */ 196 /* start dma */
196 dev->oss.recording_on = 1; 197 dev->dmasound.recording_on = 1;
197 spin_lock_irqsave(&dev->slock,flags); 198 spin_lock_irqsave(&dev->slock,flags);
198 dsp_dma_start(dev); 199 dsp_dma_start(dev);
199 spin_unlock_irqrestore(&dev->slock,flags); 200 spin_unlock_irqrestore(&dev->slock,flags);
200 return 0; 201 return 0;
201 202
202 fail2: 203 fail2:
203 saa7134_pgtable_free(dev->pci,&dev->oss.pt); 204 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
204 fail1: 205 fail1:
205 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma); 206 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
206 return err; 207 return err;
207} 208}
208 209
@@ -210,17 +211,17 @@ static int dsp_rec_stop(struct saa7134_dev *dev)
210{ 211{
211 unsigned long flags; 212 unsigned long flags;
212 213
213 dprintk("rec_stop dma_blk=%d\n",dev->oss.dma_blk); 214 dprintk("rec_stop dma_blk=%d\n",dev->dmasound.dma_blk);
214 215
215 /* stop dma */ 216 /* stop dma */
216 dev->oss.recording_on = 0; 217 dev->dmasound.recording_on = 0;
217 spin_lock_irqsave(&dev->slock,flags); 218 spin_lock_irqsave(&dev->slock,flags);
218 dsp_dma_stop(dev); 219 dsp_dma_stop(dev);
219 spin_unlock_irqrestore(&dev->slock,flags); 220 spin_unlock_irqrestore(&dev->slock,flags);
220 221
221 /* unlock buffer */ 222 /* unlock buffer */
222 saa7134_pgtable_free(dev->pci,&dev->oss.pt); 223 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
223 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma); 224 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
224 return 0; 225 return 0;
225} 226}
226 227
@@ -235,35 +236,35 @@ static int dsp_open(struct inode *inode, struct file *file)
235 236
236 list_for_each(list,&saa7134_devlist) { 237 list_for_each(list,&saa7134_devlist) {
237 h = list_entry(list, struct saa7134_dev, devlist); 238 h = list_entry(list, struct saa7134_dev, devlist);
238 if (h->oss.minor_dsp == minor) 239 if (h->dmasound.minor_dsp == minor)
239 dev = h; 240 dev = h;
240 } 241 }
241 if (NULL == dev) 242 if (NULL == dev)
242 return -ENODEV; 243 return -ENODEV;
243 244
244 down(&dev->oss.lock); 245 down(&dev->dmasound.lock);
245 err = -EBUSY; 246 err = -EBUSY;
246 if (dev->oss.users_dsp) 247 if (dev->dmasound.users_dsp)
247 goto fail1; 248 goto fail1;
248 dev->oss.users_dsp++; 249 dev->dmasound.users_dsp++;
249 file->private_data = dev; 250 file->private_data = dev;
250 251
251 dev->oss.afmt = AFMT_U8; 252 dev->dmasound.afmt = AFMT_U8;
252 dev->oss.channels = 1; 253 dev->dmasound.channels = 1;
253 dev->oss.read_count = 0; 254 dev->dmasound.read_count = 0;
254 dev->oss.read_offset = 0; 255 dev->dmasound.read_offset = 0;
255 dsp_buffer_conf(dev,PAGE_SIZE,64); 256 dsp_buffer_conf(dev,PAGE_SIZE,64);
256 err = dsp_buffer_init(dev); 257 err = dsp_buffer_init(dev);
257 if (0 != err) 258 if (0 != err)
258 goto fail2; 259 goto fail2;
259 260
260 up(&dev->oss.lock); 261 up(&dev->dmasound.lock);
261 return 0; 262 return 0;
262 263
263 fail2: 264 fail2:
264 dev->oss.users_dsp--; 265 dev->dmasound.users_dsp--;
265 fail1: 266 fail1:
266 up(&dev->oss.lock); 267 up(&dev->dmasound.lock);
267 return err; 268 return err;
268} 269}
269 270
@@ -271,13 +272,13 @@ static int dsp_release(struct inode *inode, struct file *file)
271{ 272{
272 struct saa7134_dev *dev = file->private_data; 273 struct saa7134_dev *dev = file->private_data;
273 274
274 down(&dev->oss.lock); 275 down(&dev->dmasound.lock);
275 if (dev->oss.recording_on) 276 if (dev->dmasound.recording_on)
276 dsp_rec_stop(dev); 277 dsp_rec_stop(dev);
277 dsp_buffer_free(dev); 278 dsp_buffer_free(dev);
278 dev->oss.users_dsp--; 279 dev->dmasound.users_dsp--;
279 file->private_data = NULL; 280 file->private_data = NULL;
280 up(&dev->oss.lock); 281 up(&dev->dmasound.lock);
281 return 0; 282 return 0;
282} 283}
283 284
@@ -290,12 +291,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
290 unsigned long flags; 291 unsigned long flags;
291 int err,ret = 0; 292 int err,ret = 0;
292 293
293 add_wait_queue(&dev->oss.wq, &wait); 294 add_wait_queue(&dev->dmasound.wq, &wait);
294 down(&dev->oss.lock); 295 down(&dev->dmasound.lock);
295 while (count > 0) { 296 while (count > 0) {
296 /* wait for data if needed */ 297 /* wait for data if needed */
297 if (0 == dev->oss.read_count) { 298 if (0 == dev->dmasound.read_count) {
298 if (!dev->oss.recording_on) { 299 if (!dev->dmasound.recording_on) {
299 err = dsp_rec_start(dev); 300 err = dsp_rec_start(dev);
300 if (err < 0) { 301 if (err < 0) {
301 if (0 == ret) 302 if (0 == ret)
@@ -303,8 +304,8 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
303 break; 304 break;
304 } 305 }
305 } 306 }
306 if (dev->oss.recording_on && 307 if (dev->dmasound.recording_on &&
307 !dev->oss.dma_running) { 308 !dev->dmasound.dma_running) {
308 /* recover from overruns */ 309 /* recover from overruns */
309 spin_lock_irqsave(&dev->slock,flags); 310 spin_lock_irqsave(&dev->slock,flags);
310 dsp_dma_start(dev); 311 dsp_dma_start(dev);
@@ -315,12 +316,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
315 ret = -EAGAIN; 316 ret = -EAGAIN;
316 break; 317 break;
317 } 318 }
318 up(&dev->oss.lock); 319 up(&dev->dmasound.lock);
319 set_current_state(TASK_INTERRUPTIBLE); 320 set_current_state(TASK_INTERRUPTIBLE);
320 if (0 == dev->oss.read_count) 321 if (0 == dev->dmasound.read_count)
321 schedule(); 322 schedule();
322 set_current_state(TASK_RUNNING); 323 set_current_state(TASK_RUNNING);
323 down(&dev->oss.lock); 324 down(&dev->dmasound.lock);
324 if (signal_pending(current)) { 325 if (signal_pending(current)) {
325 if (0 == ret) 326 if (0 == ret)
326 ret = -EINTR; 327 ret = -EINTR;
@@ -330,12 +331,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
330 331
331 /* copy data to userspace */ 332 /* copy data to userspace */
332 bytes = count; 333 bytes = count;
333 if (bytes > dev->oss.read_count) 334 if (bytes > dev->dmasound.read_count)
334 bytes = dev->oss.read_count; 335 bytes = dev->dmasound.read_count;
335 if (bytes > dev->oss.bufsize - dev->oss.read_offset) 336 if (bytes > dev->dmasound.bufsize - dev->dmasound.read_offset)
336 bytes = dev->oss.bufsize - dev->oss.read_offset; 337 bytes = dev->dmasound.bufsize - dev->dmasound.read_offset;
337 if (copy_to_user(buffer + ret, 338 if (copy_to_user(buffer + ret,
338 dev->oss.dma.vmalloc + dev->oss.read_offset, 339 dev->dmasound.dma.vmalloc + dev->dmasound.read_offset,
339 bytes)) { 340 bytes)) {
340 if (0 == ret) 341 if (0 == ret)
341 ret = -EFAULT; 342 ret = -EFAULT;
@@ -344,13 +345,13 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
344 345
345 ret += bytes; 346 ret += bytes;
346 count -= bytes; 347 count -= bytes;
347 dev->oss.read_count -= bytes; 348 dev->dmasound.read_count -= bytes;
348 dev->oss.read_offset += bytes; 349 dev->dmasound.read_offset += bytes;
349 if (dev->oss.read_offset == dev->oss.bufsize) 350 if (dev->dmasound.read_offset == dev->dmasound.bufsize)
350 dev->oss.read_offset = 0; 351 dev->dmasound.read_offset = 0;
351 } 352 }
352 up(&dev->oss.lock); 353 up(&dev->dmasound.lock);
353 remove_wait_queue(&dev->oss.wq, &wait); 354 remove_wait_queue(&dev->dmasound.wq, &wait);
354 return ret; 355 return ret;
355} 356}
356 357
@@ -370,53 +371,53 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
370 371
371 if (oss_debug > 1) 372 if (oss_debug > 1)
372 saa7134_print_ioctl(dev->name,cmd); 373 saa7134_print_ioctl(dev->name,cmd);
373 switch (cmd) { 374 switch (cmd) {
374 case OSS_GETVERSION: 375 case OSS_GETVERSION:
375 return put_user(SOUND_VERSION, p); 376 return put_user(SOUND_VERSION, p);
376 case SNDCTL_DSP_GETCAPS: 377 case SNDCTL_DSP_GETCAPS:
377 return 0; 378 return 0;
378 379
379 case SNDCTL_DSP_SPEED: 380 case SNDCTL_DSP_SPEED:
380 if (get_user(val, p)) 381 if (get_user(val, p))
381 return -EFAULT; 382 return -EFAULT;
382 /* fall through */ 383 /* fall through */
383 case SOUND_PCM_READ_RATE: 384 case SOUND_PCM_READ_RATE:
384 return put_user(dev->oss.rate, p); 385 return put_user(dev->dmasound.rate, p);
385 386
386 case SNDCTL_DSP_STEREO: 387 case SNDCTL_DSP_STEREO:
387 if (get_user(val, p)) 388 if (get_user(val, p))
388 return -EFAULT; 389 return -EFAULT;
389 down(&dev->oss.lock); 390 down(&dev->dmasound.lock);
390 dev->oss.channels = val ? 2 : 1; 391 dev->dmasound.channels = val ? 2 : 1;
391 if (dev->oss.recording_on) { 392 if (dev->dmasound.recording_on) {
392 dsp_rec_stop(dev); 393 dsp_rec_stop(dev);
393 dsp_rec_start(dev); 394 dsp_rec_start(dev);
394 } 395 }
395 up(&dev->oss.lock); 396 up(&dev->dmasound.lock);
396 return put_user(dev->oss.channels-1, p); 397 return put_user(dev->dmasound.channels-1, p);
397 398
398 case SNDCTL_DSP_CHANNELS: 399 case SNDCTL_DSP_CHANNELS:
399 if (get_user(val, p)) 400 if (get_user(val, p))
400 return -EFAULT; 401 return -EFAULT;
401 if (val != 1 && val != 2) 402 if (val != 1 && val != 2)
402 return -EINVAL; 403 return -EINVAL;
403 down(&dev->oss.lock); 404 down(&dev->dmasound.lock);
404 dev->oss.channels = val; 405 dev->dmasound.channels = val;
405 if (dev->oss.recording_on) { 406 if (dev->dmasound.recording_on) {
406 dsp_rec_stop(dev); 407 dsp_rec_stop(dev);
407 dsp_rec_start(dev); 408 dsp_rec_start(dev);
408 } 409 }
409 up(&dev->oss.lock); 410 up(&dev->dmasound.lock);
410 /* fall through */ 411 /* fall through */
411 case SOUND_PCM_READ_CHANNELS: 412 case SOUND_PCM_READ_CHANNELS:
412 return put_user(dev->oss.channels, p); 413 return put_user(dev->dmasound.channels, p);
413 414
414 case SNDCTL_DSP_GETFMTS: /* Returns a mask */ 415 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
415 return put_user(AFMT_U8 | AFMT_S8 | 416 return put_user(AFMT_U8 | AFMT_S8 |
416 AFMT_U16_LE | AFMT_U16_BE | 417 AFMT_U16_LE | AFMT_U16_BE |
417 AFMT_S16_LE | AFMT_S16_BE, p); 418 AFMT_S16_LE | AFMT_S16_BE, p);
418 419
419 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */ 420 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
420 if (get_user(val, p)) 421 if (get_user(val, p))
421 return -EFAULT; 422 return -EFAULT;
422 switch (val) { 423 switch (val) {
@@ -429,20 +430,20 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
429 case AFMT_U16_BE: 430 case AFMT_U16_BE:
430 case AFMT_S16_LE: 431 case AFMT_S16_LE:
431 case AFMT_S16_BE: 432 case AFMT_S16_BE:
432 down(&dev->oss.lock); 433 down(&dev->dmasound.lock);
433 dev->oss.afmt = val; 434 dev->dmasound.afmt = val;
434 if (dev->oss.recording_on) { 435 if (dev->dmasound.recording_on) {
435 dsp_rec_stop(dev); 436 dsp_rec_stop(dev);
436 dsp_rec_start(dev); 437 dsp_rec_start(dev);
437 } 438 }
438 up(&dev->oss.lock); 439 up(&dev->dmasound.lock);
439 return put_user(dev->oss.afmt, p); 440 return put_user(dev->dmasound.afmt, p);
440 default: 441 default:
441 return -EINVAL; 442 return -EINVAL;
442 } 443 }
443 444
444 case SOUND_PCM_READ_BITS: 445 case SOUND_PCM_READ_BITS:
445 switch (dev->oss.afmt) { 446 switch (dev->dmasound.afmt) {
446 case AFMT_U8: 447 case AFMT_U8:
447 case AFMT_S8: 448 case AFMT_S8:
448 return put_user(8, p); 449 return put_user(8, p);
@@ -455,23 +456,23 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
455 return -EINVAL; 456 return -EINVAL;
456 } 457 }
457 458
458 case SNDCTL_DSP_NONBLOCK: 459 case SNDCTL_DSP_NONBLOCK:
459 file->f_flags |= O_NONBLOCK; 460 file->f_flags |= O_NONBLOCK;
460 return 0; 461 return 0;
461 462
462 case SNDCTL_DSP_RESET: 463 case SNDCTL_DSP_RESET:
463 down(&dev->oss.lock); 464 down(&dev->dmasound.lock);
464 if (dev->oss.recording_on) 465 if (dev->dmasound.recording_on)
465 dsp_rec_stop(dev); 466 dsp_rec_stop(dev);
466 up(&dev->oss.lock); 467 up(&dev->dmasound.lock);
467 return 0; 468 return 0;
468 case SNDCTL_DSP_GETBLKSIZE: 469 case SNDCTL_DSP_GETBLKSIZE:
469 return put_user(dev->oss.blksize, p); 470 return put_user(dev->dmasound.blksize, p);
470 471
471 case SNDCTL_DSP_SETFRAGMENT: 472 case SNDCTL_DSP_SETFRAGMENT:
472 if (get_user(val, p)) 473 if (get_user(val, p))
473 return -EFAULT; 474 return -EFAULT;
474 if (dev->oss.recording_on) 475 if (dev->dmasound.recording_on)
475 return -EBUSY; 476 return -EBUSY;
476 dsp_buffer_free(dev); 477 dsp_buffer_free(dev);
477 /* used to be arg >> 16 instead of val >> 16; fixed */ 478 /* used to be arg >> 16 instead of val >> 16; fixed */
@@ -479,16 +480,16 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
479 dsp_buffer_init(dev); 480 dsp_buffer_init(dev);
480 return 0; 481 return 0;
481 482
482 case SNDCTL_DSP_SYNC: 483 case SNDCTL_DSP_SYNC:
483 /* NOP */ 484 /* NOP */
484 return 0; 485 return 0;
485 486
486 case SNDCTL_DSP_GETISPACE: 487 case SNDCTL_DSP_GETISPACE:
487 { 488 {
488 audio_buf_info info; 489 audio_buf_info info;
489 info.fragsize = dev->oss.blksize; 490 info.fragsize = dev->dmasound.blksize;
490 info.fragstotal = dev->oss.blocks; 491 info.fragstotal = dev->dmasound.blocks;
491 info.bytes = dev->oss.read_count; 492 info.bytes = dev->dmasound.read_count;
492 info.fragments = info.bytes / info.fragsize; 493 info.fragments = info.bytes / info.fragsize;
493 if (copy_to_user(argp, &info, sizeof(info))) 494 if (copy_to_user(argp, &info, sizeof(info)))
494 return -EFAULT; 495 return -EFAULT;
@@ -504,13 +505,13 @@ static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
504 struct saa7134_dev *dev = file->private_data; 505 struct saa7134_dev *dev = file->private_data;
505 unsigned int mask = 0; 506 unsigned int mask = 0;
506 507
507 poll_wait(file, &dev->oss.wq, wait); 508 poll_wait(file, &dev->dmasound.wq, wait);
508 509
509 if (0 == dev->oss.read_count) { 510 if (0 == dev->dmasound.read_count) {
510 down(&dev->oss.lock); 511 down(&dev->dmasound.lock);
511 if (!dev->oss.recording_on) 512 if (!dev->dmasound.recording_on)
512 dsp_rec_start(dev); 513 dsp_rec_start(dev);
513 up(&dev->oss.lock); 514 up(&dev->dmasound.lock);
514 } else 515 } else
515 mask |= (POLLIN | POLLRDNORM); 516 mask |= (POLLIN | POLLRDNORM);
516 return mask; 517 return mask;
@@ -534,7 +535,7 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
534{ 535{
535 int analog_io,rate; 536 int analog_io,rate;
536 537
537 switch (dev->oss.input) { 538 switch (dev->dmasound.input) {
538 case TV: 539 case TV:
539 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0); 540 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
540 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00); 541 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
@@ -542,8 +543,8 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
542 case LINE1: 543 case LINE1:
543 case LINE2: 544 case LINE2:
544 case LINE2_LEFT: 545 case LINE2_LEFT:
545 analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08; 546 analog_io = (LINE1 == dev->dmasound.input) ? 0x00 : 0x08;
546 rate = (32000 == dev->oss.rate) ? 0x01 : 0x03; 547 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
547 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io); 548 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
548 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80); 549 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
549 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate); 550 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
@@ -559,10 +560,10 @@ mixer_recsrc_7133(struct saa7134_dev *dev)
559 560
560 xbarin = 0x03; // adc 561 xbarin = 0x03; // adc
561 anabar = 0; 562 anabar = 0;
562 switch (dev->oss.input) { 563 switch (dev->dmasound.input) {
563 case TV: 564 case TV:
564 xbarin = 0; // Demodulator 565 xbarin = 0; // Demodulator
565 anabar = 2; // DACs 566 anabar = 2; // DACs
566 break; 567 break;
567 case LINE1: 568 case LINE1:
568 anabar = 0; // aux1, aux1 569 anabar = 0; // aux1, aux1
@@ -585,9 +586,9 @@ mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
585{ 586{
586 static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" }; 587 static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
587 588
588 dev->oss.count++; 589 dev->dmasound.count++;
589 dev->oss.input = src; 590 dev->dmasound.input = src;
590 dprintk("mixer input = %s\n",iname[dev->oss.input]); 591 dprintk("mixer input = %s\n",iname[dev->dmasound.input]);
591 592
592 switch (dev->pci->device) { 593 switch (dev->pci->device) {
593 case PCI_DEVICE_ID_PHILIPS_SAA7134: 594 case PCI_DEVICE_ID_PHILIPS_SAA7134:
@@ -639,7 +640,7 @@ static int mixer_open(struct inode *inode, struct file *file)
639 640
640 list_for_each(list,&saa7134_devlist) { 641 list_for_each(list,&saa7134_devlist) {
641 h = list_entry(list, struct saa7134_dev, devlist); 642 h = list_entry(list, struct saa7134_dev, devlist);
642 if (h->oss.minor_mixer == minor) 643 if (h->dmasound.minor_mixer == minor)
643 dev = h; 644 dev = h;
644 } 645 }
645 if (NULL == dev) 646 if (NULL == dev)
@@ -666,28 +667,28 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
666 667
667 if (oss_debug > 1) 668 if (oss_debug > 1)
668 saa7134_print_ioctl(dev->name,cmd); 669 saa7134_print_ioctl(dev->name,cmd);
669 switch (cmd) { 670 switch (cmd) {
670 case OSS_GETVERSION: 671 case OSS_GETVERSION:
671 return put_user(SOUND_VERSION, p); 672 return put_user(SOUND_VERSION, p);
672 case SOUND_MIXER_INFO: 673 case SOUND_MIXER_INFO:
673 { 674 {
674 mixer_info info; 675 mixer_info info;
675 memset(&info,0,sizeof(info)); 676 memset(&info,0,sizeof(info));
676 strlcpy(info.id, "TV audio", sizeof(info.id)); 677 strlcpy(info.id, "TV audio", sizeof(info.id));
677 strlcpy(info.name, dev->name, sizeof(info.name)); 678 strlcpy(info.name, dev->name, sizeof(info.name));
678 info.modify_counter = dev->oss.count; 679 info.modify_counter = dev->dmasound.count;
679 if (copy_to_user(argp, &info, sizeof(info))) 680 if (copy_to_user(argp, &info, sizeof(info)))
680 return -EFAULT; 681 return -EFAULT;
681 return 0; 682 return 0;
682 } 683 }
683 case SOUND_OLD_MIXER_INFO: 684 case SOUND_OLD_MIXER_INFO:
684 { 685 {
685 _old_mixer_info info; 686 _old_mixer_info info;
686 memset(&info,0,sizeof(info)); 687 memset(&info,0,sizeof(info));
687 strlcpy(info.id, "TV audio", sizeof(info.id)); 688 strlcpy(info.id, "TV audio", sizeof(info.id));
688 strlcpy(info.name, dev->name, sizeof(info.name)); 689 strlcpy(info.name, dev->name, sizeof(info.name));
689 if (copy_to_user(argp, &info, sizeof(info))) 690 if (copy_to_user(argp, &info, sizeof(info)))
690 return -EFAULT; 691 return -EFAULT;
691 return 0; 692 return 0;
692 } 693 }
693 case MIXER_READ(SOUND_MIXER_CAPS): 694 case MIXER_READ(SOUND_MIXER_CAPS):
@@ -697,26 +698,26 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
697 case MIXER_READ(SOUND_MIXER_RECMASK): 698 case MIXER_READ(SOUND_MIXER_RECMASK):
698 case MIXER_READ(SOUND_MIXER_DEVMASK): 699 case MIXER_READ(SOUND_MIXER_DEVMASK):
699 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2; 700 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2;
700 if (32000 == dev->oss.rate) 701 if (32000 == dev->dmasound.rate)
701 val |= SOUND_MASK_VIDEO; 702 val |= SOUND_MASK_VIDEO;
702 return put_user(val, p); 703 return put_user(val, p);
703 704
704 case MIXER_WRITE(SOUND_MIXER_RECSRC): 705 case MIXER_WRITE(SOUND_MIXER_RECSRC):
705 if (get_user(val, p)) 706 if (get_user(val, p))
706 return -EFAULT; 707 return -EFAULT;
707 input = dev->oss.input; 708 input = dev->dmasound.input;
708 if (32000 == dev->oss.rate && 709 if (32000 == dev->dmasound.rate &&
709 val & SOUND_MASK_VIDEO && dev->oss.input != TV) 710 val & SOUND_MASK_VIDEO && dev->dmasound.input != TV)
710 input = TV; 711 input = TV;
711 if (val & SOUND_MASK_LINE1 && dev->oss.input != LINE1) 712 if (val & SOUND_MASK_LINE1 && dev->dmasound.input != LINE1)
712 input = LINE1; 713 input = LINE1;
713 if (val & SOUND_MASK_LINE2 && dev->oss.input != LINE2) 714 if (val & SOUND_MASK_LINE2 && dev->dmasound.input != LINE2)
714 input = LINE2; 715 input = LINE2;
715 if (input != dev->oss.input) 716 if (input != dev->dmasound.input)
716 mixer_recsrc(dev,input); 717 mixer_recsrc(dev,input);
717 /* fall throuth */ 718 /* fall throuth */
718 case MIXER_READ(SOUND_MIXER_RECSRC): 719 case MIXER_READ(SOUND_MIXER_RECSRC):
719 switch (dev->oss.input) { 720 switch (dev->dmasound.input) {
720 case TV: ret = SOUND_MASK_VIDEO; break; 721 case TV: ret = SOUND_MASK_VIDEO; break;
721 case LINE1: ret = SOUND_MASK_LINE1; break; 722 case LINE1: ret = SOUND_MASK_LINE1; break;
722 case LINE2: ret = SOUND_MASK_LINE2; break; 723 case LINE2: ret = SOUND_MASK_LINE2; break;
@@ -726,7 +727,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
726 727
727 case MIXER_WRITE(SOUND_MIXER_VIDEO): 728 case MIXER_WRITE(SOUND_MIXER_VIDEO):
728 case MIXER_READ(SOUND_MIXER_VIDEO): 729 case MIXER_READ(SOUND_MIXER_VIDEO):
729 if (32000 != dev->oss.rate) 730 if (32000 != dev->dmasound.rate)
730 return -EINVAL; 731 return -EINVAL;
731 return put_user(100 | 100 << 8, p); 732 return put_user(100 | 100 << 8, p);
732 733
@@ -735,22 +736,22 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
735 return -EFAULT; 736 return -EFAULT;
736 val &= 0xff; 737 val &= 0xff;
737 val = (val <= 50) ? 50 : 100; 738 val = (val <= 50) ? 50 : 100;
738 dev->oss.line1 = val; 739 dev->dmasound.line1 = val;
739 mixer_level(dev,LINE1,dev->oss.line1); 740 mixer_level(dev,LINE1,dev->dmasound.line1);
740 /* fall throuth */ 741 /* fall throuth */
741 case MIXER_READ(SOUND_MIXER_LINE1): 742 case MIXER_READ(SOUND_MIXER_LINE1):
742 return put_user(dev->oss.line1 | dev->oss.line1 << 8, p); 743 return put_user(dev->dmasound.line1 | dev->dmasound.line1 << 8, p);
743 744
744 case MIXER_WRITE(SOUND_MIXER_LINE2): 745 case MIXER_WRITE(SOUND_MIXER_LINE2):
745 if (get_user(val, p)) 746 if (get_user(val, p))
746 return -EFAULT; 747 return -EFAULT;
747 val &= 0xff; 748 val &= 0xff;
748 val = (val <= 50) ? 50 : 100; 749 val = (val <= 50) ? 50 : 100;
749 dev->oss.line2 = val; 750 dev->dmasound.line2 = val;
750 mixer_level(dev,LINE2,dev->oss.line2); 751 mixer_level(dev,LINE2,dev->dmasound.line2);
751 /* fall throuth */ 752 /* fall throuth */
752 case MIXER_READ(SOUND_MIXER_LINE2): 753 case MIXER_READ(SOUND_MIXER_LINE2):
753 return put_user(dev->oss.line2 | dev->oss.line2 << 8, p); 754 return put_user(dev->dmasound.line2 | dev->dmasound.line2 << 8, p);
754 755
755 default: 756 default:
756 return -EINVAL; 757 return -EINVAL;
@@ -770,8 +771,8 @@ struct file_operations saa7134_mixer_fops = {
770int saa7134_oss_init1(struct saa7134_dev *dev) 771int saa7134_oss_init1(struct saa7134_dev *dev)
771{ 772{
772 /* general */ 773 /* general */
773 init_MUTEX(&dev->oss.lock); 774 init_MUTEX(&dev->dmasound.lock);
774 init_waitqueue_head(&dev->oss.wq); 775 init_waitqueue_head(&dev->dmasound.wq);
775 776
776 switch (dev->pci->device) { 777 switch (dev->pci->device) {
777 case PCI_DEVICE_ID_PHILIPS_SAA7133: 778 case PCI_DEVICE_ID_PHILIPS_SAA7133:
@@ -783,17 +784,17 @@ int saa7134_oss_init1(struct saa7134_dev *dev)
783 } 784 }
784 785
785 /* dsp */ 786 /* dsp */
786 dev->oss.rate = 32000; 787 dev->dmasound.rate = 32000;
787 if (oss_rate) 788 if (oss_rate)
788 dev->oss.rate = oss_rate; 789 dev->dmasound.rate = oss_rate;
789 dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000; 790 dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000;
790 791
791 /* mixer */ 792 /* mixer */
792 dev->oss.line1 = 50; 793 dev->dmasound.line1 = 50;
793 dev->oss.line2 = 50; 794 dev->dmasound.line2 = 50;
794 mixer_level(dev,LINE1,dev->oss.line1); 795 mixer_level(dev,LINE1,dev->dmasound.line1);
795 mixer_level(dev,LINE2,dev->oss.line2); 796 mixer_level(dev,LINE2,dev->dmasound.line2);
796 mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2); 797 mixer_recsrc(dev, (dev->dmasound.rate == 32000) ? TV : LINE2);
797 798
798 return 0; 799 return 0;
799} 800}
@@ -809,7 +810,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
809 int next_blk, reg = 0; 810 int next_blk, reg = 0;
810 811
811 spin_lock(&dev->slock); 812 spin_lock(&dev->slock);
812 if (UNSET == dev->oss.dma_blk) { 813 if (UNSET == dev->dmasound.dma_blk) {
813 dprintk("irq: recording stopped\n"); 814 dprintk("irq: recording stopped\n");
814 goto done; 815 goto done;
815 } 816 }
@@ -817,11 +818,11 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
817 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f); 818 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
818 if (0 == (status & 0x10000000)) { 819 if (0 == (status & 0x10000000)) {
819 /* odd */ 820 /* odd */
820 if (0 == (dev->oss.dma_blk & 0x01)) 821 if (0 == (dev->dmasound.dma_blk & 0x01))
821 reg = SAA7134_RS_BA1(6); 822 reg = SAA7134_RS_BA1(6);
822 } else { 823 } else {
823 /* even */ 824 /* even */
824 if (1 == (dev->oss.dma_blk & 0x01)) 825 if (1 == (dev->dmasound.dma_blk & 0x01))
825 reg = SAA7134_RS_BA2(6); 826 reg = SAA7134_RS_BA2(6);
826 } 827 }
827 if (0 == reg) { 828 if (0 == reg) {
@@ -829,25 +830,25 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
829 (status & 0x10000000) ? "even" : "odd"); 830 (status & 0x10000000) ? "even" : "odd");
830 goto done; 831 goto done;
831 } 832 }
832 if (dev->oss.read_count >= dev->oss.blksize * (dev->oss.blocks-2)) { 833 if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
833 dprintk("irq: overrun [full=%d/%d]\n",dev->oss.read_count, 834 dprintk("irq: overrun [full=%d/%d]\n",dev->dmasound.read_count,
834 dev->oss.bufsize); 835 dev->dmasound.bufsize);
835 dsp_dma_stop(dev); 836 dsp_dma_stop(dev);
836 goto done; 837 goto done;
837 } 838 }
838 839
839 /* next block addr */ 840 /* next block addr */
840 next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks; 841 next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
841 saa_writel(reg,next_blk * dev->oss.blksize); 842 saa_writel(reg,next_blk * dev->dmasound.blksize);
842 if (oss_debug > 2) 843 if (oss_debug > 2)
843 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n", 844 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
844 (status & 0x10000000) ? "even" : "odd ", next_blk, 845 (status & 0x10000000) ? "even" : "odd ", next_blk,
845 next_blk * dev->oss.blksize); 846 next_blk * dev->dmasound.blksize);
846 847
847 /* update status & wake waiting readers */ 848 /* update status & wake waiting readers */
848 dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks; 849 dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
849 dev->oss.read_count += dev->oss.blksize; 850 dev->dmasound.read_count += dev->dmasound.blksize;
850 wake_up(&dev->oss.wq); 851 wake_up(&dev->dmasound.wq);
851 852
852 done: 853 done:
853 spin_unlock(&dev->slock); 854 spin_unlock(&dev->slock);
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
index ae0c7a165390..ac6431ba4fc3 100644
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -27,7 +27,7 @@
27 27
28/* DMA channels, n = 0 ... 6 */ 28/* DMA channels, n = 0 ... 6 */
29#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n) 29#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n)
30#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n) 30#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n)
31#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n) 31#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n)
32#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n) 32#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n)
33#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25) 33#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25)
@@ -43,16 +43,24 @@
43#define SAA7134_FIFO_SIZE (0x2a0 >> 2) 43#define SAA7134_FIFO_SIZE (0x2a0 >> 2)
44#define SAA7134_THRESHOULD (0x2a4 >> 2) 44#define SAA7134_THRESHOULD (0x2a4 >> 2)
45 45
46#define SAA7133_NUM_SAMPLES (0x588 >> 2)
47#define SAA7133_AUDIO_CHANNEL (0x58c >> 2)
48#define SAA7133_AUDIO_FORMAT (0x58f >> 2)
49#define SAA7133_DIGITAL_OUTPUT_SEL1 (0x46c >> 2)
50#define SAA7133_DIGITAL_OUTPUT_SEL2 (0x470 >> 2)
51#define SAA7133_DIGITAL_INPUT_XBAR1 (0x464 >> 2)
52#define SAA7133_ANALOG_IO_SELECT (0x594 >> 2)
53
46/* main control */ 54/* main control */
47#define SAA7134_MAIN_CTRL (0x2a8 >> 2) 55#define SAA7134_MAIN_CTRL (0x2a8 >> 2)
48#define SAA7134_MAIN_CTRL_VPLLE (1 << 15) 56#define SAA7134_MAIN_CTRL_VPLLE (1 << 15)
49#define SAA7134_MAIN_CTRL_APLLE (1 << 14) 57#define SAA7134_MAIN_CTRL_APLLE (1 << 14)
50#define SAA7134_MAIN_CTRL_EXOSC (1 << 13) 58#define SAA7134_MAIN_CTRL_EXOSC (1 << 13)
51#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12) 59#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12)
52#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11) 60#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11)
53#define SAA7134_MAIN_CTRL_ESFE (1 << 10) 61#define SAA7134_MAIN_CTRL_ESFE (1 << 10)
54#define SAA7134_MAIN_CTRL_EBADC (1 << 9) 62#define SAA7134_MAIN_CTRL_EBADC (1 << 9)
55#define SAA7134_MAIN_CTRL_EBDAC (1 << 8) 63#define SAA7134_MAIN_CTRL_EBDAC (1 << 8)
56#define SAA7134_MAIN_CTRL_TE6 (1 << 6) 64#define SAA7134_MAIN_CTRL_TE6 (1 << 6)
57#define SAA7134_MAIN_CTRL_TE5 (1 << 5) 65#define SAA7134_MAIN_CTRL_TE5 (1 << 5)
58#define SAA7134_MAIN_CTRL_TE4 (1 << 4) 66#define SAA7134_MAIN_CTRL_TE4 (1 << 4)
@@ -348,6 +356,7 @@
348 356
349/* test modes */ 357/* test modes */
350#define SAA7134_SPECIAL_MODE 0x1d0 358#define SAA7134_SPECIAL_MODE 0x1d0
359#define SAA7134_PRODUCTION_TEST_MODE 0x1d1
351 360
352/* audio -- saa7133 + saa7135 only */ 361/* audio -- saa7133 + saa7135 only */
353#define SAA7135_DSP_RWSTATE 0x580 362#define SAA7135_DSP_RWSTATE 0x580
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index 463885601ab4..470903e2f5e5 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -46,17 +46,11 @@ static int buffer_activate(struct saa7134_dev *dev,
46 struct saa7134_buf *buf, 46 struct saa7134_buf *buf,
47 struct saa7134_buf *next) 47 struct saa7134_buf *next)
48{ 48{
49 u32 control;
50 49
51 dprintk("buffer_activate [%p]",buf); 50 dprintk("buffer_activate [%p]",buf);
52 buf->vb.state = STATE_ACTIVE; 51 buf->vb.state = STATE_ACTIVE;
53 buf->top_seen = 0; 52 buf->top_seen = 0;
54 53
55 /* dma: setup channel 5 (= TS) */
56 control = SAA7134_RS_CONTROL_BURST_16 |
57 SAA7134_RS_CONTROL_ME |
58 (buf->pt->dma >> 12);
59
60 if (NULL == next) 54 if (NULL == next)
61 next = buf; 55 next = buf;
62 if (V4L2_FIELD_TOP == buf->vb.field) { 56 if (V4L2_FIELD_TOP == buf->vb.field) {
@@ -68,8 +62,6 @@ static int buffer_activate(struct saa7134_dev *dev,
68 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); 62 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
69 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); 63 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
70 } 64 }
71 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
72 saa_writel(SAA7134_RS_CONTROL(5),control);
73 65
74 /* start DMA */ 66 /* start DMA */
75 saa7134_set_dmabits(dev); 67 saa7134_set_dmabits(dev);
@@ -84,6 +76,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
84 struct saa7134_dev *dev = q->priv_data; 76 struct saa7134_dev *dev = q->priv_data;
85 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 77 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
86 unsigned int lines, llength, size; 78 unsigned int lines, llength, size;
79 u32 control;
87 int err; 80 int err;
88 81
89 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); 82 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
@@ -115,6 +108,18 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
115 if (err) 108 if (err)
116 goto oops; 109 goto oops;
117 } 110 }
111
112 /* dma: setup channel 5 (= TS) */
113 control = SAA7134_RS_CONTROL_BURST_16 |
114 SAA7134_RS_CONTROL_ME |
115 (buf->pt->dma >> 12);
116
117 saa_writeb(SAA7134_TS_DMA0, ((lines-1)&0xff));
118 saa_writeb(SAA7134_TS_DMA1, (((lines-1)>>8)&0xff));
119 saa_writeb(SAA7134_TS_DMA2, ((((lines-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */
120 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
121 saa_writel(SAA7134_RS_CONTROL(5),control);
122
118 buf->vb.state = STATE_PREPARED; 123 buf->vb.state = STATE_PREPARED;
119 buf->activate = buffer_activate; 124 buf->activate = buffer_activate;
120 buf->vb.field = field; 125 buf->vb.field = field;
@@ -164,11 +169,11 @@ EXPORT_SYMBOL_GPL(saa7134_ts_qops);
164/* ----------------------------------------------------------- */ 169/* ----------------------------------------------------------- */
165/* exported stuff */ 170/* exported stuff */
166 171
167static unsigned int tsbufs = 4; 172static unsigned int tsbufs = 8;
168module_param(tsbufs, int, 0444); 173module_param(tsbufs, int, 0444);
169MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); 174MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32");
170 175
171static unsigned int ts_nr_packets = 30; 176static unsigned int ts_nr_packets = 64;
172module_param(ts_nr_packets, int, 0444); 177module_param(ts_nr_packets, int, 0444);
173MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)"); 178MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
174 179
@@ -220,10 +225,10 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
220 if (dev->ts_q.curr) { 225 if (dev->ts_q.curr) {
221 field = dev->ts_q.curr->vb.field; 226 field = dev->ts_q.curr->vb.field;
222 if (field == V4L2_FIELD_TOP) { 227 if (field == V4L2_FIELD_TOP) {
223 if ((status & 0x100000) != 0x100000) 228 if ((status & 0x100000) != 0x000000)
224 goto done; 229 goto done;
225 } else { 230 } else {
226 if ((status & 0x100000) != 0x000000) 231 if ((status & 0x100000) != 0x100000)
227 goto done; 232 goto done;
228 } 233 }
229 saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE); 234 saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 61a2d6b50eef..93268427750d 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -207,6 +207,10 @@ static void tvaudio_setcarrier(struct saa7134_dev *dev,
207 saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary)); 207 saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary));
208} 208}
209 209
210#define SAA7134_MUTE_MASK 0xbb
211#define SAA7134_MUTE_ANALOG 0x04
212#define SAA7134_MUTE_I2S 0x40
213
210static void mute_input_7134(struct saa7134_dev *dev) 214static void mute_input_7134(struct saa7134_dev *dev)
211{ 215{
212 unsigned int mute; 216 unsigned int mute;
@@ -241,7 +245,11 @@ static void mute_input_7134(struct saa7134_dev *dev)
241 245
242 if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device) 246 if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device)
243 /* 7134 mute */ 247 /* 7134 mute */
244 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xbf : 0xbb); 248 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ?
249 SAA7134_MUTE_MASK |
250 SAA7134_MUTE_ANALOG |
251 SAA7134_MUTE_I2S :
252 SAA7134_MUTE_MASK);
245 253
246 /* switch internal audio mux */ 254 /* switch internal audio mux */
247 switch (in->amux) { 255 switch (in->amux) {
@@ -753,17 +761,17 @@ static int mute_input_7133(struct saa7134_dev *dev)
753 761
754 762
755 /* switch gpio-connected external audio mux */ 763 /* switch gpio-connected external audio mux */
756 if (0 != card(dev).gpiomask) { 764 if (0 != card(dev).gpiomask) {
757 mask = card(dev).gpiomask; 765 mask = card(dev).gpiomask;
758 766
759 if (card(dev).mute.name && dev->ctl_mute) 767 if (card(dev).mute.name && dev->ctl_mute)
760 in = &card(dev).mute; 768 in = &card(dev).mute;
761 else 769 else
762 in = dev->input; 770 in = dev->input;
763 771
764 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask); 772 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
765 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio); 773 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
766 saa7134_track_gpio(dev,in->name); 774 saa7134_track_gpio(dev,in->name);
767 } 775 }
768 776
769 return 0; 777 return 0;
@@ -1016,9 +1024,12 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
1016 return 0; 1024 return 0;
1017} 1025}
1018 1026
1027EXPORT_SYMBOL(saa_dsp_writel);
1028
1019/* ----------------------------------------------------------- */ 1029/* ----------------------------------------------------------- */
1020/* 1030/*
1021 * Local variables: 1031 * Local variables:
1022 * c-basic-offset: 8 1032 * c-basic-offset: 8
1023 * End: 1033 * End:
1024 */ 1034 */
1035
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 35e5e85f669a..45c852df13ed 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -30,6 +30,9 @@
30#include "saa7134-reg.h" 30#include "saa7134-reg.h"
31#include "saa7134.h" 31#include "saa7134.h"
32 32
33/* Include V4L1 specific functions. Should be removed soon */
34#include <linux/videodev.h>
35
33/* ------------------------------------------------------------------ */ 36/* ------------------------------------------------------------------ */
34 37
35static unsigned int video_debug = 0; 38static unsigned int video_debug = 0;
@@ -48,6 +51,43 @@ MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced");
48 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg) 51 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
49 52
50/* ------------------------------------------------------------------ */ 53/* ------------------------------------------------------------------ */
54/* Defines for Video Output Port Register at address 0x191 */
55
56/* Bit 0: VIP code T bit polarity */
57
58#define VP_T_CODE_P_NON_INVERTED 0x00
59#define VP_T_CODE_P_INVERTED 0x01
60
61/* ------------------------------------------------------------------ */
62/* Defines for Video Output Port Register at address 0x195 */
63
64/* Bit 2: Video output clock delay control */
65
66#define VP_CLK_CTRL2_NOT_DELAYED 0x00
67#define VP_CLK_CTRL2_DELAYED 0x04
68
69/* Bit 1: Video output clock invert control */
70
71#define VP_CLK_CTRL1_NON_INVERTED 0x00
72#define VP_CLK_CTRL1_INVERTED 0x02
73
74/* ------------------------------------------------------------------ */
75/* Defines for Video Output Port Register at address 0x196 */
76
77/* Bits 2 to 0: VSYNC pin video vertical sync type */
78
79#define VP_VS_TYPE_MASK 0x07
80
81#define VP_VS_TYPE_OFF 0x00
82#define VP_VS_TYPE_V123 0x01
83#define VP_VS_TYPE_V_ITU 0x02
84#define VP_VS_TYPE_VGATE_L 0x03
85#define VP_VS_TYPE_RESERVED1 0x04
86#define VP_VS_TYPE_RESERVED2 0x05
87#define VP_VS_TYPE_F_ITU 0x06
88#define VP_VS_TYPE_SC_FID 0x07
89
90/* ------------------------------------------------------------------ */
51/* data structs for video */ 91/* data structs for video */
52 92
53static int video_out[][9] = { 93static int video_out[][9] = {
@@ -273,12 +313,12 @@ static struct saa7134_tvnorm tvnorms[] = {
273 313
274 .h_start = 0, 314 .h_start = 0,
275 .h_stop = 719, 315 .h_stop = 719,
276 .video_v_start = 23, 316 .video_v_start = 23,
277 .video_v_stop = 262, 317 .video_v_stop = 262,
278 .vbi_v_start_0 = 10, 318 .vbi_v_start_0 = 10,
279 .vbi_v_stop_0 = 21, 319 .vbi_v_stop_0 = 21,
280 .vbi_v_start_1 = 273, 320 .vbi_v_start_1 = 273,
281 .src_timing = 7, 321 .src_timing = 7,
282 322
283 .sync_control = 0x18, 323 .sync_control = 0x18,
284 .luma_control = 0x40, 324 .luma_control = 0x40,
@@ -622,7 +662,7 @@ static void set_size(struct saa7134_dev *dev, int task,
622 prescale = 1; 662 prescale = 1;
623 xscale = 1024 * dev->crop_current.width / prescale / width; 663 xscale = 1024 * dev->crop_current.width / prescale / width;
624 yscale = 512 * div * dev->crop_current.height / height; 664 yscale = 512 * div * dev->crop_current.height / height;
625 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale); 665 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
626 set_h_prescale(dev,task,prescale); 666 set_h_prescale(dev,task,prescale);
627 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff); 667 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff);
628 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8); 668 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8);
@@ -752,20 +792,20 @@ static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
752 maxh = dev->crop_current.height; 792 maxh = dev->crop_current.height;
753 793
754 if (V4L2_FIELD_ANY == field) { 794 if (V4L2_FIELD_ANY == field) {
755 field = (win->w.height > maxh/2) 795 field = (win->w.height > maxh/2)
756 ? V4L2_FIELD_INTERLACED 796 ? V4L2_FIELD_INTERLACED
757 : V4L2_FIELD_TOP; 797 : V4L2_FIELD_TOP;
758 } 798 }
759 switch (field) { 799 switch (field) {
760 case V4L2_FIELD_TOP: 800 case V4L2_FIELD_TOP:
761 case V4L2_FIELD_BOTTOM: 801 case V4L2_FIELD_BOTTOM:
762 maxh = maxh / 2; 802 maxh = maxh / 2;
763 break; 803 break;
764 case V4L2_FIELD_INTERLACED: 804 case V4L2_FIELD_INTERLACED:
765 break; 805 break;
766 default: 806 default:
767 return -EINVAL; 807 return -EINVAL;
768 } 808 }
769 809
770 win->field = field; 810 win->field = field;
771 if (win->w.width > maxw) 811 if (win->w.width > maxw)
@@ -1306,13 +1346,13 @@ video_poll(struct file *file, struct poll_table_struct *wait)
1306 if (res_locked(fh->dev,RESOURCE_VIDEO)) { 1346 if (res_locked(fh->dev,RESOURCE_VIDEO)) {
1307 up(&fh->cap.lock); 1347 up(&fh->cap.lock);
1308 return POLLERR; 1348 return POLLERR;
1309 } 1349 }
1310 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { 1350 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
1311 up(&fh->cap.lock); 1351 up(&fh->cap.lock);
1312 return POLLERR; 1352 return POLLERR;
1313 } 1353 }
1314 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); 1354 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
1315 fh->cap.read_off = 0; 1355 fh->cap.read_off = 0;
1316 } 1356 }
1317 up(&fh->cap.lock); 1357 up(&fh->cap.lock);
1318 buf = fh->cap.read_buf; 1358 buf = fh->cap.read_buf;
@@ -1666,9 +1706,10 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1666 case VIDIOC_QUERYCAP: 1706 case VIDIOC_QUERYCAP:
1667 { 1707 {
1668 struct v4l2_capability *cap = arg; 1708 struct v4l2_capability *cap = arg;
1709 unsigned int tuner_type = dev->tuner_type;
1669 1710
1670 memset(cap,0,sizeof(*cap)); 1711 memset(cap,0,sizeof(*cap));
1671 strcpy(cap->driver, "saa7134"); 1712 strcpy(cap->driver, "saa7134");
1672 strlcpy(cap->card, saa7134_boards[dev->board].name, 1713 strlcpy(cap->card, saa7134_boards[dev->board].name,
1673 sizeof(cap->card)); 1714 sizeof(cap->card));
1674 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 1715 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -1677,9 +1718,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1677 V4L2_CAP_VIDEO_CAPTURE | 1718 V4L2_CAP_VIDEO_CAPTURE |
1678 V4L2_CAP_VIDEO_OVERLAY | 1719 V4L2_CAP_VIDEO_OVERLAY |
1679 V4L2_CAP_VBI_CAPTURE | 1720 V4L2_CAP_VBI_CAPTURE |
1680 V4L2_CAP_TUNER |
1681 V4L2_CAP_READWRITE | 1721 V4L2_CAP_READWRITE |
1682 V4L2_CAP_STREAMING; 1722 V4L2_CAP_STREAMING |
1723 V4L2_CAP_TUNER;
1724
1725 if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
1726 cap->capabilities &= ~V4L2_CAP_TUNER;
1727
1683 return 0; 1728 return 0;
1684 } 1729 }
1685 1730
@@ -1793,9 +1838,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1793 crop->c.height = b->top - crop->c.top + b->height; 1838 crop->c.height = b->top - crop->c.top + b->height;
1794 1839
1795 if (crop->c.left < b->left) 1840 if (crop->c.left < b->left)
1796 crop->c.top = b->left; 1841 crop->c.left = b->left;
1797 if (crop->c.left > b->left + b->width) 1842 if (crop->c.left > b->left + b->width)
1798 crop->c.top = b->left + b->width; 1843 crop->c.left = b->left + b->width;
1799 if (crop->c.width > b->left - crop->c.left + b->width) 1844 if (crop->c.width > b->left - crop->c.left + b->width)
1800 crop->c.width = b->left - crop->c.left + b->width; 1845 crop->c.width = b->left - crop->c.left + b->width;
1801 1846
@@ -1817,6 +1862,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1817 break; 1862 break;
1818 if (NULL != card_in(dev,n).name) { 1863 if (NULL != card_in(dev,n).name) {
1819 strcpy(t->name, "Television"); 1864 strcpy(t->name, "Television");
1865 t->type = V4L2_TUNER_ANALOG_TV;
1820 t->capability = V4L2_TUNER_CAP_NORM | 1866 t->capability = V4L2_TUNER_CAP_NORM |
1821 V4L2_TUNER_CAP_STEREO | 1867 V4L2_TUNER_CAP_STEREO |
1822 V4L2_TUNER_CAP_LANG1 | 1868 V4L2_TUNER_CAP_LANG1 |
@@ -1892,26 +1938,26 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1892 } 1938 }
1893 case VIDIOC_S_AUDIO: 1939 case VIDIOC_S_AUDIO:
1894 return 0; 1940 return 0;
1895 case VIDIOC_G_PARM: 1941 case VIDIOC_G_PARM:
1896 { 1942 {
1897 struct v4l2_captureparm *parm = arg; 1943 struct v4l2_captureparm *parm = arg;
1898 memset(parm,0,sizeof(*parm)); 1944 memset(parm,0,sizeof(*parm));
1899 return 0; 1945 return 0;
1900 } 1946 }
1901 1947
1902 case VIDIOC_G_PRIORITY: 1948 case VIDIOC_G_PRIORITY:
1903 { 1949 {
1904 enum v4l2_priority *p = arg; 1950 enum v4l2_priority *p = arg;
1905 1951
1906 *p = v4l2_prio_max(&dev->prio); 1952 *p = v4l2_prio_max(&dev->prio);
1907 return 0; 1953 return 0;
1908 } 1954 }
1909 case VIDIOC_S_PRIORITY: 1955 case VIDIOC_S_PRIORITY:
1910 { 1956 {
1911 enum v4l2_priority *prio = arg; 1957 enum v4l2_priority *prio = arg;
1912 1958
1913 return v4l2_prio_change(&dev->prio, &fh->prio, *prio); 1959 return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
1914 } 1960 }
1915 1961
1916 /* --- preview ioctls ---------------------------------------- */ 1962 /* --- preview ioctls ---------------------------------------- */
1917 case VIDIOC_ENUM_FMT: 1963 case VIDIOC_ENUM_FMT:
@@ -2018,7 +2064,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2018 struct v4l2_format *f = arg; 2064 struct v4l2_format *f = arg;
2019 return saa7134_try_fmt(dev,fh,f); 2065 return saa7134_try_fmt(dev,fh,f);
2020 } 2066 }
2021 2067#ifdef HAVE_V4L1
2022 case VIDIOCGMBUF: 2068 case VIDIOCGMBUF:
2023 { 2069 {
2024 struct video_mbuf *mbuf = arg; 2070 struct video_mbuf *mbuf = arg;
@@ -2043,6 +2089,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2043 } 2089 }
2044 return 0; 2090 return 0;
2045 } 2091 }
2092#endif
2046 case VIDIOC_REQBUFS: 2093 case VIDIOC_REQBUFS:
2047 return videobuf_reqbufs(saa7134_queue(fh),arg); 2094 return videobuf_reqbufs(saa7134_queue(fh),arg);
2048 2095
@@ -2060,7 +2107,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2060 { 2107 {
2061 int res = saa7134_resource(fh); 2108 int res = saa7134_resource(fh);
2062 2109
2063 if (!res_get(dev,fh,res)) 2110 if (!res_get(dev,fh,res))
2064 return -EBUSY; 2111 return -EBUSY;
2065 return videobuf_streamon(saa7134_queue(fh)); 2112 return videobuf_streamon(saa7134_queue(fh));
2066 } 2113 }
@@ -2102,7 +2149,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
2102 struct v4l2_capability *cap = arg; 2149 struct v4l2_capability *cap = arg;
2103 2150
2104 memset(cap,0,sizeof(*cap)); 2151 memset(cap,0,sizeof(*cap));
2105 strcpy(cap->driver, "saa7134"); 2152 strcpy(cap->driver, "saa7134");
2106 strlcpy(cap->card, saa7134_boards[dev->board].name, 2153 strlcpy(cap->card, saa7134_boards[dev->board].name,
2107 sizeof(cap->card)); 2154 sizeof(cap->card));
2108 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 2155 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -2119,6 +2166,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
2119 2166
2120 memset(t,0,sizeof(*t)); 2167 memset(t,0,sizeof(*t));
2121 strcpy(t->name, "Radio"); 2168 strcpy(t->name, "Radio");
2169 t->type = V4L2_TUNER_RADIO;
2122 2170
2123 saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); 2171 saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
2124 2172
@@ -2233,7 +2281,7 @@ struct video_device saa7134_video_template =
2233{ 2281{
2234 .name = "saa7134-video", 2282 .name = "saa7134-video",
2235 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| 2283 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
2236 VID_TYPE_CLIPPING|VID_TYPE_SCALES, 2284 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
2237 .hardware = 0, 2285 .hardware = 0,
2238 .fops = &video_fops, 2286 .fops = &video_fops,
2239 .minor = -1, 2287 .minor = -1,
@@ -2280,7 +2328,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
2280 dev->tda9887_conf |= TDA9887_AUTOMUTE; 2328 dev->tda9887_conf |= TDA9887_AUTOMUTE;
2281 dev->automute = 0; 2329 dev->automute = 0;
2282 2330
2283 INIT_LIST_HEAD(&dev->video_q.queue); 2331 INIT_LIST_HEAD(&dev->video_q.queue);
2284 init_timer(&dev->video_q.timeout); 2332 init_timer(&dev->video_q.timeout);
2285 dev->video_q.timeout.function = saa7134_buffer_timeout; 2333 dev->video_q.timeout.function = saa7134_buffer_timeout;
2286 dev->video_q.timeout.data = (unsigned long)(&dev->video_q); 2334 dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
@@ -2289,13 +2337,28 @@ int saa7134_video_init1(struct saa7134_dev *dev)
2289 if (saa7134_boards[dev->board].video_out) { 2337 if (saa7134_boards[dev->board].video_out) {
2290 /* enable video output */ 2338 /* enable video output */
2291 int vo = saa7134_boards[dev->board].video_out; 2339 int vo = saa7134_boards[dev->board].video_out;
2340 int video_reg;
2341 unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
2292 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]); 2342 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
2293 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]); 2343 video_reg = video_out[vo][1];
2344 if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED)
2345 video_reg &= ~VP_T_CODE_P_INVERTED;
2346 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg);
2294 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]); 2347 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
2295 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]); 2348 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
2296 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]); 2349 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
2297 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]); 2350 video_reg = video_out[vo][5];
2298 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]); 2351 if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
2352 video_reg &= ~VP_CLK_CTRL2_DELAYED;
2353 if (vid_port_opts & SET_CLOCK_INVERTED)
2354 video_reg |= VP_CLK_CTRL1_INVERTED;
2355 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg);
2356 video_reg = video_out[vo][6];
2357 if (vid_port_opts & SET_VSYNC_OFF) {
2358 video_reg &= ~VP_VS_TYPE_MASK;
2359 video_reg |= VP_VS_TYPE_OFF;
2360 }
2361 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg);
2299 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]); 2362 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
2300 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]); 2363 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
2301 } 2364 }
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 860b89530e2a..fb9727471661 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -24,16 +24,18 @@
24 24
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/videodev.h> 27#include <linux/videodev2.h>
28#include <linux/kdev_t.h> 28#include <linux/kdev_t.h>
29#include <linux/input.h> 29#include <linux/input.h>
30#include <linux/notifier.h>
31#include <linux/delay.h>
30 32
31#include <asm/io.h> 33#include <asm/io.h>
32 34
33#include <media/tuner.h> 35#include <media/tuner.h>
34#include <media/audiochip.h> 36#include <media/audiochip.h>
35#include <media/id.h>
36#include <media/ir-common.h> 37#include <media/ir-common.h>
38#include <media/ir-kbd-i2c.h>
37#include <media/video-buf.h> 39#include <media/video-buf.h>
38#include <media/video-buf-dvb.h> 40#include <media/video-buf-dvb.h>
39 41
@@ -45,6 +47,10 @@
45#endif 47#endif
46#define UNSET (-1U) 48#define UNSET (-1U)
47 49
50#include <sound/driver.h>
51#include <sound/core.h>
52#include <sound/pcm.h>
53
48/* ----------------------------------------------------------- */ 54/* ----------------------------------------------------------- */
49/* enums */ 55/* enums */
50 56
@@ -187,10 +193,39 @@ struct saa7134_format {
187#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64 193#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64
188#define SAA7134_BOARD_KWORLD_TERMINATOR 65 194#define SAA7134_BOARD_KWORLD_TERMINATOR 65
189#define SAA7134_BOARD_YUAN_TUN900 66 195#define SAA7134_BOARD_YUAN_TUN900 66
196#define SAA7134_BOARD_BEHOLD_409FM 67
197#define SAA7134_BOARD_GOTVIEW_7135 68
198#define SAA7134_BOARD_PHILIPS_EUROPA 69
199#define SAA7134_BOARD_VIDEOMATE_DVBT_300 70
200#define SAA7134_BOARD_VIDEOMATE_DVBT_200 71
201#define SAA7134_BOARD_RTD_VFG7350 72
202#define SAA7134_BOARD_RTD_VFG7330 73
203#define SAA7134_BOARD_FLYTVPLATINUM_MINI2 74
204#define SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180 75
205#define SAA7134_BOARD_MONSTERTV_MOBILE 76
206#define SAA7134_BOARD_PINNACLE_PCTV_110i 77
207#define SAA7134_BOARD_ASUSTeK_P7131_DUAL 78
208#define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS 79
209#define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
210#define SAA7134_BOARD_PHILIPS_TIGER 81
190 211
191#define SAA7134_MAXBOARDS 8 212#define SAA7134_MAXBOARDS 8
192#define SAA7134_INPUT_MAX 8 213#define SAA7134_INPUT_MAX 8
193 214
215/* ----------------------------------------------------------- */
216/* Since we support 2 remote types, lets tell them apart */
217
218#define SAA7134_REMOTE_GPIO 1
219#define SAA7134_REMOTE_I2C 2
220
221/* ----------------------------------------------------------- */
222/* Video Output Port Register Initialization Options */
223
224#define SET_T_CODE_POLARITY_NON_INVERTED (1 << 0)
225#define SET_CLOCK_NOT_DELAYED (1 << 1)
226#define SET_CLOCK_INVERTED (1 << 2)
227#define SET_VSYNC_OFF (1 << 3)
228
194struct saa7134_input { 229struct saa7134_input {
195 char *name; 230 char *name;
196 unsigned int vmux; 231 unsigned int vmux;
@@ -226,6 +261,7 @@ struct saa7134_board {
226 /* peripheral I/O */ 261 /* peripheral I/O */
227 enum saa7134_video_out video_out; 262 enum saa7134_video_out video_out;
228 enum saa7134_mpeg_type mpeg; 263 enum saa7134_mpeg_type mpeg;
264 unsigned int vid_port_opts;
229}; 265};
230 266
231#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name) 267#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
@@ -319,9 +355,9 @@ struct saa7134_fh {
319 struct saa7134_pgtable pt_vbi; 355 struct saa7134_pgtable pt_vbi;
320}; 356};
321 357
322/* oss dsp status */ 358/* dmasound dsp status */
323struct saa7134_oss { 359struct saa7134_dmasound {
324 struct semaphore lock; 360 struct semaphore lock;
325 int minor_mixer; 361 int minor_mixer;
326 int minor_dsp; 362 int minor_dsp;
327 unsigned int users_dsp; 363 unsigned int users_dsp;
@@ -347,6 +383,7 @@ struct saa7134_oss {
347 unsigned int dma_blk; 383 unsigned int dma_blk;
348 unsigned int read_offset; 384 unsigned int read_offset;
349 unsigned int read_count; 385 unsigned int read_count;
386 snd_pcm_substream_t *substream;
350}; 387};
351 388
352/* IR input */ 389/* IR input */
@@ -358,9 +395,9 @@ struct saa7134_ir {
358 u32 mask_keycode; 395 u32 mask_keycode;
359 u32 mask_keydown; 396 u32 mask_keydown;
360 u32 mask_keyup; 397 u32 mask_keyup;
361 int polling; 398 int polling;
362 u32 last_gpio; 399 u32 last_gpio;
363 struct timer_list timer; 400 struct timer_list timer;
364}; 401};
365 402
366/* ts/mpeg status */ 403/* ts/mpeg status */
@@ -383,8 +420,8 @@ struct saa7134_mpeg_ops {
383/* global device status */ 420/* global device status */
384struct saa7134_dev { 421struct saa7134_dev {
385 struct list_head devlist; 422 struct list_head devlist;
386 struct semaphore lock; 423 struct semaphore lock;
387 spinlock_t slock; 424 spinlock_t slock;
388#ifdef VIDIOC_G_PRIORITY 425#ifdef VIDIOC_G_PRIORITY
389 struct v4l2_prio_state prio; 426 struct v4l2_prio_state prio;
390#endif 427#endif
@@ -394,7 +431,7 @@ struct saa7134_dev {
394 struct video_device *video_dev; 431 struct video_device *video_dev;
395 struct video_device *radio_dev; 432 struct video_device *radio_dev;
396 struct video_device *vbi_dev; 433 struct video_device *vbi_dev;
397 struct saa7134_oss oss; 434 struct saa7134_dmasound dmasound;
398 435
399 /* infrared remote */ 436 /* infrared remote */
400 int has_remote; 437 int has_remote;
@@ -421,7 +458,7 @@ struct saa7134_dev {
421 /* i2c i/o */ 458 /* i2c i/o */
422 struct i2c_adapter i2c_adap; 459 struct i2c_adapter i2c_adap;
423 struct i2c_client i2c_client; 460 struct i2c_client i2c_client;
424 unsigned char eedata[64]; 461 unsigned char eedata[128];
425 462
426 /* video overlay */ 463 /* video overlay */
427 struct v4l2_framebuffer ovbuf; 464 struct v4l2_framebuffer ovbuf;
@@ -626,6 +663,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
626int saa7134_input_init1(struct saa7134_dev *dev); 663int saa7134_input_init1(struct saa7134_dev *dev);
627void saa7134_input_fini(struct saa7134_dev *dev); 664void saa7134_input_fini(struct saa7134_dev *dev);
628void saa7134_input_irq(struct saa7134_dev *dev); 665void saa7134_input_irq(struct saa7134_dev *dev);
666void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
629 667
630/* 668/*
631 * Local variables: 669 * Local variables:
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 255b6088ebf9..d32737dd2142 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -50,7 +50,6 @@
50 50
51#include "bttv.h" 51#include "bttv.h"
52#include <media/audiochip.h> 52#include <media/audiochip.h>
53#include <media/id.h>
54 53
55#ifndef VIDEO_AUDIO_BALANCE 54#ifndef VIDEO_AUDIO_BALANCE
56# define VIDEO_AUDIO_BALANCE 32 55# define VIDEO_AUDIO_BALANCE 32
@@ -310,9 +309,9 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
310 memset(t,0,sizeof *t); 309 memset(t,0,sizeof *t);
311 310
312 client = &t->c; 311 client = &t->c;
313 memcpy(client,&client_template,sizeof(struct i2c_client)); 312 memcpy(client,&client_template,sizeof(struct i2c_client));
314 client->adapter = adap; 313 client->adapter = adap;
315 client->addr = addr; 314 client->addr = addr;
316 i2c_set_clientdata(client, t); 315 i2c_set_clientdata(client, t);
317 316
318 do_tda7432_init(client); 317 do_tda7432_init(client);
@@ -472,7 +471,7 @@ static int tda7432_command(struct i2c_client *client,
472 } 471 }
473 } 472 }
474 473
475 t->muted=(va->flags & VIDEO_AUDIO_MUTE); 474 t->muted=(va->flags & VIDEO_AUDIO_MUTE);
476 if (t->muted) 475 if (t->muted)
477 { 476 {
478 /* Mute & update balance*/ 477 /* Mute & update balance*/
@@ -503,12 +502,12 @@ static int tda7432_command(struct i2c_client *client,
503 502
504static struct i2c_driver driver = { 503static struct i2c_driver driver = {
505 .owner = THIS_MODULE, 504 .owner = THIS_MODULE,
506 .name = "i2c tda7432 driver", 505 .name = "i2c tda7432 driver",
507 .id = I2C_DRIVERID_TDA7432, 506 .id = I2C_DRIVERID_TDA7432,
508 .flags = I2C_DF_NOTIFY, 507 .flags = I2C_DF_NOTIFY,
509 .attach_adapter = tda7432_probe, 508 .attach_adapter = tda7432_probe,
510 .detach_client = tda7432_detach, 509 .detach_client = tda7432_detach,
511 .command = tda7432_command, 510 .command = tda7432_command,
512}; 511};
513 512
514static struct i2c_client client_template = 513static struct i2c_client client_template =
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index c65f0c7680a2..b2dfe07e9f9d 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,172 +1,406 @@
1/* 1/*
2 * 2
3 * i2c tv tuner chip device driver 3 i2c tv tuner chip device driver
4 * controls the philips tda8290+75 tuner chip combo. 4 controls the philips tda8290+75 tuner chip combo.
5 */ 5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
6#include <linux/i2c.h> 21#include <linux/i2c.h>
7#include <linux/videodev.h> 22#include <linux/videodev.h>
8#include <linux/delay.h> 23#include <linux/delay.h>
9#include <media/tuner.h> 24#include <media/tuner.h>
10 25
11#define I2C_ADDR_TDA8290 0x4b
12#define I2C_ADDR_TDA8275 0x61
13
14/* ---------------------------------------------------------------------- */ 26/* ---------------------------------------------------------------------- */
15 27
16struct freq_entry { 28struct tda827x_data {
17 u16 freq; 29 u32 lomax;
18 u8 value; 30 u8 spd;
31 u8 bs;
32 u8 bp;
33 u8 cp;
34 u8 gc3;
35 u8 div1p5;
19}; 36};
20 37
21static struct freq_entry band_table[] = { 38 /* Note lomax entry is lo / 62500 */
22 { 0x2DF4, 0x1C }, 39
23 { 0x2574, 0x14 }, 40static struct tda827x_data tda827x_analog[] = {
24 { 0x22B4, 0x0C }, 41 { .lomax = 992, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 62 MHz */
25 { 0x20D4, 0x0B }, 42 { .lomax = 1056, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 66 MHz */
26 { 0x1E74, 0x3B }, 43 { .lomax = 1216, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 76 MHz */
27 { 0x1C34, 0x33 }, 44 { .lomax = 1344, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 84 MHz */
28 { 0x16F4, 0x5B }, 45 { .lomax = 1488, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 93 MHz */
29 { 0x1454, 0x53 }, 46 { .lomax = 1568, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 98 MHz */
30 { 0x12D4, 0x52 }, 47 { .lomax = 1744, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 109 MHz */
31 { 0x1034, 0x4A }, 48 { .lomax = 1968, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 123 MHz */
32 { 0x0EE4, 0x7A }, 49 { .lomax = 2128, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 133 MHz */
33 { 0x0D34, 0x72 }, 50 { .lomax = 2416, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 151 MHz */
34 { 0x0B54, 0x9A }, 51 { .lomax = 2464, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 154 MHz */
35 { 0x0914, 0x91 }, 52 { .lomax = 2896, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 181 MHz */
36 { 0x07F4, 0x89 }, 53 { .lomax = 2960, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 185 MHz */
37 { 0x0774, 0xB9 }, 54 { .lomax = 3472, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 217 MHz */
38 { 0x067B, 0xB1 }, 55 { .lomax = 3904, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 244 MHz */
39 { 0x0634, 0xD9 }, 56 { .lomax = 4240, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 265 MHz */
40 { 0x05A4, 0xD8 }, // FM radio 57 { .lomax = 4832, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 302 MHz */
41 { 0x0494, 0xD0 }, 58 { .lomax = 5184, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 324 MHz */
42 { 0x03BC, 0xC8 }, 59 { .lomax = 5920, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 370 MHz */
43 { 0x0394, 0xF8 }, // 57250000 Hz 60 { .lomax = 7264, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 454 MHz */
44 { 0x0000, 0xF0 }, // 0 61 { .lomax = 7888, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 493 MHz */
62 { .lomax = 8480, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 530 MHz */
63 { .lomax = 8864, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 554 MHz */
64 { .lomax = 9664, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 604 MHz */
65 { .lomax = 11088, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 696 MHz */
66 { .lomax = 11840, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 740 MHz */
67 { .lomax = 13120, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 820 MHz */
68 { .lomax = 13840, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 865 MHz */
69 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} /* End */
45}; 70};
46 71
47static struct freq_entry div_table[] = { 72static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
48 { 0x1C34, 3 }, 73{
49 { 0x0D34, 2 }, 74 unsigned char tuner_reg[8];
50 { 0x067B, 1 }, 75 unsigned char reg2[2];
51 { 0x0000, 0 }, 76 u32 N;
52}; 77 int i;
78 struct tuner *t = i2c_get_clientdata(c);
79 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};
53 80
54static struct freq_entry agc_table[] = { 81 if (t->mode == V4L2_TUNER_RADIO)
55 { 0x22B4, 0x8F }, 82 freq = freq / 1000;
56 { 0x0B54, 0x9F },
57 { 0x09A4, 0x8F },
58 { 0x0554, 0x9F },
59 { 0x0000, 0xBF },
60};
61 83
62static __u8 get_freq_entry( struct freq_entry* table, __u16 freq) 84 N = freq + ifc;
63{ 85 i = 0;
64 while(table->freq && table->freq > freq) 86 while (tda827x_analog[i].lomax < N) {
65 table++; 87 if(tda827x_analog[i + 1].lomax == 0)
66 return table->value; 88 break;
67} 89 i++;
90 }
91
92 N = N << tda827x_analog[i].spd;
93
94 tuner_reg[0] = 0;
95 tuner_reg[1] = (unsigned char)(N>>8);
96 tuner_reg[2] = (unsigned char) N;
97 tuner_reg[3] = 0x40;
98 tuner_reg[4] = 0x52 + (t->tda827x_lpsel << 5);
99 tuner_reg[5] = (tda827x_analog[i].spd << 6) + (tda827x_analog[i].div1p5 <<5) +
100 (tda827x_analog[i].bs <<3) + tda827x_analog[i].bp;
101 tuner_reg[6] = 0x8f + (tda827x_analog[i].gc3 << 4);
102 tuner_reg[7] = 0x8f;
103
104 msg.buf = tuner_reg;
105 msg.len = 8;
106 i2c_transfer(c->adapter, &msg, 1);
107
108 msg.buf= reg2;
109 msg.len = 2;
110 reg2[0] = 0x80;
111 reg2[1] = 0;
112 i2c_transfer(c->adapter, &msg, 1);
113
114 reg2[0] = 0x60;
115 reg2[1] = 0xbf;
116 i2c_transfer(c->adapter, &msg, 1);
117
118 reg2[0] = 0x30;
119 reg2[1] = tuner_reg[4] + 0x80;
120 i2c_transfer(c->adapter, &msg, 1);
121
122 msleep(1);
123 reg2[0] = 0x30;
124 reg2[1] = tuner_reg[4] + 4;
125 i2c_transfer(c->adapter, &msg, 1);
126
127 msleep(1);
128 reg2[0] = 0x30;
129 reg2[1] = tuner_reg[4];
130 i2c_transfer(c->adapter, &msg, 1);
68 131
69/* ---------------------------------------------------------------------- */ 132 msleep(550);
133 reg2[0] = 0x30;
134 reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_analog[i].cp ;
135 i2c_transfer(c->adapter, &msg, 1);
70 136
71static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 }; 137 reg2[0] = 0x60;
72static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 }; 138 reg2[1] = 0x3f;
73static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00, 139 i2c_transfer(c->adapter, &msg, 1);
74 0xfC, 0x04, 0xA3, 0x3F,
75 0x2A, 0x04, 0xFF, 0x00,
76 0x00, 0x40 };
77static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
78static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B };
79static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 };
80static unsigned char i2c_tda8290_standby[2] = { 0x00, 0x02 };
81static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 };
82static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 };
83static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 };
84static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF };
85static unsigned char i2c_cb1_D0[2] = { 0x30, 0xD0 };
86static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 };
87static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 };
88static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 };
89static unsigned char i2c_cb1_50[2] = { 0x30, 0x50 };
90static unsigned char i2c_agc2_7F[2] = { 0x60, 0x7F };
91static unsigned char i2c_agc3_08[2] = { 0x80, 0x08 };
92
93static struct i2c_msg i2c_msg_init[] = {
94 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_init_tda8275), i2c_init_tda8275 },
95 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
96 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_VS), i2c_set_VS },
97 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_GP01_CF), i2c_set_GP01_CF },
98};
99 140
100static struct i2c_msg i2c_msg_prolog[] = { 141 reg2[0] = 0x80;
101// { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_easy_mode), i2c_easy_mode }, 142 reg2[1] = 0x08; // Vsync en
102 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_off), i2c_gainset_off }, 143 i2c_transfer(c->adapter, &msg, 1);
103 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_reset), i2c_tda8290_reset }, 144}
104 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge },
105};
106 145
107static struct i2c_msg i2c_msg_config[] = { 146static void tda827x_agcf(struct i2c_client *c)
108// { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_set_freq), i2c_set_freq }, 147{
109 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_00), i2c_agc3_00 }, 148 struct tuner *t = i2c_get_clientdata(c);
110 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_BF), i2c_agc2_BF }, 149 unsigned char data[] = {0x80, 0x0c};
111 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D2), i2c_cb1_D2 }, 150 struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,
112 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_56), i2c_cb1_56 }, 151 .flags = 0, .len = 2};
113 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_52), i2c_cb1_52 }, 152 i2c_transfer(c->adapter, &msg, 1);
114}; 153}
115 154
116static struct i2c_msg i2c_msg_epilog[] = { 155/* ---------------------------------------------------------------------- */
117 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_50), i2c_cb1_50 }, 156
118 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_7F), i2c_agc2_7F }, 157struct tda827xa_data {
119 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_08), i2c_agc3_08 }, 158 u32 lomax;
120 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, 159 u8 svco;
121 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on }, 160 u8 spd;
161 u8 scr;
162 u8 sbs;
163 u8 gc3;
122}; 164};
123 165
124static struct i2c_msg i2c_msg_standby[] = { 166static struct tda827xa_data tda827xa_analog[] = {
125 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge }, 167 { .lomax = 910, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, /* 56.875 MHz */
126 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D0), i2c_cb1_D0 }, 168 { .lomax = 1076, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 67.25 MHz */
127 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, 169 { .lomax = 1300, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 81.25 MHz */
128 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_standby), i2c_tda8290_standby }, 170 { .lomax = 1560, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 97.5 MHz */
171 { .lomax = 1820, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, /* 113.75 MHz */
172 { .lomax = 2152, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 134.5 MHz */
173 { .lomax = 2464, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 154 MHz */
174 { .lomax = 2600, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 162.5 MHz */
175 { .lomax = 2928, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 183 MHz */
176 { .lomax = 3120, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, /* 195 MHz */
177 { .lomax = 3640, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3}, /* 227.5 MHz */
178 { .lomax = 4304, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3}, /* 269 MHz */
179 { .lomax = 5200, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, /* 325 MHz */
180 { .lomax = 6240, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 390 MHz */
181 { .lomax = 7280, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 455 MHz */
182 { .lomax = 8320, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 520 MHz */
183 { .lomax = 8608, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, /* 538 MHz */
184 { .lomax = 8864, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 554 MHz */
185 { .lomax = 9920, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 620 MHz */
186 { .lomax = 10400, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 650 MHz */
187 { .lomax = 11200, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 700 MHz */
188 { .lomax = 12480, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 780 MHz */
189 { .lomax = 13120, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 820 MHz */
190 { .lomax = 13920, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 870 MHz */
191 { .lomax = 14576, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, /* 911 MHz */
192 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */
129}; 193};
130 194
131static int tda8290_tune(struct i2c_client *c) 195static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
132{ 196{
197 unsigned char tuner_reg[14];
198 unsigned char reg2[2];
199 u32 N;
200 int i;
133 struct tuner *t = i2c_get_clientdata(c); 201 struct tuner *t = i2c_get_clientdata(c);
134 struct i2c_msg easy_mode = 202 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};
135 { I2C_ADDR_TDA8290, 0, 2, t->i2c_easy_mode };
136 struct i2c_msg set_freq =
137 { I2C_ADDR_TDA8275, 0, 8, t->i2c_set_freq };
138 203
139 i2c_transfer(c->adapter, &easy_mode, 1); 204 if (t->mode == V4L2_TUNER_RADIO)
140 i2c_transfer(c->adapter, i2c_msg_prolog, ARRAY_SIZE(i2c_msg_prolog)); 205 freq = freq / 1000;
141 206
142 i2c_transfer(c->adapter, &set_freq, 1); 207 N = freq + ifc;
143 i2c_transfer(c->adapter, i2c_msg_config, ARRAY_SIZE(i2c_msg_config)); 208 i = 0;
209 while (tda827xa_analog[i].lomax < N) {
210 if(tda827xa_analog[i + 1].lomax == 0)
211 break;
212 i++;
213 }
214
215 N = N << tda827xa_analog[i].spd;
216
217 tuner_reg[0] = 0;
218 tuner_reg[1] = (unsigned char)(N>>8);
219 tuner_reg[2] = (unsigned char) N;
220 tuner_reg[3] = 0;
221 tuner_reg[4] = 0x16;
222 tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) +
223 tda827xa_analog[i].sbs;
224 tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
225 tuner_reg[7] = 0x0c;
226 tuner_reg[8] = 4;
227 tuner_reg[9] = 0x20;
228 tuner_reg[10] = 0xff;
229 tuner_reg[11] = 0xe0;
230 tuner_reg[12] = 0;
231 tuner_reg[13] = 0x39 + (t->tda827x_lpsel << 1);
232
233 msg.buf = tuner_reg;
234 msg.len = 14;
235 i2c_transfer(c->adapter, &msg, 1);
236
237 msg.buf= reg2;
238 msg.len = 2;
239 reg2[0] = 0x60;
240 reg2[1] = 0x3c;
241 i2c_transfer(c->adapter, &msg, 1);
242
243 reg2[0] = 0xa0;
244 reg2[1] = 0xc0;
245 i2c_transfer(c->adapter, &msg, 1);
246
247 msleep(2);
248 reg2[0] = 0x30;
249 reg2[1] = 0x10 + tda827xa_analog[i].scr;
250 i2c_transfer(c->adapter, &msg, 1);
144 251
145 msleep(550); 252 msleep(550);
146 i2c_transfer(c->adapter, i2c_msg_epilog, ARRAY_SIZE(i2c_msg_epilog)); 253 reg2[0] = 0x50;
147 return 0; 254 reg2[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
255 i2c_transfer(c->adapter, &msg, 1);
256
257 reg2[0] = 0x80;
258 reg2[1] = 0x28;
259 i2c_transfer(c->adapter, &msg, 1);
260
261 reg2[0] = 0xb0;
262 reg2[1] = 0x01;
263 i2c_transfer(c->adapter, &msg, 1);
264
265 reg2[0] = 0xc0;
266 reg2[1] = 0x19 + (t->tda827x_lpsel << 1);
267 i2c_transfer(c->adapter, &msg, 1);
148} 268}
149 269
150static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq) 270static void tda827xa_agcf(struct i2c_client *c)
151{ 271{
152 u32 N; 272 struct tuner *t = i2c_get_clientdata(c);
273 unsigned char data[] = {0x80, 0x2c};
274 struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,
275 .flags = 0, .len = 2};
276 i2c_transfer(c->adapter, &msg, 1);
277}
153 278
154 if (t->mode == V4L2_TUNER_RADIO) 279/*---------------------------------------------------------------------*/
155 freq = freq / 1000;
156 280
157 N = (((freq<<3)+ifc)&0x3fffc); 281static void tda8290_i2c_bridge(struct i2c_client *c, int close)
158 282{
159 N = N >> get_freq_entry(div_table, freq); 283 unsigned char enable[2] = { 0x21, 0xC0 };
160 t->i2c_set_freq[0] = 0; 284 unsigned char disable[2] = { 0x21, 0x80 };
161 t->i2c_set_freq[1] = (unsigned char)(N>>8); 285 unsigned char *msg;
162 t->i2c_set_freq[2] = (unsigned char) N; 286 if(close) {
163 t->i2c_set_freq[3] = 0x40; 287 msg = enable;
164 t->i2c_set_freq[4] = 0x52; 288 i2c_master_send(c, msg, 2);
165 t->i2c_set_freq[5] = get_freq_entry(band_table, freq); 289 /* let the bridge stabilize */
166 t->i2c_set_freq[6] = get_freq_entry(agc_table, freq); 290 msleep(20);
167 t->i2c_set_freq[7] = 0x8f; 291 } else {
292 msg = disable;
293 i2c_master_send(c, msg, 2);
294 }
168} 295}
169 296
297/*---------------------------------------------------------------------*/
298
299static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
300{
301 struct tuner *t = i2c_get_clientdata(c);
302 unsigned char soft_reset[] = { 0x00, 0x00 };
303 unsigned char easy_mode[] = { 0x01, t->tda8290_easy_mode };
304 unsigned char expert_mode[] = { 0x01, 0x80 };
305 unsigned char gainset_off[] = { 0x28, 0x14 };
306 unsigned char if_agc_spd[] = { 0x0f, 0x88 };
307 unsigned char adc_head_6[] = { 0x05, 0x04 };
308 unsigned char adc_head_9[] = { 0x05, 0x02 };
309 unsigned char adc_head_12[] = { 0x05, 0x01 };
310 unsigned char pll_bw_nom[] = { 0x0d, 0x47 };
311 unsigned char pll_bw_low[] = { 0x0d, 0x27 };
312 unsigned char gainset_2[] = { 0x28, 0x64 };
313 unsigned char agc_rst_on[] = { 0x0e, 0x0b };
314 unsigned char agc_rst_off[] = { 0x0e, 0x09 };
315 unsigned char if_agc_set[] = { 0x0f, 0x81 };
316 unsigned char addr_adc_sat = 0x1a;
317 unsigned char addr_agc_stat = 0x1d;
318 unsigned char addr_pll_stat = 0x1b;
319 unsigned char adc_sat, agc_stat,
320 pll_stat;
321
322 i2c_master_send(c, easy_mode, 2);
323 i2c_master_send(c, soft_reset, 2);
324 msleep(1);
325
326 expert_mode[1] = t->tda8290_easy_mode + 0x80;
327 i2c_master_send(c, expert_mode, 2);
328 i2c_master_send(c, gainset_off, 2);
329 i2c_master_send(c, if_agc_spd, 2);
330 if (t->tda8290_easy_mode & 0x60)
331 i2c_master_send(c, adc_head_9, 2);
332 else
333 i2c_master_send(c, adc_head_6, 2);
334 i2c_master_send(c, pll_bw_nom, 2);
335
336 tda8290_i2c_bridge(c, 1);
337 if (t->tda827x_ver != 0)
338 tda827xa_tune(c, ifc, freq);
339 else
340 tda827x_tune(c, ifc, freq);
341 /* adjust headroom resp. gain */
342 i2c_master_send(c, &addr_adc_sat, 1);
343 i2c_master_recv(c, &adc_sat, 1);
344 i2c_master_send(c, &addr_agc_stat, 1);
345 i2c_master_recv(c, &agc_stat, 1);
346 i2c_master_send(c, &addr_pll_stat, 1);
347 i2c_master_recv(c, &pll_stat, 1);
348 if (pll_stat & 0x80)
349 tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
350 else
351 tuner_dbg("tda8290 not locked, no signal?\n");
352 if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
353 tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
354 agc_stat, adc_sat, pll_stat & 0x80);
355 i2c_master_send(c, gainset_2, 2);
356 msleep(100);
357 i2c_master_send(c, &addr_agc_stat, 1);
358 i2c_master_recv(c, &agc_stat, 1);
359 i2c_master_send(c, &addr_pll_stat, 1);
360 i2c_master_recv(c, &pll_stat, 1);
361 if ((agc_stat > 115) || !(pll_stat & 0x80)) {
362 tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
363 agc_stat, pll_stat & 0x80);
364 if (t->tda827x_ver != 0)
365 tda827xa_agcf(c);
366 else
367 tda827x_agcf(c);
368 msleep(100);
369 i2c_master_send(c, &addr_agc_stat, 1);
370 i2c_master_recv(c, &agc_stat, 1);
371 i2c_master_send(c, &addr_pll_stat, 1);
372 i2c_master_recv(c, &pll_stat, 1);
373 if((agc_stat > 115) || !(pll_stat & 0x80)) {
374 tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
375 i2c_master_send(c, adc_head_12, 2);
376 i2c_master_send(c, pll_bw_low, 2);
377 msleep(100);
378 }
379 }
380 }
381
382 /* l/ l' deadlock? */
383 if(t->tda8290_easy_mode & 0x60) {
384 i2c_master_send(c, &addr_adc_sat, 1);
385 i2c_master_recv(c, &adc_sat, 1);
386 i2c_master_send(c, &addr_pll_stat, 1);
387 i2c_master_recv(c, &pll_stat, 1);
388 if ((adc_sat > 20) || !(pll_stat & 0x80)) {
389 tuner_dbg("trying to resolve SECAM L deadlock\n");
390 i2c_master_send(c, agc_rst_on, 2);
391 msleep(40);
392 i2c_master_send(c, agc_rst_off, 2);
393 }
394 }
395
396 tda8290_i2c_bridge(c, 0);
397 i2c_master_send(c, if_agc_set, 2);
398 return 0;
399}
400
401
402/*---------------------------------------------------------------------*/
403
170#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) 404#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
171#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) 405#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
172#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) 406#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
@@ -174,20 +408,37 @@ static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq)
174 408
175static void set_audio(struct tuner *t) 409static void set_audio(struct tuner *t)
176{ 410{
177 t->i2c_easy_mode[0] = 0x01; 411 char* mode;
178 412
179 if (t->std & V4L2_STD_MN) 413 t->tda827x_lpsel = 0;
180 t->i2c_easy_mode[1] = 0x01; 414 mode = "xx";
181 else if (t->std & V4L2_STD_B) 415 if (t->std & V4L2_STD_MN) {
182 t->i2c_easy_mode[1] = 0x02; 416 t->sgIF = 92;
183 else if (t->std & V4L2_STD_GH) 417 t->tda8290_easy_mode = 0x01;
184 t->i2c_easy_mode[1] = 0x04; 418 t->tda827x_lpsel = 1;
185 else if (t->std & V4L2_STD_PAL_I) 419 mode = "MN";
186 t->i2c_easy_mode[1] = 0x08; 420 } else if (t->std & V4L2_STD_B) {
187 else if (t->std & V4L2_STD_DK) 421 t->sgIF = 108;
188 t->i2c_easy_mode[1] = 0x10; 422 t->tda8290_easy_mode = 0x02;
189 else if (t->std & V4L2_STD_SECAM_L) 423 mode = "B";
190 t->i2c_easy_mode[1] = 0x20; 424 } else if (t->std & V4L2_STD_GH) {
425 t->sgIF = 124;
426 t->tda8290_easy_mode = 0x04;
427 mode = "GH";
428 } else if (t->std & V4L2_STD_PAL_I) {
429 t->sgIF = 124;
430 t->tda8290_easy_mode = 0x08;
431 mode = "I";
432 } else if (t->std & V4L2_STD_DK) {
433 t->sgIF = 124;
434 t->tda8290_easy_mode = 0x10;
435 mode = "DK";
436 } else if (t->std & V4L2_STD_SECAM_L) {
437 t->sgIF = 124;
438 t->tda8290_easy_mode = 0x20;
439 mode = "L";
440 }
441 tuner_dbg("setting tda8290 to system %s\n", mode);
191} 442}
192 443
193static void set_tv_freq(struct i2c_client *c, unsigned int freq) 444static void set_tv_freq(struct i2c_client *c, unsigned int freq)
@@ -195,15 +446,13 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
195 struct tuner *t = i2c_get_clientdata(c); 446 struct tuner *t = i2c_get_clientdata(c);
196 447
197 set_audio(t); 448 set_audio(t);
198 set_frequency(t, 864, freq); 449 tda8290_tune(c, t->sgIF, freq);
199 tda8290_tune(c);
200} 450}
201 451
202static void set_radio_freq(struct i2c_client *c, unsigned int freq) 452static void set_radio_freq(struct i2c_client *c, unsigned int freq)
203{ 453{
204 struct tuner *t = i2c_get_clientdata(c); 454 /* if frequency is 5.5 MHz */
205 set_frequency(t, 704, freq); 455 tda8290_tune(c, 88, freq);
206 tda8290_tune(c);
207} 456}
208 457
209static int has_signal(struct i2c_client *c) 458static int has_signal(struct i2c_client *c)
@@ -216,27 +465,145 @@ static int has_signal(struct i2c_client *c)
216 return (afc & 0x80)? 65535:0; 465 return (afc & 0x80)? 65535:0;
217} 466}
218 467
468/*---------------------------------------------------------------------*/
469
219static void standby(struct i2c_client *c) 470static void standby(struct i2c_client *c)
220{ 471{
221 i2c_transfer(c->adapter, i2c_msg_standby, ARRAY_SIZE(i2c_msg_standby)); 472 struct tuner *t = i2c_get_clientdata(c);
473 unsigned char cb1[] = { 0x30, 0xD0 };
474 unsigned char tda8290_standby[] = { 0x00, 0x02 };
475 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
476
477 tda8290_i2c_bridge(c, 1);
478 if (t->tda827x_ver != 0)
479 cb1[1] = 0x90;
480 i2c_transfer(c->adapter, &msg, 1);
481 tda8290_i2c_bridge(c, 0);
482 i2c_master_send(c, tda8290_standby, 2);
222} 483}
223 484
224int tda8290_init(struct i2c_client *c) 485
486static void tda8290_init_if(struct i2c_client *c)
487{
488 unsigned char set_VS[] = { 0x30, 0x6F };
489 unsigned char set_GP01_CF[] = { 0x20, 0x0B };
490
491 i2c_master_send(c, set_VS, 2);
492 i2c_master_send(c, set_GP01_CF, 2);
493}
494
495static void tda8290_init_tuner(struct i2c_client *c)
225{ 496{
226 struct tuner *t = i2c_get_clientdata(c); 497 struct tuner *t = i2c_get_clientdata(c);
498 unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
499 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
500 unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
501 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
502 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0,
503 .buf=tda8275_init, .len = 14};
504 if (t->tda827x_ver != 0)
505 msg.buf = tda8275a_init;
506
507 tda8290_i2c_bridge(c, 1);
508 i2c_transfer(c->adapter, &msg, 1);
509 tda8290_i2c_bridge(c, 0);
510}
227 511
228 strlcpy(c->name, "tda8290+75", sizeof(c->name)); 512/*---------------------------------------------------------------------*/
513
514int tda8290_init(struct i2c_client *c)
515{
516 struct tuner *t = i2c_get_clientdata(c);
517 u8 data;
518 int i, ret, tuners_found;
519 u32 tuner_addrs;
520 struct i2c_msg msg = {.flags=I2C_M_RD, .buf=&data, .len = 1};
521
522 tda8290_i2c_bridge(c, 1);
523 /* probe for tuner chip */
524 tuners_found = 0;
525 tuner_addrs = 0;
526 for (i=0x60; i<= 0x63; i++) {
527 msg.addr = i;
528 ret = i2c_transfer(c->adapter, &msg, 1);
529 if (ret == 1) {
530 tuners_found++;
531 tuner_addrs = (tuner_addrs << 8) + i;
532 }
533 }
534 /* if there is more than one tuner, we expect the right one is
535 behind the bridge and we choose the highest address that doesn't
536 give a response now
537 */
538 tda8290_i2c_bridge(c, 0);
539 if(tuners_found > 1)
540 for (i = 0; i < tuners_found; i++) {
541 msg.addr = tuner_addrs & 0xff;
542 ret = i2c_transfer(c->adapter, &msg, 1);
543 if(ret == 1)
544 tuner_addrs = tuner_addrs >> 8;
545 else
546 break;
547 }
548 if (tuner_addrs == 0) {
549 tuner_addrs = 0x61;
550 tuner_info ("could not clearly identify tuner address, defaulting to %x\n",
551 tuner_addrs);
552 } else {
553 tuner_addrs = tuner_addrs & 0xff;
554 tuner_info ("setting tuner address to %x\n", tuner_addrs);
555 }
556 t->tda827x_addr = tuner_addrs;
557 msg.addr = tuner_addrs;
558
559 tda8290_i2c_bridge(c, 1);
560 ret = i2c_transfer(c->adapter, &msg, 1);
561 if( ret != 1)
562 tuner_warn ("TDA827x access failed!\n");
563 if ((data & 0x3c) == 0) {
564 strlcpy(c->name, "tda8290+75", sizeof(c->name));
565 t->tda827x_ver = 0;
566 } else {
567 strlcpy(c->name, "tda8290+75a", sizeof(c->name));
568 t->tda827x_ver = 2;
569 }
229 tuner_info("tuner: type set to %s\n", c->name); 570 tuner_info("tuner: type set to %s\n", c->name);
571
230 t->tv_freq = set_tv_freq; 572 t->tv_freq = set_tv_freq;
231 t->radio_freq = set_radio_freq; 573 t->radio_freq = set_radio_freq;
232 t->has_signal = has_signal; 574 t->has_signal = has_signal;
233 t->standby = standby; 575 t->standby = standby;
576 t->tda827x_lpsel = 0;
234 577
235 i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge)); 578 tda8290_init_tuner(c);
236 i2c_transfer(c->adapter, i2c_msg_init, ARRAY_SIZE(i2c_msg_init)); 579 tda8290_init_if(c);
237 return 0; 580 return 0;
238} 581}
239 582
583int tda8290_probe(struct i2c_client *c)
584{
585 unsigned char soft_reset[] = { 0x00, 0x00 };
586 unsigned char easy_mode_b[] = { 0x01, 0x02 };
587 unsigned char easy_mode_g[] = { 0x01, 0x04 };
588 unsigned char addr_dto_lsb = 0x07;
589 unsigned char data;
590
591 i2c_master_send(c, easy_mode_b, 2);
592 i2c_master_send(c, soft_reset, 2);
593 i2c_master_send(c, &addr_dto_lsb, 1);
594 i2c_master_recv(c, &data, 1);
595 if (data == 0) {
596 i2c_master_send(c, easy_mode_g, 2);
597 i2c_master_send(c, soft_reset, 2);
598 i2c_master_send(c, &addr_dto_lsb, 1);
599 i2c_master_recv(c, &data, 1);
600 if (data == 0x7b) {
601 return 0;
602 }
603 }
604 return -1;
605}
606
240/* 607/*
241 * Overrides for Emacs so that we follow Linus's tabbing style. 608 * Overrides for Emacs so that we follow Linus's tabbing style.
242 * --------------------------------------------------------------------------- 609 * ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 7e3dcdb262b0..a5e37dc91f39 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -32,7 +32,6 @@
32 32
33#include "bttv.h" 33#include "bttv.h"
34#include <media/audiochip.h> 34#include <media/audiochip.h>
35#include <media/id.h>
36 35
37static int debug; /* insmod parameter */ 36static int debug; /* insmod parameter */
38module_param(debug, int, S_IRUGO | S_IWUSR); 37module_param(debug, int, S_IRUGO | S_IWUSR);
@@ -126,20 +125,20 @@ static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char v
126 125
127static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg) 126static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg)
128{ 127{
129 unsigned char write[1]; 128 unsigned char write[1];
130 unsigned char read[1]; 129 unsigned char read[1];
131 struct i2c_msg msgs[2] = { 130 struct i2c_msg msgs[2] = {
132 { addr, 0, 1, write }, 131 { addr, 0, 1, write },
133 { addr, I2C_M_RD, 1, read } 132 { addr, I2C_M_RD, 1, read }
134 }; 133 };
135 write[0] = reg; 134 write[0] = reg;
136 135
137 if (2 != i2c_transfer(adap,msgs,2)) { 136 if (2 != i2c_transfer(adap,msgs,2)) {
138 printk(KERN_WARNING "tda9875: I/O error (read2)\n"); 137 printk(KERN_WARNING "tda9875: I/O error (read2)\n");
139 return -1; 138 return -1;
140 } 139 }
141 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]); 140 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]);
142 return read[0]; 141 return read[0];
143} 142}
144 143
145static void tda9875_set(struct i2c_client *client) 144static void tda9875_set(struct i2c_client *client)
@@ -184,7 +183,7 @@ static void do_tda9875_init(struct i2c_client *client)
184 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/ 183 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/
185 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/ 184 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/
186 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/ 185 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/
187 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */ 186 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */
188 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */ 187 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */
189 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */ 188 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */
190 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/ 189 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/
@@ -200,7 +199,7 @@ static void do_tda9875_init(struct i2c_client *client)
200 199
201 t->mode=AUDIO_UNMUTE; 200 t->mode=AUDIO_UNMUTE;
202 t->lvol=t->rvol =0; /* 0dB */ 201 t->lvol=t->rvol =0; /* 0dB */
203 t->bass=0; /* 0dB */ 202 t->bass=0; /* 0dB */
204 t->treble=0; /* 0dB */ 203 t->treble=0; /* 0dB */
205 tda9875_set(client); 204 tda9875_set(client);
206 205
@@ -239,9 +238,9 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind)
239 memset(t,0,sizeof *t); 238 memset(t,0,sizeof *t);
240 239
241 client = &t->c; 240 client = &t->c;
242 memcpy(client,&client_template,sizeof(struct i2c_client)); 241 memcpy(client,&client_template,sizeof(struct i2c_client));
243 client->adapter = adap; 242 client->adapter = adap;
244 client->addr = addr; 243 client->addr = addr;
245 i2c_set_clientdata(client, t); 244 i2c_set_clientdata(client, t);
246 245
247 if(!tda9875_checkit(adap,addr)) { 246 if(!tda9875_checkit(adap,addr)) {
@@ -287,7 +286,7 @@ static int tda9875_command(struct i2c_client *client,
287 dprintk("In tda9875_command...\n"); 286 dprintk("In tda9875_command...\n");
288 287
289 switch (cmd) { 288 switch (cmd) {
290 /* --- v4l ioctls --- */ 289 /* --- v4l ioctls --- */
291 /* take care: bttv does userspace copying, we'll get a 290 /* take care: bttv does userspace copying, we'll get a
292 kernel pointer here... */ 291 kernel pointer here... */
293 case VIDIOCGAUDIO: 292 case VIDIOCGAUDIO:
@@ -355,7 +354,7 @@ static int tda9875_command(struct i2c_client *client,
355//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble); 354//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble);
356 355
357 356
358 tda9875_set(client); 357 tda9875_set(client);
359 358
360 break; 359 break;
361 360
@@ -374,18 +373,18 @@ static int tda9875_command(struct i2c_client *client,
374 373
375static struct i2c_driver driver = { 374static struct i2c_driver driver = {
376 .owner = THIS_MODULE, 375 .owner = THIS_MODULE,
377 .name = "i2c tda9875 driver", 376 .name = "i2c tda9875 driver",
378 .id = I2C_DRIVERID_TDA9875, 377 .id = I2C_DRIVERID_TDA9875,
379 .flags = I2C_DF_NOTIFY, 378 .flags = I2C_DF_NOTIFY,
380 .attach_adapter = tda9875_probe, 379 .attach_adapter = tda9875_probe,
381 .detach_client = tda9875_detach, 380 .detach_client = tda9875_detach,
382 .command = tda9875_command, 381 .command = tda9875_command,
383}; 382};
384 383
385static struct i2c_client client_template = 384static struct i2c_client client_template =
386{ 385{
387 .name = "tda9875", 386 .name = "tda9875",
388 .driver = &driver, 387 .driver = &driver,
389}; 388};
390 389
391static int __init tda9875_init(void) 390static int __init tda9875_init(void)
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 94053f149ddf..4249127c0a1d 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -11,7 +11,6 @@
11 11
12#include <media/audiochip.h> 12#include <media/audiochip.h>
13#include <media/tuner.h> 13#include <media/tuner.h>
14#include <media/id.h>
15 14
16/* Chips: 15/* Chips:
17 TDA9885 (PAL, NTSC) 16 TDA9885 (PAL, NTSC)
@@ -44,8 +43,13 @@ MODULE_LICENSE("GPL");
44/* ---------------------------------------------------------------------- */ 43/* ---------------------------------------------------------------------- */
45 44
46#define UNSET (-1U) 45#define UNSET (-1U)
47#define PREFIX "tda9885/6/7: " 46#define tda9887_info(fmt, arg...) do {\
48#define dprintk if (debug) printk 47 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
48 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
49#define tda9887_dbg(fmt, arg...) do {\
50 if (debug) \
51 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
52 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
49 53
50struct tda9887 { 54struct tda9887 {
51 struct i2c_client client; 55 struct i2c_client client;
@@ -55,6 +59,7 @@ struct tda9887 {
55 unsigned int pinnacle_id; 59 unsigned int pinnacle_id;
56 unsigned int using_v4l2; 60 unsigned int using_v4l2;
57 unsigned int radio_mode; 61 unsigned int radio_mode;
62 unsigned char data[4];
58}; 63};
59 64
60struct tvnorm { 65struct tvnorm {
@@ -180,7 +185,8 @@ static struct tvnorm tvnorms[] = {
180 .name = "SECAM-L", 185 .name = "SECAM-L",
181 .b = ( cPositiveAmTV | 186 .b = ( cPositiveAmTV |
182 cQSS ), 187 cQSS ),
183 .e = ( cAudioIF_6_5 | 188 .e = ( cGating_36 |
189 cAudioIF_6_5 |
184 cVideoIF_38_90 ), 190 cVideoIF_38_90 ),
185 },{ 191 },{
186 .std = V4L2_STD_SECAM_DK, 192 .std = V4L2_STD_SECAM_DK,
@@ -236,7 +242,7 @@ static struct tvnorm radio_mono = {
236 242
237/* ---------------------------------------------------------------------- */ 243/* ---------------------------------------------------------------------- */
238 244
239static void dump_read_message(unsigned char *buf) 245static void dump_read_message(struct tda9887 *t, unsigned char *buf)
240{ 246{
241 static char *afc[16] = { 247 static char *afc[16] = {
242 "- 12.5 kHz", 248 "- 12.5 kHz",
@@ -256,15 +262,15 @@ static void dump_read_message(unsigned char *buf)
256 "+ 37.5 kHz", 262 "+ 37.5 kHz",
257 "+ 12.5 kHz", 263 "+ 12.5 kHz",
258 }; 264 };
259 printk(PREFIX "read: 0x%2x\n", buf[0]); 265 tda9887_info("read: 0x%2x\n", buf[0]);
260 printk(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no"); 266 tda9887_info(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
261 printk(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]); 267 tda9887_info(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
262 printk(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low"); 268 tda9887_info(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
263 printk(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out"); 269 tda9887_info(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
264 printk(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); 270 tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
265} 271}
266 272
267static void dump_write_message(unsigned char *buf) 273static void dump_write_message(struct tda9887 *t, unsigned char *buf)
268{ 274{
269 static char *sound[4] = { 275 static char *sound[4] = {
270 "AM/TV", 276 "AM/TV",
@@ -304,58 +310,58 @@ static void dump_write_message(unsigned char *buf)
304 "44 MHz", 310 "44 MHz",
305 }; 311 };
306 312
307 printk(PREFIX "write: byte B 0x%02x\n",buf[1]); 313 tda9887_info("write: byte B 0x%02x\n",buf[1]);
308 printk(" B0 video mode : %s\n", 314 tda9887_info(" B0 video mode : %s\n",
309 (buf[1] & 0x01) ? "video trap" : "sound trap"); 315 (buf[1] & 0x01) ? "video trap" : "sound trap");
310 printk(" B1 auto mute fm : %s\n", 316 tda9887_info(" B1 auto mute fm : %s\n",
311 (buf[1] & 0x02) ? "yes" : "no"); 317 (buf[1] & 0x02) ? "yes" : "no");
312 printk(" B2 carrier mode : %s\n", 318 tda9887_info(" B2 carrier mode : %s\n",
313 (buf[1] & 0x04) ? "QSS" : "Intercarrier"); 319 (buf[1] & 0x04) ? "QSS" : "Intercarrier");
314 printk(" B3-4 tv sound/radio : %s\n", 320 tda9887_info(" B3-4 tv sound/radio : %s\n",
315 sound[(buf[1] & 0x18) >> 3]); 321 sound[(buf[1] & 0x18) >> 3]);
316 printk(" B5 force mute audio: %s\n", 322 tda9887_info(" B5 force mute audio: %s\n",
317 (buf[1] & 0x20) ? "yes" : "no"); 323 (buf[1] & 0x20) ? "yes" : "no");
318 printk(" B6 output port 1 : %s\n", 324 tda9887_info(" B6 output port 1 : %s\n",
319 (buf[1] & 0x40) ? "high (inactive)" : "low (active)"); 325 (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
320 printk(" B7 output port 2 : %s\n", 326 tda9887_info(" B7 output port 2 : %s\n",
321 (buf[1] & 0x80) ? "high (inactive)" : "low (active)"); 327 (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
322 328
323 printk(PREFIX "write: byte C 0x%02x\n",buf[2]); 329 tda9887_info("write: byte C 0x%02x\n",buf[2]);
324 printk(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]); 330 tda9887_info(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]);
325 printk(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]); 331 tda9887_info(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]);
326 printk(" C7 audio gain : %s\n", 332 tda9887_info(" C7 audio gain : %s\n",
327 (buf[2] & 0x80) ? "-6" : "0"); 333 (buf[2] & 0x80) ? "-6" : "0");
328 334
329 printk(PREFIX "write: byte E 0x%02x\n",buf[3]); 335 tda9887_info("write: byte E 0x%02x\n",buf[3]);
330 printk(" E0-1 sound carrier : %s\n", 336 tda9887_info(" E0-1 sound carrier : %s\n",
331 carrier[(buf[3] & 0x03)]); 337 carrier[(buf[3] & 0x03)]);
332 printk(" E6 l pll ganting : %s\n", 338 tda9887_info(" E6 l pll gating : %s\n",
333 (buf[3] & 0x40) ? "36" : "13"); 339 (buf[3] & 0x40) ? "36" : "13");
334 340
335 if (buf[1] & 0x08) { 341 if (buf[1] & 0x08) {
336 /* radio */ 342 /* radio */
337 printk(" E2-4 video if : %s\n", 343 tda9887_info(" E2-4 video if : %s\n",
338 rif[(buf[3] & 0x0c) >> 2]); 344 rif[(buf[3] & 0x0c) >> 2]);
339 printk(" E7 vif agc output : %s\n", 345 tda9887_info(" E7 vif agc output : %s\n",
340 (buf[3] & 0x80) 346 (buf[3] & 0x80)
341 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio") 347 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
342 : "fm radio carrier afc"); 348 : "fm radio carrier afc");
343 } else { 349 } else {
344 /* video */ 350 /* video */
345 printk(" E2-4 video if : %s\n", 351 tda9887_info(" E2-4 video if : %s\n",
346 vif[(buf[3] & 0x1c) >> 2]); 352 vif[(buf[3] & 0x1c) >> 2]);
347 printk(" E5 tuner gain : %s\n", 353 tda9887_info(" E5 tuner gain : %s\n",
348 (buf[3] & 0x80) 354 (buf[3] & 0x80)
349 ? ((buf[3] & 0x20) ? "external" : "normal") 355 ? ((buf[3] & 0x20) ? "external" : "normal")
350 : ((buf[3] & 0x20) ? "minimum" : "normal")); 356 : ((buf[3] & 0x20) ? "minimum" : "normal"));
351 printk(" E7 vif agc output : %s\n", 357 tda9887_info(" E7 vif agc output : %s\n",
352 (buf[3] & 0x80) 358 (buf[3] & 0x80)
353 ? ((buf[3] & 0x20) 359 ? ((buf[3] & 0x20)
354 ? "pin3 port, pin22 vif agc out" 360 ? "pin3 port, pin22 vif agc out"
355 : "pin22 port, pin3 vif acg ext in") 361 : "pin22 port, pin3 vif acg ext in")
356 : "pin3+pin22 port"); 362 : "pin3+pin22 port");
357 } 363 }
358 printk("--\n"); 364 tda9887_info("--\n");
359} 365}
360 366
361/* ---------------------------------------------------------------------- */ 367/* ---------------------------------------------------------------------- */
@@ -379,11 +385,11 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
379 } 385 }
380 } 386 }
381 if (NULL == norm) { 387 if (NULL == norm) {
382 dprintk(PREFIX "Unsupported tvnorm entry - audio muted\n"); 388 tda9887_dbg("Unsupported tvnorm entry - audio muted\n");
383 return -1; 389 return -1;
384 } 390 }
385 391
386 dprintk(PREFIX "configure for: %s\n",norm->name); 392 tda9887_dbg("configure for: %s\n",norm->name);
387 buf[1] = norm->b; 393 buf[1] = norm->b;
388 buf[2] = norm->c; 394 buf[2] = norm->c;
389 buf[3] = norm->e; 395 buf[3] = norm->e;
@@ -458,6 +464,8 @@ static int tda9887_set_config(struct tda9887 *t, char *buf)
458 break; 464 break;
459 } 465 }
460 } 466 }
467 if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
468 buf[1] &= ~cQSS;
461 return 0; 469 return 0;
462} 470}
463 471
@@ -475,11 +483,11 @@ static int tda9887_set_pinnacle(struct tda9887 *t, char *buf)
475 } 483 }
476 } 484 }
477 if (t->std & V4L2_STD_525_60) { 485 if (t->std & V4L2_STD_525_60) {
478 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) { 486 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
479 bCarrierMode = cIntercarrier; 487 bCarrierMode = cIntercarrier;
480 } else { 488 } else {
481 bCarrierMode = cQSS; 489 bCarrierMode = cQSS;
482 } 490 }
483 } 491 }
484 492
485 if (bCarrierMode != UNSET) { 493 if (bCarrierMode != UNSET) {
@@ -505,26 +513,26 @@ static int tda9887_fixup_std(struct tda9887 *t)
505 case 'B': 513 case 'B':
506 case 'g': 514 case 'g':
507 case 'G': 515 case 'G':
508 dprintk(PREFIX "insmod fixup: PAL => PAL-BG\n"); 516 tda9887_dbg("insmod fixup: PAL => PAL-BG\n");
509 t->std = V4L2_STD_PAL_BG; 517 t->std = V4L2_STD_PAL_BG;
510 break; 518 break;
511 case 'i': 519 case 'i':
512 case 'I': 520 case 'I':
513 dprintk(PREFIX "insmod fixup: PAL => PAL-I\n"); 521 tda9887_dbg("insmod fixup: PAL => PAL-I\n");
514 t->std = V4L2_STD_PAL_I; 522 t->std = V4L2_STD_PAL_I;
515 break; 523 break;
516 case 'd': 524 case 'd':
517 case 'D': 525 case 'D':
518 case 'k': 526 case 'k':
519 case 'K': 527 case 'K':
520 dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n"); 528 tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
521 t->std = V4L2_STD_PAL_DK; 529 t->std = V4L2_STD_PAL_DK;
522 break; 530 break;
523 case '-': 531 case '-':
524 /* default parameter, do nothing */ 532 /* default parameter, do nothing */
525 break; 533 break;
526 default: 534 default:
527 printk(PREFIX "pal= argument not recognised\n"); 535 tda9887_info("pal= argument not recognised\n");
528 break; 536 break;
529 } 537 }
530 } 538 }
@@ -534,19 +542,19 @@ static int tda9887_fixup_std(struct tda9887 *t)
534 case 'D': 542 case 'D':
535 case 'k': 543 case 'k':
536 case 'K': 544 case 'K':
537 dprintk(PREFIX "insmod fixup: SECAM => SECAM-DK\n"); 545 tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n");
538 t->std = V4L2_STD_SECAM_DK; 546 t->std = V4L2_STD_SECAM_DK;
539 break; 547 break;
540 case 'l': 548 case 'l':
541 case 'L': 549 case 'L':
542 dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n"); 550 tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");
543 t->std = V4L2_STD_SECAM_L; 551 t->std = V4L2_STD_SECAM_L;
544 break; 552 break;
545 case '-': 553 case '-':
546 /* default parameter, do nothing */ 554 /* default parameter, do nothing */
547 break; 555 break;
548 default: 556 default:
549 printk(PREFIX "secam= argument not recognised\n"); 557 tda9887_info("secam= argument not recognised\n");
550 break; 558 break;
551 } 559 }
552 } 560 }
@@ -559,41 +567,40 @@ static int tda9887_status(struct tda9887 *t)
559 int rc; 567 int rc;
560 568
561 memset(buf,0,sizeof(buf)); 569 memset(buf,0,sizeof(buf));
562 if (1 != (rc = i2c_master_recv(&t->client,buf,1))) 570 if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
563 printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc); 571 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
564 dump_read_message(buf); 572 dump_read_message(t, buf);
565 return 0; 573 return 0;
566} 574}
567 575
568static int tda9887_configure(struct tda9887 *t) 576static int tda9887_configure(struct tda9887 *t)
569{ 577{
570 unsigned char buf[4];
571 int rc; 578 int rc;
572 579
573 memset(buf,0,sizeof(buf)); 580 memset(t->data,0,sizeof(t->data));
574 tda9887_set_tvnorm(t,buf); 581 tda9887_set_tvnorm(t,t->data);
575 582
576 buf[1] |= cOutputPort1Inactive; 583 t->data[1] |= cOutputPort1Inactive;
577 buf[1] |= cOutputPort2Inactive; 584 t->data[1] |= cOutputPort2Inactive;
578 585
579 if (UNSET != t->pinnacle_id) { 586 if (UNSET != t->pinnacle_id) {
580 tda9887_set_pinnacle(t,buf); 587 tda9887_set_pinnacle(t,t->data);
581 } 588 }
582 tda9887_set_config(t,buf); 589 tda9887_set_config(t,t->data);
583 tda9887_set_insmod(t,buf); 590 tda9887_set_insmod(t,t->data);
584 591
585 if (t->mode == T_STANDBY) { 592 if (t->mode == T_STANDBY) {
586 buf[1] |= cForcedMuteAudioON; 593 t->data[1] |= cForcedMuteAudioON;
587 } 594 }
588 595
589 596
590 dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n", 597 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
591 buf[1],buf[2],buf[3]); 598 t->data[1],t->data[2],t->data[3]);
592 if (debug > 1) 599 if (debug > 1)
593 dump_write_message(buf); 600 dump_write_message(t, t->data);
594 601
595 if (4 != (rc = i2c_master_send(&t->client,buf,4))) 602 if (4 != (rc = i2c_master_send(&t->client,t->data,4)))
596 printk(PREFIX "i2c i/o error: rc == %d (should be 4)\n",rc); 603 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
597 604
598 if (debug > 2) { 605 if (debug > 2) {
599 msleep_interruptible(1000); 606 msleep_interruptible(1000);
@@ -608,13 +615,11 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
608{ 615{
609 struct tda9887 *t; 616 struct tda9887 *t;
610 617
611 client_template.adapter = adap; 618 client_template.adapter = adap;
612 client_template.addr = addr; 619 client_template.addr = addr;
613
614 printk(PREFIX "chip found @ 0x%x\n", addr<<1);
615 620
616 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) 621 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
617 return -ENOMEM; 622 return -ENOMEM;
618 memset(t,0,sizeof(*t)); 623 memset(t,0,sizeof(*t));
619 624
620 t->client = client_template; 625 t->client = client_template;
@@ -622,6 +627,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
622 t->pinnacle_id = UNSET; 627 t->pinnacle_id = UNSET;
623 t->radio_mode = V4L2_TUNER_MODE_STEREO; 628 t->radio_mode = V4L2_TUNER_MODE_STEREO;
624 629
630 tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
631
625 i2c_set_clientdata(&t->client, t); 632 i2c_set_clientdata(&t->client, t);
626 i2c_attach_client(&t->client); 633 i2c_attach_client(&t->client);
627 634
@@ -655,18 +662,18 @@ static int tda9887_detach(struct i2c_client *client)
655} 662}
656 663
657#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ 664#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \
658 printk(PREFIX "switching to v4l2\n"); \ 665 tda9887_info("switching to v4l2\n"); \
659 t->using_v4l2 = 1; 666 t->using_v4l2 = 1;
660#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ 667#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \
661 printk(PREFIX "ignore v4l1 call\n"); \ 668 tda9887_info("ignore v4l1 call\n"); \
662 return 0; } 669 return 0; }
663 670
664static int 671static int
665tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) 672tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
666{ 673{
667 struct tda9887 *t = i2c_get_clientdata(client); 674 struct tda9887 *t = i2c_get_clientdata(client);
668 675
669 switch (cmd) { 676 switch (cmd) {
670 677
671 /* --- configuration --- */ 678 /* --- configuration --- */
672 case AUDC_SET_RADIO: 679 case AUDC_SET_RADIO:
@@ -777,6 +784,11 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
777 } 784 }
778 break; 785 break;
779 } 786 }
787 case VIDIOC_LOG_STATUS:
788 {
789 tda9887_info("Data bytes: b=%02x c=%02x e=%02x\n", t->data[1], t->data[2], t->data[3]);
790 break;
791 }
780 default: 792 default:
781 /* nothing */ 793 /* nothing */
782 break; 794 break;
@@ -786,7 +798,10 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
786 798
787static int tda9887_suspend(struct device * dev, pm_message_t state) 799static int tda9887_suspend(struct device * dev, pm_message_t state)
788{ 800{
789 dprintk("tda9887: suspend\n"); 801 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
802 struct tda9887 *t = i2c_get_clientdata(c);
803
804 tda9887_dbg("suspend\n");
790 return 0; 805 return 0;
791} 806}
792 807
@@ -795,7 +810,7 @@ static int tda9887_resume(struct device * dev)
795 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 810 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
796 struct tda9887 *t = i2c_get_clientdata(c); 811 struct tda9887 *t = i2c_get_clientdata(c);
797 812
798 dprintk("tda9887: resume\n"); 813 tda9887_dbg("resume\n");
799 tda9887_configure(t); 814 tda9887_configure(t);
800 return 0; 815 return 0;
801} 816}
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index 38bf50943798..a9375ef05de1 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -117,10 +117,10 @@
117#define TEA5767_RESERVED_MASK 0xff 117#define TEA5767_RESERVED_MASK 0xff
118 118
119enum tea5767_xtal_freq { 119enum tea5767_xtal_freq {
120 TEA5767_LOW_LO_32768 = 0, 120 TEA5767_LOW_LO_32768 = 0,
121 TEA5767_HIGH_LO_32768 = 1, 121 TEA5767_HIGH_LO_32768 = 1,
122 TEA5767_LOW_LO_13MHz = 2, 122 TEA5767_LOW_LO_13MHz = 2,
123 TEA5767_HIGH_LO_13MHz = 3, 123 TEA5767_HIGH_LO_13MHz = 3,
124}; 124};
125 125
126 126
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index ad85bef1c3d5..73c4041c35d7 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -28,7 +28,7 @@
28 28
29/* standard i2c insmod options */ 29/* standard i2c insmod options */
30static unsigned short normal_i2c[] = { 30static unsigned short normal_i2c[] = {
31 0x4b, /* tda8290 */ 31 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
32 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 32 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
33 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 33 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
34 I2C_CLIENT_END 34 I2C_CLIENT_END
@@ -189,6 +189,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
189 i2c_master_send(c, buffer, 4); 189 i2c_master_send(c, buffer, 4);
190 default_tuner_init(c); 190 default_tuner_init(c);
191 break; 191 break;
192 case TUNER_PHILIPS_TD1316:
193 buffer[0] = 0x0b;
194 buffer[1] = 0xdc;
195 buffer[2] = 0x86;
196 buffer[3] = 0xa4;
197 i2c_master_send(c,buffer,4);
198 default_tuner_init(c);
192 default: 199 default:
193 default_tuner_init(c); 200 default_tuner_init(c);
194 break; 201 break;
@@ -215,9 +222,9 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
215{ 222{
216 struct tuner *t = i2c_get_clientdata(c); 223 struct tuner *t = i2c_get_clientdata(c);
217 224
218 if ((tun_setup->addr == ADDR_UNSET && 225 if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET &&
219 (t->mode_mask & tun_setup->mode_mask)) || 226 (t->mode_mask & tun_setup->mode_mask)) ||
220 tun_setup->addr == c->addr) { 227 tun_setup->addr == c->addr)) {
221 set_type(c, tun_setup->type, tun_setup->mode_mask); 228 set_type(c, tun_setup->type, tun_setup->mode_mask);
222 } 229 }
223} 230}
@@ -341,23 +348,33 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
341 t->audmode = V4L2_TUNER_MODE_STEREO; 348 t->audmode = V4L2_TUNER_MODE_STEREO;
342 t->mode_mask = T_UNINITIALIZED; 349 t->mode_mask = T_UNINITIALIZED;
343 350
344
345 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
346
347 if (show_i2c) { 351 if (show_i2c) {
348 unsigned char buffer[16]; 352 unsigned char buffer[16];
349 int i,rc; 353 int i,rc;
350 354
351 memset(buffer, 0, sizeof(buffer)); 355 memset(buffer, 0, sizeof(buffer));
352 rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer)); 356 rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer));
353 printk("tuner-%04x I2C RECV = ",addr); 357 tuner_info("I2C RECV = ");
354 for (i=0;i<rc;i++) 358 for (i=0;i<rc;i++)
355 printk("%02x ",buffer[i]); 359 printk("%02x ",buffer[i]);
356 printk("\n"); 360 printk("\n");
357 } 361 }
358 /* TEA5767 autodetection code - only for addr = 0xc0 */ 362 /* TEA5767 autodetection code - only for addr = 0xc0 */
359 if (!no_autodetect) { 363 if (!no_autodetect) {
360 if (addr == 0x60) { 364 switch (addr) {
365 case 0x42:
366 case 0x43:
367 case 0x4a:
368 case 0x4b:
369 /* If chip is not tda8290, don't register.
370 since it can be tda9887*/
371 if (tda8290_probe(&t->i2c) != 0) {
372 tuner_dbg("chip at addr %x is not a tda8290\n", addr);
373 kfree(t);
374 return 0;
375 }
376 break;
377 case 0x60:
361 if (tea5767_autodetection(&t->i2c) != EINVAL) { 378 if (tea5767_autodetection(&t->i2c) != EINVAL) {
362 t->type = TUNER_TEA5767; 379 t->type = TUNER_TEA5767;
363 t->mode_mask = T_RADIO; 380 t->mode_mask = T_RADIO;
@@ -365,10 +382,9 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
365 t->freq = 87.5 * 16; /* Sets freq to FM range */ 382 t->freq = 87.5 * 16; /* Sets freq to FM range */
366 default_mode_mask &= ~T_RADIO; 383 default_mode_mask &= ~T_RADIO;
367 384
368 i2c_attach_client (&t->i2c); 385 goto register_client;
369 set_type(&t->i2c,t->type, t->mode_mask);
370 return 0;
371 } 386 }
387 break;
372 } 388 }
373 } 389 }
374 390
@@ -381,6 +397,8 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
381 } 397 }
382 398
383 /* Should be just before return */ 399 /* Should be just before return */
400register_client:
401 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
384 i2c_attach_client (&t->i2c); 402 i2c_attach_client (&t->i2c);
385 set_type (&t->i2c,t->type, t->mode_mask); 403 set_type (&t->i2c,t->type, t->mode_mask);
386 return 0; 404 return 0;
@@ -425,23 +443,23 @@ static int tuner_detach(struct i2c_client *client)
425 443
426static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd) 444static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
427{ 445{
428 if (mode == t->mode) 446 if (mode == t->mode)
429 return 0; 447 return 0;
430 448
431 t->mode = mode; 449 t->mode = mode;
432 450
433 if (check_mode(t, cmd) == EINVAL) { 451 if (check_mode(t, cmd) == EINVAL) {
434 t->mode = T_STANDBY; 452 t->mode = T_STANDBY;
435 if (t->standby) 453 if (t->standby)
436 t->standby (client); 454 t->standby (client);
437 return EINVAL; 455 return EINVAL;
438 } 456 }
439 return 0; 457 return 0;
440} 458}
441 459
442#define switch_v4l2() if (!t->using_v4l2) \ 460#define switch_v4l2() if (!t->using_v4l2) \
443 tuner_dbg("switching to v4l2\n"); \ 461 tuner_dbg("switching to v4l2\n"); \
444 t->using_v4l2 = 1; 462 t->using_v4l2 = 1;
445 463
446static inline int check_v4l2(struct tuner *t) 464static inline int check_v4l2(struct tuner *t)
447{ 465{
@@ -479,8 +497,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
479 break; 497 break;
480 } 498 }
481 case AUDC_CONFIG_PINNACLE: 499 case AUDC_CONFIG_PINNACLE:
482 if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL)
483 return 0;
484 switch (*iarg) { 500 switch (*iarg) {
485 case 2: 501 case 2:
486 tuner_dbg("pinnacle pal\n"); 502 tuner_dbg("pinnacle pal\n");
@@ -616,7 +632,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
616 switch_v4l2(); 632 switch_v4l2();
617 if (V4L2_TUNER_RADIO == f->type && 633 if (V4L2_TUNER_RADIO == f->type &&
618 V4L2_TUNER_RADIO != t->mode) { 634 V4L2_TUNER_RADIO != t->mode) {
619 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") 635 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
620 == EINVAL) 636 == EINVAL)
621 return 0; 637 return 0;
622 } 638 }
@@ -688,7 +704,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
688 break; 704 break;
689 } 705 }
690 default: 706 default:
691 tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp=0x%02x,nr=%d,sz=%d)\n", 707 tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp='%c',nr=%d,sz=%d)\n",
692 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd), 708 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd),
693 _IOC_NR(cmd), _IOC_SIZE(cmd)); 709 _IOC_NR(cmd), _IOC_SIZE(cmd));
694 break; 710 break;
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 8edd73abe1d8..d832205818f2 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -102,7 +102,7 @@ struct tunertype
102 */ 102 */
103static struct tunertype tuners[] = { 103static struct tunertype tuners[] = {
104 /* 0-9 */ 104 /* 0-9 */
105 { "Temic PAL (4002 FH5)", TEMIC, PAL, 105 { "Temic PAL (4002 FH5)", TEMIC, PAL,
106 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623}, 106 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
107 { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I, 107 { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I,
108 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, 108 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
@@ -118,41 +118,41 @@ static struct tunertype tuners[] = {
118 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, 118 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
119 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, 119 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I,
120 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, 120 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
121 { "Temic NTSC (4036 FY5)", TEMIC, NTSC, 121 { "Temic NTSC (4036 FY5)", TEMIC, NTSC,
122 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, 122 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
123 { "Alps HSBH1", TEMIC, NTSC, 123 { "Alps HSBH1", TEMIC, NTSC,
124 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, 124 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
125 125
126 /* 10-19 */ 126 /* 10-19 */
127 { "Alps TSBE1", TEMIC, PAL, 127 { "Alps TSBE1", TEMIC, PAL,
128 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, 128 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
129 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */ 129 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */
130 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632}, 130 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
131 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 131 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
132 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, 132 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
133 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 133 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
134 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, 134 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
135 { "Temic PAL_BG (4006FH5)", TEMIC, PAL, 135 { "Temic PAL_BG (4006FH5)", TEMIC, PAL,
136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
137 { "Alps TSCH6", Alps, NTSC, 137 { "Alps TSCH6", Alps, NTSC,
138 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, 138 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
139 { "Temic PAL_DK (4016 FY5)", TEMIC, PAL, 139 { "Temic PAL_DK (4016 FY5)", TEMIC, PAL,
140 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, 140 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
141 { "Philips NTSC_M (MK2)", Philips, NTSC, 141 { "Philips NTSC_M (MK2)", Philips, NTSC,
142 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, 142 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
143 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, 143 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
144 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 144 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
145 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, 145 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
146 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 146 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
147 147
148 /* 20-29 */ 148 /* 20-29 */
149 { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL, 149 { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL,
150 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 150 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
151 { "Temic NTSC (4039 FR5)", TEMIC, NTSC, 151 { "Temic NTSC (4039 FR5)", TEMIC, NTSC,
152 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, 152 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
153 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL, 153 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL,
154 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 154 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
155 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, 155 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
156 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 156 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
157 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, 157 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
158 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 158 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
@@ -173,21 +173,21 @@ static struct tunertype tuners[] = {
173 { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */ 173 { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
174 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, 174 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 },
175 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */ 175 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
176 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, 176 16*169,16*464,0xA0,0x90,0x30,0x8e,623},
177 { "MT20xx universal", Microtune, PAL|NTSC, 177 { "MT20xx universal", Microtune, PAL|NTSC,
178 /* see mt20xx.c for details */ }, 178 /* see mt20xx.c for details */ },
179 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, 179 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
180 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 180 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
181 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, 181 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
182 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, 182 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
183 { "Temic NTSC (4136 FY5)", TEMIC, NTSC, 183 { "Temic NTSC (4136 FY5)", TEMIC, NTSC,
184 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, 184 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
185 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, 185 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
186 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623}, 186 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
187 { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL, 187 { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL,
188 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, 188 16*158.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
189 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, 189 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC,
190 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, 190 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
191 191
192 /* 40-49 */ 192 /* 40-49 */
193 { "HITACHI V7-J180AT", HITACHI, NTSC, 193 { "HITACHI V7-J180AT", HITACHI, NTSC,
@@ -196,24 +196,24 @@ static struct tunertype tuners[] = {
196 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, 196 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623},
197 { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC, 197 { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC,
198 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, 198 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732},
199 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, 199 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
200 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 200 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
201 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, 201 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC,
202 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 202 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
203 { "Microtune 4049 FM5", Microtune, PAL, 203 { "Microtune 4049 FM5", Microtune, PAL,
204 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, 204 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623},
205 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, 205 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC,
206 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, 206 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940},
207 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, 207 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
208 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, 208 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
209 { "Tenna TNF 8831 BGFF)", Philips, PAL, 209 { "Tenna TNF 8831 BGFF)", Philips, PAL,
210 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, 210 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
211 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, 211 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC,
212 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, 212 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732},
213 213
214 /* 50-59 */ 214 /* 50-59 */
215 { "TCL 2002N", TCL, NTSC, 215 { "TCL 2002N", TCL, NTSC,
216 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, 216 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
217 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, 217 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
218 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, 218 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
219 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, 219 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC,
@@ -222,8 +222,8 @@ static struct tunertype tuners[] = {
222 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */ 222 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */
223 { "tda8290+75", Philips, PAL|NTSC, 223 { "tda8290+75", Philips, PAL|NTSC,
224 /* see tda8290.c for details */ }, 224 /* see tda8290.c for details */ },
225 { "LG PAL (TAPE series)", LGINNOTEK, PAL, 225 { "TCL 2002MB", TCL, PAL,
226 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, 226 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
227 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, 227 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
228 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, 228 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
229 { "Philips FQ1236A MK4", Philips, NTSC, 229 { "Philips FQ1236A MK4", Philips, NTSC,
@@ -233,21 +233,25 @@ static struct tunertype tuners[] = {
233 { "Ymec TVision TVF-5533MF", Philips, NTSC, 233 { "Ymec TVision TVF-5533MF", Philips, NTSC,
234 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, 234 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
235 235
236 /* 60-66 */ 236 /* 60-68 */
237 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, 237 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
238 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, 238 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
239 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, 239 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
240 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, 240 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
241 { "Philips TEA5767HN FM Radio", Philips, RADIO, 241 { "Philips TEA5767HN FM Radio", Philips, RADIO,
242 /* see tea5767.c for details */}, 242 /* see tea5767.c for details */},
243 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, 243 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
244 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, 244 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
245 { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC, 245 { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC,
246 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, 246 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732},
247 { "Ymec TVF66T5-B/DFF", Philips, PAL, 247 { "Ymec TVF66T5-B/DFF", Philips, PAL,
248 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623}, 248 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623},
249 { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC, 249 { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC,
250 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 }, 250 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 },
251 { "Philips TD1316 Hybrid Tuner", Philips, PAL,
252 16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 },
253 { "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC,
254 16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 },
251}; 255};
252 256
253unsigned const int tuner_count = ARRAY_SIZE(tuners); 257unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -277,7 +281,7 @@ static int tuner_stereo(struct i2c_client *c)
277 status = tuner_getstatus (c); 281 status = tuner_getstatus (c);
278 282
279 switch (t->type) { 283 switch (t->type) {
280 case TUNER_PHILIPS_FM1216ME_MK3: 284 case TUNER_PHILIPS_FM1216ME_MK3:
281 case TUNER_PHILIPS_FM1236_MK3: 285 case TUNER_PHILIPS_FM1236_MK3:
282 case TUNER_PHILIPS_FM1256_IH3: 286 case TUNER_PHILIPS_FM1256_IH3:
283 stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); 287 stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
@@ -295,10 +299,10 @@ static int tuner_stereo(struct i2c_client *c)
295static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) 299static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
296{ 300{
297 struct tuner *t = i2c_get_clientdata(c); 301 struct tuner *t = i2c_get_clientdata(c);
298 u8 config; 302 u8 config, tuneraddr;
299 u16 div; 303 u16 div;
300 struct tunertype *tun; 304 struct tunertype *tun;
301 unsigned char buffer[4]; 305 unsigned char buffer[4];
302 int rc; 306 int rc;
303 307
304 tun = &tuners[t->type]; 308 tun = &tuners[t->type];
@@ -373,6 +377,31 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
373 /* Set the charge pump for fast tuning */ 377 /* Set the charge pump for fast tuning */
374 tun->config |= TUNER_CHARGE_PUMP; 378 tun->config |= TUNER_CHARGE_PUMP;
375 break; 379 break;
380
381 case TUNER_PHILIPS_TUV1236D:
382 /* 0x40 -> ATSC antenna input 1 */
383 /* 0x48 -> ATSC antenna input 2 */
384 /* 0x00 -> NTSC antenna input 1 */
385 /* 0x08 -> NTSC antenna input 2 */
386 buffer[0] = 0x14;
387 buffer[1] = 0x00;
388 buffer[2] = 0x17;
389 buffer[3] = 0x00;
390 config &= ~0x40;
391 if (t->std & V4L2_STD_ATSC) {
392 config |= 0x40;
393 buffer[1] = 0x04;
394 }
395 /* set to the correct mode (analog or digital) */
396 tuneraddr = c->addr;
397 c->addr = 0x0a;
398 if (2 != (rc = i2c_master_send(c,&buffer[0],2)))
399 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
400 if (2 != (rc = i2c_master_send(c,&buffer[2],2)))
401 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
402 c->addr = tuneraddr;
403 /* FIXME: input */
404 break;
376 } 405 }
377 406
378 /* 407 /*
@@ -404,7 +433,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
404 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", 433 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
405 buffer[0],buffer[1],buffer[2],buffer[3]); 434 buffer[0],buffer[1],buffer[2],buffer[3]);
406 435
407 if (4 != (rc = i2c_master_send(c,buffer,4))) 436 if (4 != (rc = i2c_master_send(c,buffer,4)))
408 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); 437 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
409 438
410 if (t->type == TUNER_MICROTUNE_4042FI5) { 439 if (t->type == TUNER_MICROTUNE_4042FI5) {
@@ -443,7 +472,7 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
443{ 472{
444 struct tunertype *tun; 473 struct tunertype *tun;
445 struct tuner *t = i2c_get_clientdata(c); 474 struct tuner *t = i2c_get_clientdata(c);
446 unsigned char buffer[4]; 475 unsigned char buffer[4];
447 unsigned div; 476 unsigned div;
448 int rc; 477 int rc;
449 478
@@ -476,13 +505,13 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
476 buffer[3] = 0xa4; 505 buffer[3] = 0xa4;
477 break; 506 break;
478 } 507 }
479 buffer[0] = (div>>8) & 0x7f; 508 buffer[0] = (div>>8) & 0x7f;
480 buffer[1] = div & 0xff; 509 buffer[1] = div & 0xff;
481 510
482 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", 511 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
483 buffer[0],buffer[1],buffer[2],buffer[3]); 512 buffer[0],buffer[1],buffer[2],buffer[3]);
484 513
485 if (4 != (rc = i2c_master_send(c,buffer,4))) 514 if (4 != (rc = i2c_master_send(c,buffer,4)))
486 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); 515 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
487} 516}
488 517
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 1c31ef52f863..c31bf28b73fe 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -31,7 +31,6 @@
31#include <linux/smp_lock.h> 31#include <linux/smp_lock.h>
32 32
33#include <media/audiochip.h> 33#include <media/audiochip.h>
34#include <media/id.h>
35 34
36#include "tvaudio.h" 35#include "tvaudio.h"
37 36
@@ -458,8 +457,8 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode)
458#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */ 457#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */
459#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */ 458#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */
460 /* Bits 0 to 3 select various combinations 459 /* Bits 0 to 3 select various combinations
461 * of line in and line out, only the 460 * of line in and line out, only the
462 * interesting ones are defined */ 461 * interesting ones are defined */
463#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */ 462#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */
464#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */ 463#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */
465 464
@@ -1028,7 +1027,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
1028#define TEA6300_TR 0x03 /* treble */ 1027#define TEA6300_TR 0x03 /* treble */
1029#define TEA6300_FA 0x04 /* fader control */ 1028#define TEA6300_FA 0x04 /* fader control */
1030#define TEA6300_S 0x05 /* switch register */ 1029#define TEA6300_S 0x05 /* switch register */
1031 /* values for those registers: */ 1030 /* values for those registers: */
1032#define TEA6300_S_SA 0x01 /* stereo A input */ 1031#define TEA6300_S_SA 0x01 /* stereo A input */
1033#define TEA6300_S_SB 0x02 /* stereo B */ 1032#define TEA6300_S_SB 0x02 /* stereo B */
1034#define TEA6300_S_SC 0x04 /* stereo C */ 1033#define TEA6300_S_SC 0x04 /* stereo C */
@@ -1042,7 +1041,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
1042#define TEA6320_BA 0x05 /* bass (0-4) */ 1041#define TEA6320_BA 0x05 /* bass (0-4) */
1043#define TEA6320_TR 0x06 /* treble (0-4) */ 1042#define TEA6320_TR 0x06 /* treble (0-4) */
1044#define TEA6320_S 0x07 /* switch register */ 1043#define TEA6320_S 0x07 /* switch register */
1045 /* values for those registers: */ 1044 /* values for those registers: */
1046#define TEA6320_S_SA 0x07 /* stereo A input */ 1045#define TEA6320_S_SA 0x07 /* stereo A input */
1047#define TEA6320_S_SB 0x06 /* stereo B */ 1046#define TEA6320_S_SB 0x06 /* stereo B */
1048#define TEA6320_S_SC 0x05 /* stereo C */ 1047#define TEA6320_S_SC 0x05 /* stereo C */
@@ -1082,7 +1081,7 @@ static int tea6320_initialize(struct CHIPSTATE * chip)
1082#define TDA8425_BA 0x02 /* bass */ 1081#define TDA8425_BA 0x02 /* bass */
1083#define TDA8425_TR 0x03 /* treble */ 1082#define TDA8425_TR 0x03 /* treble */
1084#define TDA8425_S1 0x08 /* switch functions */ 1083#define TDA8425_S1 0x08 /* switch functions */
1085 /* values for those registers: */ 1084 /* values for those registers: */
1086#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */ 1085#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */
1087#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */ 1086#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */
1088#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */ 1087#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */
@@ -1148,7 +1147,7 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
1148 1147
1149/* bit definition of the RESET register, I2C data. */ 1148/* bit definition of the RESET register, I2C data. */
1150#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */ 1149#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */
1151 /* code of remote controller */ 1150 /* code of remote controller */
1152#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */ 1151#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */
1153#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */ 1152#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */
1154#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */ 1153#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */
@@ -1281,7 +1280,7 @@ static struct CHIPDESC chiplist[] = {
1281 .setmode = tda9840_setmode, 1280 .setmode = tda9840_setmode,
1282 .checkmode = generic_checkmode, 1281 .checkmode = generic_checkmode,
1283 1282
1284 .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN 1283 .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
1285 /* ,TDA9840_SW, TDA9840_MONO */} } 1284 /* ,TDA9840_SW, TDA9840_MONO */} }
1286 }, 1285 },
1287 { 1286 {
@@ -1438,7 +1437,7 @@ static struct CHIPDESC chiplist[] = {
1438 }, 1437 },
1439 { 1438 {
1440 .name = "pic16c54 (PV951)", 1439 .name = "pic16c54 (PV951)",
1441 .id = I2C_DRIVERID_PIC16C54_PV951, 1440 .id = I2C_DRIVERID_PIC16C54_PV9,
1442 .insmodopt = &pic16c54, 1441 .insmodopt = &pic16c54,
1443 .addr_lo = I2C_PIC16C54 >> 1, 1442 .addr_lo = I2C_PIC16C54 >> 1,
1444 .addr_hi = I2C_PIC16C54>> 1, 1443 .addr_hi = I2C_PIC16C54>> 1,
@@ -1467,7 +1466,7 @@ static struct CHIPDESC chiplist[] = {
1467 .setmode = ta8874z_setmode, 1466 .setmode = ta8874z_setmode,
1468 .checkmode = generic_checkmode, 1467 .checkmode = generic_checkmode,
1469 1468
1470 .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, 1469 .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
1471 }, 1470 },
1472 { .name = NULL } /* EOF */ 1471 { .name = NULL } /* EOF */
1473}; 1472};
@@ -1486,8 +1485,8 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1486 return -ENOMEM; 1485 return -ENOMEM;
1487 memset(chip,0,sizeof(*chip)); 1486 memset(chip,0,sizeof(*chip));
1488 memcpy(&chip->c,&client_template,sizeof(struct i2c_client)); 1487 memcpy(&chip->c,&client_template,sizeof(struct i2c_client));
1489 chip->c.adapter = adap; 1488 chip->c.adapter = adap;
1490 chip->c.addr = addr; 1489 chip->c.addr = addr;
1491 i2c_set_clientdata(&chip->c, chip); 1490 i2c_set_clientdata(&chip->c, chip);
1492 1491
1493 /* find description for the chip */ 1492 /* find description for the chip */
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 5344d5592199..72e8741e8b59 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -6,12 +6,12 @@
6 * which are: 6 * which are:
7 7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de) 9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> 10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11 11
12 * Adjustments to fit a more general model and all bugs: 12 * Adjustments to fit a more general model and all bugs:
13 13
14 Copyright (C) 2003 John Klar <linpvr at projectplasma.com> 14 Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
15 15
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@
40 40
41#include <media/tuner.h> 41#include <media/tuner.h>
42#include <media/tveeprom.h> 42#include <media/tveeprom.h>
43#include <media/audiochip.h>
43 44
44MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); 45MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
45MODULE_AUTHOR("John Klar"); 46MODULE_AUTHOR("John Klar");
@@ -53,14 +54,14 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
53 54
54#define tveeprom_info(fmt, arg...) do {\ 55#define tveeprom_info(fmt, arg...) do {\
55 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ 56 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
56 c->adapter->nr, c->addr , ##arg); } while (0) 57 c->adapter->nr, c->addr , ##arg); } while (0)
57#define tveeprom_warn(fmt, arg...) do {\ 58#define tveeprom_warn(fmt, arg...) do {\
58 printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \ 59 printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \
59 c->adapter->nr, c->addr , ##arg); } while (0) 60 c->adapter->nr, c->addr , ##arg); } while (0)
60#define tveeprom_dbg(fmt, arg...) do {\ 61#define tveeprom_dbg(fmt, arg...) do {\
61 if (debug) \ 62 if (debug) \
62 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ 63 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
63 c->adapter->nr, c->addr , ##arg); } while (0) 64 c->adapter->nr, c->addr , ##arg); } while (0)
64 65
65 66
66/* ----------------------------------------------------------------------- */ 67/* ----------------------------------------------------------------------- */
@@ -134,8 +135,8 @@ hauppauge_tuner[] =
134 { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" }, 135 { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
135 { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" }, 136 { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" },
136 { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" }, 137 { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
137 { TUNER_PHILIPS_NTSC, "Philips TD1536" }, 138 { TUNER_PHILIPS_NTSC, "Philips TD1536" },
138 { TUNER_PHILIPS_NTSC, "Philips TD1536D" }, 139 { TUNER_PHILIPS_NTSC, "Philips TD1536D" },
139 { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */ 140 { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */
140 { TUNER_ABSENT, "Philips FI1256MP" }, 141 { TUNER_ABSENT, "Philips FI1256MP" },
141 /* 40-49 */ 142 /* 40-49 */
@@ -189,7 +190,7 @@ hauppauge_tuner[] =
189 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, 190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"}, 191 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
191 { TUNER_TCL_2002N, "TCL 2002N 6A"}, 192 { TUNER_TCL_2002N, "TCL 2002N 6A"},
192 { TUNER_ABSENT, "Philips FQ1236 MK3"}, 193 { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"},
193 { TUNER_ABSENT, "Samsung TCPN 2121P30A"}, 194 { TUNER_ABSENT, "Samsung TCPN 2121P30A"},
194 { TUNER_ABSENT, "Samsung TCPE 4121P30A"}, 195 { TUNER_ABSENT, "Samsung TCPE 4121P30A"},
195 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"}, 196 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"},
@@ -200,95 +201,137 @@ hauppauge_tuner[] =
200 { TUNER_ABSENT, "Philips FQ1286A MK4"}, 201 { TUNER_ABSENT, "Philips FQ1286A MK4"},
201 { TUNER_ABSENT, "Philips FQ1216ME MK5"}, 202 { TUNER_ABSENT, "Philips FQ1216ME MK5"},
202 { TUNER_ABSENT, "Philips FQ1236 MK5"}, 203 { TUNER_ABSENT, "Philips FQ1236 MK5"},
203 { TUNER_ABSENT, "Unspecified"}, 204 { TUNER_ABSENT, "Samsung TCPG_6121P30A"},
204 { TUNER_LG_PAL_TAPE, "LG PAL (TAPE Series)"}, 205 { TUNER_TCL_2002MB, "TCL 2002MB_3H"},
205 { TUNER_ABSENT, "Unspecified"}, 206 { TUNER_ABSENT, "TCL 2002MI_3H"},
206 { TUNER_TCL_2002N, "TCL 2002N 5H"}, 207 { TUNER_TCL_2002N, "TCL 2002N 5H"},
207 /* 100-103 */ 208 /* 100-109 */
208 { TUNER_ABSENT, "Unspecified"}, 209 { TUNER_ABSENT, "Philips FMD1216ME"},
209 { TUNER_TEA5767, "Philips TEA5767HN FM Radio"}, 210 { TUNER_TEA5767, "Philips TEA5768HL FM Radio"},
210 { TUNER_ABSENT, "Unspecified"}, 211 { TUNER_ABSENT, "Panasonic ENV57H12D5"},
211 { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05 4"}, 212 { TUNER_ABSENT, "TCL MFNM05-4"},
213 { TUNER_ABSENT, "TCL MNM05-4"},
214 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"},
215 { TUNER_ABSENT, "TCL MQNM05-4"},
216 { TUNER_ABSENT, "LG TAPC-W701D"},
217 { TUNER_ABSENT, "TCL 9886P-WM"},
218 { TUNER_ABSENT, "TCL 1676NM-WM"},
212}; 219};
213 220
214/* This list is supplied by Hauppauge. Thanks! */ 221static struct HAUPPAUGE_AUDIOIC
215static const char *audioIC[] = { 222{
216 /* 0-4 */ 223 enum audiochip id;
217 "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C", 224 char *name;
218 /* 5-9 */ 225}
219 "MSP3410D", "MSP3415", "MSP3430", "MSP3438", "CS5331", 226audioIC[] =
220 /* 10-14 */ 227{
221 "MSP3435", "MSP3440", "MSP3445", "MSP3411", "MSP3416", 228 /* 0-4 */
222 /* 15-19 */ 229 {AUDIO_CHIP_NONE, "None"},
223 "MSP3425", "MSP3451", "MSP3418", "Type 0x12", "OKI7716", 230 {AUDIO_CHIP_TEA6300, "TEA6300"},
224 /* 20-24 */ 231 {AUDIO_CHIP_TEA6300, "TEA6320"},
225 "MSP4410", "MSP4420", "MSP4440", "MSP4450", "MSP4408", 232 {AUDIO_CHIP_TDA985X, "TDA9850"},
226 /* 25-29 */ 233 {AUDIO_CHIP_MSP34XX, "MSP3400C"},
227 "MSP4418", "MSP4428", "MSP4448", "MSP4458", "Type 0x1d", 234 /* 5-9 */
228 /* 30-34 */ 235 {AUDIO_CHIP_MSP34XX, "MSP3410D"},
229 "CX880", "CX881", "CX883", "CX882", "CX25840", 236 {AUDIO_CHIP_MSP34XX, "MSP3415"},
230 /* 35-38 */ 237 {AUDIO_CHIP_MSP34XX, "MSP3430"},
231 "CX25841", "CX25842", "CX25843", "CX23418", 238 {AUDIO_CHIP_UNKNOWN, "MSP3438"},
239 {AUDIO_CHIP_UNKNOWN, "CS5331"},
240 /* 10-14 */
241 {AUDIO_CHIP_MSP34XX, "MSP3435"},
242 {AUDIO_CHIP_MSP34XX, "MSP3440"},
243 {AUDIO_CHIP_MSP34XX, "MSP3445"},
244 {AUDIO_CHIP_UNKNOWN, "MSP3411"},
245 {AUDIO_CHIP_UNKNOWN, "MSP3416"},
246 /* 15-19 */
247 {AUDIO_CHIP_MSP34XX, "MSP3425"},
248 {AUDIO_CHIP_UNKNOWN, "MSP3451"},
249 {AUDIO_CHIP_UNKNOWN, "MSP3418"},
250 {AUDIO_CHIP_UNKNOWN, "Type 0x12"},
251 {AUDIO_CHIP_UNKNOWN, "OKI7716"},
252 /* 20-24 */
253 {AUDIO_CHIP_UNKNOWN, "MSP4410"},
254 {AUDIO_CHIP_UNKNOWN, "MSP4420"},
255 {AUDIO_CHIP_UNKNOWN, "MSP4440"},
256 {AUDIO_CHIP_UNKNOWN, "MSP4450"},
257 {AUDIO_CHIP_UNKNOWN, "MSP4408"},
258 /* 25-29 */
259 {AUDIO_CHIP_UNKNOWN, "MSP4418"},
260 {AUDIO_CHIP_UNKNOWN, "MSP4428"},
261 {AUDIO_CHIP_UNKNOWN, "MSP4448"},
262 {AUDIO_CHIP_UNKNOWN, "MSP4458"},
263 {AUDIO_CHIP_UNKNOWN, "Type 0x1d"},
264 /* 30-34 */
265 {AUDIO_CHIP_INTERNAL, "CX880"},
266 {AUDIO_CHIP_INTERNAL, "CX881"},
267 {AUDIO_CHIP_INTERNAL, "CX883"},
268 {AUDIO_CHIP_INTERNAL, "CX882"},
269 {AUDIO_CHIP_INTERNAL, "CX25840"},
270 /* 35-38 */
271 {AUDIO_CHIP_INTERNAL, "CX25841"},
272 {AUDIO_CHIP_INTERNAL, "CX25842"},
273 {AUDIO_CHIP_INTERNAL, "CX25843"},
274 {AUDIO_CHIP_INTERNAL, "CX23418"},
232}; 275};
233 276
234/* This list is supplied by Hauppauge. Thanks! */ 277/* This list is supplied by Hauppauge. Thanks! */
235static const char *decoderIC[] = { 278static const char *decoderIC[] = {
236 /* 0-4 */ 279 /* 0-4 */
237 "None", "BT815", "BT817", "BT819", "BT815A", 280 "None", "BT815", "BT817", "BT819", "BT815A",
238 /* 5-9 */ 281 /* 5-9 */
239 "BT817A", "BT819A", "BT827", "BT829", "BT848", 282 "BT817A", "BT819A", "BT827", "BT829", "BT848",
240 /* 10-14 */ 283 /* 10-14 */
241 "BT848A", "BT849A", "BT829A", "BT827A", "BT878", 284 "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
242 /* 15-19 */ 285 /* 15-19 */
243 "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115", 286 "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
244 /* 20-24 */ 287 /* 20-24 */
245 "CX880", "CX881", "CX883", "SAA7111", "SAA7113", 288 "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
246 /* 25-29 */ 289 /* 25-29 */
247 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842", 290 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
248 /* 30-31 */ 291 /* 30-31 */
249 "CX25843", "CX23418", 292 "CX25843", "CX23418",
250}; 293};
251 294
252static int hasRadioTuner(int tunerType) 295static int hasRadioTuner(int tunerType)
253{ 296{
254 switch (tunerType) { 297 switch (tunerType) {
255 case 18: //PNPEnv_TUNER_FR1236_MK2: 298 case 18: //PNPEnv_TUNER_FR1236_MK2:
256 case 23: //PNPEnv_TUNER_FM1236: 299 case 23: //PNPEnv_TUNER_FM1236:
257 case 38: //PNPEnv_TUNER_FMR1236: 300 case 38: //PNPEnv_TUNER_FMR1236:
258 case 16: //PNPEnv_TUNER_FR1216_MK2: 301 case 16: //PNPEnv_TUNER_FR1216_MK2:
259 case 19: //PNPEnv_TUNER_FR1246_MK2: 302 case 19: //PNPEnv_TUNER_FR1246_MK2:
260 case 21: //PNPEnv_TUNER_FM1216: 303 case 21: //PNPEnv_TUNER_FM1216:
261 case 24: //PNPEnv_TUNER_FM1246: 304 case 24: //PNPEnv_TUNER_FM1246:
262 case 17: //PNPEnv_TUNER_FR1216MF_MK2: 305 case 17: //PNPEnv_TUNER_FR1216MF_MK2:
263 case 22: //PNPEnv_TUNER_FM1216MF: 306 case 22: //PNPEnv_TUNER_FM1216MF:
264 case 20: //PNPEnv_TUNER_FR1256_MK2: 307 case 20: //PNPEnv_TUNER_FR1256_MK2:
265 case 25: //PNPEnv_TUNER_FM1256: 308 case 25: //PNPEnv_TUNER_FM1256:
266 case 33: //PNPEnv_TUNER_4039FR5: 309 case 33: //PNPEnv_TUNER_4039FR5:
267 case 42: //PNPEnv_TUNER_4009FR5: 310 case 42: //PNPEnv_TUNER_4009FR5:
268 case 52: //PNPEnv_TUNER_4049FM5: 311 case 52: //PNPEnv_TUNER_4049FM5:
269 case 54: //PNPEnv_TUNER_4049FM5_AltI2C: 312 case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
270 case 44: //PNPEnv_TUNER_4009FN5: 313 case 44: //PNPEnv_TUNER_4009FN5:
271 case 31: //PNPEnv_TUNER_TCPB9085P: 314 case 31: //PNPEnv_TUNER_TCPB9085P:
272 case 30: //PNPEnv_TUNER_TCPN9085D: 315 case 30: //PNPEnv_TUNER_TCPN9085D:
273 case 46: //PNPEnv_TUNER_TP18NSR01F: 316 case 46: //PNPEnv_TUNER_TP18NSR01F:
274 case 47: //PNPEnv_TUNER_TP18PSB01D: 317 case 47: //PNPEnv_TUNER_TP18PSB01D:
275 case 49: //PNPEnv_TUNER_TAPC_I001D: 318 case 49: //PNPEnv_TUNER_TAPC_I001D:
276 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3: 319 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
277 case 57: //PNPEnv_TUNER_FM1216ME_MK3: 320 case 57: //PNPEnv_TUNER_FM1216ME_MK3:
278 case 59: //PNPEnv_TUNER_FM1216MP_MK3: 321 case 59: //PNPEnv_TUNER_FM1216MP_MK3:
279 case 58: //PNPEnv_TUNER_FM1236_MK3: 322 case 58: //PNPEnv_TUNER_FM1236_MK3:
280 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3: 323 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
281 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3: 324 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
282 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM: 325 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
283 case 89: //PNPEnv_TUNER_TCL_MFPE05_2: 326 case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
284 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4: 327 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
285 return 1; 328 return 1;
286 } 329 }
287 return 0; 330 return 0;
288} 331}
289 332
290void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, 333void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
291 unsigned char *eeprom_data) 334 unsigned char *eeprom_data)
292{ 335{
293 /* ---------------------------------------------- 336 /* ----------------------------------------------
294 ** The hauppauge eeprom format is tagged 337 ** The hauppauge eeprom format is tagged
@@ -312,19 +355,27 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
312 ** # of inputs/outputs ??? 355 ** # of inputs/outputs ???
313 */ 356 */
314 357
315 int i, j, len, done, beenhere, tag; 358 int i, j, len, done, beenhere, tag,start;
316 359
317 int tuner1 = 0, t_format1 = 0; 360 int tuner1 = 0, t_format1 = 0, audioic=-1;
318 char *t_name1 = NULL; 361 char *t_name1 = NULL;
319 const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" }; 362 const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
320 363
321 int tuner2 = 0, t_format2 = 0; 364 int tuner2 = 0, t_format2 = 0;
322 char *t_name2 = NULL; 365 char *t_name2 = NULL;
323 const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" }; 366 const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
324 367
325 memset(tvee, 0, sizeof(*tvee)); 368 memset(tvee, 0, sizeof(*tvee));
326 done = len = beenhere = 0; 369 done = len = beenhere = 0;
327 for (i = 0; !done && i < 256; i += len) { 370
371 /* Hack for processing eeprom for em28xx */
372 if ((eeprom_data[0]==0x1a)&&(eeprom_data[1]==0xeb)&&
373 (eeprom_data[2]==0x67)&&(eeprom_data[3]==0x95))
374 start=0xa0;
375 else
376 start=0;
377
378 for (i = start; !done && i < 256; i += len) {
328 if (eeprom_data[i] == 0x84) { 379 if (eeprom_data[i] == 0x84) {
329 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8); 380 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
330 i += 3; 381 i += 3;
@@ -338,28 +389,28 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
338 ++i; 389 ++i;
339 } else { 390 } else {
340 tveeprom_warn("Encountered bad packet header [%02x]. " 391 tveeprom_warn("Encountered bad packet header [%02x]. "
341 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]); 392 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
342 return; 393 return;
343 } 394 }
344 395
345 if (debug) { 396 if (debug) {
346 tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1); 397 tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1);
347 for(j = 1; j < len; j++) { 398 for(j = 1; j < len; j++) {
348 printk(" %02x", eeprom_data[i + j]); 399 printk(" %02x", eeprom_data[i + j]);
349 } 400 }
350 printk("\n"); 401 printk("\n");
351 } 402 }
352 403
353 /* process by tag */ 404 /* process by tag */
354 tag = eeprom_data[i]; 405 tag = eeprom_data[i];
355 switch (tag) { 406 switch (tag) {
356 case 0x00: 407 case 0x00:
357 /* tag: 'Comprehensive' */ 408 /* tag: 'Comprehensive' */
358 tuner1 = eeprom_data[i+6]; 409 tuner1 = eeprom_data[i+6];
359 t_format1 = eeprom_data[i+5]; 410 t_format1 = eeprom_data[i+5];
360 tvee->has_radio = eeprom_data[i+len-1]; 411 tvee->has_radio = eeprom_data[i+len-1];
361 /* old style tag, don't know how to detect 412 /* old style tag, don't know how to detect
362 IR presence, mark as unknown. */ 413 IR presence, mark as unknown. */
363 tvee->has_ir = 2; 414 tvee->has_ir = 2;
364 tvee->model = 415 tvee->model =
365 eeprom_data[i+8] + 416 eeprom_data[i+8] +
@@ -370,7 +421,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
370 break; 421 break;
371 422
372 case 0x01: 423 case 0x01:
373 /* tag: 'SerialID' */ 424 /* tag: 'SerialID' */
374 tvee->serial_number = 425 tvee->serial_number =
375 eeprom_data[i+6] + 426 eeprom_data[i+6] +
376 (eeprom_data[i+7] << 8) + 427 (eeprom_data[i+7] << 8) +
@@ -378,17 +429,21 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
378 break; 429 break;
379 430
380 case 0x02: 431 case 0x02:
381 /* tag 'AudioInfo' 432 /* tag 'AudioInfo'
382 Note mask with 0x7F, high bit used on some older models 433 Note mask with 0x7F, high bit used on some older models
383 to indicate 4052 mux was removed in favor of using MSP 434 to indicate 4052 mux was removed in favor of using MSP
384 inputs directly. */ 435 inputs directly. */
385 tvee->audio_processor = eeprom_data[i+2] & 0x7f; 436 audioic = eeprom_data[i+2] & 0x7f;
437 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
438 tvee->audio_processor = audioIC[audioic].id;
439 else
440 tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
386 break; 441 break;
387 442
388 /* case 0x03: tag 'EEInfo' */ 443 /* case 0x03: tag 'EEInfo' */
389 444
390 case 0x04: 445 case 0x04:
391 /* tag 'SerialID2' */ 446 /* tag 'SerialID2' */
392 tvee->serial_number = 447 tvee->serial_number =
393 eeprom_data[i+5] + 448 eeprom_data[i+5] +
394 (eeprom_data[i+6] << 8) + 449 (eeprom_data[i+6] << 8) +
@@ -396,15 +451,20 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
396 break; 451 break;
397 452
398 case 0x05: 453 case 0x05:
399 /* tag 'Audio2' 454 /* tag 'Audio2'
400 Note mask with 0x7F, high bit used on some older models 455 Note mask with 0x7F, high bit used on some older models
401 to indicate 4052 mux was removed in favor of using MSP 456 to indicate 4052 mux was removed in favor of using MSP
402 inputs directly. */ 457 inputs directly. */
403 tvee->audio_processor = eeprom_data[i+1] & 0x7f; 458 audioic = eeprom_data[i+1] & 0x7f;
459 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
460 tvee->audio_processor = audioIC[audioic].id;
461 else
462 tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
463
404 break; 464 break;
405 465
406 case 0x06: 466 case 0x06:
407 /* tag 'ModelRev' */ 467 /* tag 'ModelRev' */
408 tvee->model = 468 tvee->model =
409 eeprom_data[i+1] + 469 eeprom_data[i+1] +
410 (eeprom_data[i+2] << 8); 470 (eeprom_data[i+2] << 8);
@@ -414,55 +474,55 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
414 break; 474 break;
415 475
416 case 0x07: 476 case 0x07:
417 /* tag 'Details': according to Hauppauge not interesting 477 /* tag 'Details': according to Hauppauge not interesting
418 on any PCI-era or later boards. */ 478 on any PCI-era or later boards. */
419 break; 479 break;
420 480
421 /* there is no tag 0x08 defined */ 481 /* there is no tag 0x08 defined */
422 482
423 case 0x09: 483 case 0x09:
424 /* tag 'Video' */ 484 /* tag 'Video' */
425 tvee->decoder_processor = eeprom_data[i + 1]; 485 tvee->decoder_processor = eeprom_data[i + 1];
426 break; 486 break;
427 487
428 case 0x0a: 488 case 0x0a:
429 /* tag 'Tuner' */ 489 /* tag 'Tuner' */
430 if (beenhere == 0) { 490 if (beenhere == 0) {
431 tuner1 = eeprom_data[i+2]; 491 tuner1 = eeprom_data[i+2];
432 t_format1 = eeprom_data[i+1]; 492 t_format1 = eeprom_data[i+1];
433 beenhere = 1; 493 beenhere = 1;
434 } else { 494 } else {
435 /* a second (radio) tuner may be present */ 495 /* a second (radio) tuner may be present */
436 tuner2 = eeprom_data[i+2]; 496 tuner2 = eeprom_data[i+2];
437 t_format2 = eeprom_data[i+1]; 497 t_format2 = eeprom_data[i+1];
438 if (t_format2 == 0) { /* not a TV tuner? */ 498 if (t_format2 == 0) { /* not a TV tuner? */
439 tvee->has_radio = 1; /* must be radio */ 499 tvee->has_radio = 1; /* must be radio */
440 } 500 }
441 } 501 }
442 break; 502 break;
443 503
444 case 0x0b: 504 case 0x0b:
445 /* tag 'Inputs': according to Hauppauge this is specific 505 /* tag 'Inputs': according to Hauppauge this is specific
446 to each driver family, so no good assumptions can be 506 to each driver family, so no good assumptions can be
447 made. */ 507 made. */
448 break; 508 break;
449 509
450 /* case 0x0c: tag 'Balun' */ 510 /* case 0x0c: tag 'Balun' */
451 /* case 0x0d: tag 'Teletext' */ 511 /* case 0x0d: tag 'Teletext' */
452 512
453 case 0x0e: 513 case 0x0e:
454 /* tag: 'Radio' */ 514 /* tag: 'Radio' */
455 tvee->has_radio = eeprom_data[i+1]; 515 tvee->has_radio = eeprom_data[i+1];
456 break; 516 break;
457 517
458 case 0x0f: 518 case 0x0f:
459 /* tag 'IRInfo' */ 519 /* tag 'IRInfo' */
460 tvee->has_ir = eeprom_data[i+1]; 520 tvee->has_ir = eeprom_data[i+1];
461 break; 521 break;
462 522
463 /* case 0x10: tag 'VBIInfo' */ 523 /* case 0x10: tag 'VBIInfo' */
464 /* case 0x11: tag 'QCInfo' */ 524 /* case 0x11: tag 'QCInfo' */
465 /* case 0x12: tag 'InfoBits' */ 525 /* case 0x12: tag 'InfoBits' */
466 526
467 default: 527 default:
468 tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag); 528 tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag);
@@ -483,11 +543,11 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
483 tvee->rev_str[4] = 0; 543 tvee->rev_str[4] = 0;
484 } 544 }
485 545
486 if (hasRadioTuner(tuner1) && !tvee->has_radio) { 546 if (hasRadioTuner(tuner1) && !tvee->has_radio) {
487 tveeprom_info("The eeprom says no radio is present, but the tuner type\n"); 547 tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
488 tveeprom_info("indicates otherwise. I will assume that radio is present.\n"); 548 tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
489 tvee->has_radio = 1; 549 tvee->has_radio = 1;
490 } 550 }
491 551
492 if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { 552 if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
493 tvee->tuner_type = hauppauge_tuner[tuner1].id; 553 tvee->tuner_type = hauppauge_tuner[tuner1].id;
@@ -510,45 +570,53 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
510 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id; 570 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
511 t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name; 571 t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
512 } 572 }
513 if (t_format2 & (1 << i)) { 573 if (t_format2 & (1 << i)) {
514 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id; 574 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
515 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name; 575 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
516 } 576 }
517 } 577 }
518 578
519 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n", 579 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
520 tvee->model, tvee->rev_str, tvee->serial_number); 580 tvee->model, tvee->rev_str, tvee->serial_number);
521 tveeprom_info("tuner model is %s (idx %d, type %d)\n", 581 tveeprom_info("tuner model is %s (idx %d, type %d)\n",
522 t_name1, tuner1, tvee->tuner_type); 582 t_name1, tuner1, tvee->tuner_type);
523 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 583 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
524 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3], 584 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
525 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7], 585 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
526 t_format1); 586 t_format1);
527 if (tuner2) { 587 if (tuner2) {
528 tveeprom_info("second tuner model is %s (idx %d, type %d)\n", 588 tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
529 t_name2, tuner2, tvee->tuner2_type); 589 t_name2, tuner2, tvee->tuner2_type);
530 } 590 }
531 if (t_format2) { 591 if (t_format2) {
532 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 592 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
533 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3], 593 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
534 t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7], 594 t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
535 t_format2); 595 t_format2);
536 } 596 }
537 tveeprom_info("audio processor is %s (idx %d)\n", 597 if (audioic<0) {
538 STRM(audioIC, tvee->audio_processor), 598 tveeprom_info("audio processor is unknown (no idx)\n");
539 tvee->audio_processor); 599 tvee->audio_processor=AUDIO_CHIP_UNKNOWN;
540 if (tvee->decoder_processor) { 600 } else {
541 tveeprom_info("decoder processor is %s (idx %d)\n", 601 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
542 STRM(decoderIC, tvee->decoder_processor), 602 tveeprom_info("audio processor is %s (idx %d)\n",
543 tvee->decoder_processor); 603 audioIC[audioic].name,audioic);
544 } 604 else
545 if (tvee->has_ir == 2) 605 tveeprom_info("audio processor is unknown (idx %d)\n",
546 tveeprom_info("has %sradio\n", 606 audioic);
547 tvee->has_radio ? "" : "no "); 607 }
548 else 608 if (tvee->decoder_processor) {
549 tveeprom_info("has %sradio, has %sIR remote\n", 609 tveeprom_info("decoder processor is %s (idx %d)\n",
550 tvee->has_radio ? "" : "no ", 610 STRM(decoderIC, tvee->decoder_processor),
551 tvee->has_ir ? "" : "no "); 611 tvee->decoder_processor);
612 }
613 if (tvee->has_ir == 2)
614 tveeprom_info("has %sradio\n",
615 tvee->has_radio ? "" : "no ");
616 else
617 tveeprom_info("has %sradio, has %sIR remote\n",
618 tvee->has_radio ? "" : "no ",
619 tvee->has_ir ? "" : "no ");
552} 620}
553EXPORT_SYMBOL(tveeprom_hauppauge_analog); 621EXPORT_SYMBOL(tveeprom_hauppauge_analog);
554 622
@@ -569,18 +637,18 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
569 tveeprom_warn("i2c eeprom read error (err=%d)\n", err); 637 tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
570 return -1; 638 return -1;
571 } 639 }
572 if (debug) { 640 if (debug) {
573 int i; 641 int i;
574 642
575 tveeprom_info("full 256-byte eeprom dump:\n"); 643 tveeprom_info("full 256-byte eeprom dump:\n");
576 for (i = 0; i < len; i++) { 644 for (i = 0; i < len; i++) {
577 if (0 == (i % 16)) 645 if (0 == (i % 16))
578 tveeprom_info("%02x:", i); 646 tveeprom_info("%02x:", i);
579 printk(" %02x", eedata[i]); 647 printk(" %02x", eedata[i]);
580 if (15 == (i % 16)) 648 if (15 == (i % 16))
581 printk("\n"); 649 printk("\n");
582 } 650 }
583 } 651 }
584 return 0; 652 return 0;
585} 653}
586EXPORT_SYMBOL(tveeprom_read); 654EXPORT_SYMBOL(tveeprom_read);
@@ -590,10 +658,6 @@ EXPORT_SYMBOL(tveeprom_read);
590/* run, just call the exported tveeprom_* directly, there is no point in */ 658/* run, just call the exported tveeprom_* directly, there is no point in */
591/* using the indirect way via i2c_driver->command() */ 659/* using the indirect way via i2c_driver->command() */
592 660
593#ifndef I2C_DRIVERID_TVEEPROM
594# define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2
595#endif
596
597static unsigned short normal_i2c[] = { 661static unsigned short normal_i2c[] = {
598 0xa0 >> 1, 662 0xa0 >> 1,
599 I2C_CLIENT_END, 663 I2C_CLIENT_END,
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index d86e08ebddfc..8318bd1aad00 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -79,7 +79,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
79{ 79{
80 struct video_audio va; 80 struct video_audio va;
81 int left,right,ret,val = 0; 81 int left,right,ret,val = 0;
82 struct TVMIXER *mix = file->private_data; 82 struct TVMIXER *mix = file->private_data;
83 struct i2c_client *client = mix->dev; 83 struct i2c_client *client = mix->dev;
84 void __user *argp = (void __user *)arg; 84 void __user *argp = (void __user *)arg;
85 int __user *p = argp; 85 int __user *p = argp;
@@ -87,25 +87,25 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
87 if (NULL == client) 87 if (NULL == client)
88 return -ENODEV; 88 return -ENODEV;
89 89
90 if (cmd == SOUND_MIXER_INFO) { 90 if (cmd == SOUND_MIXER_INFO) {
91 mixer_info info; 91 mixer_info info;
92 strlcpy(info.id, "tv card", sizeof(info.id)); 92 strlcpy(info.id, "tv card", sizeof(info.id));
93 strlcpy(info.name, client->name, sizeof(info.name)); 93 strlcpy(info.name, client->name, sizeof(info.name));
94 info.modify_counter = 42 /* FIXME */; 94 info.modify_counter = 42 /* FIXME */;
95 if (copy_to_user(argp, &info, sizeof(info))) 95 if (copy_to_user(argp, &info, sizeof(info)))
96 return -EFAULT; 96 return -EFAULT;
97 return 0; 97 return 0;
98 } 98 }
99 if (cmd == SOUND_OLD_MIXER_INFO) { 99 if (cmd == SOUND_OLD_MIXER_INFO) {
100 _old_mixer_info info; 100 _old_mixer_info info;
101 strlcpy(info.id, "tv card", sizeof(info.id)); 101 strlcpy(info.id, "tv card", sizeof(info.id));
102 strlcpy(info.name, client->name, sizeof(info.name)); 102 strlcpy(info.name, client->name, sizeof(info.name));
103 if (copy_to_user(argp, &info, sizeof(info))) 103 if (copy_to_user(argp, &info, sizeof(info)))
104 return -EFAULT; 104 return -EFAULT;
105 return 0; 105 return 0;
106 } 106 }
107 if (cmd == OSS_GETVERSION) 107 if (cmd == OSS_GETVERSION)
108 return put_user(SOUND_VERSION, p); 108 return put_user(SOUND_VERSION, p);
109 109
110 if (_SIOC_DIR(cmd) & _SIOC_WRITE) 110 if (_SIOC_DIR(cmd) & _SIOC_WRITE)
111 if (get_user(val, p)) 111 if (get_user(val, p))
@@ -181,8 +181,8 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
181 181
182static int tvmixer_open(struct inode *inode, struct file *file) 182static int tvmixer_open(struct inode *inode, struct file *file)
183{ 183{
184 int i, minor = iminor(inode); 184 int i, minor = iminor(inode);
185 struct TVMIXER *mix = NULL; 185 struct TVMIXER *mix = NULL;
186 struct i2c_client *client = NULL; 186 struct i2c_client *client = NULL;
187 187
188 for (i = 0; i < DEV_MAX; i++) { 188 for (i = 0; i < DEV_MAX; i++) {
@@ -204,7 +204,7 @@ static int tvmixer_open(struct inode *inode, struct file *file)
204#endif 204#endif
205 if (client->adapter->owner) 205 if (client->adapter->owner)
206 try_module_get(client->adapter->owner); 206 try_module_get(client->adapter->owner);
207 return 0; 207 return 0;
208} 208}
209 209
210static int tvmixer_release(struct inode *inode, struct file *file) 210static int tvmixer_release(struct inode *inode, struct file *file)
@@ -231,15 +231,15 @@ static struct i2c_driver driver = {
231 .owner = THIS_MODULE, 231 .owner = THIS_MODULE,
232#endif 232#endif
233 .name = "tv card mixer driver", 233 .name = "tv card mixer driver",
234 .id = I2C_DRIVERID_TVMIXER, 234 .id = I2C_DRIVERID_TVMIXER,
235#ifdef I2C_DF_DUMMY 235#ifdef I2C_DF_DUMMY
236 .flags = I2C_DF_DUMMY, 236 .flags = I2C_DF_DUMMY,
237#else 237#else
238 .flags = I2C_DF_NOTIFY, 238 .flags = I2C_DF_NOTIFY,
239 .detach_adapter = tvmixer_adapters, 239 .detach_adapter = tvmixer_adapters,
240#endif 240#endif
241 .attach_adapter = tvmixer_adapters, 241 .attach_adapter = tvmixer_adapters,
242 .detach_client = tvmixer_clients, 242 .detach_client = tvmixer_clients,
243}; 243};
244 244
245static struct file_operations tvmixer_fops = { 245static struct file_operations tvmixer_fops = {
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
new file mode 100644
index 000000000000..81e6d4494e7d
--- /dev/null
+++ b/drivers/media/video/tvp5150.c
@@ -0,0 +1,829 @@
1/*
2 * tvp5150 - Texas Instruments TVP5150A(M) video decoder driver
3 *
4 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
5 * This code is placed under the terms of the GNU General Public License
6 */
7
8#include <linux/i2c.h>
9#include <linux/videodev.h>
10#include <linux/delay.h>
11#include <linux/video_decoder.h>
12
13#include "tvp5150_reg.h"
14
15MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); /* standard i2c insmod options */
16MODULE_AUTHOR("Mauro Carvalho Chehab");
17MODULE_LICENSE("GPL");
18
19static unsigned short normal_i2c[] = {
20 0xb8 >> 1,
21 0xba >> 1,
22 I2C_CLIENT_END
23};
24
25I2C_CLIENT_INSMOD;
26
27static int debug = 0;
28module_param(debug, int, 0);
29MODULE_PARM_DESC(debug, "Debug level (0-1)");
30
31#define dprintk(num, format, args...) \
32 do { \
33 if (debug >= num) \
34 printk(format , ##args); \
35 } while (0)
36
37/* supported controls */
38static struct v4l2_queryctrl tvp5150_qctrl[] = {
39 {
40 .id = V4L2_CID_BRIGHTNESS,
41 .type = V4L2_CTRL_TYPE_INTEGER,
42 .name = "Brightness",
43 .minimum = 0,
44 .maximum = 255,
45 .step = 1,
46 .default_value = 0,
47 .flags = 0,
48 }, {
49 .id = V4L2_CID_CONTRAST,
50 .type = V4L2_CTRL_TYPE_INTEGER,
51 .name = "Contrast",
52 .minimum = 0,
53 .maximum = 255,
54 .step = 0x1,
55 .default_value = 0x10,
56 .flags = 0,
57 }, {
58 .id = V4L2_CID_SATURATION,
59 .type = V4L2_CTRL_TYPE_INTEGER,
60 .name = "Saturation",
61 .minimum = 0,
62 .maximum = 255,
63 .step = 0x1,
64 .default_value = 0x10,
65 .flags = 0,
66 }, {
67 .id = V4L2_CID_HUE,
68 .type = V4L2_CTRL_TYPE_INTEGER,
69 .name = "Hue",
70 .minimum = -128,
71 .maximum = 127,
72 .step = 0x1,
73 .default_value = 0x10,
74 .flags = 0,
75 }
76};
77
78struct tvp5150 {
79 struct i2c_client *client;
80
81 int norm;
82 int input;
83 int enable;
84 int bright;
85 int contrast;
86 int hue;
87 int sat;
88};
89
90static inline int tvp5150_read(struct i2c_client *c, unsigned char addr)
91{
92 unsigned char buffer[1];
93 int rc;
94
95 buffer[0] = addr;
96 if (1 != (rc = i2c_master_send(c, buffer, 1)))
97 dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
98
99 msleep(10);
100
101 if (1 != (rc = i2c_master_recv(c, buffer, 1)))
102 dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
103
104 return (buffer[0]);
105}
106
107static inline void tvp5150_write(struct i2c_client *c, unsigned char addr,
108 unsigned char value)
109{
110 unsigned char buffer[2];
111 int rc;
112/* struct tvp5150 *core = i2c_get_clientdata(c); */
113
114 buffer[0] = addr;
115 buffer[1] = value;
116 dprintk(1, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
117 if (2 != (rc = i2c_master_send(c, buffer, 2)))
118 dprintk(0, "i2c i/o error: rc == %d (should be 2)\n", rc);
119}
120
121static void dump_reg(struct i2c_client *c)
122{
123 printk("tvp5150: Video input source selection #1 = 0x%02x\n",
124 tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1));
125 printk("tvp5150: Analog channel controls = 0x%02x\n",
126 tvp5150_read(c, TVP5150_ANAL_CHL_CTL));
127 printk("tvp5150: Operation mode controls = 0x%02x\n",
128 tvp5150_read(c, TVP5150_OP_MODE_CTL));
129 printk("tvp5150: Miscellaneous controls = 0x%02x\n",
130 tvp5150_read(c, TVP5150_MISC_CTL));
131 printk("tvp5150: Autoswitch mask: TVP5150A / TVP5150AM = 0x%02x\n",
132 tvp5150_read(c, TVP5150_AUTOSW_MSK));
133 printk("tvp5150: Color killer threshold control = 0x%02x\n",
134 tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL));
135 printk("tvp5150: Luminance processing control #1 = 0x%02x\n",
136 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1));
137 printk("tvp5150: Luminance processing control #2 = 0x%02x\n",
138 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2));
139 printk("tvp5150: Brightness control = 0x%02x\n",
140 tvp5150_read(c, TVP5150_BRIGHT_CTL));
141 printk("tvp5150: Color saturation control = 0x%02x\n",
142 tvp5150_read(c, TVP5150_SATURATION_CTL));
143 printk("tvp5150: Hue control = 0x%02x\n",
144 tvp5150_read(c, TVP5150_HUE_CTL));
145 printk("tvp5150: Contrast control = 0x%02x\n",
146 tvp5150_read(c, TVP5150_CONTRAST_CTL));
147 printk("tvp5150: Outputs and data rates select = 0x%02x\n",
148 tvp5150_read(c, TVP5150_DATA_RATE_SEL));
149 printk("tvp5150: Luminance processing control #3 = 0x%02x\n",
150 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3));
151 printk("tvp5150: Configuration shared pins = 0x%02x\n",
152 tvp5150_read(c, TVP5150_CONF_SHARED_PIN));
153 printk("tvp5150: Active video cropping start MSB = 0x%02x\n",
154 tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB));
155 printk("tvp5150: Active video cropping start LSB = 0x%02x\n",
156 tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB));
157 printk("tvp5150: Active video cropping stop MSB = 0x%02x\n",
158 tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB));
159 printk("tvp5150: Active video cropping stop LSB = 0x%02x\n",
160 tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB));
161 printk("tvp5150: Genlock/RTC = 0x%02x\n",
162 tvp5150_read(c, TVP5150_GENLOCK));
163 printk("tvp5150: Horizontal sync start = 0x%02x\n",
164 tvp5150_read(c, TVP5150_HORIZ_SYNC_START));
165 printk("tvp5150: Vertical blanking start = 0x%02x\n",
166 tvp5150_read(c, TVP5150_VERT_BLANKING_START));
167 printk("tvp5150: Vertical blanking stop = 0x%02x\n",
168 tvp5150_read(c, TVP5150_VERT_BLANKING_STOP));
169 printk("tvp5150: Chrominance processing control #1 = 0x%02x\n",
170 tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1));
171 printk("tvp5150: Chrominance processing control #2 = 0x%02x\n",
172 tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2));
173 printk("tvp5150: Interrupt reset register B = 0x%02x\n",
174 tvp5150_read(c, TVP5150_INT_RESET_REG_B));
175 printk("tvp5150: Interrupt enable register B = 0x%02x\n",
176 tvp5150_read(c, TVP5150_INT_ENABLE_REG_B));
177 printk("tvp5150: Interrupt configuration register B = 0x%02x\n",
178 tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B));
179 printk("tvp5150: Video standard = 0x%02x\n",
180 tvp5150_read(c, TVP5150_VIDEO_STD));
181 printk("tvp5150: Cb gain factor = 0x%02x\n",
182 tvp5150_read(c, TVP5150_CB_GAIN_FACT));
183 printk("tvp5150: Cr gain factor = 0x%02x\n",
184 tvp5150_read(c, TVP5150_CR_GAIN_FACTOR));
185 printk("tvp5150: Macrovision on counter = 0x%02x\n",
186 tvp5150_read(c, TVP5150_MACROVISION_ON_CTR));
187 printk("tvp5150: Macrovision off counter = 0x%02x\n",
188 tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR));
189 printk("tvp5150: revision select (TVP5150AM1 only) = 0x%02x\n",
190 tvp5150_read(c, TVP5150_REV_SELECT));
191 printk("tvp5150: MSB of device ID = 0x%02x\n",
192 tvp5150_read(c, TVP5150_MSB_DEV_ID));
193 printk("tvp5150: LSB of device ID = 0x%02x\n",
194 tvp5150_read(c, TVP5150_LSB_DEV_ID));
195 printk("tvp5150: ROM major version = 0x%02x\n",
196 tvp5150_read(c, TVP5150_ROM_MAJOR_VER));
197 printk("tvp5150: ROM minor version = 0x%02x\n",
198 tvp5150_read(c, TVP5150_ROM_MINOR_VER));
199 printk("tvp5150: Vertical line count MSB = 0x%02x\n",
200 tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB));
201 printk("tvp5150: Vertical line count LSB = 0x%02x\n",
202 tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB));
203 printk("tvp5150: Interrupt status register B = 0x%02x\n",
204 tvp5150_read(c, TVP5150_INT_STATUS_REG_B));
205 printk("tvp5150: Interrupt active register B = 0x%02x\n",
206 tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B));
207 printk("tvp5150: Status register #1 = 0x%02x\n",
208 tvp5150_read(c, TVP5150_STATUS_REG_1));
209 printk("tvp5150: Status register #2 = 0x%02x\n",
210 tvp5150_read(c, TVP5150_STATUS_REG_2));
211 printk("tvp5150: Status register #3 = 0x%02x\n",
212 tvp5150_read(c, TVP5150_STATUS_REG_3));
213 printk("tvp5150: Status register #4 = 0x%02x\n",
214 tvp5150_read(c, TVP5150_STATUS_REG_4));
215 printk("tvp5150: Status register #5 = 0x%02x\n",
216 tvp5150_read(c, TVP5150_STATUS_REG_5));
217 printk("tvp5150: Closed caption data registers = 0x%02x\n",
218 tvp5150_read(c, TVP5150_CC_DATA_REG1));
219 printk("tvp5150: Closed caption data registers = 0x%02x\n",
220 tvp5150_read(c, TVP5150_CC_DATA_REG2));
221 printk("tvp5150: Closed caption data registers = 0x%02x\n",
222 tvp5150_read(c, TVP5150_CC_DATA_REG3));
223 printk("tvp5150: Closed caption data registers = 0x%02x\n",
224 tvp5150_read(c, TVP5150_CC_DATA_REG4));
225 printk("tvp5150: WSS data registers = 0x%02x\n",
226 tvp5150_read(c, TVP5150_WSS_DATA_REG1));
227 printk("tvp5150: WSS data registers = 0x%02x\n",
228 tvp5150_read(c, TVP5150_WSS_DATA_REG2));
229 printk("tvp5150: WSS data registers = 0x%02x\n",
230 tvp5150_read(c, TVP5150_WSS_DATA_REG3));
231 printk("tvp5150: WSS data registers = 0x%02x\n",
232 tvp5150_read(c, TVP5150_WSS_DATA_REG4));
233 printk("tvp5150: WSS data registers = 0x%02x\n",
234 tvp5150_read(c, TVP5150_WSS_DATA_REG5));
235 printk("tvp5150: WSS data registers = 0x%02x\n",
236 tvp5150_read(c, TVP5150_WSS_DATA_REG6));
237 printk("tvp5150: VPS data registers = 0x%02x\n",
238 tvp5150_read(c, TVP5150_VPS_DATA_REG1));
239 printk("tvp5150: VPS data registers = 0x%02x\n",
240 tvp5150_read(c, TVP5150_VPS_DATA_REG2));
241 printk("tvp5150: VPS data registers = 0x%02x\n",
242 tvp5150_read(c, TVP5150_VPS_DATA_REG3));
243 printk("tvp5150: VPS data registers = 0x%02x\n",
244 tvp5150_read(c, TVP5150_VPS_DATA_REG4));
245 printk("tvp5150: VPS data registers = 0x%02x\n",
246 tvp5150_read(c, TVP5150_VPS_DATA_REG5));
247 printk("tvp5150: VPS data registers = 0x%02x\n",
248 tvp5150_read(c, TVP5150_VPS_DATA_REG6));
249 printk("tvp5150: VPS data registers = 0x%02x\n",
250 tvp5150_read(c, TVP5150_VPS_DATA_REG7));
251 printk("tvp5150: VPS data registers = 0x%02x\n",
252 tvp5150_read(c, TVP5150_VPS_DATA_REG8));
253 printk("tvp5150: VPS data registers = 0x%02x\n",
254 tvp5150_read(c, TVP5150_VPS_DATA_REG9));
255 printk("tvp5150: VPS data registers = 0x%02x\n",
256 tvp5150_read(c, TVP5150_VPS_DATA_REG10));
257 printk("tvp5150: VPS data registers = 0x%02x\n",
258 tvp5150_read(c, TVP5150_VPS_DATA_REG11));
259 printk("tvp5150: VPS data registers = 0x%02x\n",
260 tvp5150_read(c, TVP5150_VPS_DATA_REG12));
261 printk("tvp5150: VPS data registers = 0x%02x\n",
262 tvp5150_read(c, TVP5150_VPS_DATA_REG13));
263 printk("tvp5150: VITC data registers = 0x%02x\n",
264 tvp5150_read(c, TVP5150_VITC_DATA_REG1));
265 printk("tvp5150: VITC data registers = 0x%02x\n",
266 tvp5150_read(c, TVP5150_VITC_DATA_REG2));
267 printk("tvp5150: VITC data registers = 0x%02x\n",
268 tvp5150_read(c, TVP5150_VITC_DATA_REG3));
269 printk("tvp5150: VITC data registers = 0x%02x\n",
270 tvp5150_read(c, TVP5150_VITC_DATA_REG4));
271 printk("tvp5150: VITC data registers = 0x%02x\n",
272 tvp5150_read(c, TVP5150_VITC_DATA_REG5));
273 printk("tvp5150: VITC data registers = 0x%02x\n",
274 tvp5150_read(c, TVP5150_VITC_DATA_REG6));
275 printk("tvp5150: VITC data registers = 0x%02x\n",
276 tvp5150_read(c, TVP5150_VITC_DATA_REG7));
277 printk("tvp5150: VITC data registers = 0x%02x\n",
278 tvp5150_read(c, TVP5150_VITC_DATA_REG8));
279 printk("tvp5150: VITC data registers = 0x%02x\n",
280 tvp5150_read(c, TVP5150_VITC_DATA_REG9));
281 printk("tvp5150: VBI FIFO read data = 0x%02x\n",
282 tvp5150_read(c, TVP5150_VBI_FIFO_READ_DATA));
283 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
284 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_1));
285 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
286 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_2));
287 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
288 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_3));
289 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
290 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_4));
291 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
292 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_5));
293 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
294 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_1));
295 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
296 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_2));
297 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
298 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_3));
299 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
300 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_4));
301 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
302 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_5));
303 printk("tvp5150: Teletext filter enable = 0x%02x\n",
304 tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA));
305 printk("tvp5150: Interrupt status register A = 0x%02x\n",
306 tvp5150_read(c, TVP5150_INT_STATUS_REG_A));
307 printk("tvp5150: Interrupt enable register A = 0x%02x\n",
308 tvp5150_read(c, TVP5150_INT_ENABLE_REG_A));
309 printk("tvp5150: Interrupt configuration = 0x%02x\n",
310 tvp5150_read(c, TVP5150_INT_CONF));
311 printk("tvp5150: VDP configuration RAM data = 0x%02x\n",
312 tvp5150_read(c, TVP5150_VDP_CONF_RAM_DATA));
313 printk("tvp5150: Configuration RAM address low byte = 0x%02x\n",
314 tvp5150_read(c, TVP5150_CONF_RAM_ADDR_LOW));
315 printk("tvp5150: Configuration RAM address high byte = 0x%02x\n",
316 tvp5150_read(c, TVP5150_CONF_RAM_ADDR_HIGH));
317 printk("tvp5150: VDP status register = 0x%02x\n",
318 tvp5150_read(c, TVP5150_VDP_STATUS_REG));
319 printk("tvp5150: FIFO word count = 0x%02x\n",
320 tvp5150_read(c, TVP5150_FIFO_WORD_COUNT));
321 printk("tvp5150: FIFO interrupt threshold = 0x%02x\n",
322 tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD));
323 printk("tvp5150: FIFO reset = 0x%02x\n",
324 tvp5150_read(c, TVP5150_FIFO_RESET));
325 printk("tvp5150: Line number interrupt = 0x%02x\n",
326 tvp5150_read(c, TVP5150_LINE_NUMBER_INT));
327 printk("tvp5150: Pixel alignment register low byte = 0x%02x\n",
328 tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW));
329 printk("tvp5150: Pixel alignment register high byte = 0x%02x\n",
330 tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH));
331 printk("tvp5150: FIFO output control = 0x%02x\n",
332 tvp5150_read(c, TVP5150_FIFO_OUT_CTRL));
333 printk("tvp5150: Full field enable 1 = 0x%02x\n",
334 tvp5150_read(c, TVP5150_FULL_FIELD_ENA_1));
335 printk("tvp5150: Full field enable 2 = 0x%02x\n",
336 tvp5150_read(c, TVP5150_FULL_FIELD_ENA_2));
337 printk("tvp5150: Line mode registers = 0x%02x\n",
338 tvp5150_read(c, TVP5150_LINE_MODE_REG_1));
339 printk("tvp5150: Line mode registers = 0x%02x\n",
340 tvp5150_read(c, TVP5150_LINE_MODE_REG_2));
341 printk("tvp5150: Line mode registers = 0x%02x\n",
342 tvp5150_read(c, TVP5150_LINE_MODE_REG_3));
343 printk("tvp5150: Line mode registers = 0x%02x\n",
344 tvp5150_read(c, TVP5150_LINE_MODE_REG_4));
345 printk("tvp5150: Line mode registers = 0x%02x\n",
346 tvp5150_read(c, TVP5150_LINE_MODE_REG_5));
347 printk("tvp5150: Line mode registers = 0x%02x\n",
348 tvp5150_read(c, TVP5150_LINE_MODE_REG_6));
349 printk("tvp5150: Line mode registers = 0x%02x\n",
350 tvp5150_read(c, TVP5150_LINE_MODE_REG_7));
351 printk("tvp5150: Line mode registers = 0x%02x\n",
352 tvp5150_read(c, TVP5150_LINE_MODE_REG_8));
353 printk("tvp5150: Line mode registers = 0x%02x\n",
354 tvp5150_read(c, TVP5150_LINE_MODE_REG_9));
355 printk("tvp5150: Line mode registers = 0x%02x\n",
356 tvp5150_read(c, TVP5150_LINE_MODE_REG_10));
357 printk("tvp5150: Line mode registers = 0x%02x\n",
358 tvp5150_read(c, TVP5150_LINE_MODE_REG_11));
359 printk("tvp5150: Line mode registers = 0x%02x\n",
360 tvp5150_read(c, TVP5150_LINE_MODE_REG_12));
361 printk("tvp5150: Line mode registers = 0x%02x\n",
362 tvp5150_read(c, TVP5150_LINE_MODE_REG_13));
363 printk("tvp5150: Line mode registers = 0x%02x\n",
364 tvp5150_read(c, TVP5150_LINE_MODE_REG_14));
365 printk("tvp5150: Line mode registers = 0x%02x\n",
366 tvp5150_read(c, TVP5150_LINE_MODE_REG_15));
367 printk("tvp5150: Line mode registers = 0x%02x\n",
368 tvp5150_read(c, TVP5150_LINE_MODE_REG_16));
369 printk("tvp5150: Line mode registers = 0x%02x\n",
370 tvp5150_read(c, TVP5150_LINE_MODE_REG_17));
371 printk("tvp5150: Line mode registers = 0x%02x\n",
372 tvp5150_read(c, TVP5150_LINE_MODE_REG_18));
373 printk("tvp5150: Line mode registers = 0x%02x\n",
374 tvp5150_read(c, TVP5150_LINE_MODE_REG_19));
375 printk("tvp5150: Line mode registers = 0x%02x\n",
376 tvp5150_read(c, TVP5150_LINE_MODE_REG_20));
377 printk("tvp5150: Line mode registers = 0x%02x\n",
378 tvp5150_read(c, TVP5150_LINE_MODE_REG_21));
379 printk("tvp5150: Line mode registers = 0x%02x\n",
380 tvp5150_read(c, TVP5150_LINE_MODE_REG_22));
381 printk("tvp5150: Line mode registers = 0x%02x\n",
382 tvp5150_read(c, TVP5150_LINE_MODE_REG_23));
383 printk("tvp5150: Line mode registers = 0x%02x\n",
384 tvp5150_read(c, TVP5150_LINE_MODE_REG_24));
385 printk("tvp5150: Line mode registers = 0x%02x\n",
386 tvp5150_read(c, TVP5150_LINE_MODE_REG_25));
387 printk("tvp5150: Line mode registers = 0x%02x\n",
388 tvp5150_read(c, TVP5150_LINE_MODE_REG_27));
389 printk("tvp5150: Line mode registers = 0x%02x\n",
390 tvp5150_read(c, TVP5150_LINE_MODE_REG_28));
391 printk("tvp5150: Line mode registers = 0x%02x\n",
392 tvp5150_read(c, TVP5150_LINE_MODE_REG_29));
393 printk("tvp5150: Line mode registers = 0x%02x\n",
394 tvp5150_read(c, TVP5150_LINE_MODE_REG_30));
395 printk("tvp5150: Line mode registers = 0x%02x\n",
396 tvp5150_read(c, TVP5150_LINE_MODE_REG_31));
397 printk("tvp5150: Line mode registers = 0x%02x\n",
398 tvp5150_read(c, TVP5150_LINE_MODE_REG_32));
399 printk("tvp5150: Line mode registers = 0x%02x\n",
400 tvp5150_read(c, TVP5150_LINE_MODE_REG_33));
401 printk("tvp5150: Line mode registers = 0x%02x\n",
402 tvp5150_read(c, TVP5150_LINE_MODE_REG_34));
403 printk("tvp5150: Line mode registers = 0x%02x\n",
404 tvp5150_read(c, TVP5150_LINE_MODE_REG_35));
405 printk("tvp5150: Line mode registers = 0x%02x\n",
406 tvp5150_read(c, TVP5150_LINE_MODE_REG_36));
407 printk("tvp5150: Line mode registers = 0x%02x\n",
408 tvp5150_read(c, TVP5150_LINE_MODE_REG_37));
409 printk("tvp5150: Line mode registers = 0x%02x\n",
410 tvp5150_read(c, TVP5150_LINE_MODE_REG_38));
411 printk("tvp5150: Line mode registers = 0x%02x\n",
412 tvp5150_read(c, TVP5150_LINE_MODE_REG_39));
413 printk("tvp5150: Line mode registers = 0x%02x\n",
414 tvp5150_read(c, TVP5150_LINE_MODE_REG_40));
415 printk("tvp5150: Line mode registers = 0x%02x\n",
416 tvp5150_read(c, TVP5150_LINE_MODE_REG_41));
417 printk("tvp5150: Line mode registers = 0x%02x\n",
418 tvp5150_read(c, TVP5150_LINE_MODE_REG_42));
419 printk("tvp5150: Line mode registers = 0x%02x\n",
420 tvp5150_read(c, TVP5150_LINE_MODE_REG_43));
421 printk("tvp5150: Line mode registers = 0x%02x\n",
422 tvp5150_read(c, TVP5150_LINE_MODE_REG_44));
423 printk("tvp5150: Full field mode register = 0x%02x\n",
424 tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG));
425}
426
427/****************************************************************************
428 Basic functions
429 ****************************************************************************/
430enum tvp5150_input {
431 TVP5150_ANALOG_CH0 = 0,
432 TVP5150_SVIDEO = 1,
433 TVP5150_ANALOG_CH1 = 2,
434 TVP5150_BLACK_SCREEN = 8
435};
436
437static inline void tvp5150_selmux(struct i2c_client *c,
438 enum tvp5150_input input)
439{
440 struct tvp5150 *decoder = i2c_get_clientdata(c);
441
442 if (!decoder->enable)
443 input |= TVP5150_BLACK_SCREEN;
444
445 tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);
446};
447
448static inline void tvp5150_reset(struct i2c_client *c)
449{
450 struct tvp5150 *decoder = i2c_get_clientdata(c);
451
452 tvp5150_write(c, TVP5150_CONF_SHARED_PIN, 2);
453
454 /* Automatic offset and AGC enabled */
455 tvp5150_write(c, TVP5150_ANAL_CHL_CTL, 0x15);
456
457 /* Normal Operation */
458// tvp5150_write(c, TVP5150_OP_MODE_CTL, 0x00);
459
460 /* Activate YCrCb output 0x9 or 0xd ? */
461 tvp5150_write(c, TVP5150_MISC_CTL, 0x6f);
462
463 /* Activates video std autodetection for all standards */
464 tvp5150_write(c, TVP5150_AUTOSW_MSK, 0x0);
465
466 /* Default format: 0x47, 4:2:2: 0x40 */
467 tvp5150_write(c, TVP5150_DATA_RATE_SEL, 0x47);
468
469 tvp5150_selmux(c, decoder->input);
470
471 tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_1, 0x0c);
472 tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_2, 0x54);
473
474 tvp5150_write(c, 0x27, 0x20); /* ?????????? */
475
476 tvp5150_write(c, TVP5150_VIDEO_STD, 0x0); /* Auto switch */
477
478 tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8);
479 tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8);
480 tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8);
481 tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8);
482};
483
484static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
485{
486/* struct tvp5150 *decoder = i2c_get_clientdata(c); */
487
488 switch (ctrl->id) {
489 case V4L2_CID_BRIGHTNESS:
490 ctrl->value = tvp5150_read(c, TVP5150_BRIGHT_CTL);
491 return 0;
492 case V4L2_CID_CONTRAST:
493 ctrl->value = tvp5150_read(c, TVP5150_CONTRAST_CTL);
494 return 0;
495 case V4L2_CID_SATURATION:
496 ctrl->value = tvp5150_read(c, TVP5150_SATURATION_CTL);
497 return 0;
498 case V4L2_CID_HUE:
499 ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL);
500 return 0;
501 default:
502 return -EINVAL;
503 }
504}
505
506static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
507{
508/* struct tvp5150 *decoder = i2c_get_clientdata(c); */
509
510 switch (ctrl->id) {
511 case V4L2_CID_BRIGHTNESS:
512 tvp5150_write(c, TVP5150_BRIGHT_CTL, ctrl->value);
513 return 0;
514 case V4L2_CID_CONTRAST:
515 tvp5150_write(c, TVP5150_CONTRAST_CTL, ctrl->value);
516 return 0;
517 case V4L2_CID_SATURATION:
518 tvp5150_write(c, TVP5150_SATURATION_CTL, ctrl->value);
519 return 0;
520 case V4L2_CID_HUE:
521 tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value);
522 return 0;
523 default:
524 return -EINVAL;
525 }
526}
527
528/****************************************************************************
529 I2C Command
530 ****************************************************************************/
531static int tvp5150_command(struct i2c_client *client,
532 unsigned int cmd, void *arg)
533{
534 struct tvp5150 *decoder = i2c_get_clientdata(client);
535
536 switch (cmd) {
537
538 case 0:
539 case DECODER_INIT:
540 tvp5150_reset(client);
541 break;
542
543 case DECODER_DUMP:
544 dump_reg(client);
545 break;
546
547 case DECODER_GET_CAPABILITIES:
548 {
549 struct video_decoder_capability *cap = arg;
550
551 cap->flags = VIDEO_DECODER_PAL |
552 VIDEO_DECODER_NTSC |
553 VIDEO_DECODER_SECAM |
554 VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
555 cap->inputs = 3;
556 cap->outputs = 1;
557 break;
558 }
559 case DECODER_GET_STATUS:
560 {
561 break;
562 }
563
564 case DECODER_SET_GPIO:
565 break;
566
567 case DECODER_SET_VBI_BYPASS:
568 break;
569
570 case DECODER_SET_NORM:
571 {
572 int *iarg = arg;
573
574 switch (*iarg) {
575
576 case VIDEO_MODE_NTSC:
577 break;
578
579 case VIDEO_MODE_PAL:
580 break;
581
582 case VIDEO_MODE_SECAM:
583 break;
584
585 case VIDEO_MODE_AUTO:
586 break;
587
588 default:
589 return -EINVAL;
590
591 }
592 decoder->norm = *iarg;
593 break;
594 }
595 case DECODER_SET_INPUT:
596 {
597 int *iarg = arg;
598 if (*iarg < 0 || *iarg > 3) {
599 return -EINVAL;
600 }
601
602 decoder->input = *iarg;
603 tvp5150_selmux(client, decoder->input);
604
605 break;
606 }
607 case DECODER_SET_OUTPUT:
608 {
609 int *iarg = arg;
610
611 /* not much choice of outputs */
612 if (*iarg != 0) {
613 return -EINVAL;
614 }
615 break;
616 }
617 case DECODER_ENABLE_OUTPUT:
618 {
619 int *iarg = arg;
620
621 decoder->enable = (*iarg != 0);
622
623 tvp5150_selmux(client, decoder->input);
624
625 break;
626 }
627 case VIDIOC_QUERYCTRL:
628 {
629 struct v4l2_queryctrl *qc = arg;
630 u8 i, n;
631
632 dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL");
633
634 n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
635 for (i = 0; i < n; i++)
636 if (qc->id && qc->id == tvp5150_qctrl[i].id) {
637 memcpy(qc, &(tvp5150_qctrl[i]),
638 sizeof(*qc));
639 return 0;
640 }
641
642 return -EINVAL;
643 }
644 case VIDIOC_G_CTRL:
645 {
646 struct v4l2_control *ctrl = arg;
647 dprintk(1, KERN_DEBUG "VIDIOC_G_CTRL");
648
649 return tvp5150_get_ctrl(client, ctrl);
650 }
651 case VIDIOC_S_CTRL_OLD: /* ??? */
652 case VIDIOC_S_CTRL:
653 {
654 struct v4l2_control *ctrl = arg;
655 u8 i, n;
656 dprintk(1, KERN_DEBUG "VIDIOC_S_CTRL");
657 n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
658 for (i = 0; i < n; i++)
659 if (ctrl->id == tvp5150_qctrl[i].id) {
660 if (ctrl->value <
661 tvp5150_qctrl[i].minimum
662 || ctrl->value >
663 tvp5150_qctrl[i].maximum)
664 return -ERANGE;
665 dprintk(1,
666 KERN_DEBUG
667 "VIDIOC_S_CTRL: id=%d, value=%d",
668 ctrl->id, ctrl->value);
669 return tvp5150_set_ctrl(client, ctrl);
670 }
671 return -EINVAL;
672 }
673
674 case DECODER_SET_PICTURE:
675 {
676 struct video_picture *pic = arg;
677 if (decoder->bright != pic->brightness) {
678 /* We want 0 to 255 we get 0-65535 */
679 decoder->bright = pic->brightness;
680 tvp5150_write(client, TVP5150_BRIGHT_CTL,
681 decoder->bright >> 8);
682 }
683 if (decoder->contrast != pic->contrast) {
684 /* We want 0 to 255 we get 0-65535 */
685 decoder->contrast = pic->contrast;
686 tvp5150_write(client, TVP5150_CONTRAST_CTL,
687 decoder->contrast >> 8);
688 }
689 if (decoder->sat != pic->colour) {
690 /* We want 0 to 255 we get 0-65535 */
691 decoder->sat = pic->colour;
692 tvp5150_write(client, TVP5150_SATURATION_CTL,
693 decoder->contrast >> 8);
694 }
695 if (decoder->hue != pic->hue) {
696 /* We want -128 to 127 we get 0-65535 */
697 decoder->hue = pic->hue;
698 tvp5150_write(client, TVP5150_HUE_CTL,
699 (decoder->hue - 32768) >> 8);
700 }
701 break;
702 }
703 default:
704 return -EINVAL;
705 }
706
707 return 0;
708}
709
710/****************************************************************************
711 I2C Client & Driver
712 ****************************************************************************/
713static struct i2c_driver driver;
714
715static struct i2c_client client_template = {
716 .name = "(unset)",
717 .flags = I2C_CLIENT_ALLOW_USE,
718 .driver = &driver,
719};
720
721static int tvp5150_detect_client(struct i2c_adapter *adapter,
722 int address, int kind)
723{
724 struct i2c_client *client;
725 struct tvp5150 *core;
726 int rv;
727
728 dprintk(1,
729 KERN_INFO
730 "tvp5150.c: detecting tvp5150 client on address 0x%x\n",
731 address << 1);
732
733 client_template.adapter = adapter;
734 client_template.addr = address;
735
736 /* Check if the adapter supports the needed features */
737 if (!i2c_check_functionality
738 (adapter,
739 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
740 return 0;
741
742 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
743 if (client == 0)
744 return -ENOMEM;
745 memcpy(client, &client_template, sizeof(struct i2c_client));
746
747 core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL);
748 if (core == 0) {
749 kfree(client);
750 return -ENOMEM;
751 }
752 memset(core, 0, sizeof(struct tvp5150));
753 i2c_set_clientdata(client, core);
754
755 rv = i2c_attach_client(client);
756
757 core->norm = VIDEO_MODE_AUTO;
758 core->input = 2;
759 core->enable = 1;
760 core->bright = 32768;
761 core->contrast = 32768;
762 core->hue = 32768;
763 core->sat = 32768;
764
765 if (rv) {
766 kfree(client);
767 kfree(core);
768 return rv;
769 }
770
771 if (debug > 1)
772 dump_reg(client);
773
774 return 0;
775}
776
777static int tvp5150_attach_adapter(struct i2c_adapter *adapter)
778{
779 dprintk(1,
780 KERN_INFO
781 "tvp5150.c: starting probe for adapter %s (0x%x)\n",
782 adapter->name, adapter->id);
783 return i2c_probe(adapter, &addr_data, &tvp5150_detect_client);
784}
785
786static int tvp5150_detach_client(struct i2c_client *client)
787{
788 struct tvp5150 *decoder = i2c_get_clientdata(client);
789 int err;
790
791 err = i2c_detach_client(client);
792 if (err) {
793 return err;
794 }
795
796 kfree(decoder);
797 kfree(client);
798
799 return 0;
800}
801
802/* ----------------------------------------------------------------------- */
803
804static struct i2c_driver driver = {
805 .owner = THIS_MODULE,
806 .name = "tvp5150",
807
808 /* FIXME */
809 .id = I2C_DRIVERID_SAA7110,
810 .flags = I2C_DF_NOTIFY,
811
812 .attach_adapter = tvp5150_attach_adapter,
813 .detach_client = tvp5150_detach_client,
814
815 .command = tvp5150_command,
816};
817
818static int __init tvp5150_init(void)
819{
820 return i2c_add_driver(&driver);
821}
822
823static void __exit tvp5150_exit(void)
824{
825 i2c_del_driver(&driver);
826}
827
828module_init(tvp5150_init);
829module_exit(tvp5150_exit);
diff --git a/drivers/media/video/tvp5150_reg.h b/drivers/media/video/tvp5150_reg.h
new file mode 100644
index 000000000000..cd45c1ded786
--- /dev/null
+++ b/drivers/media/video/tvp5150_reg.h
@@ -0,0 +1,173 @@
1#define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */
2#define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */
3#define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */
4#define TVP5150_MISC_CTL 0x03 /* Miscellaneous controls */
5#define TVP5150_AUTOSW_MSK 0x04 /* Autoswitch mask: TVP5150A / TVP5150AM */
6
7/* Reserved 05h */
8
9#define TVP5150_COLOR_KIL_THSH_CTL 0x06 /* Color killer threshold control */
10#define TVP5150_LUMA_PROC_CTL_1 0x07 /* Luminance processing control #1 */
11#define TVP5150_LUMA_PROC_CTL_2 0x08 /* Luminance processing control #2 */
12#define TVP5150_BRIGHT_CTL 0x09 /* Brightness control */
13#define TVP5150_SATURATION_CTL 0x0a /* Color saturation control */
14#define TVP5150_HUE_CTL 0x0b /* Hue control */
15#define TVP5150_CONTRAST_CTL 0x0c /* Contrast control */
16#define TVP5150_DATA_RATE_SEL 0x0d /* Outputs and data rates select */
17#define TVP5150_LUMA_PROC_CTL_3 0x0e /* Luminance processing control #3 */
18#define TVP5150_CONF_SHARED_PIN 0x0f /* Configuration shared pins */
19
20/* Reserved 10h */
21
22#define TVP5150_ACT_VD_CROP_ST_MSB 0x11 /* Active video cropping start MSB */
23#define TVP5150_ACT_VD_CROP_ST_LSB 0x12 /* Active video cropping start LSB */
24#define TVP5150_ACT_VD_CROP_STP_MSB 0x13 /* Active video cropping stop MSB */
25#define TVP5150_ACT_VD_CROP_STP_LSB 0x14 /* Active video cropping stop LSB */
26#define TVP5150_GENLOCK 0x15 /* Genlock/RTC */
27#define TVP5150_HORIZ_SYNC_START 0x16 /* Horizontal sync start */
28
29/* Reserved 17h */
30
31#define TVP5150_VERT_BLANKING_START 0x18 /* Vertical blanking start */
32#define TVP5150_VERT_BLANKING_STOP 0x19 /* Vertical blanking stop */
33#define TVP5150_CHROMA_PROC_CTL_1 0x1a /* Chrominance processing control #1 */
34#define TVP5150_CHROMA_PROC_CTL_2 0x1b /* Chrominance processing control #2 */
35#define TVP5150_INT_RESET_REG_B 0x1c /* Interrupt reset register B */
36#define TVP5150_INT_ENABLE_REG_B 0x1d /* Interrupt enable register B */
37#define TVP5150_INTT_CONFIG_REG_B 0x1e /* Interrupt configuration register B */
38
39/* Reserved 1Fh-27h */
40
41#define TVP5150_VIDEO_STD 0x28 /* Video standard */
42
43/* Reserved 29h-2bh */
44
45#define TVP5150_CB_GAIN_FACT 0x2c /* Cb gain factor */
46#define TVP5150_CR_GAIN_FACTOR 0x2d /* Cr gain factor */
47#define TVP5150_MACROVISION_ON_CTR 0x2e /* Macrovision on counter */
48#define TVP5150_MACROVISION_OFF_CTR 0x2f /* Macrovision off counter */
49#define TVP5150_REV_SELECT 0x30 /* revision select (TVP5150AM1 only) */
50
51/* Reserved 31h-7Fh */
52
53#define TVP5150_MSB_DEV_ID 0x80 /* MSB of device ID */
54#define TVP5150_LSB_DEV_ID 0x81 /* LSB of device ID */
55#define TVP5150_ROM_MAJOR_VER 0x82 /* ROM major version */
56#define TVP5150_ROM_MINOR_VER 0x83 /* ROM minor version */
57#define TVP5150_VERT_LN_COUNT_MSB 0x84 /* Vertical line count MSB */
58#define TVP5150_VERT_LN_COUNT_LSB 0x85 /* Vertical line count LSB */
59#define TVP5150_INT_STATUS_REG_B 0x86 /* Interrupt status register B */
60#define TVP5150_INT_ACTIVE_REG_B 0x87 /* Interrupt active register B */
61#define TVP5150_STATUS_REG_1 0x88 /* Status register #1 */
62#define TVP5150_STATUS_REG_2 0x89 /* Status register #2 */
63#define TVP5150_STATUS_REG_3 0x8a /* Status register #3 */
64#define TVP5150_STATUS_REG_4 0x8b /* Status register #4 */
65#define TVP5150_STATUS_REG_5 0x8c /* Status register #5 */
66/* Reserved 8Dh-8Fh */
67#define TVP5150_CC_DATA_REG1 0x90 /* Closed caption data registers */
68#define TVP5150_CC_DATA_REG2 0x91 /* Closed caption data registers */
69#define TVP5150_CC_DATA_REG3 0x92 /* Closed caption data registers */
70#define TVP5150_CC_DATA_REG4 0x93 /* Closed caption data registers */
71#define TVP5150_WSS_DATA_REG1 0X94 /* WSS data registers */
72#define TVP5150_WSS_DATA_REG2 0X95 /* WSS data registers */
73#define TVP5150_WSS_DATA_REG3 0X96 /* WSS data registers */
74#define TVP5150_WSS_DATA_REG4 0X97 /* WSS data registers */
75#define TVP5150_WSS_DATA_REG5 0X98 /* WSS data registers */
76#define TVP5150_WSS_DATA_REG6 0X99 /* WSS data registers */
77#define TVP5150_VPS_DATA_REG1 0x9a /* VPS data registers */
78#define TVP5150_VPS_DATA_REG2 0x9b /* VPS data registers */
79#define TVP5150_VPS_DATA_REG3 0x9c /* VPS data registers */
80#define TVP5150_VPS_DATA_REG4 0x9d /* VPS data registers */
81#define TVP5150_VPS_DATA_REG5 0x9e /* VPS data registers */
82#define TVP5150_VPS_DATA_REG6 0x9f /* VPS data registers */
83#define TVP5150_VPS_DATA_REG7 0xa0 /* VPS data registers */
84#define TVP5150_VPS_DATA_REG8 0xa1 /* VPS data registers */
85#define TVP5150_VPS_DATA_REG9 0xa2 /* VPS data registers */
86#define TVP5150_VPS_DATA_REG10 0xa3 /* VPS data registers */
87#define TVP5150_VPS_DATA_REG11 0xa4 /* VPS data registers */
88#define TVP5150_VPS_DATA_REG12 0xa5 /* VPS data registers */
89#define TVP5150_VPS_DATA_REG13 0xa6 /* VPS data registers */
90#define TVP5150_VITC_DATA_REG1 0xa7 /* VITC data registers */
91#define TVP5150_VITC_DATA_REG2 0xa8 /* VITC data registers */
92#define TVP5150_VITC_DATA_REG3 0xa9 /* VITC data registers */
93#define TVP5150_VITC_DATA_REG4 0xaa /* VITC data registers */
94#define TVP5150_VITC_DATA_REG5 0xab /* VITC data registers */
95#define TVP5150_VITC_DATA_REG6 0xac /* VITC data registers */
96#define TVP5150_VITC_DATA_REG7 0xad /* VITC data registers */
97#define TVP5150_VITC_DATA_REG8 0xae /* VITC data registers */
98#define TVP5150_VITC_DATA_REG9 0xaf /* VITC data registers */
99#define TVP5150_VBI_FIFO_READ_DATA 0xb0 /* VBI FIFO read data */
100#define TVP5150_TELETEXT_FIL_1_1 0xb1 /* Teletext filter 1 */
101#define TVP5150_TELETEXT_FIL_1_2 0xb2 /* Teletext filter 1 */
102#define TVP5150_TELETEXT_FIL_1_3 0xb3 /* Teletext filter 1 */
103#define TVP5150_TELETEXT_FIL_1_4 0xb4 /* Teletext filter 1 */
104#define TVP5150_TELETEXT_FIL_1_5 0xb5 /* Teletext filter 1 */
105#define TVP5150_TELETEXT_FIL_2_1 0xb6 /* Teletext filter 2 */
106#define TVP5150_TELETEXT_FIL_2_2 0xb7 /* Teletext filter 2 */
107#define TVP5150_TELETEXT_FIL_2_3 0xb8 /* Teletext filter 2 */
108#define TVP5150_TELETEXT_FIL_2_4 0xb9 /* Teletext filter 2 */
109#define TVP5150_TELETEXT_FIL_2_5 0xba /* Teletext filter 2 */
110#define TVP5150_TELETEXT_FIL_ENA 0xbb /* Teletext filter enable */
111/* Reserved BCh-BFh */
112#define TVP5150_INT_STATUS_REG_A 0xc0 /* Interrupt status register A */
113#define TVP5150_INT_ENABLE_REG_A 0xc1 /* Interrupt enable register A */
114#define TVP5150_INT_CONF 0xc2 /* Interrupt configuration */
115#define TVP5150_VDP_CONF_RAM_DATA 0xc3 /* VDP configuration RAM data */
116#define TVP5150_CONF_RAM_ADDR_LOW 0xc4 /* Configuration RAM address low byte */
117#define TVP5150_CONF_RAM_ADDR_HIGH 0xc5 /* Configuration RAM address high byte */
118#define TVP5150_VDP_STATUS_REG 0xc6 /* VDP status register */
119#define TVP5150_FIFO_WORD_COUNT 0xc7 /* FIFO word count */
120#define TVP5150_FIFO_INT_THRESHOLD 0xc8 /* FIFO interrupt threshold */
121#define TVP5150_FIFO_RESET 0xc9 /* FIFO reset */
122#define TVP5150_LINE_NUMBER_INT 0xca /* Line number interrupt */
123#define TVP5150_PIX_ALIGN_REG_LOW 0xcb /* Pixel alignment register low byte */
124#define TVP5150_PIX_ALIGN_REG_HIGH 0xcc /* Pixel alignment register high byte */
125#define TVP5150_FIFO_OUT_CTRL 0xcd /* FIFO output control */
126/* Reserved CEh */
127#define TVP5150_FULL_FIELD_ENA_1 0xcf /* Full field enable 1 */
128#define TVP5150_FULL_FIELD_ENA_2 0xd0 /* Full field enable 2 */
129#define TVP5150_LINE_MODE_REG_1 0xd1 /* Line mode registers */
130#define TVP5150_LINE_MODE_REG_2 0xd2 /* Line mode registers */
131#define TVP5150_LINE_MODE_REG_3 0xd3 /* Line mode registers */
132#define TVP5150_LINE_MODE_REG_4 0xd4 /* Line mode registers */
133#define TVP5150_LINE_MODE_REG_5 0xd5 /* Line mode registers */
134#define TVP5150_LINE_MODE_REG_6 0xd6 /* Line mode registers */
135#define TVP5150_LINE_MODE_REG_7 0xd7 /* Line mode registers */
136#define TVP5150_LINE_MODE_REG_8 0xd8 /* Line mode registers */
137#define TVP5150_LINE_MODE_REG_9 0xd9 /* Line mode registers */
138#define TVP5150_LINE_MODE_REG_10 0xda /* Line mode registers */
139#define TVP5150_LINE_MODE_REG_11 0xdb /* Line mode registers */
140#define TVP5150_LINE_MODE_REG_12 0xdc /* Line mode registers */
141#define TVP5150_LINE_MODE_REG_13 0xdd /* Line mode registers */
142#define TVP5150_LINE_MODE_REG_14 0xde /* Line mode registers */
143#define TVP5150_LINE_MODE_REG_15 0xdf /* Line mode registers */
144#define TVP5150_LINE_MODE_REG_16 0xe0 /* Line mode registers */
145#define TVP5150_LINE_MODE_REG_17 0xe1 /* Line mode registers */
146#define TVP5150_LINE_MODE_REG_18 0xe2 /* Line mode registers */
147#define TVP5150_LINE_MODE_REG_19 0xe3 /* Line mode registers */
148#define TVP5150_LINE_MODE_REG_20 0xe4 /* Line mode registers */
149#define TVP5150_LINE_MODE_REG_21 0xe5 /* Line mode registers */
150#define TVP5150_LINE_MODE_REG_22 0xe6 /* Line mode registers */
151#define TVP5150_LINE_MODE_REG_23 0xe7 /* Line mode registers */
152#define TVP5150_LINE_MODE_REG_24 0xe8 /* Line mode registers */
153#define TVP5150_LINE_MODE_REG_25 0xe9 /* Line mode registers */
154#define TVP5150_LINE_MODE_REG_27 0xea /* Line mode registers */
155#define TVP5150_LINE_MODE_REG_28 0xeb /* Line mode registers */
156#define TVP5150_LINE_MODE_REG_29 0xec /* Line mode registers */
157#define TVP5150_LINE_MODE_REG_30 0xed /* Line mode registers */
158#define TVP5150_LINE_MODE_REG_31 0xee /* Line mode registers */
159#define TVP5150_LINE_MODE_REG_32 0xef /* Line mode registers */
160#define TVP5150_LINE_MODE_REG_33 0xf0 /* Line mode registers */
161#define TVP5150_LINE_MODE_REG_34 0xf1 /* Line mode registers */
162#define TVP5150_LINE_MODE_REG_35 0xf2 /* Line mode registers */
163#define TVP5150_LINE_MODE_REG_36 0xf3 /* Line mode registers */
164#define TVP5150_LINE_MODE_REG_37 0xf4 /* Line mode registers */
165#define TVP5150_LINE_MODE_REG_38 0xf5 /* Line mode registers */
166#define TVP5150_LINE_MODE_REG_39 0xf6 /* Line mode registers */
167#define TVP5150_LINE_MODE_REG_40 0xf7 /* Line mode registers */
168#define TVP5150_LINE_MODE_REG_41 0xf8 /* Line mode registers */
169#define TVP5150_LINE_MODE_REG_42 0xf9 /* Line mode registers */
170#define TVP5150_LINE_MODE_REG_43 0xfa /* Line mode registers */
171#define TVP5150_LINE_MODE_REG_44 0xfb /* Line mode registers */
172#define TVP5150_FULL_FIELD_MODE_REG 0xfc /* Full field mode register */
173/* Reserved FDh-FFh */
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index d679ca23ded7..4134549d11a8 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -708,7 +708,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
708 } 708 }
709 case VIDIOCGFREQ: /* get frequency */ 709 case VIDIOCGFREQ: /* get frequency */
710 { 710 {
711 int *freq = arg; 711 unsigned long *freq = arg;
712 712
713 freq2.tuner = 0; 713 freq2.tuner = 0;
714 err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); 714 err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
@@ -720,7 +720,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
720 } 720 }
721 case VIDIOCSFREQ: /* set frequency */ 721 case VIDIOCSFREQ: /* set frequency */
722 { 722 {
723 int *freq = arg; 723 unsigned long *freq = arg;
724 724
725 freq2.tuner = 0; 725 freq2.tuner = 0;
726 drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); 726 drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
@@ -960,7 +960,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
960 fmt->start[1] = fmt2->fmt.vbi.start[1]; 960 fmt->start[1] = fmt2->fmt.vbi.start[1];
961 fmt->count[1] = fmt2->fmt.vbi.count[1]; 961 fmt->count[1] = fmt2->fmt.vbi.count[1];
962 fmt->flags = fmt2->fmt.vbi.flags & 0x03; 962 fmt->flags = fmt2->fmt.vbi.flags & 0x03;
963 break; 963 break;
964 } 964 }
965 case VIDIOCSVBIFMT: 965 case VIDIOCSVBIFMT:
966 { 966 {
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
index 574b8e36f3c6..acfd3a103f35 100644
--- a/drivers/media/video/video-buf.c
+++ b/drivers/media/video/video-buf.c
@@ -147,7 +147,7 @@ int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
147 data,size,dma->nr_pages); 147 data,size,dma->nr_pages);
148 148
149 down_read(&current->mm->mmap_sem); 149 down_read(&current->mm->mmap_sem);
150 err = get_user_pages(current,current->mm, 150 err = get_user_pages(current,current->mm,
151 data & PAGE_MASK, dma->nr_pages, 151 data & PAGE_MASK, dma->nr_pages,
152 rw == READ, 1, /* force */ 152 rw == READ, 1, /* force */
153 dma->pages, NULL); 153 dma->pages, NULL);
@@ -750,9 +750,9 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
750{ 750{
751 enum v4l2_field field; 751 enum v4l2_field field;
752 unsigned long flags; 752 unsigned long flags;
753 int retval; 753 int retval;
754 754
755 /* setup stuff */ 755 /* setup stuff */
756 retval = -ENOMEM; 756 retval = -ENOMEM;
757 q->read_buf = videobuf_alloc(q->msize); 757 q->read_buf = videobuf_alloc(q->msize);
758 if (NULL == q->read_buf) 758 if (NULL == q->read_buf)
@@ -760,18 +760,18 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
760 760
761 q->read_buf->memory = V4L2_MEMORY_USERPTR; 761 q->read_buf->memory = V4L2_MEMORY_USERPTR;
762 q->read_buf->baddr = (unsigned long)data; 762 q->read_buf->baddr = (unsigned long)data;
763 q->read_buf->bsize = count; 763 q->read_buf->bsize = count;
764 field = videobuf_next_field(q); 764 field = videobuf_next_field(q);
765 retval = q->ops->buf_prepare(q,q->read_buf,field); 765 retval = q->ops->buf_prepare(q,q->read_buf,field);
766 if (0 != retval) 766 if (0 != retval)
767 goto done; 767 goto done;
768 768
769 /* start capture & wait */ 769 /* start capture & wait */
770 spin_lock_irqsave(q->irqlock,flags); 770 spin_lock_irqsave(q->irqlock,flags);
771 q->ops->buf_queue(q,q->read_buf); 771 q->ops->buf_queue(q,q->read_buf);
772 spin_unlock_irqrestore(q->irqlock,flags); 772 spin_unlock_irqrestore(q->irqlock,flags);
773 retval = videobuf_waiton(q->read_buf,0,0); 773 retval = videobuf_waiton(q->read_buf,0,0);
774 if (0 == retval) { 774 if (0 == retval) {
775 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); 775 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
776 if (STATE_ERROR == q->read_buf->state) 776 if (STATE_ERROR == q->read_buf->state)
777 retval = -EIO; 777 retval = -EIO;
@@ -828,7 +828,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
828 } 828 }
829 829
830 /* wait until capture is done */ 830 /* wait until capture is done */
831 retval = videobuf_waiton(q->read_buf, nonblocking, 1); 831 retval = videobuf_waiton(q->read_buf, nonblocking, 1);
832 if (0 != retval) 832 if (0 != retval)
833 goto done; 833 goto done;
834 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); 834 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
@@ -1096,7 +1096,7 @@ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
1096 1096
1097 dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n", 1097 dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n",
1098 vaddr,vma->vm_start,vma->vm_end); 1098 vaddr,vma->vm_start,vma->vm_end);
1099 if (vaddr > vma->vm_end) 1099 if (vaddr > vma->vm_end)
1100 return NOPAGE_SIGBUS; 1100 return NOPAGE_SIGBUS;
1101 page = alloc_page(GFP_USER); 1101 page = alloc_page(GFP_USER);
1102 if (!page) 1102 if (!page)
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
new file mode 100644
index 000000000000..22f286222004
--- /dev/null
+++ b/drivers/media/video/wm8775.c
@@ -0,0 +1,254 @@
1/*
2 * wm8775 - driver version 0.0.1
3 *
4 * Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to>
5 *
6 * Based on saa7115 driver
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#include <linux/module.h>
25#include <linux/types.h>
26#include <linux/ioctl.h>
27#include <asm/uaccess.h>
28#include <linux/i2c.h>
29#include <linux/i2c-id.h>
30#include <linux/videodev.h>
31#include <media/audiochip.h>
32
33MODULE_DESCRIPTION("wm8775 driver");
34MODULE_AUTHOR("Ulf Eklund");
35MODULE_LICENSE("GPL");
36
37#define wm8775_err(fmt, arg...) do { \
38 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
39 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
40#define wm8775_info(fmt, arg...) do { \
41 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
42 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
43
44
45static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
46
47
48I2C_CLIENT_INSMOD;
49
50/* ----------------------------------------------------------------------- */
51
52enum {
53 R7 = 7, R11 = 11,
54 R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R23 = 23,
55 TOT_REGS
56};
57
58struct wm8775_state {
59 u8 input; /* Last selected input (0-0xf) */
60 u8 muted;
61};
62
63static int wm8775_write(struct i2c_client *client, int reg, u16 val)
64{
65 int i;
66
67 if (reg < 0 || reg >= TOT_REGS) {
68 wm8775_err("Invalid register R%d\n", reg);
69 return -1;
70 }
71
72 for (i = 0; i < 3; i++) {
73 if (i2c_smbus_write_byte_data(client, (reg << 1) |
74 (val >> 8), val & 0xff) == 0) {
75 return 0;
76 }
77 }
78 wm8775_err("I2C: cannot write %03x to register R%d\n", val, reg);
79 return -1;
80}
81
82static int wm8775_command(struct i2c_client *client, unsigned int cmd,
83 void *arg)
84{
85 struct wm8775_state *state = i2c_get_clientdata(client);
86 int *input = arg;
87
88 switch (cmd) {
89 case AUDC_SET_INPUT:
90 wm8775_write(client, R21, 0x0c0);
91 wm8775_write(client, R14, 0x1d4);
92 wm8775_write(client, R15, 0x1d4);
93
94 if (*input == AUDIO_RADIO) {
95 wm8775_write(client, R21, 0x108);
96 state->input = 8;
97 state->muted = 0;
98 break;
99 }
100 if (*input == AUDIO_MUTE) {
101 state->muted = 1;
102 break;
103 }
104 if (*input == AUDIO_UNMUTE) {
105 wm8775_write(client, R21, 0x100 + state->input);
106 state->muted = 0;
107 break;
108 }
109 /* All other inputs... */
110 wm8775_write(client, R21, 0x102);
111 state->input = 2;
112 state->muted = 0;
113 break;
114
115 case VIDIOC_LOG_STATUS:
116 wm8775_info("Input: %s%s\n",
117 state->input == 8 ? "radio" : "default",
118 state->muted ? " (muted)" : "");
119 break;
120
121 case VIDIOC_S_FREQUENCY:
122 /* If I remove this, then it can happen that I have no
123 sound the first time I tune from static to a valid channel.
124 It's difficult to reproduce and is almost certainly related
125 to the zero cross detect circuit. */
126 wm8775_write(client, R21, 0x0c0);
127 wm8775_write(client, R14, 0x1d4);
128 wm8775_write(client, R15, 0x1d4);
129 wm8775_write(client, R21, 0x100 + state->input);
130 break;
131
132 default:
133 return -EINVAL;
134 }
135 return 0;
136}
137
138/* ----------------------------------------------------------------------- */
139
140/* i2c implementation */
141
142/*
143 * Generic i2c probe
144 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
145 */
146
147static struct i2c_driver i2c_driver;
148
149static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind)
150{
151 struct i2c_client *client;
152 struct wm8775_state *state;
153
154 /* Check if the adapter supports the needed features */
155 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
156 return 0;
157
158 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
159 if (client == 0)
160 return -ENOMEM;
161
162 memset(client, 0, sizeof(struct i2c_client));
163 client->addr = address;
164 client->adapter = adapter;
165 client->driver = &i2c_driver;
166 client->flags = I2C_CLIENT_ALLOW_USE;
167 snprintf(client->name, sizeof(client->name) - 1, "wm8775");
168
169 wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
170
171 state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL);
172 if (state == NULL) {
173 kfree(client);
174 return -ENOMEM;
175 }
176 state->input = 2;
177 state->muted = 0;
178 i2c_set_clientdata(client, state);
179
180 /* initialize wm8775 */
181 wm8775_write(client, R23, 0x000); /* RESET */
182 wm8775_write(client, R7, 0x000); /* Disable zero cross detect timeout */
183 wm8775_write(client, R11, 0x021); /* Left justified, 24-bit mode */
184 wm8775_write(client, R12, 0x102); /* Master mode, clock ratio 256fs */
185 wm8775_write(client, R13, 0x000); /* Powered up */
186 wm8775_write(client, R14, 0x1d4); /* ADC gain +2.5dB, enable zero cross */
187 wm8775_write(client, R15, 0x1d4); /* ADC gain +2.5dB, enable zero cross */
188 wm8775_write(client, R16, 0x1bf); /* ALC Stereo, ALC target level -1dB FS */
189 /* max gain +8dB */
190 wm8775_write(client, R17, 0x185); /* Enable gain control, use zero cross */
191 /* detection, ALC hold time 42.6 ms */
192 wm8775_write(client, R18, 0x0a2); /* ALC gain ramp up delay 34 s, */
193 /* ALC gain ramp down delay 33 ms */
194 wm8775_write(client, R19, 0x005); /* Enable noise gate, threshold -72dBfs */
195 wm8775_write(client, R20, 0x07a); /* Transient window 4ms, lower PGA gain */
196 /* limit -1dB */
197 wm8775_write(client, R21, 0x102); /* LRBOTH = 1, use input 2. */
198 i2c_attach_client(client);
199
200 return 0;
201}
202
203static int wm8775_probe(struct i2c_adapter *adapter)
204{
205#ifdef I2C_CLASS_TV_ANALOG
206 if (adapter->class & I2C_CLASS_TV_ANALOG)
207#else
208 if (adapter->id == I2C_HW_B_BT848)
209#endif
210 return i2c_probe(adapter, &addr_data, wm8775_attach);
211 return 0;
212}
213
214static int wm8775_detach(struct i2c_client *client)
215{
216 int err;
217
218 err = i2c_detach_client(client);
219 if (err) {
220 return err;
221 }
222 kfree(client);
223
224 return 0;
225}
226
227/* ----------------------------------------------------------------------- */
228
229/* i2c implementation */
230static struct i2c_driver i2c_driver = {
231 .name = "wm8775",
232
233 .id = I2C_DRIVERID_WM8775,
234 .flags = I2C_DF_NOTIFY,
235
236 .attach_adapter = wm8775_probe,
237 .detach_client = wm8775_detach,
238 .command = wm8775_command,
239 .owner = THIS_MODULE,
240};
241
242
243static int __init wm8775_init_module(void)
244{
245 return i2c_add_driver(&i2c_driver);
246}
247
248static void __exit wm8775_cleanup_module(void)
249{
250 i2c_del_driver(&i2c_driver);
251}
252
253module_init(wm8775_init_module);
254module_exit(wm8775_cleanup_module);
diff --git a/drivers/media/video/zr36016.c b/drivers/media/video/zr36016.c
index d4740a89cea1..4ed898585c70 100644
--- a/drivers/media/video/zr36016.c
+++ b/drivers/media/video/zr36016.c
@@ -26,7 +26,6 @@
26 26
27#define ZR016_VERSION "v0.7" 27#define ZR016_VERSION "v0.7"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c
index 13b1e7b6fd6e..0144576a6123 100644
--- a/drivers/media/video/zr36050.c
+++ b/drivers/media/video/zr36050.c
@@ -26,7 +26,6 @@
26 26
27#define ZR050_VERSION "v0.7.1" 27#define ZR050_VERSION "v0.7.1"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c
index b50dc403e6db..129744a07abd 100644
--- a/drivers/media/video/zr36060.c
+++ b/drivers/media/video/zr36060.c
@@ -26,7 +26,6 @@
26 26
27#define ZR060_VERSION "v0.7" 27#define ZR060_VERSION "v0.7"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 790a2932ded9..74022316fc63 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -47,7 +47,6 @@
47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48 48
49#include <linux/config.h> 49#include <linux/config.h>
50#include <linux/version.h>
51#include <linux/kernel.h> 50#include <linux/kernel.h>
52#include <linux/module.h> 51#include <linux/module.h>
53#include <linux/errno.h> 52#include <linux/errno.h>
@@ -92,9 +91,9 @@ static int mfcounter = 0;
92 * Public data... 91 * Public data...
93 */ 92 */
94int mpt_lan_index = -1; 93int mpt_lan_index = -1;
95int mpt_stm_index = -1; 94static int mpt_stm_index = -1;
96 95
97struct proc_dir_entry *mpt_proc_root_dir; 96static struct proc_dir_entry *mpt_proc_root_dir;
98 97
99#define WHOINIT_UNKNOWN 0xAA 98#define WHOINIT_UNKNOWN 0xAA
100 99
@@ -6272,7 +6271,6 @@ EXPORT_SYMBOL(mpt_resume);
6272EXPORT_SYMBOL(mpt_suspend); 6271EXPORT_SYMBOL(mpt_suspend);
6273#endif 6272#endif
6274EXPORT_SYMBOL(ioc_list); 6273EXPORT_SYMBOL(ioc_list);
6275EXPORT_SYMBOL(mpt_proc_root_dir);
6276EXPORT_SYMBOL(mpt_register); 6274EXPORT_SYMBOL(mpt_register);
6277EXPORT_SYMBOL(mpt_deregister); 6275EXPORT_SYMBOL(mpt_deregister);
6278EXPORT_SYMBOL(mpt_event_register); 6276EXPORT_SYMBOL(mpt_event_register);
@@ -6290,7 +6288,6 @@ EXPORT_SYMBOL(mpt_verify_adapter);
6290EXPORT_SYMBOL(mpt_GetIocState); 6288EXPORT_SYMBOL(mpt_GetIocState);
6291EXPORT_SYMBOL(mpt_print_ioc_summary); 6289EXPORT_SYMBOL(mpt_print_ioc_summary);
6292EXPORT_SYMBOL(mpt_lan_index); 6290EXPORT_SYMBOL(mpt_lan_index);
6293EXPORT_SYMBOL(mpt_stm_index);
6294EXPORT_SYMBOL(mpt_HardResetHandler); 6291EXPORT_SYMBOL(mpt_HardResetHandler);
6295EXPORT_SYMBOL(mpt_config); 6292EXPORT_SYMBOL(mpt_config);
6296EXPORT_SYMBOL(mpt_toolbox); 6293EXPORT_SYMBOL(mpt_toolbox);
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index e7efeb7740b9..8ad277a9afa1 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -49,7 +49,6 @@
49#define MPTBASE_H_INCLUDED 49#define MPTBASE_H_INCLUDED
50/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 50/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
51 51
52#include <linux/version.h>
53#include <linux/config.h> 52#include <linux/config.h>
54#include <linux/kernel.h> 53#include <linux/kernel.h>
55#include <linux/pci.h> 54#include <linux/pci.h>
@@ -1007,10 +1006,8 @@ extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
1007 * Public data decl's... 1006 * Public data decl's...
1008 */ 1007 */
1009extern struct list_head ioc_list; 1008extern struct list_head ioc_list;
1010extern struct proc_dir_entry *mpt_proc_root_dir;
1011 1009
1012extern int mpt_lan_index; /* needed by mptlan.c */ 1010extern int mpt_lan_index; /* needed by mptlan.c */
1013extern int mpt_stm_index; /* needed by mptstm.c */
1014 1011
1015/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1012/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1016#endif /* } __KERNEL__ */ 1013#endif /* } __KERNEL__ */
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index cb2d59d5f5af..602138f8544d 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -45,7 +45,6 @@
45*/ 45*/
46/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 46/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
47 47
48#include <linux/version.h>
49#include <linux/kernel.h> 48#include <linux/kernel.h>
50#include <linux/module.h> 49#include <linux/module.h>
51#include <linux/errno.h> 50#include <linux/errno.h>
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
index 28754a9cb803..518996e03481 100644
--- a/drivers/message/fusion/mptctl.h
+++ b/drivers/message/fusion/mptctl.h
@@ -49,7 +49,6 @@
49#define MPTCTL_H_INCLUDED 49#define MPTCTL_H_INCLUDED
50/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 50/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
51 51
52#include "linux/version.h"
53 52
54 53
55/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 54/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h
index 750e343eb981..3726ecba5707 100644
--- a/drivers/message/fusion/mptlan.h
+++ b/drivers/message/fusion/mptlan.h
@@ -66,7 +66,6 @@
66#include <linux/slab.h> 66#include <linux/slab.h>
67#include <linux/miscdevice.h> 67#include <linux/miscdevice.h>
68#include <linux/spinlock.h> 68#include <linux/spinlock.h>
69#include <linux/version.h>
70#include <linux/workqueue.h> 69#include <linux/workqueue.h>
71#include <linux/delay.h> 70#include <linux/delay.h>
72// #include <linux/trdevice.h> 71// #include <linux/trdevice.h>
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
index 9c4dd682ac74..bc2b72b32905 100644
--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
+++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/version.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/spinlock.h> 19#include <linux/spinlock.h>
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c
index 165f3405df27..4bb461793851 100644
--- a/drivers/misc/hdpuftrs/hdpu_nexus.c
+++ b/drivers/misc/hdpuftrs/hdpu_nexus.c
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/version.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
index ecce4ffd3e23..d7e20a34f88d 100644
--- a/drivers/misc/ibmasm/ibmasm.h
+++ b/drivers/misc/ibmasm/ibmasm.h
@@ -31,7 +31,6 @@
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/config.h> 32#include <linux/config.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/version.h>
35#include <linux/interrupt.h> 34#include <linux/interrupt.h>
36#include <linux/device.h> 35#include <linux/device.h>
37#include <linux/input.h> 36#include <linux/input.h>
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index c4a19d2dc67f..0807c1c91e55 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -20,7 +20,6 @@
20 * - Plugged memory leak in cfi_staa_writev(). 20 * - Plugged memory leak in cfi_staa_writev().
21 */ 21 */
22 22
23#include <linux/version.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/types.h> 24#include <linux/types.h>
26#include <linux/kernel.h> 25#include <linux/kernel.h>
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index de48b35f5609..666cce1bf60c 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -82,7 +82,6 @@
82 * * Comb the init routine. It's still a bit cludgy on a few things. 82 * * Comb the init routine. It's still a bit cludgy on a few things.
83 */ 83 */
84 84
85#include <linux/version.h>
86#include <linux/config.h> 85#include <linux/config.h>
87#include <linux/kernel.h> 86#include <linux/kernel.h>
88#include <linux/module.h> 87#include <linux/module.h>
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
index c0daf58357ca..60a6e51d662f 100644
--- a/drivers/mtd/maps/ebony.c
+++ b/drivers/mtd/maps/ebony.c
@@ -21,7 +21,6 @@
21#include <linux/mtd/map.h> 21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/version.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <asm/ibm44x.h> 25#include <asm/ibm44x.h>
27#include <platforms/4xx/ebony.h> 26#include <platforms/4xx/ebony.h>
diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c
index 6e559bc14636..c223514ca2eb 100644
--- a/drivers/mtd/maps/ocotea.c
+++ b/drivers/mtd/maps/ocotea.c
@@ -19,7 +19,6 @@
19#include <linux/mtd/map.h> 19#include <linux/mtd/map.h>
20#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
21#include <linux/config.h> 21#include <linux/config.h>
22#include <linux/version.h>
23#include <asm/io.h> 22#include <asm/io.h>
24#include <asm/ibm44x.h> 23#include <asm/ibm44x.h>
25#include <platforms/4xx/ocotea.h> 24#include <platforms/4xx/ocotea.h>
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c
index 5c17bca3a37e..f46bec66150f 100644
--- a/drivers/mtd/maps/walnut.c
+++ b/drivers/mtd/maps/walnut.c
@@ -21,7 +21,6 @@
21#include <linux/mtd/map.h> 21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/version.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <asm/ibm4xx.h> 25#include <asm/ibm4xx.h>
27#include <platforms/4xx/walnut.h> 26#include <platforms/4xx/walnut.h>
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 3cafcdf28aed..9c5945d6df88 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -17,6 +17,7 @@
17#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
18#include <linux/mtd/nand.h> 18#include <linux/mtd/nand.h>
19#include <linux/mtd/partitions.h> 19#include <linux/mtd/partitions.h>
20#include <linux/version.h>
20#include <asm/io.h> 21#include <asm/io.h>
21 22
22/* fixme: this is ugly */ 23/* fixme: this is ugly */
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index 056dfc17a075..a3c7fea404d0 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -27,7 +27,6 @@
27 * 10-06-2002 TG 128K card support added 27 * 10-06-2002 TG 128K card support added
28 */ 28 */
29 29
30#include <linux/version.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/module.h> 32#include <linux/module.h>
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index cc38fa0d45c6..f67d5d6eb9a6 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -12,6 +12,8 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/sched.h>
16#include <linux/jiffies.h>
15#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
16#include <linux/mtd/onenand.h> 18#include <linux/mtd/onenand.h>
17#include <linux/mtd/partitions.h> 19#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index 041ee59ea77d..0ab8d29caeea 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -18,6 +18,7 @@
18#include <linux/mtd/blktrans.h> 18#include <linux/mtd/blktrans.h>
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
20#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
21#include <linux/jiffies.h>
21 22
22#include <asm/types.h> 23#include <asm/types.h>
23 24
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 1958d9e16a3a..5c69d57f8548 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -447,7 +447,7 @@ config NET_SB1250_MAC
447 447
448config SGI_IOC3_ETH 448config SGI_IOC3_ETH
449 bool "SGI IOC3 Ethernet" 449 bool "SGI IOC3 Ethernet"
450 depends on NET_ETHERNET && PCI && SGI_IP27 && BROKEN 450 depends on NET_ETHERNET && PCI && SGI_IP27
451 select CRC32 451 select CRC32
452 select MII 452 select MII
453 help 453 help
@@ -2523,6 +2523,19 @@ config PPP_BSDCOMP
2523 module; it is called bsd_comp and will show up in the directory 2523 module; it is called bsd_comp and will show up in the directory
2524 modules once you have said "make modules". If unsure, say N. 2524 modules once you have said "make modules". If unsure, say N.
2525 2525
2526config PPP_MPPE
2527 tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
2528 depends on PPP && EXPERIMENTAL
2529 select CRYPTO
2530 select CRYPTO_SHA1
2531 select CRYPTO_ARC4
2532 ---help---
2533 Support for the MPPE Encryption protocol, as employed by the
2534 Microsoft Point-to-Point Tunneling Protocol.
2535
2536 See http://pptpclient.sourceforge.net/ for information on
2537 configuring PPTP clients and servers to utilize this method.
2538
2526config PPPOE 2539config PPPOE
2527 tristate "PPP over Ethernet (EXPERIMENTAL)" 2540 tristate "PPP over Ethernet (EXPERIMENTAL)"
2528 depends on EXPERIMENTAL && PPP 2541 depends on EXPERIMENTAL && PPP
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 7c313cb341b8..4cffd34442aa 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -112,6 +112,7 @@ obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
112obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o 112obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
113obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o 113obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
114obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o 114obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
115obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
115obj-$(CONFIG_PPPOE) += pppox.o pppoe.o 116obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
116 117
117obj-$(CONFIG_SLIP) += slip.o 118obj-$(CONFIG_SLIP) += slip.o
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 0ee3e27969c6..c53848f787eb 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -18,7 +18,6 @@
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/version.h>
22#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
23 22
24#include <asm/uaccess.h> 23#include <asm/uaccess.h>
@@ -29,8 +28,8 @@
29 28
30#define DRV_MODULE_NAME "b44" 29#define DRV_MODULE_NAME "b44"
31#define PFX DRV_MODULE_NAME ": " 30#define PFX DRV_MODULE_NAME ": "
32#define DRV_MODULE_VERSION "0.95" 31#define DRV_MODULE_VERSION "0.96"
33#define DRV_MODULE_RELDATE "Aug 3, 2004" 32#define DRV_MODULE_RELDATE "Nov 8, 2005"
34 33
35#define B44_DEF_MSG_ENABLE \ 34#define B44_DEF_MSG_ENABLE \
36 (NETIF_MSG_DRV | \ 35 (NETIF_MSG_DRV | \
@@ -102,14 +101,16 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
102static void b44_halt(struct b44 *); 101static void b44_halt(struct b44 *);
103static void b44_init_rings(struct b44 *); 102static void b44_init_rings(struct b44 *);
104static void b44_init_hw(struct b44 *); 103static void b44_init_hw(struct b44 *);
105static int b44_poll(struct net_device *dev, int *budget);
106#ifdef CONFIG_NET_POLL_CONTROLLER
107static void b44_poll_controller(struct net_device *dev);
108#endif
109 104
110static int dma_desc_align_mask; 105static int dma_desc_align_mask;
111static int dma_desc_sync_size; 106static int dma_desc_sync_size;
112 107
108static const char b44_gstrings[][ETH_GSTRING_LEN] = {
109#define _B44(x...) # x,
110B44_STAT_REG_DECLARE
111#undef _B44
112};
113
113static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev, 114static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
114 dma_addr_t dma_base, 115 dma_addr_t dma_base,
115 unsigned long offset, 116 unsigned long offset,
@@ -502,7 +503,10 @@ static void b44_stats_update(struct b44 *bp)
502 for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { 503 for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
503 *val++ += br32(bp, reg); 504 *val++ += br32(bp, reg);
504 } 505 }
505 val = &bp->hw_stats.rx_good_octets; 506
507 /* Pad */
508 reg += 8*4UL;
509
506 for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { 510 for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
507 *val++ += br32(bp, reg); 511 *val++ += br32(bp, reg);
508 } 512 }
@@ -653,7 +657,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
653 657
654 /* Hardware bug work-around, the chip is unable to do PCI DMA 658 /* Hardware bug work-around, the chip is unable to do PCI DMA
655 to/from anything above 1GB :-( */ 659 to/from anything above 1GB :-( */
656 if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { 660 if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
657 /* Sigh... */ 661 /* Sigh... */
658 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); 662 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
659 dev_kfree_skb_any(skb); 663 dev_kfree_skb_any(skb);
@@ -663,7 +667,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
663 mapping = pci_map_single(bp->pdev, skb->data, 667 mapping = pci_map_single(bp->pdev, skb->data,
664 RX_PKT_BUF_SZ, 668 RX_PKT_BUF_SZ,
665 PCI_DMA_FROMDEVICE); 669 PCI_DMA_FROMDEVICE);
666 if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { 670 if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
667 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); 671 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
668 dev_kfree_skb_any(skb); 672 dev_kfree_skb_any(skb);
669 return -ENOMEM; 673 return -ENOMEM;
@@ -890,11 +894,10 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
890{ 894{
891 struct net_device *dev = dev_id; 895 struct net_device *dev = dev_id;
892 struct b44 *bp = netdev_priv(dev); 896 struct b44 *bp = netdev_priv(dev);
893 unsigned long flags;
894 u32 istat, imask; 897 u32 istat, imask;
895 int handled = 0; 898 int handled = 0;
896 899
897 spin_lock_irqsave(&bp->lock, flags); 900 spin_lock(&bp->lock);
898 901
899 istat = br32(bp, B44_ISTAT); 902 istat = br32(bp, B44_ISTAT);
900 imask = br32(bp, B44_IMASK); 903 imask = br32(bp, B44_IMASK);
@@ -905,6 +908,12 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
905 istat &= imask; 908 istat &= imask;
906 if (istat) { 909 if (istat) {
907 handled = 1; 910 handled = 1;
911
912 if (unlikely(!netif_running(dev))) {
913 printk(KERN_INFO "%s: late interrupt.\n", dev->name);
914 goto irq_ack;
915 }
916
908 if (netif_rx_schedule_prep(dev)) { 917 if (netif_rx_schedule_prep(dev)) {
909 /* NOTE: These writes are posted by the readback of 918 /* NOTE: These writes are posted by the readback of
910 * the ISTAT register below. 919 * the ISTAT register below.
@@ -917,10 +926,11 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
917 dev->name); 926 dev->name);
918 } 927 }
919 928
929irq_ack:
920 bw32(bp, B44_ISTAT, istat); 930 bw32(bp, B44_ISTAT, istat);
921 br32(bp, B44_ISTAT); 931 br32(bp, B44_ISTAT);
922 } 932 }
923 spin_unlock_irqrestore(&bp->lock, flags); 933 spin_unlock(&bp->lock);
924 return IRQ_RETVAL(handled); 934 return IRQ_RETVAL(handled);
925} 935}
926 936
@@ -948,6 +958,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
948{ 958{
949 struct b44 *bp = netdev_priv(dev); 959 struct b44 *bp = netdev_priv(dev);
950 struct sk_buff *bounce_skb; 960 struct sk_buff *bounce_skb;
961 int rc = NETDEV_TX_OK;
951 dma_addr_t mapping; 962 dma_addr_t mapping;
952 u32 len, entry, ctrl; 963 u32 len, entry, ctrl;
953 964
@@ -957,29 +968,28 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
957 /* This is a hard error, log it. */ 968 /* This is a hard error, log it. */
958 if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) { 969 if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
959 netif_stop_queue(dev); 970 netif_stop_queue(dev);
960 spin_unlock_irq(&bp->lock);
961 printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", 971 printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
962 dev->name); 972 dev->name);
963 return 1; 973 goto err_out;
964 } 974 }
965 975
966 mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); 976 mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
967 if(mapping+len > B44_DMA_MASK) { 977 if (mapping + len > B44_DMA_MASK) {
968 /* Chip can't handle DMA to/from >1GB, use bounce buffer */ 978 /* Chip can't handle DMA to/from >1GB, use bounce buffer */
969 pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); 979 pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
970 980
971 bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, 981 bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
972 GFP_ATOMIC|GFP_DMA); 982 GFP_ATOMIC|GFP_DMA);
973 if (!bounce_skb) 983 if (!bounce_skb)
974 return NETDEV_TX_BUSY; 984 goto err_out;
975 985
976 mapping = pci_map_single(bp->pdev, bounce_skb->data, 986 mapping = pci_map_single(bp->pdev, bounce_skb->data,
977 len, PCI_DMA_TODEVICE); 987 len, PCI_DMA_TODEVICE);
978 if(mapping+len > B44_DMA_MASK) { 988 if (mapping + len > B44_DMA_MASK) {
979 pci_unmap_single(bp->pdev, mapping, 989 pci_unmap_single(bp->pdev, mapping,
980 len, PCI_DMA_TODEVICE); 990 len, PCI_DMA_TODEVICE);
981 dev_kfree_skb_any(bounce_skb); 991 dev_kfree_skb_any(bounce_skb);
982 return NETDEV_TX_BUSY; 992 goto err_out;
983 } 993 }
984 994
985 memcpy(skb_put(bounce_skb, len), skb->data, skb->len); 995 memcpy(skb_put(bounce_skb, len), skb->data, skb->len);
@@ -1019,11 +1029,16 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
1019 if (TX_BUFFS_AVAIL(bp) < 1) 1029 if (TX_BUFFS_AVAIL(bp) < 1)
1020 netif_stop_queue(dev); 1030 netif_stop_queue(dev);
1021 1031
1032 dev->trans_start = jiffies;
1033
1034out_unlock:
1022 spin_unlock_irq(&bp->lock); 1035 spin_unlock_irq(&bp->lock);
1023 1036
1024 dev->trans_start = jiffies; 1037 return rc;
1025 1038
1026 return 0; 1039err_out:
1040 rc = NETDEV_TX_BUSY;
1041 goto out_unlock;
1027} 1042}
1028 1043
1029static int b44_change_mtu(struct net_device *dev, int new_mtu) 1044static int b44_change_mtu(struct net_device *dev, int new_mtu)
@@ -1097,8 +1112,7 @@ static void b44_free_rings(struct b44 *bp)
1097 * 1112 *
1098 * The chip has been shut down and the driver detached from 1113 * The chip has been shut down and the driver detached from
1099 * the networking, so no interrupts or new tx packets will 1114 * the networking, so no interrupts or new tx packets will
1100 * end up in the driver. bp->lock is not held and we are not 1115 * end up in the driver.
1101 * in an interrupt context and thus may sleep.
1102 */ 1116 */
1103static void b44_init_rings(struct b44 *bp) 1117static void b44_init_rings(struct b44 *bp)
1104{ 1118{
@@ -1170,16 +1184,14 @@ static int b44_alloc_consistent(struct b44 *bp)
1170 int size; 1184 int size;
1171 1185
1172 size = B44_RX_RING_SIZE * sizeof(struct ring_info); 1186 size = B44_RX_RING_SIZE * sizeof(struct ring_info);
1173 bp->rx_buffers = kmalloc(size, GFP_KERNEL); 1187 bp->rx_buffers = kzalloc(size, GFP_KERNEL);
1174 if (!bp->rx_buffers) 1188 if (!bp->rx_buffers)
1175 goto out_err; 1189 goto out_err;
1176 memset(bp->rx_buffers, 0, size);
1177 1190
1178 size = B44_TX_RING_SIZE * sizeof(struct ring_info); 1191 size = B44_TX_RING_SIZE * sizeof(struct ring_info);
1179 bp->tx_buffers = kmalloc(size, GFP_KERNEL); 1192 bp->tx_buffers = kzalloc(size, GFP_KERNEL);
1180 if (!bp->tx_buffers) 1193 if (!bp->tx_buffers)
1181 goto out_err; 1194 goto out_err;
1182 memset(bp->tx_buffers, 0, size);
1183 1195
1184 size = DMA_TABLE_BYTES; 1196 size = DMA_TABLE_BYTES;
1185 bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma); 1197 bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
@@ -1190,10 +1202,10 @@ static int b44_alloc_consistent(struct b44 *bp)
1190 struct dma_desc *rx_ring; 1202 struct dma_desc *rx_ring;
1191 dma_addr_t rx_ring_dma; 1203 dma_addr_t rx_ring_dma;
1192 1204
1193 if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) 1205 rx_ring = kzalloc(size, GFP_KERNEL);
1206 if (!rx_ring)
1194 goto out_err; 1207 goto out_err;
1195 1208
1196 memset(rx_ring, 0, size);
1197 rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring, 1209 rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
1198 DMA_TABLE_BYTES, 1210 DMA_TABLE_BYTES,
1199 DMA_BIDIRECTIONAL); 1211 DMA_BIDIRECTIONAL);
@@ -1216,10 +1228,10 @@ static int b44_alloc_consistent(struct b44 *bp)
1216 struct dma_desc *tx_ring; 1228 struct dma_desc *tx_ring;
1217 dma_addr_t tx_ring_dma; 1229 dma_addr_t tx_ring_dma;
1218 1230
1219 if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) 1231 tx_ring = kzalloc(size, GFP_KERNEL);
1232 if (!tx_ring)
1220 goto out_err; 1233 goto out_err;
1221 1234
1222 memset(tx_ring, 0, size);
1223 tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring, 1235 tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
1224 DMA_TABLE_BYTES, 1236 DMA_TABLE_BYTES,
1225 DMA_TO_DEVICE); 1237 DMA_TO_DEVICE);
@@ -1382,22 +1394,21 @@ static int b44_open(struct net_device *dev)
1382 1394
1383 err = b44_alloc_consistent(bp); 1395 err = b44_alloc_consistent(bp);
1384 if (err) 1396 if (err)
1385 return err; 1397 goto out;
1386
1387 err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
1388 if (err)
1389 goto err_out_free;
1390
1391 spin_lock_irq(&bp->lock);
1392 1398
1393 b44_init_rings(bp); 1399 b44_init_rings(bp);
1394 b44_init_hw(bp); 1400 b44_init_hw(bp);
1395 bp->flags |= B44_FLAG_INIT_COMPLETE;
1396 1401
1397 netif_carrier_off(dev); 1402 netif_carrier_off(dev);
1398 b44_check_phy(bp); 1403 b44_check_phy(bp);
1399 1404
1400 spin_unlock_irq(&bp->lock); 1405 err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
1406 if (unlikely(err < 0)) {
1407 b44_chip_reset(bp);
1408 b44_free_rings(bp);
1409 b44_free_consistent(bp);
1410 goto out;
1411 }
1401 1412
1402 init_timer(&bp->timer); 1413 init_timer(&bp->timer);
1403 bp->timer.expires = jiffies + HZ; 1414 bp->timer.expires = jiffies + HZ;
@@ -1406,11 +1417,7 @@ static int b44_open(struct net_device *dev)
1406 add_timer(&bp->timer); 1417 add_timer(&bp->timer);
1407 1418
1408 b44_enable_ints(bp); 1419 b44_enable_ints(bp);
1409 1420out:
1410 return 0;
1411
1412err_out_free:
1413 b44_free_consistent(bp);
1414 return err; 1421 return err;
1415} 1422}
1416 1423
@@ -1445,6 +1452,8 @@ static int b44_close(struct net_device *dev)
1445 1452
1446 netif_stop_queue(dev); 1453 netif_stop_queue(dev);
1447 1454
1455 netif_poll_disable(dev);
1456
1448 del_timer_sync(&bp->timer); 1457 del_timer_sync(&bp->timer);
1449 1458
1450 spin_lock_irq(&bp->lock); 1459 spin_lock_irq(&bp->lock);
@@ -1454,13 +1463,14 @@ static int b44_close(struct net_device *dev)
1454#endif 1463#endif
1455 b44_halt(bp); 1464 b44_halt(bp);
1456 b44_free_rings(bp); 1465 b44_free_rings(bp);
1457 bp->flags &= ~B44_FLAG_INIT_COMPLETE;
1458 netif_carrier_off(bp->dev); 1466 netif_carrier_off(bp->dev);
1459 1467
1460 spin_unlock_irq(&bp->lock); 1468 spin_unlock_irq(&bp->lock);
1461 1469
1462 free_irq(dev->irq, dev); 1470 free_irq(dev->irq, dev);
1463 1471
1472 netif_poll_enable(dev);
1473
1464 b44_free_consistent(bp); 1474 b44_free_consistent(bp);
1465 1475
1466 return 0; 1476 return 0;
@@ -1525,8 +1535,6 @@ static void __b44_set_rx_mode(struct net_device *dev)
1525{ 1535{
1526 struct b44 *bp = netdev_priv(dev); 1536 struct b44 *bp = netdev_priv(dev);
1527 u32 val; 1537 u32 val;
1528 int i=0;
1529 unsigned char zero[6] = {0,0,0,0,0,0};
1530 1538
1531 val = br32(bp, B44_RXCONFIG); 1539 val = br32(bp, B44_RXCONFIG);
1532 val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI); 1540 val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
@@ -1534,14 +1542,17 @@ static void __b44_set_rx_mode(struct net_device *dev)
1534 val |= RXCONFIG_PROMISC; 1542 val |= RXCONFIG_PROMISC;
1535 bw32(bp, B44_RXCONFIG, val); 1543 bw32(bp, B44_RXCONFIG, val);
1536 } else { 1544 } else {
1545 unsigned char zero[6] = {0, 0, 0, 0, 0, 0};
1546 int i = 0;
1547
1537 __b44_set_mac_addr(bp); 1548 __b44_set_mac_addr(bp);
1538 1549
1539 if (dev->flags & IFF_ALLMULTI) 1550 if (dev->flags & IFF_ALLMULTI)
1540 val |= RXCONFIG_ALLMULTI; 1551 val |= RXCONFIG_ALLMULTI;
1541 else 1552 else
1542 i=__b44_load_mcast(bp, dev); 1553 i = __b44_load_mcast(bp, dev);
1543 1554
1544 for(;i<64;i++) { 1555 for (; i < 64; i++) {
1545 __b44_cam_write(bp, zero, i); 1556 __b44_cam_write(bp, zero, i);
1546 } 1557 }
1547 bw32(bp, B44_RXCONFIG, val); 1558 bw32(bp, B44_RXCONFIG, val);
@@ -1605,7 +1616,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1605{ 1616{
1606 struct b44 *bp = netdev_priv(dev); 1617 struct b44 *bp = netdev_priv(dev);
1607 1618
1608 if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) 1619 if (!netif_running(dev))
1609 return -EAGAIN; 1620 return -EAGAIN;
1610 cmd->supported = (SUPPORTED_Autoneg); 1621 cmd->supported = (SUPPORTED_Autoneg);
1611 cmd->supported |= (SUPPORTED_100baseT_Half | 1622 cmd->supported |= (SUPPORTED_100baseT_Half |
@@ -1643,7 +1654,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1643{ 1654{
1644 struct b44 *bp = netdev_priv(dev); 1655 struct b44 *bp = netdev_priv(dev);
1645 1656
1646 if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) 1657 if (!netif_running(dev))
1647 return -EAGAIN; 1658 return -EAGAIN;
1648 1659
1649 /* We do not support gigabit. */ 1660 /* We do not support gigabit. */
@@ -1773,6 +1784,37 @@ static int b44_set_pauseparam(struct net_device *dev,
1773 return 0; 1784 return 0;
1774} 1785}
1775 1786
1787static void b44_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1788{
1789 switch(stringset) {
1790 case ETH_SS_STATS:
1791 memcpy(data, *b44_gstrings, sizeof(b44_gstrings));
1792 break;
1793 }
1794}
1795
1796static int b44_get_stats_count(struct net_device *dev)
1797{
1798 return ARRAY_SIZE(b44_gstrings);
1799}
1800
1801static void b44_get_ethtool_stats(struct net_device *dev,
1802 struct ethtool_stats *stats, u64 *data)
1803{
1804 struct b44 *bp = netdev_priv(dev);
1805 u32 *val = &bp->hw_stats.tx_good_octets;
1806 u32 i;
1807
1808 spin_lock_irq(&bp->lock);
1809
1810 b44_stats_update(bp);
1811
1812 for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++)
1813 *data++ = *val++;
1814
1815 spin_unlock_irq(&bp->lock);
1816}
1817
1776static struct ethtool_ops b44_ethtool_ops = { 1818static struct ethtool_ops b44_ethtool_ops = {
1777 .get_drvinfo = b44_get_drvinfo, 1819 .get_drvinfo = b44_get_drvinfo,
1778 .get_settings = b44_get_settings, 1820 .get_settings = b44_get_settings,
@@ -1785,6 +1827,9 @@ static struct ethtool_ops b44_ethtool_ops = {
1785 .set_pauseparam = b44_set_pauseparam, 1827 .set_pauseparam = b44_set_pauseparam,
1786 .get_msglevel = b44_get_msglevel, 1828 .get_msglevel = b44_get_msglevel,
1787 .set_msglevel = b44_set_msglevel, 1829 .set_msglevel = b44_set_msglevel,
1830 .get_strings = b44_get_strings,
1831 .get_stats_count = b44_get_stats_count,
1832 .get_ethtool_stats = b44_get_ethtool_stats,
1788 .get_perm_addr = ethtool_op_get_perm_addr, 1833 .get_perm_addr = ethtool_op_get_perm_addr,
1789}; 1834};
1790 1835
@@ -1893,9 +1938,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
1893 1938
1894 err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); 1939 err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
1895 if (err) { 1940 if (err) {
1896 printk(KERN_ERR PFX "No usable DMA configuration, " 1941 printk(KERN_ERR PFX "No usable DMA configuration, "
1897 "aborting.\n"); 1942 "aborting.\n");
1898 goto err_out_free_res; 1943 goto err_out_free_res;
1899 } 1944 }
1900 1945
1901 b44reg_base = pci_resource_start(pdev, 0); 1946 b44reg_base = pci_resource_start(pdev, 0);
@@ -1917,10 +1962,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
1917 bp = netdev_priv(dev); 1962 bp = netdev_priv(dev);
1918 bp->pdev = pdev; 1963 bp->pdev = pdev;
1919 bp->dev = dev; 1964 bp->dev = dev;
1920 if (b44_debug >= 0) 1965
1921 bp->msg_enable = (1 << b44_debug) - 1; 1966 bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
1922 else
1923 bp->msg_enable = B44_DEF_MSG_ENABLE;
1924 1967
1925 spin_lock_init(&bp->lock); 1968 spin_lock_init(&bp->lock);
1926 1969
@@ -2010,17 +2053,14 @@ err_out_disable_pdev:
2010static void __devexit b44_remove_one(struct pci_dev *pdev) 2053static void __devexit b44_remove_one(struct pci_dev *pdev)
2011{ 2054{
2012 struct net_device *dev = pci_get_drvdata(pdev); 2055 struct net_device *dev = pci_get_drvdata(pdev);
2056 struct b44 *bp = netdev_priv(dev);
2013 2057
2014 if (dev) { 2058 unregister_netdev(dev);
2015 struct b44 *bp = netdev_priv(dev); 2059 iounmap(bp->regs);
2016 2060 free_netdev(dev);
2017 unregister_netdev(dev); 2061 pci_release_regions(pdev);
2018 iounmap(bp->regs); 2062 pci_disable_device(pdev);
2019 free_netdev(dev); 2063 pci_set_drvdata(pdev, NULL);
2020 pci_release_regions(pdev);
2021 pci_disable_device(pdev);
2022 pci_set_drvdata(pdev, NULL);
2023 }
2024} 2064}
2025 2065
2026static int b44_suspend(struct pci_dev *pdev, pm_message_t state) 2066static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index 593cb0ad4100..b178662978f3 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -346,29 +346,63 @@ struct ring_info {
346 346
347#define B44_MCAST_TABLE_SIZE 32 347#define B44_MCAST_TABLE_SIZE 32
348 348
349#define B44_STAT_REG_DECLARE \
350 _B44(tx_good_octets) \
351 _B44(tx_good_pkts) \
352 _B44(tx_octets) \
353 _B44(tx_pkts) \
354 _B44(tx_broadcast_pkts) \
355 _B44(tx_multicast_pkts) \
356 _B44(tx_len_64) \
357 _B44(tx_len_65_to_127) \
358 _B44(tx_len_128_to_255) \
359 _B44(tx_len_256_to_511) \
360 _B44(tx_len_512_to_1023) \
361 _B44(tx_len_1024_to_max) \
362 _B44(tx_jabber_pkts) \
363 _B44(tx_oversize_pkts) \
364 _B44(tx_fragment_pkts) \
365 _B44(tx_underruns) \
366 _B44(tx_total_cols) \
367 _B44(tx_single_cols) \
368 _B44(tx_multiple_cols) \
369 _B44(tx_excessive_cols) \
370 _B44(tx_late_cols) \
371 _B44(tx_defered) \
372 _B44(tx_carrier_lost) \
373 _B44(tx_pause_pkts) \
374 _B44(rx_good_octets) \
375 _B44(rx_good_pkts) \
376 _B44(rx_octets) \
377 _B44(rx_pkts) \
378 _B44(rx_broadcast_pkts) \
379 _B44(rx_multicast_pkts) \
380 _B44(rx_len_64) \
381 _B44(rx_len_65_to_127) \
382 _B44(rx_len_128_to_255) \
383 _B44(rx_len_256_to_511) \
384 _B44(rx_len_512_to_1023) \
385 _B44(rx_len_1024_to_max) \
386 _B44(rx_jabber_pkts) \
387 _B44(rx_oversize_pkts) \
388 _B44(rx_fragment_pkts) \
389 _B44(rx_missed_pkts) \
390 _B44(rx_crc_align_errs) \
391 _B44(rx_undersize) \
392 _B44(rx_crc_errs) \
393 _B44(rx_align_errs) \
394 _B44(rx_symbol_errs) \
395 _B44(rx_pause_pkts) \
396 _B44(rx_nonpause_pkts)
397
349/* SW copy of device statistics, kept up to date by periodic timer 398/* SW copy of device statistics, kept up to date by periodic timer
350 * which probes HW values. Must have same relative layout as HW 399 * which probes HW values. Check b44_stats_update if you mess with
351 * register above, because b44_stats_update depends upon this. 400 * the layout
352 */ 401 */
353struct b44_hw_stats { 402struct b44_hw_stats {
354 u32 tx_good_octets, tx_good_pkts, tx_octets; 403#define _B44(x) u32 x;
355 u32 tx_pkts, tx_broadcast_pkts, tx_multicast_pkts; 404B44_STAT_REG_DECLARE
356 u32 tx_len_64, tx_len_65_to_127, tx_len_128_to_255; 405#undef _B44
357 u32 tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max;
358 u32 tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts;
359 u32 tx_underruns, tx_total_cols, tx_single_cols;
360 u32 tx_multiple_cols, tx_excessive_cols, tx_late_cols;
361 u32 tx_defered, tx_carrier_lost, tx_pause_pkts;
362 u32 __pad1[8];
363
364 u32 rx_good_octets, rx_good_pkts, rx_octets;
365 u32 rx_pkts, rx_broadcast_pkts, rx_multicast_pkts;
366 u32 rx_len_64, rx_len_65_to_127, rx_len_128_to_255;
367 u32 rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max;
368 u32 rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts;
369 u32 rx_missed_pkts, rx_crc_align_errs, rx_undersize;
370 u32 rx_crc_errs, rx_align_errs, rx_symbol_errs;
371 u32 rx_pause_pkts, rx_nonpause_pkts;
372}; 406};
373 407
374struct b44 { 408struct b44 {
@@ -386,7 +420,6 @@ struct b44 {
386 420
387 u32 dma_offset; 421 u32 dma_offset;
388 u32 flags; 422 u32 flags;
389#define B44_FLAG_INIT_COMPLETE 0x00000001
390#define B44_FLAG_BUGGY_TXPTR 0x00000002 423#define B44_FLAG_BUGGY_TXPTR 0x00000002
391#define B44_FLAG_REORDER_BUG 0x00000004 424#define B44_FLAG_REORDER_BUG 0x00000004
392#define B44_FLAG_PAUSE_AUTO 0x00008000 425#define B44_FLAG_PAUSE_AUTO 0x00008000
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 8032126fd589..94cec3cf2a13 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1604,35 +1604,27 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_
1604 (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) 1604 (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
1605 1605
1606/* 1606/*
1607 * Compute the features available to the bonding device by 1607 * Compute the common dev->feature set available to all slaves. Some
1608 * intersection of all of the slave devices' BOND_INTERSECT_FEATURES. 1608 * feature bits are managed elsewhere, so preserve feature bits set on
1609 * Call this after attaching or detaching a slave to update the 1609 * master device that are not part of the examined set.
1610 * bond's features.
1611 */ 1610 */
1612static int bond_compute_features(struct bonding *bond) 1611static int bond_compute_features(struct bonding *bond)
1613{ 1612{
1614 int i; 1613 unsigned long features = BOND_INTERSECT_FEATURES;
1615 struct slave *slave; 1614 struct slave *slave;
1616 struct net_device *bond_dev = bond->dev; 1615 struct net_device *bond_dev = bond->dev;
1617 int features = bond->bond_features; 1616 int i;
1618 1617
1619 bond_for_each_slave(bond, slave, i) { 1618 bond_for_each_slave(bond, slave, i)
1620 struct net_device * slave_dev = slave->dev; 1619 features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
1621 if (i == 0) {
1622 features |= BOND_INTERSECT_FEATURES;
1623 }
1624 features &=
1625 ~(~slave_dev->features & BOND_INTERSECT_FEATURES);
1626 }
1627 1620
1628 /* turn off NETIF_F_SG if we need a csum and h/w can't do it */
1629 if ((features & NETIF_F_SG) && 1621 if ((features & NETIF_F_SG) &&
1630 !(features & (NETIF_F_IP_CSUM | 1622 !(features & (NETIF_F_IP_CSUM |
1631 NETIF_F_NO_CSUM | 1623 NETIF_F_NO_CSUM |
1632 NETIF_F_HW_CSUM))) { 1624 NETIF_F_HW_CSUM)))
1633 features &= ~NETIF_F_SG; 1625 features &= ~NETIF_F_SG;
1634 }
1635 1626
1627 features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
1636 bond_dev->features = features; 1628 bond_dev->features = features;
1637 1629
1638 return 0; 1630 return 0;
@@ -4561,8 +4553,6 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
4561 NETIF_F_HW_VLAN_RX | 4553 NETIF_F_HW_VLAN_RX |
4562 NETIF_F_HW_VLAN_FILTER); 4554 NETIF_F_HW_VLAN_FILTER);
4563 4555
4564 bond->bond_features = bond_dev->features;
4565
4566#ifdef CONFIG_PROC_FS 4556#ifdef CONFIG_PROC_FS
4567 bond_create_proc_entry(bond); 4557 bond_create_proc_entry(bond);
4568#endif 4558#endif
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index bbf9da8af624..1433e91db0f7 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -40,8 +40,8 @@
40#include "bond_3ad.h" 40#include "bond_3ad.h"
41#include "bond_alb.h" 41#include "bond_alb.h"
42 42
43#define DRV_VERSION "2.6.4" 43#define DRV_VERSION "2.6.5"
44#define DRV_RELDATE "September 26, 2005" 44#define DRV_RELDATE "November 4, 2005"
45#define DRV_NAME "bonding" 45#define DRV_NAME "bonding"
46#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 46#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
47 47
@@ -211,9 +211,6 @@ struct bonding {
211 struct bond_params params; 211 struct bond_params params;
212 struct list_head vlan_list; 212 struct list_head vlan_list;
213 struct vlan_group *vlgrp; 213 struct vlan_group *vlgrp;
214 /* the features the bonding device supports, independently
215 * of any slaves */
216 int bond_features;
217}; 214};
218 215
219/** 216/**
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 50f43dbf31ae..1f7ca453bb4a 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -67,7 +67,6 @@
67 */ 67 */
68 68
69#include <linux/config.h> 69#include <linux/config.h>
70#include <linux/version.h>
71 70
72#include <linux/module.h> 71#include <linux/module.h>
73#include <linux/kernel.h> 72#include <linux/kernel.h>
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index b68b9cad76e9..64105e4eaf31 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -409,7 +409,6 @@ static irqreturn_t e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs)
409static void e100_rx(struct net_device *dev); 409static void e100_rx(struct net_device *dev);
410static int e100_close(struct net_device *dev); 410static int e100_close(struct net_device *dev);
411static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 411static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
412static int e100_ethtool_ioctl(struct net_device* dev, struct ifreq *ifr);
413static int e100_set_config(struct net_device* dev, struct ifmap* map); 412static int e100_set_config(struct net_device* dev, struct ifmap* map);
414static void e100_tx_timeout(struct net_device *dev); 413static void e100_tx_timeout(struct net_device *dev);
415static struct net_device_stats *e100_get_stats(struct net_device *dev); 414static struct net_device_stats *e100_get_stats(struct net_device *dev);
@@ -436,6 +435,8 @@ static void e100_reset_transceiver(struct net_device* net);
436static void e100_clear_network_leds(unsigned long dummy); 435static void e100_clear_network_leds(unsigned long dummy);
437static void e100_set_network_leds(int active); 436static void e100_set_network_leds(int active);
438 437
438static struct ethtool_ops e100_ethtool_ops;
439
439static void broadcom_check_speed(struct net_device* dev); 440static void broadcom_check_speed(struct net_device* dev);
440static void broadcom_check_duplex(struct net_device* dev); 441static void broadcom_check_duplex(struct net_device* dev);
441static void tdk_check_speed(struct net_device* dev); 442static void tdk_check_speed(struct net_device* dev);
@@ -495,6 +496,7 @@ etrax_ethernet_init(void)
495 dev->get_stats = e100_get_stats; 496 dev->get_stats = e100_get_stats;
496 dev->set_multicast_list = set_multicast_list; 497 dev->set_multicast_list = set_multicast_list;
497 dev->set_mac_address = e100_set_mac_address; 498 dev->set_mac_address = e100_set_mac_address;
499 dev->ethtool_ops = &e100_ethtool_ops;
498 dev->do_ioctl = e100_ioctl; 500 dev->do_ioctl = e100_ioctl;
499 dev->set_config = e100_set_config; 501 dev->set_config = e100_set_config;
500 dev->tx_timeout = e100_tx_timeout; 502 dev->tx_timeout = e100_tx_timeout;
@@ -1448,8 +1450,6 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1448 1450
1449 spin_lock(&np->lock); /* Preempt protection */ 1451 spin_lock(&np->lock); /* Preempt protection */
1450 switch (cmd) { 1452 switch (cmd) {
1451 case SIOCETHTOOL:
1452 return e100_ethtool_ioctl(dev,ifr);
1453 case SIOCGMIIPHY: /* Get PHY address */ 1453 case SIOCGMIIPHY: /* Get PHY address */
1454 data->phy_id = mdio_phy_addr; 1454 data->phy_id = mdio_phy_addr;
1455 break; 1455 break;
@@ -1486,88 +1486,81 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1486 return 0; 1486 return 0;
1487} 1487}
1488 1488
1489static int 1489static int e100_set_settings(struct net_device *dev,
1490e100_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) 1490 struct ethtool_cmd *ecmd)
1491{ 1491{
1492 struct ethtool_cmd ecmd; 1492 ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
1493
1494 if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd)))
1495 return -EFAULT;
1496
1497 switch (ecmd.cmd) {
1498 case ETHTOOL_GSET:
1499 {
1500 memset((void *) &ecmd, 0, sizeof (ecmd));
1501 ecmd.supported =
1502 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
1503 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | 1493 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
1504 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; 1494 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
1505 ecmd.port = PORT_TP; 1495 ecmd->port = PORT_TP;
1506 ecmd.transceiver = XCVR_EXTERNAL; 1496 ecmd->transceiver = XCVR_EXTERNAL;
1507 ecmd.phy_address = mdio_phy_addr; 1497 ecmd->phy_address = mdio_phy_addr;
1508 ecmd.speed = current_speed; 1498 ecmd->speed = current_speed;
1509 ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF; 1499 ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
1510 ecmd.advertising = ADVERTISED_TP; 1500 ecmd->advertising = ADVERTISED_TP;
1511 if (current_duplex == autoneg && current_speed_selection == 0) 1501
1512 ecmd.advertising |= ADVERTISED_Autoneg; 1502 if (current_duplex == autoneg && current_speed_selection == 0)
1513 else { 1503 ecmd->advertising |= ADVERTISED_Autoneg;
1514 ecmd.advertising |= 1504 else {
1515 ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | 1505 ecmd->advertising |=
1516 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; 1506 ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
1517 if (current_speed_selection == 10) 1507 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
1518 ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full); 1508 if (current_speed_selection == 10)
1519 else if (current_speed_selection == 100) 1509 ecmd->advertising &= ~(ADVERTISED_100baseT_Half |
1520 ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full); 1510 ADVERTISED_100baseT_Full);
1521 if (current_duplex == half) 1511 else if (current_speed_selection == 100)
1522 ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full); 1512 ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
1523 else if (current_duplex == full) 1513 ADVERTISED_10baseT_Full);
1524 ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half); 1514 if (current_duplex == half)
1525 } 1515 ecmd->advertising &= ~(ADVERTISED_10baseT_Full |
1526 ecmd.autoneg = AUTONEG_ENABLE; 1516 ADVERTISED_100baseT_Full);
1527 if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd))) 1517 else if (current_duplex == full)
1528 return -EFAULT; 1518 ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
1529 } 1519 ADVERTISED_100baseT_Half);
1530 break; 1520 }
1531 case ETHTOOL_SSET: 1521
1532 { 1522 ecmd->autoneg = AUTONEG_ENABLE;
1533 if (!capable(CAP_NET_ADMIN)) { 1523 return 0;
1534 return -EPERM; 1524}
1535 } 1525
1536 if (ecmd.autoneg == AUTONEG_ENABLE) { 1526static int e100_set_settings(struct net_device *dev,
1537 e100_set_duplex(dev, autoneg); 1527 struct ethtool_cmd *ecmd)
1538 e100_set_speed(dev, 0); 1528{
1539 } else { 1529 if (ecmd->autoneg == AUTONEG_ENABLE) {
1540 e100_set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full); 1530 e100_set_duplex(dev, autoneg);
1541 e100_set_speed(dev, ecmd.speed == SPEED_10 ? 10: 100); 1531 e100_set_speed(dev, 0);
1542 } 1532 } else {
1543 } 1533 e100_set_duplex(dev, ecmd->duplex == DUPLEX_HALF ? half : full);
1544 break; 1534 e100_set_speed(dev, ecmd->speed == SPEED_10 ? 10: 100);
1545 case ETHTOOL_GDRVINFO:
1546 {
1547 struct ethtool_drvinfo info;
1548 memset((void *) &info, 0, sizeof (info));
1549 strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1);
1550 strncpy(info.version, "$Revision: 1.31 $", sizeof(info.version) - 1);
1551 strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1);
1552 strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1);
1553 info.regdump_len = 0;
1554 info.eedump_len = 0;
1555 info.testinfo_len = 0;
1556 if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
1557 return -EFAULT;
1558 }
1559 break;
1560 case ETHTOOL_NWAY_RST:
1561 if (current_duplex == autoneg && current_speed_selection == 0)
1562 e100_negotiate(dev);
1563 break;
1564 default:
1565 return -EOPNOTSUPP;
1566 break;
1567 } 1535 }
1536
1537 return 0;
1538}
1539
1540static void e100_get_drvinfo(struct net_device *dev,
1541 struct ethtool_drvinfo *info)
1542{
1543 strncpy(info->driver, "ETRAX 100LX", sizeof(info->driver) - 1);
1544 strncpy(info->version, "$Revision: 1.31 $", sizeof(info->version) - 1);
1545 strncpy(info->fw_version, "N/A", sizeof(info->fw_version) - 1);
1546 strncpy(info->bus_info, "N/A", sizeof(info->bus_info) - 1);
1547}
1548
1549static int e100_nway_reset(struct net_device *dev)
1550{
1551 if (current_duplex == autoneg && current_speed_selection == 0)
1552 e100_negotiate(dev);
1568 return 0; 1553 return 0;
1569} 1554}
1570 1555
1556static struct ethtool_ops e100_ethtool_ops = {
1557 .get_settings = e100_get_settings,
1558 .set_settings = e100_set_settings,
1559 .get_drvinfo = e100_get_drvinfo,
1560 .nway_reset = e100_nway_reset,
1561 .get_link = ethtool_op_get_link,
1562};
1563
1571static int 1564static int
1572e100_set_config(struct net_device *dev, struct ifmap *map) 1565e100_set_config(struct net_device *dev, struct ifmap *map)
1573{ 1566{
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
index 7809838e6c4c..2a290cc397ad 100644
--- a/drivers/net/dgrs.c
+++ b/drivers/net/dgrs.c
@@ -1549,7 +1549,7 @@ MODULE_PARM_DESC(nicmode, "Digi RightSwitch operating mode (1: switch, 2: multi-
1549static int __init dgrs_init_module (void) 1549static int __init dgrs_init_module (void)
1550{ 1550{
1551 int i; 1551 int i;
1552 int eisacount = 0, pcicount = 0; 1552 int cardcount = 0;
1553 1553
1554 /* 1554 /*
1555 * Command line variable overrides 1555 * Command line variable overrides
@@ -1591,15 +1591,13 @@ static int __init dgrs_init_module (void)
1591 * Find and configure all the cards 1591 * Find and configure all the cards
1592 */ 1592 */
1593#ifdef CONFIG_EISA 1593#ifdef CONFIG_EISA
1594 eisacount = eisa_driver_register(&dgrs_eisa_driver); 1594 cardcount = eisa_driver_register(&dgrs_eisa_driver);
1595 if (eisacount < 0) 1595 if (cardcount < 0)
1596 return eisacount; 1596 return cardcount;
1597#endif
1598#ifdef CONFIG_PCI
1599 pcicount = pci_register_driver(&dgrs_pci_driver);
1600 if (pcicount)
1601 return pcicount;
1602#endif 1597#endif
1598 cardcount = pci_register_driver(&dgrs_pci_driver);
1599 if (cardcount)
1600 return cardcount;
1603 return 0; 1601 return 0;
1604} 1602}
1605 1603
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index c0af6fb1fbba..f8c9bcdab68b 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -60,7 +60,6 @@
60#include <linux/etherdevice.h> 60#include <linux/etherdevice.h>
61#include <linux/init.h> 61#include <linux/init.h>
62#include <linux/skbuff.h> 62#include <linux/skbuff.h>
63#include <linux/version.h>
64#include <linux/spinlock.h> 63#include <linux/spinlock.h>
65#include <linux/crc32.h> 64#include <linux/crc32.h>
66#include <linux/mii.h> 65#include <linux/mii.h>
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index eb169a8e8773..7a6aeae2c9fa 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1478,7 +1478,7 @@ static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
1478 1478
1479 if(pci_dma_mapping_error(rx->dma_addr)) { 1479 if(pci_dma_mapping_error(rx->dma_addr)) {
1480 dev_kfree_skb_any(rx->skb); 1480 dev_kfree_skb_any(rx->skb);
1481 rx->skb = 0; 1481 rx->skb = NULL;
1482 rx->dma_addr = 0; 1482 rx->dma_addr = 0;
1483 return -ENOMEM; 1483 return -ENOMEM;
1484 } 1484 }
@@ -1764,7 +1764,7 @@ static int e100_up(struct nic *nic)
1764 if((err = e100_hw_init(nic))) 1764 if((err = e100_hw_init(nic)))
1765 goto err_clean_cbs; 1765 goto err_clean_cbs;
1766 e100_set_multicast_list(nic->netdev); 1766 e100_set_multicast_list(nic->netdev);
1767 e100_start_receiver(nic, 0); 1767 e100_start_receiver(nic, NULL);
1768 mod_timer(&nic->watchdog, jiffies); 1768 mod_timer(&nic->watchdog, jiffies);
1769 if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ, 1769 if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
1770 nic->netdev->name, nic->netdev))) 1770 nic->netdev->name, nic->netdev)))
@@ -1844,7 +1844,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
1844 mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 1844 mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
1845 BMCR_LOOPBACK); 1845 BMCR_LOOPBACK);
1846 1846
1847 e100_start_receiver(nic, 0); 1847 e100_start_receiver(nic, NULL);
1848 1848
1849 if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) { 1849 if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) {
1850 err = -ENOMEM; 1850 err = -ENOMEM;
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index 1105543b9d88..e7ec96c964a9 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -4,7 +4,6 @@
4#include <linux/mii.h> 4#include <linux/mii.h>
5#include <linux/netdevice.h> 5#include <linux/netdevice.h>
6#include <linux/types.h> 6#include <linux/types.h>
7#include <linux/version.h>
8#include <linux/list.h> 7#include <linux/list.h>
9 8
10#include <linux/fs_enet_pd.h> 9#include <linux/fs_enet_pd.h>
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 962580f2c4ab..54d294ad6df5 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -90,7 +90,6 @@
90#include <asm/irq.h> 90#include <asm/irq.h>
91#include <asm/uaccess.h> 91#include <asm/uaccess.h>
92#include <linux/module.h> 92#include <linux/module.h>
93#include <linux/version.h>
94#include <linux/dma-mapping.h> 93#include <linux/dma-mapping.h>
95#include <linux/crc32.h> 94#include <linux/crc32.h>
96#include <linux/mii.h> 95#include <linux/mii.h>
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index c77ca6c0d04a..220084e53341 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -43,7 +43,6 @@
43#include <asm/irq.h> 43#include <asm/irq.h>
44#include <asm/uaccess.h> 44#include <asm/uaccess.h>
45#include <linux/module.h> 45#include <linux/module.h>
46#include <linux/version.h>
47#include <linux/crc32.h> 46#include <linux/crc32.h>
48#include <linux/workqueue.h> 47#include <linux/workqueue.h>
49#include <linux/ethtool.h> 48#include <linux/ethtool.h>
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 68e3578e7613..5a2d810ce575 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -34,7 +34,6 @@
34#include <asm/irq.h> 34#include <asm/irq.h>
35#include <asm/uaccess.h> 35#include <asm/uaccess.h>
36#include <linux/module.h> 36#include <linux/module.h>
37#include <linux/version.h>
38#include <linux/crc32.h> 37#include <linux/crc32.h>
39#include <asm/types.h> 38#include <asm/types.h>
40#include <asm/uaccess.h> 39#include <asm/uaccess.h>
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 5a74d3d3dbe1..7263395d78bb 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -32,7 +32,6 @@
32#include <linux/spinlock.h> 32#include <linux/spinlock.h>
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/version.h>
36#include <linux/platform_device.h> 35#include <linux/platform_device.h>
37#include <asm/ocp.h> 36#include <asm/ocp.h>
38#include <linux/crc32.h> 37#include <linux/crc32.h>
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index b71fab6e34f4..e92c17f6931c 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -96,7 +96,6 @@
96 96
97#undef HP100_MULTICAST_FILTER /* Need to be debugged... */ 97#undef HP100_MULTICAST_FILTER /* Need to be debugged... */
98 98
99#include <linux/version.h>
100#include <linux/module.h> 99#include <linux/module.h>
101#include <linux/kernel.h> 100#include <linux/kernel.h>
102#include <linux/string.h> 101#include <linux/string.h>
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 94239f67f3a3..be191d80ef9c 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -35,7 +35,6 @@
35 35
36#include <linux/config.h> 36#include <linux/config.h>
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/version.h>
39#include <linux/types.h> 38#include <linux/types.h>
40#include <linux/errno.h> 39#include <linux/errno.h>
41#include <linux/ioport.h> 40#include <linux/ioport.h>
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 49e5467bdd73..6a3129bc15a6 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -46,10 +46,8 @@
46#include <linux/udp.h> 46#include <linux/udp.h>
47 47
48#ifdef CONFIG_SERIAL_8250 48#ifdef CONFIG_SERIAL_8250
49#include <linux/serial.h> 49#include <linux/serial_core.h>
50#include <asm/serial.h> 50#include <linux/serial_8250.h>
51#define IOC3_BAUD (22000000 / (3*16))
52#define IOC3_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
53#endif 51#endif
54 52
55#include <linux/netdevice.h> 53#include <linux/netdevice.h>
@@ -1146,12 +1144,11 @@ static inline int ioc3_is_menet(struct pci_dev *pdev)
1146 * around ioc3 oddities in this respect. 1144 * around ioc3 oddities in this respect.
1147 * 1145 *
1148 * The IOC3 serials use a 22MHz clock rate with an additional divider by 3. 1146 * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
1149 * (IOC3_BAUD = (22000000 / (3*16)))
1150 */ 1147 */
1151 1148
1152static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) 1149static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
1153{ 1150{
1154 struct serial_struct req; 1151 struct uart_port port;
1155 1152
1156 /* 1153 /*
1157 * We need to recognice and treat the fourth MENET serial as it 1154 * We need to recognice and treat the fourth MENET serial as it
@@ -1165,20 +1162,25 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
1165 if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3) 1162 if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3)
1166 return; 1163 return;
1167 1164
1168 /* Register to interrupt zero because we share the interrupt with 1165 /*
1169 the serial driver which we don't properly support yet. */ 1166 * Register to interrupt zero because we share the interrupt with
1170 memset(&req, 0, sizeof(req)); 1167 * the serial driver which we don't properly support yet.
1171 req.irq = 0; 1168 *
1172 req.flags = IOC3_COM_FLAGS; 1169 * Can't use UPF_IOREMAP as the whole of IOC3 resources have already
1173 req.io_type = SERIAL_IO_MEM; 1170 * been registered.
1174 req.iomem_reg_shift = 0; 1171 */
1175 req.baud_base = IOC3_BAUD; 1172 memset(&port, 0, sizeof(port));
1176 1173 port.irq = 0;
1177 req.iomem_base = (unsigned char *) &ioc3->sregs.uarta; 1174 port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
1178 register_serial(&req); 1175 port.iotype = UPIO_MEM;
1179 1176 port.regshift = 0;
1180 req.iomem_base = (unsigned char *) &ioc3->sregs.uartb; 1177 port.uartclk = 22000000 / 3;
1181 register_serial(&req); 1178
1179 port.membase = (unsigned char *) &ioc3->sregs.uarta;
1180 serial8250_register_port(&port);
1181
1182 port.membase = (unsigned char *) &ioc3->sregs.uartb;
1183 serial8250_register_port(&port);
1182} 1184}
1183#endif 1185#endif
1184 1186
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 0282771b1cbb..3137592d60c0 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -1459,8 +1459,10 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1459 */ 1459 */
1460 IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__ 1460 IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__
1461 ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate ); 1461 ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate );
1462 if (!in_interrupt () && !capable (CAP_NET_ADMIN)) 1462 if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
1463 return -EPERM; 1463 ret = -EPERM;
1464 goto out;
1465 }
1464 1466
1465 /* self->speed=irq->ifr_baudrate; */ 1467 /* self->speed=irq->ifr_baudrate; */
1466 /* toshoboe_setbaud(self); */ 1468 /* toshoboe_setbaud(self); */
@@ -1470,8 +1472,10 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1470 case SIOCSMEDIABUSY: /* Set media busy */ 1472 case SIOCSMEDIABUSY: /* Set media busy */
1471 IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__ 1473 IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__
1472 ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) ); 1474 ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) );
1473 if (!capable (CAP_NET_ADMIN)) 1475 if (!capable (CAP_NET_ADMIN)) {
1474 return -EPERM; 1476 ret = -EPERM;
1477 goto out;
1478 }
1475 irda_device_set_media_busy (self->netdev, TRUE); 1479 irda_device_set_media_busy (self->netdev, TRUE);
1476 break; 1480 break;
1477 case SIOCGRECEIVING: /* Check if we are receiving right now */ 1481 case SIOCGRECEIVING: /* Check if we are receiving right now */
@@ -1483,7 +1487,7 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1483 IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); 1487 IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
1484 ret = -EOPNOTSUPP; 1488 ret = -EOPNOTSUPP;
1485 } 1489 }
1486 1490out:
1487 spin_unlock_irqrestore(&self->spinlock, flags); 1491 spin_unlock_irqrestore(&self->spinlock, flags);
1488 return ret; 1492 return ret;
1489 1493
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index d86d8f055a6c..77eadf84cb2c 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -58,7 +58,6 @@
58 58
59#include <linux/config.h> 59#include <linux/config.h>
60#include <linux/module.h> 60#include <linux/module.h>
61#include <linux/version.h>
62#include <linux/types.h> 61#include <linux/types.h>
63#include <linux/errno.h> 62#include <linux/errno.h>
64#include <linux/ioport.h> 63#include <linux/ioport.h>
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index ce5761816a64..d8c99f038fa0 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -15,7 +15,6 @@
15 * and fixed access to Sonic Sys card which masquerades as a Farallon 15 * and fixed access to Sonic Sys card which masquerades as a Farallon
16 * by rayk@knightsmanor.org */ 16 * by rayk@knightsmanor.org */
17 17
18#include <linux/version.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/kernel.h> 19#include <linux/kernel.h>
21#include <linux/types.h> 20#include <linux/types.h>
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
index bcfda5192da0..f769f9b626ea 100644
--- a/drivers/net/mv643xx_eth.h
+++ b/drivers/net/mv643xx_eth.h
@@ -1,7 +1,6 @@
1#ifndef __MV643XX_ETH_H__ 1#ifndef __MV643XX_ETH_H__
2#define __MV643XX_ETH_H__ 2#define __MV643XX_ETH_H__
3 3
4#include <linux/version.h>
5#include <linux/module.h> 4#include <linux/module.h>
6#include <linux/kernel.h> 5#include <linux/kernel.h>
7#include <linux/spinlock.h> 6#include <linux/spinlock.h>
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index a3c3fc9c0d8a..f857ae94d261 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -110,7 +110,6 @@
110#include <linux/init.h> 110#include <linux/init.h>
111#include <linux/ip.h> /* for iph */ 111#include <linux/ip.h> /* for iph */
112#include <linux/in.h> /* for IPPROTO_... */ 112#include <linux/in.h> /* for IPPROTO_... */
113#include <linux/eeprom.h>
114#include <linux/compiler.h> 113#include <linux/compiler.h>
115#include <linux/prefetch.h> 114#include <linux/prefetch.h>
116#include <linux/ethtool.h> 115#include <linux/ethtool.h>
@@ -445,7 +444,6 @@ struct ns83820 {
445 444
446 u32 MEAR_cache; 445 u32 MEAR_cache;
447 u32 IMR_cache; 446 u32 IMR_cache;
448 struct eeprom ee;
449 447
450 unsigned linkstate; 448 unsigned linkstate;
451 449
@@ -1558,15 +1556,13 @@ static void ns83820_getmac(struct ns83820 *dev, u8 *mac)
1558 unsigned i; 1556 unsigned i;
1559 for (i=0; i<3; i++) { 1557 for (i=0; i<3; i++) {
1560 u32 data; 1558 u32 data;
1561#if 0 /* I've left this in as an example of how to use eeprom.h */ 1559
1562 data = eeprom_readw(&dev->ee, 0xa + 2 - i);
1563#else
1564 /* Read from the perfect match memory: this is loaded by 1560 /* Read from the perfect match memory: this is loaded by
1565 * the chip from the EEPROM via the EELOAD self test. 1561 * the chip from the EEPROM via the EELOAD self test.
1566 */ 1562 */
1567 writel(i*2, dev->base + RFCR); 1563 writel(i*2, dev->base + RFCR);
1568 data = readl(dev->base + RFDR); 1564 data = readl(dev->base + RFDR);
1569#endif 1565
1570 *mac++ = data; 1566 *mac++ = data;
1571 *mac++ = data >> 8; 1567 *mac++ = data >> 8;
1572 } 1568 }
@@ -1851,8 +1847,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
1851 spin_lock_init(&dev->misc_lock); 1847 spin_lock_init(&dev->misc_lock);
1852 dev->pci_dev = pci_dev; 1848 dev->pci_dev = pci_dev;
1853 1849
1854 dev->ee.cache = &dev->MEAR_cache;
1855 dev->ee.lock = &dev->misc_lock;
1856 SET_MODULE_OWNER(ndev); 1850 SET_MODULE_OWNER(ndev);
1857 SET_NETDEV_DEV(ndev, &pci_dev->dev); 1851 SET_NETDEV_DEV(ndev, &pci_dev->dev);
1858 1852
@@ -1887,9 +1881,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
1887 1881
1888 dev->IMR_cache = 0; 1882 dev->IMR_cache = 0;
1889 1883
1890 setup_ee_mem_bitbanger(&dev->ee, dev->base + MEAR, 3, 2, 1, 0,
1891 0);
1892
1893 err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ, 1884 err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ,
1894 DRV_NAME, ndev); 1885 DRV_NAME, ndev);
1895 if (err) { 1886 if (err) {
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 59e8183c639e..400f652282d7 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -31,6 +31,7 @@
31#include <linux/spinlock.h> 31#include <linux/spinlock.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <asm/uaccess.h> 33#include <asm/uaccess.h>
34#include <asm/string.h>
34 35
35#define PPP_VERSION "2.4.2" 36#define PPP_VERSION "2.4.2"
36 37
@@ -835,8 +836,11 @@ process_input_packet(struct asyncppp *ap)
835 err: 836 err:
836 /* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */ 837 /* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */
837 ap->state = SC_PREV_ERROR; 838 ap->state = SC_PREV_ERROR;
838 if (skb) 839 if (skb) {
840 /* make skb appear as freshly allocated */
839 skb_trim(skb, 0); 841 skb_trim(skb, 0);
842 skb_reserve(skb, - skb_headroom(skb));
843 }
840} 844}
841 845
842/* Called when the tty driver has data for us. Runs parallel with the 846/* Called when the tty driver has data for us. Runs parallel with the
@@ -889,10 +893,17 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
889 skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2); 893 skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
890 if (skb == 0) 894 if (skb == 0)
891 goto nomem; 895 goto nomem;
892 /* Try to get the payload 4-byte aligned */ 896 ap->rpkt = skb;
897 }
898 if (skb->len == 0) {
899 /* Try to get the payload 4-byte aligned.
900 * This should match the
901 * PPP_ALLSTATIONS/PPP_UI/compressed tests in
902 * process_input_packet, but we do not have
903 * enough chars here to test buf[1] and buf[2].
904 */
893 if (buf[0] != PPP_ALLSTATIONS) 905 if (buf[0] != PPP_ALLSTATIONS)
894 skb_reserve(skb, 2 + (buf[0] & 1)); 906 skb_reserve(skb, 2 + (buf[0] & 1));
895 ap->rpkt = skb;
896 } 907 }
897 if (n > skb_tailroom(skb)) { 908 if (n > skb_tailroom(skb)) {
898 /* packet overflowed MRU */ 909 /* packet overflowed MRU */
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index d3c9958b00d0..50430f79f8cf 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -137,13 +137,14 @@ struct ppp {
137 137
138/* 138/*
139 * Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC, 139 * Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC,
140 * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP. 140 * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP,
141 * SC_MUST_COMP
141 * Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR. 142 * Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR.
142 * Bits in xstate: SC_COMP_RUN 143 * Bits in xstate: SC_COMP_RUN
143 */ 144 */
144#define SC_FLAG_BITS (SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC \ 145#define SC_FLAG_BITS (SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC \
145 |SC_MULTILINK|SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ \ 146 |SC_MULTILINK|SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ \
146 |SC_COMP_TCP|SC_REJ_COMP_TCP) 147 |SC_COMP_TCP|SC_REJ_COMP_TCP|SC_MUST_COMP)
147 148
148/* 149/*
149 * Private data structure for each channel. 150 * Private data structure for each channel.
@@ -1027,6 +1028,56 @@ ppp_xmit_process(struct ppp *ppp)
1027 ppp_xmit_unlock(ppp); 1028 ppp_xmit_unlock(ppp);
1028} 1029}
1029 1030
1031static inline struct sk_buff *
1032pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
1033{
1034 struct sk_buff *new_skb;
1035 int len;
1036 int new_skb_size = ppp->dev->mtu +
1037 ppp->xcomp->comp_extra + ppp->dev->hard_header_len;
1038 int compressor_skb_size = ppp->dev->mtu +
1039 ppp->xcomp->comp_extra + PPP_HDRLEN;
1040 new_skb = alloc_skb(new_skb_size, GFP_ATOMIC);
1041 if (!new_skb) {
1042 if (net_ratelimit())
1043 printk(KERN_ERR "PPP: no memory (comp pkt)\n");
1044 return NULL;
1045 }
1046 if (ppp->dev->hard_header_len > PPP_HDRLEN)
1047 skb_reserve(new_skb,
1048 ppp->dev->hard_header_len - PPP_HDRLEN);
1049
1050 /* compressor still expects A/C bytes in hdr */
1051 len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
1052 new_skb->data, skb->len + 2,
1053 compressor_skb_size);
1054 if (len > 0 && (ppp->flags & SC_CCP_UP)) {
1055 kfree_skb(skb);
1056 skb = new_skb;
1057 skb_put(skb, len);
1058 skb_pull(skb, 2); /* pull off A/C bytes */
1059 } else if (len == 0) {
1060 /* didn't compress, or CCP not up yet */
1061 kfree_skb(new_skb);
1062 new_skb = skb;
1063 } else {
1064 /*
1065 * (len < 0)
1066 * MPPE requires that we do not send unencrypted
1067 * frames. The compressor will return -1 if we
1068 * should drop the frame. We cannot simply test
1069 * the compress_proto because MPPE and MPPC share
1070 * the same number.
1071 */
1072 if (net_ratelimit())
1073 printk(KERN_ERR "ppp: compressor dropped pkt\n");
1074 kfree_skb(skb);
1075 kfree_skb(new_skb);
1076 new_skb = NULL;
1077 }
1078 return new_skb;
1079}
1080
1030/* 1081/*
1031 * Compress and send a frame. 1082 * Compress and send a frame.
1032 * The caller should have locked the xmit path, 1083 * The caller should have locked the xmit path,
@@ -1113,29 +1164,14 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
1113 /* try to do packet compression */ 1164 /* try to do packet compression */
1114 if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0 1165 if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
1115 && proto != PPP_LCP && proto != PPP_CCP) { 1166 && proto != PPP_LCP && proto != PPP_CCP) {
1116 new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len, 1167 if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) {
1117 GFP_ATOMIC); 1168 if (net_ratelimit())
1118 if (new_skb == 0) { 1169 printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n");
1119 printk(KERN_ERR "PPP: no memory (comp pkt)\n");
1120 goto drop; 1170 goto drop;
1121 } 1171 }
1122 if (ppp->dev->hard_header_len > PPP_HDRLEN) 1172 skb = pad_compress_skb(ppp, skb);
1123 skb_reserve(new_skb, 1173 if (!skb)
1124 ppp->dev->hard_header_len - PPP_HDRLEN); 1174 goto drop;
1125
1126 /* compressor still expects A/C bytes in hdr */
1127 len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
1128 new_skb->data, skb->len + 2,
1129 ppp->dev->mtu + PPP_HDRLEN);
1130 if (len > 0 && (ppp->flags & SC_CCP_UP)) {
1131 kfree_skb(skb);
1132 skb = new_skb;
1133 skb_put(skb, len);
1134 skb_pull(skb, 2); /* pull off A/C bytes */
1135 } else {
1136 /* didn't compress, or CCP not up yet */
1137 kfree_skb(new_skb);
1138 }
1139 } 1175 }
1140 1176
1141 /* 1177 /*
@@ -1155,7 +1191,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
1155 return; 1191 return;
1156 1192
1157 drop: 1193 drop:
1158 kfree_skb(skb); 1194 if (skb)
1195 kfree_skb(skb);
1159 ++ppp->stats.tx_errors; 1196 ++ppp->stats.tx_errors;
1160} 1197}
1161 1198
@@ -1552,6 +1589,9 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
1552 && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0) 1589 && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0)
1553 skb = ppp_decompress_frame(ppp, skb); 1590 skb = ppp_decompress_frame(ppp, skb);
1554 1591
1592 if (ppp->flags & SC_MUST_COMP && ppp->rstate & SC_DC_FERROR)
1593 goto err;
1594
1555 proto = PPP_PROTO(skb); 1595 proto = PPP_PROTO(skb);
1556 switch (proto) { 1596 switch (proto) {
1557 case PPP_VJC_COMP: 1597 case PPP_VJC_COMP:
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
new file mode 100644
index 000000000000..1985d1b57c45
--- /dev/null
+++ b/drivers/net/ppp_mppe.c
@@ -0,0 +1,724 @@
1/*
2 * ppp_mppe.c - interface MPPE to the PPP code.
3 * This version is for use with Linux kernel 2.6.14+
4 *
5 * By Frank Cusack <fcusack@fcusack.com>.
6 * Copyright (c) 2002,2003,2004 Google, Inc.
7 * All rights reserved.
8 *
9 * License:
10 * Permission to use, copy, modify, and distribute this software and its
11 * documentation is hereby granted, provided that the above copyright
12 * notice appears in all copies. This software is provided without any
13 * warranty, express or implied.
14 *
15 * ALTERNATIVELY, provided that this notice is retained in full, this product
16 * may be distributed under the terms of the GNU General Public License (GPL),
17 * in which case the provisions of the GPL apply INSTEAD OF those given above.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (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 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 * Changelog:
35 * 08/12/05 - Matt Domsch <Matt_Domsch@dell.com>
36 * Only need extra skb padding on transmit, not receive.
37 * 06/18/04 - Matt Domsch <Matt_Domsch@dell.com>, Oleg Makarenko <mole@quadra.ru>
38 * Use Linux kernel 2.6 arc4 and sha1 routines rather than
39 * providing our own.
40 * 2/15/04 - TS: added #include <version.h> and testing for Kernel
41 * version before using
42 * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
43 * deprecated in 2.6
44 */
45
46#include <linux/config.h>
47#include <linux/module.h>
48#include <linux/kernel.h>
49#include <linux/version.h>
50#include <linux/init.h>
51#include <linux/types.h>
52#include <linux/slab.h>
53#include <linux/string.h>
54#include <linux/crypto.h>
55#include <linux/mm.h>
56#include <linux/ppp_defs.h>
57#include <linux/ppp-comp.h>
58#include <asm/scatterlist.h>
59
60#include "ppp_mppe.h"
61
62MODULE_AUTHOR("Frank Cusack <fcusack@fcusack.com>");
63MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
64MODULE_LICENSE("Dual BSD/GPL");
65MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
66MODULE_VERSION("1.0.2");
67
68static void
69setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
70{
71 sg[0].page = virt_to_page(address);
72 sg[0].offset = offset_in_page(address);
73 sg[0].length = length;
74}
75
76#define SHA1_PAD_SIZE 40
77
78/*
79 * kernel crypto API needs its arguments to be in kmalloc'd memory, not in the module
80 * static data area. That means sha_pad needs to be kmalloc'd.
81 */
82
83struct sha_pad {
84 unsigned char sha_pad1[SHA1_PAD_SIZE];
85 unsigned char sha_pad2[SHA1_PAD_SIZE];
86};
87static struct sha_pad *sha_pad;
88
89static inline void sha_pad_init(struct sha_pad *shapad)
90{
91 memset(shapad->sha_pad1, 0x00, sizeof(shapad->sha_pad1));
92 memset(shapad->sha_pad2, 0xF2, sizeof(shapad->sha_pad2));
93}
94
95/*
96 * State for an MPPE (de)compressor.
97 */
98struct ppp_mppe_state {
99 struct crypto_tfm *arc4;
100 struct crypto_tfm *sha1;
101 unsigned char *sha1_digest;
102 unsigned char master_key[MPPE_MAX_KEY_LEN];
103 unsigned char session_key[MPPE_MAX_KEY_LEN];
104 unsigned keylen; /* key length in bytes */
105 /* NB: 128-bit == 16, 40-bit == 8! */
106 /* If we want to support 56-bit, */
107 /* the unit has to change to bits */
108 unsigned char bits; /* MPPE control bits */
109 unsigned ccount; /* 12-bit coherency count (seqno) */
110 unsigned stateful; /* stateful mode flag */
111 int discard; /* stateful mode packet loss flag */
112 int sanity_errors; /* take down LCP if too many */
113 int unit;
114 int debug;
115 struct compstat stats;
116};
117
118/* struct ppp_mppe_state.bits definitions */
119#define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */
120#define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */
121#define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */
122#define MPPE_BIT_D 0x10 /* This is an encrypted frame */
123
124#define MPPE_BIT_FLUSHED MPPE_BIT_A
125#define MPPE_BIT_ENCRYPTED MPPE_BIT_D
126
127#define MPPE_BITS(p) ((p)[4] & 0xf0)
128#define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
129#define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */
130
131#define MPPE_OVHD 2 /* MPPE overhead/packet */
132#define SANITY_MAX 1600 /* Max bogon factor we will tolerate */
133
134/*
135 * Key Derivation, from RFC 3078, RFC 3079.
136 * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
137 */
138static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey)
139{
140 struct scatterlist sg[4];
141
142 setup_sg(&sg[0], state->master_key, state->keylen);
143 setup_sg(&sg[1], sha_pad->sha_pad1, sizeof(sha_pad->sha_pad1));
144 setup_sg(&sg[2], state->session_key, state->keylen);
145 setup_sg(&sg[3], sha_pad->sha_pad2, sizeof(sha_pad->sha_pad2));
146
147 crypto_digest_digest (state->sha1, sg, 4, state->sha1_digest);
148
149 memcpy(InterimKey, state->sha1_digest, state->keylen);
150}
151
152/*
153 * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
154 * Well, not what's written there, but rather what they meant.
155 */
156static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
157{
158 unsigned char InterimKey[MPPE_MAX_KEY_LEN];
159 struct scatterlist sg_in[1], sg_out[1];
160
161 get_new_key_from_sha(state, InterimKey);
162 if (!initial_key) {
163 crypto_cipher_setkey(state->arc4, InterimKey, state->keylen);
164 setup_sg(sg_in, InterimKey, state->keylen);
165 setup_sg(sg_out, state->session_key, state->keylen);
166 if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in,
167 state->keylen) != 0) {
168 printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n");
169 }
170 } else {
171 memcpy(state->session_key, InterimKey, state->keylen);
172 }
173 if (state->keylen == 8) {
174 /* See RFC 3078 */
175 state->session_key[0] = 0xd1;
176 state->session_key[1] = 0x26;
177 state->session_key[2] = 0x9e;
178 }
179 crypto_cipher_setkey(state->arc4, state->session_key, state->keylen);
180}
181
182/*
183 * Allocate space for a (de)compressor.
184 */
185static void *mppe_alloc(unsigned char *options, int optlen)
186{
187 struct ppp_mppe_state *state;
188 unsigned int digestsize;
189
190 if (optlen != CILEN_MPPE + sizeof(state->master_key)
191 || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
192 goto out;
193
194 state = (struct ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
195 if (state == NULL)
196 goto out;
197
198 memset(state, 0, sizeof(*state));
199
200 state->arc4 = crypto_alloc_tfm("arc4", 0);
201 if (!state->arc4)
202 goto out_free;
203
204 state->sha1 = crypto_alloc_tfm("sha1", 0);
205 if (!state->sha1)
206 goto out_free;
207
208 digestsize = crypto_tfm_alg_digestsize(state->sha1);
209 if (digestsize < MPPE_MAX_KEY_LEN)
210 goto out_free;
211
212 state->sha1_digest = kmalloc(digestsize, GFP_KERNEL);
213 if (!state->sha1_digest)
214 goto out_free;
215
216 /* Save keys. */
217 memcpy(state->master_key, &options[CILEN_MPPE],
218 sizeof(state->master_key));
219 memcpy(state->session_key, state->master_key,
220 sizeof(state->master_key));
221
222 /*
223 * We defer initial key generation until mppe_init(), as mppe_alloc()
224 * is called frequently during negotiation.
225 */
226
227 return (void *)state;
228
229 out_free:
230 if (state->sha1_digest)
231 kfree(state->sha1_digest);
232 if (state->sha1)
233 crypto_free_tfm(state->sha1);
234 if (state->arc4)
235 crypto_free_tfm(state->arc4);
236 kfree(state);
237 out:
238 return NULL;
239}
240
241/*
242 * Deallocate space for a (de)compressor.
243 */
244static void mppe_free(void *arg)
245{
246 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
247 if (state) {
248 if (state->sha1_digest)
249 kfree(state->sha1_digest);
250 if (state->sha1)
251 crypto_free_tfm(state->sha1);
252 if (state->arc4)
253 crypto_free_tfm(state->arc4);
254 kfree(state);
255 }
256}
257
258/*
259 * Initialize (de)compressor state.
260 */
261static int
262mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
263 const char *debugstr)
264{
265 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
266 unsigned char mppe_opts;
267
268 if (optlen != CILEN_MPPE
269 || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
270 return 0;
271
272 MPPE_CI_TO_OPTS(&options[2], mppe_opts);
273 if (mppe_opts & MPPE_OPT_128)
274 state->keylen = 16;
275 else if (mppe_opts & MPPE_OPT_40)
276 state->keylen = 8;
277 else {
278 printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr,
279 unit);
280 return 0;
281 }
282 if (mppe_opts & MPPE_OPT_STATEFUL)
283 state->stateful = 1;
284
285 /* Generate the initial session key. */
286 mppe_rekey(state, 1);
287
288 if (debug) {
289 int i;
290 char mkey[sizeof(state->master_key) * 2 + 1];
291 char skey[sizeof(state->session_key) * 2 + 1];
292
293 printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n",
294 debugstr, unit, (state->keylen == 16) ? 128 : 40,
295 (state->stateful) ? "stateful" : "stateless");
296
297 for (i = 0; i < sizeof(state->master_key); i++)
298 sprintf(mkey + i * 2, "%02x", state->master_key[i]);
299 for (i = 0; i < sizeof(state->session_key); i++)
300 sprintf(skey + i * 2, "%02x", state->session_key[i]);
301 printk(KERN_DEBUG
302 "%s[%d]: keys: master: %s initial session: %s\n",
303 debugstr, unit, mkey, skey);
304 }
305
306 /*
307 * Initialize the coherency count. The initial value is not specified
308 * in RFC 3078, but we can make a reasonable assumption that it will
309 * start at 0. Setting it to the max here makes the comp/decomp code
310 * do the right thing (determined through experiment).
311 */
312 state->ccount = MPPE_CCOUNT_SPACE - 1;
313
314 /*
315 * Note that even though we have initialized the key table, we don't
316 * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1.
317 */
318 state->bits = MPPE_BIT_ENCRYPTED;
319
320 state->unit = unit;
321 state->debug = debug;
322
323 return 1;
324}
325
326static int
327mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
328 int hdrlen, int debug)
329{
330 /* ARGSUSED */
331 return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
332}
333
334/*
335 * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
336 * tell the compressor to rekey. Note that we MUST NOT rekey for
337 * every CCP Reset-Request; we only rekey on the next xmit packet.
338 * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
339 * So, rekeying for every CCP Reset-Request is broken as the peer will not
340 * know how many times we've rekeyed. (If we rekey and THEN get another
341 * CCP Reset-Request, we must rekey again.)
342 */
343static void mppe_comp_reset(void *arg)
344{
345 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
346
347 state->bits |= MPPE_BIT_FLUSHED;
348}
349
350/*
351 * Compress (encrypt) a packet.
352 * It's strange to call this a compressor, since the output is always
353 * MPPE_OVHD + 2 bytes larger than the input.
354 */
355static int
356mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
357 int isize, int osize)
358{
359 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
360 int proto;
361 struct scatterlist sg_in[1], sg_out[1];
362
363 /*
364 * Check that the protocol is in the range we handle.
365 */
366 proto = PPP_PROTOCOL(ibuf);
367 if (proto < 0x0021 || proto > 0x00fa)
368 return 0;
369
370 /* Make sure we have enough room to generate an encrypted packet. */
371 if (osize < isize + MPPE_OVHD + 2) {
372 /* Drop the packet if we should encrypt it, but can't. */
373 printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
374 "(have: %d need: %d)\n", state->unit,
375 osize, osize + MPPE_OVHD + 2);
376 return -1;
377 }
378
379 osize = isize + MPPE_OVHD + 2;
380
381 /*
382 * Copy over the PPP header and set control bits.
383 */
384 obuf[0] = PPP_ADDRESS(ibuf);
385 obuf[1] = PPP_CONTROL(ibuf);
386 obuf[2] = PPP_COMP >> 8; /* isize + MPPE_OVHD + 1 */
387 obuf[3] = PPP_COMP; /* isize + MPPE_OVHD + 2 */
388 obuf += PPP_HDRLEN;
389
390 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
391 if (state->debug >= 7)
392 printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
393 state->ccount);
394 obuf[0] = state->ccount >> 8;
395 obuf[1] = state->ccount & 0xff;
396
397 if (!state->stateful || /* stateless mode */
398 ((state->ccount & 0xff) == 0xff) || /* "flag" packet */
399 (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */
400 /* We must rekey */
401 if (state->debug && state->stateful)
402 printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n",
403 state->unit);
404 mppe_rekey(state, 0);
405 state->bits |= MPPE_BIT_FLUSHED;
406 }
407 obuf[0] |= state->bits;
408 state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */
409
410 obuf += MPPE_OVHD;
411 ibuf += 2; /* skip to proto field */
412 isize -= 2;
413
414 /* Encrypt packet */
415 setup_sg(sg_in, ibuf, isize);
416 setup_sg(sg_out, obuf, osize);
417 if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in, isize) != 0) {
418 printk(KERN_DEBUG "crypto_cypher_encrypt failed\n");
419 return -1;
420 }
421
422 state->stats.unc_bytes += isize;
423 state->stats.unc_packets++;
424 state->stats.comp_bytes += osize;
425 state->stats.comp_packets++;
426
427 return osize;
428}
429
430/*
431 * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
432 * to look bad ... and the longer the link is up the worse it will get.
433 */
434static void mppe_comp_stats(void *arg, struct compstat *stats)
435{
436 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
437
438 *stats = state->stats;
439}
440
441static int
442mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
443 int hdrlen, int mru, int debug)
444{
445 /* ARGSUSED */
446 return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
447}
448
449/*
450 * We received a CCP Reset-Ack. Just ignore it.
451 */
452static void mppe_decomp_reset(void *arg)
453{
454 /* ARGSUSED */
455 return;
456}
457
458/*
459 * Decompress (decrypt) an MPPE packet.
460 */
461static int
462mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
463 int osize)
464{
465 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
466 unsigned ccount;
467 int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
468 int sanity = 0;
469 struct scatterlist sg_in[1], sg_out[1];
470
471 if (isize <= PPP_HDRLEN + MPPE_OVHD) {
472 if (state->debug)
473 printk(KERN_DEBUG
474 "mppe_decompress[%d]: short pkt (%d)\n",
475 state->unit, isize);
476 return DECOMP_ERROR;
477 }
478
479 /*
480 * Make sure we have enough room to decrypt the packet.
481 * Note that for our test we only subtract 1 byte whereas in
482 * mppe_compress() we added 2 bytes (+MPPE_OVHD);
483 * this is to account for possible PFC.
484 */
485 if (osize < isize - MPPE_OVHD - 1) {
486 printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
487 "(have: %d need: %d)\n", state->unit,
488 osize, isize - MPPE_OVHD - 1);
489 return DECOMP_ERROR;
490 }
491 osize = isize - MPPE_OVHD - 2; /* assume no PFC */
492
493 ccount = MPPE_CCOUNT(ibuf);
494 if (state->debug >= 7)
495 printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n",
496 state->unit, ccount);
497
498 /* sanity checks -- terminate with extreme prejudice */
499 if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
500 printk(KERN_DEBUG
501 "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
502 state->unit);
503 state->sanity_errors += 100;
504 sanity = 1;
505 }
506 if (!state->stateful && !flushed) {
507 printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
508 "stateless mode!\n", state->unit);
509 state->sanity_errors += 100;
510 sanity = 1;
511 }
512 if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
513 printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
514 "flag packet!\n", state->unit);
515 state->sanity_errors += 100;
516 sanity = 1;
517 }
518
519 if (sanity) {
520 if (state->sanity_errors < SANITY_MAX)
521 return DECOMP_ERROR;
522 else
523 /*
524 * Take LCP down if the peer is sending too many bogons.
525 * We don't want to do this for a single or just a few
526 * instances since it could just be due to packet corruption.
527 */
528 return DECOMP_FATALERROR;
529 }
530
531 /*
532 * Check the coherency count.
533 */
534
535 if (!state->stateful) {
536 /* RFC 3078, sec 8.1. Rekey for every packet. */
537 while (state->ccount != ccount) {
538 mppe_rekey(state, 0);
539 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
540 }
541 } else {
542 /* RFC 3078, sec 8.2. */
543 if (!state->discard) {
544 /* normal state */
545 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
546 if (ccount != state->ccount) {
547 /*
548 * (ccount > state->ccount)
549 * Packet loss detected, enter the discard state.
550 * Signal the peer to rekey (by sending a CCP Reset-Request).
551 */
552 state->discard = 1;
553 return DECOMP_ERROR;
554 }
555 } else {
556 /* discard state */
557 if (!flushed) {
558 /* ccp.c will be silent (no additional CCP Reset-Requests). */
559 return DECOMP_ERROR;
560 } else {
561 /* Rekey for every missed "flag" packet. */
562 while ((ccount & ~0xff) !=
563 (state->ccount & ~0xff)) {
564 mppe_rekey(state, 0);
565 state->ccount =
566 (state->ccount +
567 256) % MPPE_CCOUNT_SPACE;
568 }
569
570 /* reset */
571 state->discard = 0;
572 state->ccount = ccount;
573 /*
574 * Another problem with RFC 3078 here. It implies that the
575 * peer need not send a Reset-Ack packet. But RFC 1962
576 * requires it. Hopefully, M$ does send a Reset-Ack; even
577 * though it isn't required for MPPE synchronization, it is
578 * required to reset CCP state.
579 */
580 }
581 }
582 if (flushed)
583 mppe_rekey(state, 0);
584 }
585
586 /*
587 * Fill in the first part of the PPP header. The protocol field
588 * comes from the decrypted data.
589 */
590 obuf[0] = PPP_ADDRESS(ibuf); /* +1 */
591 obuf[1] = PPP_CONTROL(ibuf); /* +1 */
592 obuf += 2;
593 ibuf += PPP_HDRLEN + MPPE_OVHD;
594 isize -= PPP_HDRLEN + MPPE_OVHD; /* -6 */
595 /* net osize: isize-4 */
596
597 /*
598 * Decrypt the first byte in order to check if it is
599 * a compressed or uncompressed protocol field.
600 */
601 setup_sg(sg_in, ibuf, 1);
602 setup_sg(sg_out, obuf, 1);
603 if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, 1) != 0) {
604 printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
605 return DECOMP_ERROR;
606 }
607
608 /*
609 * Do PFC decompression.
610 * This would be nicer if we were given the actual sk_buff
611 * instead of a char *.
612 */
613 if ((obuf[0] & 0x01) != 0) {
614 obuf[1] = obuf[0];
615 obuf[0] = 0;
616 obuf++;
617 osize++;
618 }
619
620 /* And finally, decrypt the rest of the packet. */
621 setup_sg(sg_in, ibuf + 1, isize - 1);
622 setup_sg(sg_out, obuf + 1, osize - 1);
623 if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, isize - 1) != 0) {
624 printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
625 return DECOMP_ERROR;
626 }
627
628 state->stats.unc_bytes += osize;
629 state->stats.unc_packets++;
630 state->stats.comp_bytes += isize;
631 state->stats.comp_packets++;
632
633 /* good packet credit */
634 state->sanity_errors >>= 1;
635
636 return osize;
637}
638
639/*
640 * Incompressible data has arrived (this should never happen!).
641 * We should probably drop the link if the protocol is in the range
642 * of what should be encrypted. At the least, we should drop this
643 * packet. (How to do this?)
644 */
645static void mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
646{
647 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
648
649 if (state->debug &&
650 (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
651 printk(KERN_DEBUG
652 "mppe_incomp[%d]: incompressible (unencrypted) data! "
653 "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
654
655 state->stats.inc_bytes += icnt;
656 state->stats.inc_packets++;
657 state->stats.unc_bytes += icnt;
658 state->stats.unc_packets++;
659}
660
661/*************************************************************
662 * Module interface table
663 *************************************************************/
664
665/*
666 * Procedures exported to if_ppp.c.
667 */
668static struct compressor ppp_mppe = {
669 .compress_proto = CI_MPPE,
670 .comp_alloc = mppe_alloc,
671 .comp_free = mppe_free,
672 .comp_init = mppe_comp_init,
673 .comp_reset = mppe_comp_reset,
674 .compress = mppe_compress,
675 .comp_stat = mppe_comp_stats,
676 .decomp_alloc = mppe_alloc,
677 .decomp_free = mppe_free,
678 .decomp_init = mppe_decomp_init,
679 .decomp_reset = mppe_decomp_reset,
680 .decompress = mppe_decompress,
681 .incomp = mppe_incomp,
682 .decomp_stat = mppe_comp_stats,
683 .owner = THIS_MODULE,
684 .comp_extra = MPPE_PAD,
685};
686
687/*
688 * ppp_mppe_init()
689 *
690 * Prior to allowing load, try to load the arc4 and sha1 crypto
691 * libraries. The actual use will be allocated later, but
692 * this way the module will fail to insmod if they aren't available.
693 */
694
695static int __init ppp_mppe_init(void)
696{
697 int answer;
698 if (!(crypto_alg_available("arc4", 0) &&
699 crypto_alg_available("sha1", 0)))
700 return -ENODEV;
701
702 sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL);
703 if (!sha_pad)
704 return -ENOMEM;
705 sha_pad_init(sha_pad);
706
707 answer = ppp_register_compressor(&ppp_mppe);
708
709 if (answer == 0)
710 printk(KERN_INFO "PPP MPPE Compression module registered\n");
711 else
712 kfree(sha_pad);
713
714 return answer;
715}
716
717static void __exit ppp_mppe_cleanup(void)
718{
719 ppp_unregister_compressor(&ppp_mppe);
720 kfree(sha_pad);
721}
722
723module_init(ppp_mppe_init);
724module_exit(ppp_mppe_cleanup);
diff --git a/drivers/net/ppp_mppe.h b/drivers/net/ppp_mppe.h
new file mode 100644
index 000000000000..7a14e058c668
--- /dev/null
+++ b/drivers/net/ppp_mppe.h
@@ -0,0 +1,86 @@
1#define MPPE_PAD 4 /* MPPE growth per frame */
2#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */
3
4/* option bits for ccp_options.mppe */
5#define MPPE_OPT_40 0x01 /* 40 bit */
6#define MPPE_OPT_128 0x02 /* 128 bit */
7#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */
8/* unsupported opts */
9#define MPPE_OPT_56 0x08 /* 56 bit */
10#define MPPE_OPT_MPPC 0x10 /* MPPC compression */
11#define MPPE_OPT_D 0x20 /* Unknown */
12#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
13#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */
14
15/*
16 * This is not nice ... the alternative is a bitfield struct though.
17 * And unfortunately, we cannot share the same bits for the option
18 * names above since C and H are the same bit. We could do a u_int32
19 * but then we have to do a htonl() all the time and/or we still need
20 * to know which octet is which.
21 */
22#define MPPE_C_BIT 0x01 /* MPPC */
23#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */
24#define MPPE_L_BIT 0x20 /* 40-bit */
25#define MPPE_S_BIT 0x40 /* 128-bit */
26#define MPPE_M_BIT 0x80 /* 56-bit, not supported */
27#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */
28
29/* Does not include H bit; used for least significant octet only. */
30#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
31
32/* Build a CI from mppe opts (see RFC 3078) */
33#define MPPE_OPTS_TO_CI(opts, ci) \
34 do { \
35 u_char *ptr = ci; /* u_char[4] */ \
36 \
37 /* H bit */ \
38 if (opts & MPPE_OPT_STATEFUL) \
39 *ptr++ = 0x0; \
40 else \
41 *ptr++ = MPPE_H_BIT; \
42 *ptr++ = 0; \
43 *ptr++ = 0; \
44 \
45 /* S,L bits */ \
46 *ptr = 0; \
47 if (opts & MPPE_OPT_128) \
48 *ptr |= MPPE_S_BIT; \
49 if (opts & MPPE_OPT_40) \
50 *ptr |= MPPE_L_BIT; \
51 /* M,D,C bits not supported */ \
52 } while (/* CONSTCOND */ 0)
53
54/* The reverse of the above */
55#define MPPE_CI_TO_OPTS(ci, opts) \
56 do { \
57 u_char *ptr = ci; /* u_char[4] */ \
58 \
59 opts = 0; \
60 \
61 /* H bit */ \
62 if (!(ptr[0] & MPPE_H_BIT)) \
63 opts |= MPPE_OPT_STATEFUL; \
64 \
65 /* S,L bits */ \
66 if (ptr[3] & MPPE_S_BIT) \
67 opts |= MPPE_OPT_128; \
68 if (ptr[3] & MPPE_L_BIT) \
69 opts |= MPPE_OPT_40; \
70 \
71 /* M,D,C bits */ \
72 if (ptr[3] & MPPE_M_BIT) \
73 opts |= MPPE_OPT_56; \
74 if (ptr[3] & MPPE_D_BIT) \
75 opts |= MPPE_OPT_D; \
76 if (ptr[3] & MPPE_C_BIT) \
77 opts |= MPPE_OPT_MPPC; \
78 \
79 /* Other bits */ \
80 if (ptr[0] & ~MPPE_H_BIT) \
81 opts |= MPPE_OPT_UNKNOWN; \
82 if (ptr[1] || ptr[2]) \
83 opts |= MPPE_OPT_UNKNOWN; \
84 if (ptr[3] & ~MPPE_ALL_BITS) \
85 opts |= MPPE_OPT_UNKNOWN; \
86 } while (/* CONSTCOND */ 0)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 0745dd9d01f3..e57df8dfe6b4 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -55,7 +55,6 @@
55#include <linux/timex.h> 55#include <linux/timex.h>
56#include <linux/sched.h> 56#include <linux/sched.h>
57#include <linux/ethtool.h> 57#include <linux/ethtool.h>
58#include <linux/version.h>
59#include <linux/workqueue.h> 58#include <linux/workqueue.h>
60#include <linux/if_vlan.h> 59#include <linux/if_vlan.h>
61 60
@@ -1532,7 +1531,7 @@ static int init_nic(struct s2io_nic *nic)
1532#define LINK_UP_DOWN_INTERRUPT 1 1531#define LINK_UP_DOWN_INTERRUPT 1
1533#define MAC_RMAC_ERR_TIMER 2 1532#define MAC_RMAC_ERR_TIMER 2
1534 1533
1535int s2io_link_fault_indication(nic_t *nic) 1534static int s2io_link_fault_indication(nic_t *nic)
1536{ 1535{
1537 if (nic->intr_type != INTA) 1536 if (nic->intr_type != INTA)
1538 return MAC_RMAC_ERR_TIMER; 1537 return MAC_RMAC_ERR_TIMER;
@@ -1864,7 +1863,7 @@ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag)
1864 * 1863 *
1865 */ 1864 */
1866 1865
1867void fix_mac_address(nic_t * sp) 1866static void fix_mac_address(nic_t * sp)
1868{ 1867{
1869 XENA_dev_config_t __iomem *bar0 = sp->bar0; 1868 XENA_dev_config_t __iomem *bar0 = sp->bar0;
1870 u64 val64; 1869 u64 val64;
@@ -2160,7 +2159,7 @@ int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb)
2160 * SUCCESS on success or an appropriate -ve value on failure. 2159 * SUCCESS on success or an appropriate -ve value on failure.
2161 */ 2160 */
2162 2161
2163int fill_rx_buffers(struct s2io_nic *nic, int ring_no) 2162static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
2164{ 2163{
2165 struct net_device *dev = nic->dev; 2164 struct net_device *dev = nic->dev;
2166 struct sk_buff *skb; 2165 struct sk_buff *skb;
@@ -2831,7 +2830,7 @@ static void alarm_intr_handler(struct s2io_nic *nic)
2831 * SUCCESS on success and FAILURE on failure. 2830 * SUCCESS on success and FAILURE on failure.
2832 */ 2831 */
2833 2832
2834int wait_for_cmd_complete(nic_t * sp) 2833static int wait_for_cmd_complete(nic_t * sp)
2835{ 2834{
2836 XENA_dev_config_t __iomem *bar0 = sp->bar0; 2835 XENA_dev_config_t __iomem *bar0 = sp->bar0;
2837 int ret = FAILURE, cnt = 0; 2836 int ret = FAILURE, cnt = 0;
@@ -3077,7 +3076,7 @@ int s2io_set_swapper(nic_t * sp)
3077 return SUCCESS; 3076 return SUCCESS;
3078} 3077}
3079 3078
3080int wait_for_msix_trans(nic_t *nic, int i) 3079static int wait_for_msix_trans(nic_t *nic, int i)
3081{ 3080{
3082 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; 3081 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
3083 u64 val64; 3082 u64 val64;
@@ -3116,7 +3115,7 @@ void restore_xmsi_data(nic_t *nic)
3116 } 3115 }
3117} 3116}
3118 3117
3119void store_xmsi_data(nic_t *nic) 3118static void store_xmsi_data(nic_t *nic)
3120{ 3119{
3121 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; 3120 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
3122 u64 val64, addr, data; 3121 u64 val64, addr, data;
@@ -3288,7 +3287,7 @@ int s2io_enable_msi_x(nic_t *nic)
3288 * file on failure. 3287 * file on failure.
3289 */ 3288 */
3290 3289
3291int s2io_open(struct net_device *dev) 3290static int s2io_open(struct net_device *dev)
3292{ 3291{
3293 nic_t *sp = dev->priv; 3292 nic_t *sp = dev->priv;
3294 int err = 0; 3293 int err = 0;
@@ -3418,7 +3417,7 @@ hw_init_failed:
3418 * file on failure. 3417 * file on failure.
3419 */ 3418 */
3420 3419
3421int s2io_close(struct net_device *dev) 3420static int s2io_close(struct net_device *dev)
3422{ 3421{
3423 nic_t *sp = dev->priv; 3422 nic_t *sp = dev->priv;
3424 int i; 3423 int i;
@@ -3467,7 +3466,7 @@ int s2io_close(struct net_device *dev)
3467 * 0 on success & 1 on failure. 3466 * 0 on success & 1 on failure.
3468 */ 3467 */
3469 3468
3470int s2io_xmit(struct sk_buff *skb, struct net_device *dev) 3469static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
3471{ 3470{
3472 nic_t *sp = dev->priv; 3471 nic_t *sp = dev->priv;
3473 u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; 3472 u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
@@ -3913,7 +3912,7 @@ static void s2io_updt_stats(nic_t *sp)
3913 * pointer to the updated net_device_stats structure. 3912 * pointer to the updated net_device_stats structure.
3914 */ 3913 */
3915 3914
3916struct net_device_stats *s2io_get_stats(struct net_device *dev) 3915static struct net_device_stats *s2io_get_stats(struct net_device *dev)
3917{ 3916{
3918 nic_t *sp = dev->priv; 3917 nic_t *sp = dev->priv;
3919 mac_info_t *mac_control; 3918 mac_info_t *mac_control;
@@ -5106,19 +5105,20 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
5106 tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; 5105 tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs;
5107} 5106}
5108 5107
5109int s2io_ethtool_get_regs_len(struct net_device *dev) 5108static int s2io_ethtool_get_regs_len(struct net_device *dev)
5110{ 5109{
5111 return (XENA_REG_SPACE); 5110 return (XENA_REG_SPACE);
5112} 5111}
5113 5112
5114 5113
5115u32 s2io_ethtool_get_rx_csum(struct net_device * dev) 5114static u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
5116{ 5115{
5117 nic_t *sp = dev->priv; 5116 nic_t *sp = dev->priv;
5118 5117
5119 return (sp->rx_csum); 5118 return (sp->rx_csum);
5120} 5119}
5121int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) 5120
5121static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
5122{ 5122{
5123 nic_t *sp = dev->priv; 5123 nic_t *sp = dev->priv;
5124 5124
@@ -5129,17 +5129,19 @@ int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
5129 5129
5130 return 0; 5130 return 0;
5131} 5131}
5132int s2io_get_eeprom_len(struct net_device *dev) 5132
5133static int s2io_get_eeprom_len(struct net_device *dev)
5133{ 5134{
5134 return (XENA_EEPROM_SPACE); 5135 return (XENA_EEPROM_SPACE);
5135} 5136}
5136 5137
5137int s2io_ethtool_self_test_count(struct net_device *dev) 5138static int s2io_ethtool_self_test_count(struct net_device *dev)
5138{ 5139{
5139 return (S2IO_TEST_LEN); 5140 return (S2IO_TEST_LEN);
5140} 5141}
5141void s2io_ethtool_get_strings(struct net_device *dev, 5142
5142 u32 stringset, u8 * data) 5143static void s2io_ethtool_get_strings(struct net_device *dev,
5144 u32 stringset, u8 * data)
5143{ 5145{
5144 switch (stringset) { 5146 switch (stringset) {
5145 case ETH_SS_TEST: 5147 case ETH_SS_TEST:
@@ -5155,7 +5157,7 @@ static int s2io_ethtool_get_stats_count(struct net_device *dev)
5155 return (S2IO_STAT_LEN); 5157 return (S2IO_STAT_LEN);
5156} 5158}
5157 5159
5158int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) 5160static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
5159{ 5161{
5160 if (data) 5162 if (data)
5161 dev->features |= NETIF_F_IP_CSUM; 5163 dev->features |= NETIF_F_IP_CSUM;
@@ -5208,7 +5210,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
5208 * function always return EOPNOTSUPPORTED 5210 * function always return EOPNOTSUPPORTED
5209 */ 5211 */
5210 5212
5211int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 5213static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5212{ 5214{
5213 return -EOPNOTSUPP; 5215 return -EOPNOTSUPP;
5214} 5216}
@@ -5224,7 +5226,7 @@ int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5224 * file on failure. 5226 * file on failure.
5225 */ 5227 */
5226 5228
5227int s2io_change_mtu(struct net_device *dev, int new_mtu) 5229static int s2io_change_mtu(struct net_device *dev, int new_mtu)
5228{ 5230{
5229 nic_t *sp = dev->priv; 5231 nic_t *sp = dev->priv;
5230 5232
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
index 308440bd0e12..91b8d4f45904 100644
--- a/drivers/net/sk98lin/h/skdrv1st.h
+++ b/drivers/net/sk98lin/h/skdrv1st.h
@@ -39,9 +39,6 @@
39#ifndef __INC_SKDRV1ST_H 39#ifndef __INC_SKDRV1ST_H
40#define __INC_SKDRV1ST_H 40#define __INC_SKDRV1ST_H
41 41
42/* Check kernel version */
43#include <linux/version.h>
44
45typedef struct s_AC SK_AC; 42typedef struct s_AC SK_AC;
46 43
47/* Set card versions */ 44/* Set card versions */
diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c
index 4c56b8d8221b..e5d6d95960c7 100644
--- a/drivers/net/sk_mca.c
+++ b/drivers/net/sk_mca.c
@@ -93,7 +93,6 @@ History:
93#include <linux/mca-legacy.h> 93#include <linux/mca-legacy.h>
94#include <linux/init.h> 94#include <linux/init.h>
95#include <linux/module.h> 95#include <linux/module.h>
96#include <linux/version.h>
97#include <linux/netdevice.h> 96#include <linux/netdevice.h>
98#include <linux/etherdevice.h> 97#include <linux/etherdevice.h>
99#include <linux/skbuff.h> 98#include <linux/skbuff.h>
diff --git a/drivers/net/sk_mca.h b/drivers/net/sk_mca.h
index 7e7c99582746..d6fa1823dfa6 100644
--- a/drivers/net/sk_mca.h
+++ b/drivers/net/sk_mca.h
@@ -1,5 +1,3 @@
1#include <linux/version.h>
2
3#ifndef _SK_MCA_INCLUDE_ 1#ifndef _SK_MCA_INCLUDE_
4#define _SK_MCA_INCLUDE_ 2#define _SK_MCA_INCLUDE_
5 3
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 572f121b1f4e..596c93b12daa 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -37,12 +37,13 @@
37#include <linux/delay.h> 37#include <linux/delay.h>
38#include <linux/crc32.h> 38#include <linux/crc32.h>
39#include <linux/dma-mapping.h> 39#include <linux/dma-mapping.h>
40#include <linux/mii.h>
40#include <asm/irq.h> 41#include <asm/irq.h>
41 42
42#include "skge.h" 43#include "skge.h"
43 44
44#define DRV_NAME "skge" 45#define DRV_NAME "skge"
45#define DRV_VERSION "1.1" 46#define DRV_VERSION "1.2"
46#define PFX DRV_NAME " " 47#define PFX DRV_NAME " "
47 48
48#define DEFAULT_TX_RING_SIZE 128 49#define DEFAULT_TX_RING_SIZE 128
@@ -88,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
88static int skge_up(struct net_device *dev); 89static int skge_up(struct net_device *dev);
89static int skge_down(struct net_device *dev); 90static int skge_down(struct net_device *dev);
90static void skge_tx_clean(struct skge_port *skge); 91static void skge_tx_clean(struct skge_port *skge);
91static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); 92static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
92static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); 93static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
93static void genesis_get_stats(struct skge_port *skge, u64 *data); 94static void genesis_get_stats(struct skge_port *skge, u64 *data);
94static void yukon_get_stats(struct skge_port *skge, u64 *data); 95static void yukon_get_stats(struct skge_port *skge, u64 *data);
95static void yukon_init(struct skge_hw *hw, int port); 96static void yukon_init(struct skge_hw *hw, int port);
@@ -129,7 +130,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
129 regs->len - B3_RI_WTO_R1); 130 regs->len - B3_RI_WTO_R1);
130} 131}
131 132
132/* Wake on Lan only supported on Yukon chps with rev 1 or above */ 133/* Wake on Lan only supported on Yukon chips with rev 1 or above */
133static int wol_supported(const struct skge_hw *hw) 134static int wol_supported(const struct skge_hw *hw)
134{ 135{
135 return !((hw->chip_id == CHIP_ID_GENESIS || 136 return !((hw->chip_id == CHIP_ID_GENESIS ||
@@ -169,8 +170,8 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
169 return 0; 170 return 0;
170} 171}
171 172
172/* Determine supported/adverised modes based on hardware. 173/* Determine supported/advertised modes based on hardware.
173 * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx 174 * Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx
174 */ 175 */
175static u32 skge_supported_modes(const struct skge_hw *hw) 176static u32 skge_supported_modes(const struct skge_hw *hw)
176{ 177{
@@ -531,13 +532,13 @@ static inline u32 hwkhz(const struct skge_hw *hw)
531 return 78215; /* or: 78.125 MHz */ 532 return 78215; /* or: 78.125 MHz */
532} 533}
533 534
534/* Chip hz to microseconds */ 535/* Chip HZ to microseconds */
535static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks) 536static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks)
536{ 537{
537 return (ticks * 1000) / hwkhz(hw); 538 return (ticks * 1000) / hwkhz(hw);
538} 539}
539 540
540/* Microseconds to chip hz */ 541/* Microseconds to chip HZ */
541static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec) 542static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec)
542{ 543{
543 return hwkhz(hw) * usec / 1000; 544 return hwkhz(hw) * usec / 1000;
@@ -883,32 +884,37 @@ static void skge_link_down(struct skge_port *skge)
883 printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); 884 printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
884} 885}
885 886
886static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) 887static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
887{ 888{
888 int i; 889 int i;
889 u16 v;
890 890
891 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); 891 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
892 v = xm_read16(hw, port, XM_PHY_DATA); 892 xm_read16(hw, port, XM_PHY_DATA);
893 893
894 /* Need to wait for external PHY */ 894 /* Need to wait for external PHY */
895 for (i = 0; i < PHY_RETRIES; i++) { 895 for (i = 0; i < PHY_RETRIES; i++) {
896 udelay(1); 896 udelay(1);
897 if (xm_read16(hw, port, XM_MMU_CMD) 897 if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
898 & XM_MMU_PHY_RDY)
899 goto ready; 898 goto ready;
900 } 899 }
901 900
902 printk(KERN_WARNING PFX "%s: phy read timed out\n", 901 return -ETIMEDOUT;
903 hw->dev[port]->name);
904 return 0;
905 ready: 902 ready:
906 v = xm_read16(hw, port, XM_PHY_DATA); 903 *val = xm_read16(hw, port, XM_PHY_DATA);
907 904
905 return 0;
906}
907
908static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
909{
910 u16 v = 0;
911 if (__xm_phy_read(hw, port, reg, &v))
912 printk(KERN_WARNING PFX "%s: phy read timed out\n",
913 hw->dev[port]->name);
908 return v; 914 return v;
909} 915}
910 916
911static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) 917static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
912{ 918{
913 int i; 919 int i;
914 920
@@ -918,19 +924,11 @@ static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
918 goto ready; 924 goto ready;
919 udelay(1); 925 udelay(1);
920 } 926 }
921 printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", 927 return -EIO;
922 hw->dev[port]->name);
923
924 928
925 ready: 929 ready:
926 xm_write16(hw, port, XM_PHY_DATA, val); 930 xm_write16(hw, port, XM_PHY_DATA, val);
927 for (i = 0; i < PHY_RETRIES; i++) { 931 return 0;
928 udelay(1);
929 if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
930 return;
931 }
932 printk(KERN_WARNING PFX "%s: phy write timed out\n",
933 hw->dev[port]->name);
934} 932}
935 933
936static void genesis_init(struct skge_hw *hw) 934static void genesis_init(struct skge_hw *hw)
@@ -1165,7 +1163,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
1165 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext); 1163 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
1166 xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl); 1164 xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
1167 1165
1168 /* Use link status change interrrupt */ 1166 /* Use link status change interrupt */
1169 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); 1167 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
1170 1168
1171 bcom_check_link(hw, port); 1169 bcom_check_link(hw, port);
@@ -1205,7 +1203,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1205 skge_write32(hw, B2_GP_IO, r); 1203 skge_write32(hw, B2_GP_IO, r);
1206 skge_read32(hw, B2_GP_IO); 1204 skge_read32(hw, B2_GP_IO);
1207 1205
1208 /* Enable GMII interfac */ 1206 /* Enable GMII interface */
1209 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); 1207 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
1210 1208
1211 bcom_phy_init(skge, jumbo); 1209 bcom_phy_init(skge, jumbo);
@@ -1256,7 +1254,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1256 * that jumbo frames larger than 8192 bytes will be 1254 * that jumbo frames larger than 8192 bytes will be
1257 * truncated. Disabling all bad frame filtering causes 1255 * truncated. Disabling all bad frame filtering causes
1258 * the RX FIFO to operate in streaming mode, in which 1256 * the RX FIFO to operate in streaming mode, in which
1259 * case the XMAC will start transfering frames out of the 1257 * case the XMAC will start transferring frames out of the
1260 * RX FIFO as soon as the FIFO threshold is reached. 1258 * RX FIFO as soon as the FIFO threshold is reached.
1261 */ 1259 */
1262 xm_write32(hw, port, XM_MODE, XM_DEF_MODE); 1260 xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
@@ -1323,7 +1321,7 @@ static void genesis_stop(struct skge_port *skge)
1323 port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); 1321 port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
1324 1322
1325 /* 1323 /*
1326 * If the transfer stucks at the MAC the STOP command will not 1324 * If the transfer sticks at the MAC the STOP command will not
1327 * terminate if we don't flush the XMAC's transmit FIFO ! 1325 * terminate if we don't flush the XMAC's transmit FIFO !
1328 */ 1326 */
1329 xm_write32(hw, port, XM_MODE, 1327 xm_write32(hw, port, XM_MODE,
@@ -1400,42 +1398,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port)
1400 } 1398 }
1401} 1399}
1402 1400
1403static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
1404{
1405 int i;
1406
1407 gma_write16(hw, port, GM_SMI_DATA, val);
1408 gma_write16(hw, port, GM_SMI_CTRL,
1409 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
1410 for (i = 0; i < PHY_RETRIES; i++) {
1411 udelay(1);
1412
1413 if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
1414 break;
1415 }
1416}
1417
1418static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
1419{
1420 int i;
1421
1422 gma_write16(hw, port, GM_SMI_CTRL,
1423 GM_SMI_CT_PHY_AD(hw->phy_addr)
1424 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
1425
1426 for (i = 0; i < PHY_RETRIES; i++) {
1427 udelay(1);
1428 if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
1429 goto ready;
1430 }
1431
1432 printk(KERN_WARNING PFX "%s: phy read timeout\n",
1433 hw->dev[port]->name);
1434 return 0;
1435 ready:
1436 return gma_read16(hw, port, GM_SMI_DATA);
1437}
1438
1439static void genesis_link_up(struct skge_port *skge) 1401static void genesis_link_up(struct skge_port *skge)
1440{ 1402{
1441 struct skge_hw *hw = skge->hw; 1403 struct skge_hw *hw = skge->hw;
@@ -1549,7 +1511,55 @@ static inline void bcom_phy_intr(struct skge_port *skge)
1549 1511
1550} 1512}
1551 1513
1552/* Marvell Phy Initailization */ 1514static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
1515{
1516 int i;
1517
1518 gma_write16(hw, port, GM_SMI_DATA, val);
1519 gma_write16(hw, port, GM_SMI_CTRL,
1520 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
1521 for (i = 0; i < PHY_RETRIES; i++) {
1522 udelay(1);
1523
1524 if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
1525 return 0;
1526 }
1527
1528 printk(KERN_WARNING PFX "%s: phy write timeout\n",
1529 hw->dev[port]->name);
1530 return -EIO;
1531}
1532
1533static int __gm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
1534{
1535 int i;
1536
1537 gma_write16(hw, port, GM_SMI_CTRL,
1538 GM_SMI_CT_PHY_AD(hw->phy_addr)
1539 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
1540
1541 for (i = 0; i < PHY_RETRIES; i++) {
1542 udelay(1);
1543 if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
1544 goto ready;
1545 }
1546
1547 return -ETIMEDOUT;
1548 ready:
1549 *val = gma_read16(hw, port, GM_SMI_DATA);
1550 return 0;
1551}
1552
1553static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
1554{
1555 u16 v = 0;
1556 if (__gm_phy_read(hw, port, reg, &v))
1557 printk(KERN_WARNING PFX "%s: phy read timeout\n",
1558 hw->dev[port]->name);
1559 return v;
1560}
1561
1562/* Marvell Phy Initialization */
1553static void yukon_init(struct skge_hw *hw, int port) 1563static void yukon_init(struct skge_hw *hw, int port)
1554{ 1564{
1555 struct skge_port *skge = netdev_priv(hw->dev[port]); 1565 struct skge_port *skge = netdev_priv(hw->dev[port]);
@@ -1794,6 +1804,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
1794 skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); 1804 skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
1795} 1805}
1796 1806
1807/* Go into power down mode */
1808static void yukon_suspend(struct skge_hw *hw, int port)
1809{
1810 u16 ctrl;
1811
1812 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
1813 ctrl |= PHY_M_PC_POL_R_DIS;
1814 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
1815
1816 ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
1817 ctrl |= PHY_CT_RESET;
1818 gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
1819
1820 /* switch IEEE compatible power down mode on */
1821 ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
1822 ctrl |= PHY_CT_PDOWN;
1823 gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
1824}
1825
1797static void yukon_stop(struct skge_port *skge) 1826static void yukon_stop(struct skge_port *skge)
1798{ 1827{
1799 struct skge_hw *hw = skge->hw; 1828 struct skge_hw *hw = skge->hw;
@@ -1807,14 +1836,7 @@ static void yukon_stop(struct skge_port *skge)
1807 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); 1836 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
1808 gma_read16(hw, port, GM_GP_CTRL); 1837 gma_read16(hw, port, GM_GP_CTRL);
1809 1838
1810 if (hw->chip_id == CHIP_ID_YUKON_LITE && 1839 yukon_suspend(hw, port);
1811 hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
1812 u32 io = skge_read32(hw, B2_GP_IO);
1813
1814 io |= GP_DIR_9 | GP_IO_9;
1815 skge_write32(hw, B2_GP_IO, io);
1816 skge_read32(hw, B2_GP_IO);
1817 }
1818 1840
1819 /* set GPHY Control reset */ 1841 /* set GPHY Control reset */
1820 skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); 1842 skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
@@ -1997,6 +2019,51 @@ static void yukon_phy_intr(struct skge_port *skge)
1997 /* XXX restart autonegotiation? */ 2019 /* XXX restart autonegotiation? */
1998} 2020}
1999 2021
2022/* Basic MII support */
2023static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2024{
2025 struct mii_ioctl_data *data = if_mii(ifr);
2026 struct skge_port *skge = netdev_priv(dev);
2027 struct skge_hw *hw = skge->hw;
2028 int err = -EOPNOTSUPP;
2029
2030 if (!netif_running(dev))
2031 return -ENODEV; /* Phy still in reset */
2032
2033 switch(cmd) {
2034 case SIOCGMIIPHY:
2035 data->phy_id = hw->phy_addr;
2036
2037 /* fallthru */
2038 case SIOCGMIIREG: {
2039 u16 val = 0;
2040 spin_lock_bh(&hw->phy_lock);
2041 if (hw->chip_id == CHIP_ID_GENESIS)
2042 err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
2043 else
2044 err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
2045 spin_unlock_bh(&hw->phy_lock);
2046 data->val_out = val;
2047 break;
2048 }
2049
2050 case SIOCSMIIREG:
2051 if (!capable(CAP_NET_ADMIN))
2052 return -EPERM;
2053
2054 spin_lock_bh(&hw->phy_lock);
2055 if (hw->chip_id == CHIP_ID_GENESIS)
2056 err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f,
2057 data->val_in);
2058 else
2059 err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f,
2060 data->val_in);
2061 spin_unlock_bh(&hw->phy_lock);
2062 break;
2063 }
2064 return err;
2065}
2066
2000static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len) 2067static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
2001{ 2068{
2002 u32 end; 2069 u32 end;
@@ -2089,7 +2156,7 @@ static int skge_up(struct net_device *dev)
2089 hw->intr_mask |= portirqmask[port]; 2156 hw->intr_mask |= portirqmask[port];
2090 skge_write32(hw, B0_IMSK, hw->intr_mask); 2157 skge_write32(hw, B0_IMSK, hw->intr_mask);
2091 2158
2092 /* Initialze MAC */ 2159 /* Initialize MAC */
2093 spin_lock_bh(&hw->phy_lock); 2160 spin_lock_bh(&hw->phy_lock);
2094 if (hw->chip_id == CHIP_ID_GENESIS) 2161 if (hw->chip_id == CHIP_ID_GENESIS)
2095 genesis_mac_init(hw, port); 2162 genesis_mac_init(hw, port);
@@ -2409,7 +2476,7 @@ static void yukon_set_multicast(struct net_device *dev)
2409 reg = gma_read16(hw, port, GM_RX_CTRL); 2476 reg = gma_read16(hw, port, GM_RX_CTRL);
2410 reg |= GM_RXCR_UCF_ENA; 2477 reg |= GM_RXCR_UCF_ENA;
2411 2478
2412 if (dev->flags & IFF_PROMISC) /* promiscious */ 2479 if (dev->flags & IFF_PROMISC) /* promiscuous */
2413 reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); 2480 reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
2414 else if (dev->flags & IFF_ALLMULTI) /* all multicast */ 2481 else if (dev->flags & IFF_ALLMULTI) /* all multicast */
2415 memset(filter, 0xff, sizeof(filter)); 2482 memset(filter, 0xff, sizeof(filter));
@@ -2560,7 +2627,7 @@ static int skge_poll(struct net_device *dev, int *budget)
2560 unsigned int to_do = min(dev->quota, *budget); 2627 unsigned int to_do = min(dev->quota, *budget);
2561 unsigned int work_done = 0; 2628 unsigned int work_done = 0;
2562 2629
2563 for (e = ring->to_clean; work_done < to_do; e = e->next) { 2630 for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) {
2564 struct skge_rx_desc *rd = e->desc; 2631 struct skge_rx_desc *rd = e->desc;
2565 struct sk_buff *skb; 2632 struct sk_buff *skb;
2566 u32 control; 2633 u32 control;
@@ -2593,11 +2660,11 @@ static int skge_poll(struct net_device *dev, int *budget)
2593 if (work_done >= to_do) 2660 if (work_done >= to_do)
2594 return 1; /* not done */ 2661 return 1; /* not done */
2595 2662
2596 local_irq_disable(); 2663 netif_rx_complete(dev);
2597 __netif_rx_complete(dev);
2598 hw->intr_mask |= portirqmask[skge->port]; 2664 hw->intr_mask |= portirqmask[skge->port];
2599 skge_write32(hw, B0_IMSK, hw->intr_mask); 2665 skge_write32(hw, B0_IMSK, hw->intr_mask);
2600 local_irq_enable(); 2666 skge_read32(hw, B0_IMSK);
2667
2601 return 0; 2668 return 0;
2602} 2669}
2603 2670
@@ -2609,7 +2676,7 @@ static inline void skge_tx_intr(struct net_device *dev)
2609 struct skge_element *e; 2676 struct skge_element *e;
2610 2677
2611 spin_lock(&skge->tx_lock); 2678 spin_lock(&skge->tx_lock);
2612 for (e = ring->to_clean; e != ring->to_use; e = e->next) { 2679 for (e = ring->to_clean; prefetch(e->next), e != ring->to_use; e = e->next) {
2613 struct skge_tx_desc *td = e->desc; 2680 struct skge_tx_desc *td = e->desc;
2614 u32 control; 2681 u32 control;
2615 2682
@@ -2732,7 +2799,7 @@ static void skge_error_irq(struct skge_hw *hw)
2732} 2799}
2733 2800
2734/* 2801/*
2735 * Interrrupt from PHY are handled in tasklet (soft irq) 2802 * Interrupt from PHY are handled in tasklet (soft irq)
2736 * because accessing phy registers requires spin wait which might 2803 * because accessing phy registers requires spin wait which might
2737 * cause excess interrupt latency. 2804 * cause excess interrupt latency.
2738 */ 2805 */
@@ -2762,6 +2829,14 @@ static void skge_extirq(unsigned long data)
2762 local_irq_enable(); 2829 local_irq_enable();
2763} 2830}
2764 2831
2832static inline void skge_wakeup(struct net_device *dev)
2833{
2834 struct skge_port *skge = netdev_priv(dev);
2835
2836 prefetch(skge->rx_ring.to_clean);
2837 netif_rx_schedule(dev);
2838}
2839
2765static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) 2840static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
2766{ 2841{
2767 struct skge_hw *hw = dev_id; 2842 struct skge_hw *hw = dev_id;
@@ -2773,12 +2848,12 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
2773 status &= hw->intr_mask; 2848 status &= hw->intr_mask;
2774 if (status & IS_R1_F) { 2849 if (status & IS_R1_F) {
2775 hw->intr_mask &= ~IS_R1_F; 2850 hw->intr_mask &= ~IS_R1_F;
2776 netif_rx_schedule(hw->dev[0]); 2851 skge_wakeup(hw->dev[0]);
2777 } 2852 }
2778 2853
2779 if (status & IS_R2_F) { 2854 if (status & IS_R2_F) {
2780 hw->intr_mask &= ~IS_R2_F; 2855 hw->intr_mask &= ~IS_R2_F;
2781 netif_rx_schedule(hw->dev[1]); 2856 skge_wakeup(hw->dev[1]);
2782 } 2857 }
2783 2858
2784 if (status & IS_XA1_F) 2859 if (status & IS_XA1_F)
@@ -2893,6 +2968,7 @@ static const char *skge_board_name(const struct skge_hw *hw)
2893 */ 2968 */
2894static int skge_reset(struct skge_hw *hw) 2969static int skge_reset(struct skge_hw *hw)
2895{ 2970{
2971 u32 reg;
2896 u16 ctst; 2972 u16 ctst;
2897 u8 t8, mac_cfg, pmd_type, phy_type; 2973 u8 t8, mac_cfg, pmd_type, phy_type;
2898 int i; 2974 int i;
@@ -2971,6 +3047,7 @@ static int skge_reset(struct skge_hw *hw)
2971 /* switch power to VCC (WA for VAUX problem) */ 3047 /* switch power to VCC (WA for VAUX problem) */
2972 skge_write8(hw, B0_POWER_CTRL, 3048 skge_write8(hw, B0_POWER_CTRL,
2973 PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); 3049 PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
3050
2974 /* avoid boards with stuck Hardware error bits */ 3051 /* avoid boards with stuck Hardware error bits */
2975 if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) && 3052 if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) &&
2976 (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) { 3053 (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) {
@@ -2978,6 +3055,14 @@ static int skge_reset(struct skge_hw *hw)
2978 hw->intr_mask &= ~IS_HW_ERR; 3055 hw->intr_mask &= ~IS_HW_ERR;
2979 } 3056 }
2980 3057
3058 /* Clear PHY COMA */
3059 skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
3060 pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg);
3061 reg &= ~PCI_PHY_COMA;
3062 pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg);
3063 skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
3064
3065
2981 for (i = 0; i < hw->ports; i++) { 3066 for (i = 0; i < hw->ports; i++) {
2982 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); 3067 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
2983 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); 3068 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
@@ -3048,6 +3133,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
3048 SET_NETDEV_DEV(dev, &hw->pdev->dev); 3133 SET_NETDEV_DEV(dev, &hw->pdev->dev);
3049 dev->open = skge_up; 3134 dev->open = skge_up;
3050 dev->stop = skge_down; 3135 dev->stop = skge_down;
3136 dev->do_ioctl = skge_ioctl;
3051 dev->hard_start_xmit = skge_xmit_frame; 3137 dev->hard_start_xmit = skge_xmit_frame;
3052 dev->get_stats = skge_get_stats; 3138 dev->get_stats = skge_get_stats;
3053 if (hw->chip_id == CHIP_ID_GENESIS) 3139 if (hw->chip_id == CHIP_ID_GENESIS)
@@ -3147,7 +3233,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3147 } 3233 }
3148 3234
3149#ifdef __BIG_ENDIAN 3235#ifdef __BIG_ENDIAN
3150 /* byte swap decriptors in hardware */ 3236 /* byte swap descriptors in hardware */
3151 { 3237 {
3152 u32 reg; 3238 u32 reg;
3153 3239
@@ -3158,14 +3244,13 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3158#endif 3244#endif
3159 3245
3160 err = -ENOMEM; 3246 err = -ENOMEM;
3161 hw = kmalloc(sizeof(*hw), GFP_KERNEL); 3247 hw = kzalloc(sizeof(*hw), GFP_KERNEL);
3162 if (!hw) { 3248 if (!hw) {
3163 printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n", 3249 printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
3164 pci_name(pdev)); 3250 pci_name(pdev));
3165 goto err_out_free_regions; 3251 goto err_out_free_regions;
3166 } 3252 }
3167 3253
3168 memset(hw, 0, sizeof(*hw));
3169 hw->pdev = pdev; 3254 hw->pdev = pdev;
3170 spin_lock_init(&hw->phy_lock); 3255 spin_lock_init(&hw->phy_lock);
3171 tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); 3256 tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw);
@@ -3188,7 +3273,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3188 if (err) 3273 if (err)
3189 goto err_out_free_irq; 3274 goto err_out_free_irq;
3190 3275
3191 printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n", 3276 printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n",
3192 pci_resource_start(pdev, 0), pdev->irq, 3277 pci_resource_start(pdev, 0), pdev->irq,
3193 skge_board_name(hw), hw->chip_rev); 3278 skge_board_name(hw), hw->chip_rev);
3194 3279
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 72c175b87a5a..ee123c15f545 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -6,6 +6,8 @@
6 6
7/* PCI config registers */ 7/* PCI config registers */
8#define PCI_DEV_REG1 0x40 8#define PCI_DEV_REG1 0x40
9#define PCI_PHY_COMA 0x8000000
10#define PCI_VIO 0x2000000
9#define PCI_DEV_REG2 0x44 11#define PCI_DEV_REG2 0x44
10#define PCI_REV_DESC 0x4 12#define PCI_REV_DESC 0x4
11 13
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 38b2b0a3ce96..d167deda9a53 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -147,7 +147,6 @@ TODO: - fix forced speed/duplexing code (broken a long time ago, when
147#define DRV_RELDATE "October 3, 2005" 147#define DRV_RELDATE "October 3, 2005"
148 148
149#include <linux/config.h> 149#include <linux/config.h>
150#include <linux/version.h>
151#include <linux/module.h> 150#include <linux/module.h>
152#include <linux/kernel.h> 151#include <linux/kernel.h>
153#include <linux/pci.h> 152#include <linux/pci.h>
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index a368d08e7d19..82c6b757d306 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -61,7 +61,6 @@
61#include <linux/timer.h> 61#include <linux/timer.h>
62#include <linux/slab.h> 62#include <linux/slab.h>
63#include <linux/interrupt.h> 63#include <linux/interrupt.h>
64#include <linux/version.h>
65#include <linux/string.h> 64#include <linux/string.h>
66#include <linux/wait.h> 65#include <linux/wait.h>
67#include <asm/io.h> 66#include <asm/io.h>
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 6afc6e5dee9b..340ab4ee4b67 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -4535,9 +4535,8 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
4535 StatusRid status_rid; 4535 StatusRid status_rid;
4536 int i; 4536 int i;
4537 4537
4538 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4538 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4539 return -ENOMEM; 4539 return -ENOMEM;
4540 memset(file->private_data, 0, sizeof(struct proc_data));
4541 data = (struct proc_data *)file->private_data; 4540 data = (struct proc_data *)file->private_data;
4542 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4541 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4543 kfree (file->private_data); 4542 kfree (file->private_data);
@@ -4615,9 +4614,8 @@ static int proc_stats_rid_open( struct inode *inode,
4615 int i, j; 4614 int i, j;
4616 u32 *vals = stats.vals; 4615 u32 *vals = stats.vals;
4617 4616
4618 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4617 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4619 return -ENOMEM; 4618 return -ENOMEM;
4620 memset(file->private_data, 0, sizeof(struct proc_data));
4621 data = (struct proc_data *)file->private_data; 4619 data = (struct proc_data *)file->private_data;
4622 if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) { 4620 if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
4623 kfree (file->private_data); 4621 kfree (file->private_data);
@@ -4881,20 +4879,18 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
4881 struct airo_info *ai = dev->priv; 4879 struct airo_info *ai = dev->priv;
4882 int i; 4880 int i;
4883 4881
4884 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4882 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4885 return -ENOMEM; 4883 return -ENOMEM;
4886 memset(file->private_data, 0, sizeof(struct proc_data));
4887 data = (struct proc_data *)file->private_data; 4884 data = (struct proc_data *)file->private_data;
4888 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4885 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4889 kfree (file->private_data); 4886 kfree (file->private_data);
4890 return -ENOMEM; 4887 return -ENOMEM;
4891 } 4888 }
4892 if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4889 if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
4893 kfree (data->rbuffer); 4890 kfree (data->rbuffer);
4894 kfree (file->private_data); 4891 kfree (file->private_data);
4895 return -ENOMEM; 4892 return -ENOMEM;
4896 } 4893 }
4897 memset( data->wbuffer, 0, 2048 );
4898 data->maxwritelen = 2048; 4894 data->maxwritelen = 2048;
4899 data->on_close = proc_config_on_close; 4895 data->on_close = proc_config_on_close;
4900 4896
@@ -5155,24 +5151,21 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) {
5155 int j=0; 5151 int j=0;
5156 int rc; 5152 int rc;
5157 5153
5158 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5154 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5159 return -ENOMEM; 5155 return -ENOMEM;
5160 memset(file->private_data, 0, sizeof(struct proc_data));
5161 memset(&wkr, 0, sizeof(wkr)); 5156 memset(&wkr, 0, sizeof(wkr));
5162 data = (struct proc_data *)file->private_data; 5157 data = (struct proc_data *)file->private_data;
5163 if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) { 5158 if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
5164 kfree (file->private_data); 5159 kfree (file->private_data);
5165 return -ENOMEM; 5160 return -ENOMEM;
5166 } 5161 }
5167 memset(data->rbuffer, 0, 180);
5168 data->writelen = 0; 5162 data->writelen = 0;
5169 data->maxwritelen = 80; 5163 data->maxwritelen = 80;
5170 if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) { 5164 if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
5171 kfree (data->rbuffer); 5165 kfree (data->rbuffer);
5172 kfree (file->private_data); 5166 kfree (file->private_data);
5173 return -ENOMEM; 5167 return -ENOMEM;
5174 } 5168 }
5175 memset( data->wbuffer, 0, 80 );
5176 data->on_close = proc_wepkey_on_close; 5169 data->on_close = proc_wepkey_on_close;
5177 5170
5178 ptr = data->rbuffer; 5171 ptr = data->rbuffer;
@@ -5203,9 +5196,8 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
5203 char *ptr; 5196 char *ptr;
5204 SsidRid SSID_rid; 5197 SsidRid SSID_rid;
5205 5198
5206 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5199 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5207 return -ENOMEM; 5200 return -ENOMEM;
5208 memset(file->private_data, 0, sizeof(struct proc_data));
5209 data = (struct proc_data *)file->private_data; 5201 data = (struct proc_data *)file->private_data;
5210 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { 5202 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5211 kfree (file->private_data); 5203 kfree (file->private_data);
@@ -5213,12 +5205,11 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
5213 } 5205 }
5214 data->writelen = 0; 5206 data->writelen = 0;
5215 data->maxwritelen = 33*3; 5207 data->maxwritelen = 33*3;
5216 if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) { 5208 if ((data->wbuffer = kzalloc( 33*3, GFP_KERNEL )) == NULL) {
5217 kfree (data->rbuffer); 5209 kfree (data->rbuffer);
5218 kfree (file->private_data); 5210 kfree (file->private_data);
5219 return -ENOMEM; 5211 return -ENOMEM;
5220 } 5212 }
5221 memset( data->wbuffer, 0, 33*3 );
5222 data->on_close = proc_SSID_on_close; 5213 data->on_close = proc_SSID_on_close;
5223 5214
5224 readSsidRid(ai, &SSID_rid); 5215 readSsidRid(ai, &SSID_rid);
@@ -5247,9 +5238,8 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
5247 char *ptr; 5238 char *ptr;
5248 APListRid APList_rid; 5239 APListRid APList_rid;
5249 5240
5250 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5241 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5251 return -ENOMEM; 5242 return -ENOMEM;
5252 memset(file->private_data, 0, sizeof(struct proc_data));
5253 data = (struct proc_data *)file->private_data; 5243 data = (struct proc_data *)file->private_data;
5254 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { 5244 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5255 kfree (file->private_data); 5245 kfree (file->private_data);
@@ -5257,12 +5247,11 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
5257 } 5247 }
5258 data->writelen = 0; 5248 data->writelen = 0;
5259 data->maxwritelen = 4*6*3; 5249 data->maxwritelen = 4*6*3;
5260 if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) { 5250 if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
5261 kfree (data->rbuffer); 5251 kfree (data->rbuffer);
5262 kfree (file->private_data); 5252 kfree (file->private_data);
5263 return -ENOMEM; 5253 return -ENOMEM;
5264 } 5254 }
5265 memset( data->wbuffer, 0, data->maxwritelen );
5266 data->on_close = proc_APList_on_close; 5255 data->on_close = proc_APList_on_close;
5267 5256
5268 readAPListRid(ai, &APList_rid); 5257 readAPListRid(ai, &APList_rid);
@@ -5297,9 +5286,8 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
5297 /* If doLoseSync is not 1, we won't do a Lose Sync */ 5286 /* If doLoseSync is not 1, we won't do a Lose Sync */
5298 int doLoseSync = -1; 5287 int doLoseSync = -1;
5299 5288
5300 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5289 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5301 return -ENOMEM; 5290 return -ENOMEM;
5302 memset(file->private_data, 0, sizeof(struct proc_data));
5303 data = (struct proc_data *)file->private_data; 5291 data = (struct proc_data *)file->private_data;
5304 if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) { 5292 if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
5305 kfree (file->private_data); 5293 kfree (file->private_data);
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 96ed8da8661d..e328547599dc 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -170,12 +170,11 @@ static dev_link_t *airo_attach(void)
170 DEBUG(0, "airo_attach()\n"); 170 DEBUG(0, "airo_attach()\n");
171 171
172 /* Initialize the dev_link_t structure */ 172 /* Initialize the dev_link_t structure */
173 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 173 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
174 if (!link) { 174 if (!link) {
175 printk(KERN_ERR "airo_cs: no memory for new device\n"); 175 printk(KERN_ERR "airo_cs: no memory for new device\n");
176 return NULL; 176 return NULL;
177 } 177 }
178 memset(link, 0, sizeof(struct dev_link_t));
179 178
180 /* Interrupt setup */ 179 /* Interrupt setup */
181 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 180 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
@@ -194,13 +193,12 @@ static dev_link_t *airo_attach(void)
194 link->conf.IntType = INT_MEMORY_AND_IO; 193 link->conf.IntType = INT_MEMORY_AND_IO;
195 194
196 /* Allocate space for private device-specific data */ 195 /* Allocate space for private device-specific data */
197 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 196 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
198 if (!local) { 197 if (!local) {
199 printk(KERN_ERR "airo_cs: no memory for new device\n"); 198 printk(KERN_ERR "airo_cs: no memory for new device\n");
200 kfree (link); 199 kfree (link);
201 return NULL; 200 return NULL;
202 } 201 }
203 memset(local, 0, sizeof(local_info_t));
204 link->priv = local; 202 link->priv = local;
205 203
206 /* Register with Card Services */ 204 /* Register with Card Services */
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 1fbe027d26b6..a3e23527fe7f 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2217,7 +2217,7 @@ static int atmel_get_range(struct net_device *dev,
2217 int k,i,j; 2217 int k,i,j;
2218 2218
2219 dwrq->length = sizeof(struct iw_range); 2219 dwrq->length = sizeof(struct iw_range);
2220 memset(range, 0, sizeof(range)); 2220 memset(range, 0, sizeof(struct iw_range));
2221 range->min_nwid = 0x0000; 2221 range->min_nwid = 0x0000;
2222 range->max_nwid = 0x0000; 2222 range->max_nwid = 0x0000;
2223 range->num_channels = 0; 2223 range->num_channels = 0;
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 195cb36619e8..1bd13146c644 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -180,12 +180,11 @@ static dev_link_t *atmel_attach(void)
180 DEBUG(0, "atmel_attach()\n"); 180 DEBUG(0, "atmel_attach()\n");
181 181
182 /* Initialize the dev_link_t structure */ 182 /* Initialize the dev_link_t structure */
183 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 183 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
184 if (!link) { 184 if (!link) {
185 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 185 printk(KERN_ERR "atmel_cs: no memory for new device\n");
186 return NULL; 186 return NULL;
187 } 187 }
188 memset(link, 0, sizeof(struct dev_link_t));
189 188
190 /* Interrupt setup */ 189 /* Interrupt setup */
191 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 190 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
@@ -204,13 +203,12 @@ static dev_link_t *atmel_attach(void)
204 link->conf.IntType = INT_MEMORY_AND_IO; 203 link->conf.IntType = INT_MEMORY_AND_IO;
205 204
206 /* Allocate space for private device-specific data */ 205 /* Allocate space for private device-specific data */
207 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 206 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
208 if (!local) { 207 if (!local) {
209 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 208 printk(KERN_ERR "atmel_cs: no memory for new device\n");
210 kfree (link); 209 kfree (link);
211 return NULL; 210 return NULL;
212 } 211 }
213 memset(local, 0, sizeof(local_info_t));
214 link->priv = local; 212 link->priv = local;
215 213
216 /* Register with Card Services */ 214 /* Register with Card Services */
diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c
index 6a96cd9f2685..3d2ea61033be 100644
--- a/drivers/net/wireless/hostap/hostap.c
+++ b/drivers/net/wireless/hostap/hostap.c
@@ -13,7 +13,6 @@
13 */ 13 */
14 14
15#include <linux/config.h> 15#include <linux/config.h>
16#include <linux/version.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 59fc15572395..abfae7fedebc 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -31,7 +31,6 @@
31 31
32 32
33#include <linux/config.h> 33#include <linux/config.h>
34#include <linux/version.h>
35 34
36#include <asm/delay.h> 35#include <asm/delay.h>
37#include <asm/uaccess.h> 36#include <asm/uaccess.h>
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index da0c80fb941c..2e85bdced2dd 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -5,7 +5,6 @@
5 * Andy Warner <andyw@pobox.com> */ 5 * Andy Warner <andyw@pobox.com> */
6 6
7#include <linux/config.h> 7#include <linux/config.h>
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/if.h> 10#include <linux/if.h>
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 78d67b408b2f..94fe2449f099 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -8,7 +8,6 @@
8 8
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/version.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/if.h> 13#include <linux/if.h>
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index ad7f8cd76db9..a2e6214169e9 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -167,17 +167,16 @@ that only one external action is invoked at a time.
167 167
168#include "ipw2100.h" 168#include "ipw2100.h"
169 169
170#define IPW2100_VERSION "1.1.0" 170#define IPW2100_VERSION "1.1.3"
171 171
172#define DRV_NAME "ipw2100" 172#define DRV_NAME "ipw2100"
173#define DRV_VERSION IPW2100_VERSION 173#define DRV_VERSION IPW2100_VERSION
174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" 174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
175#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" 175#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
176
177 176
178/* Debugging stuff */ 177/* Debugging stuff */
179#ifdef CONFIG_IPW_DEBUG 178#ifdef CONFIG_IPW_DEBUG
180#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */ 179#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */
181#endif 180#endif
182 181
183MODULE_DESCRIPTION(DRV_DESCRIPTION); 182MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -220,18 +219,18 @@ do { \
220} while (0) 219} while (0)
221#else 220#else
222#define IPW_DEBUG(level, message...) do {} while (0) 221#define IPW_DEBUG(level, message...) do {} while (0)
223#endif /* CONFIG_IPW_DEBUG */ 222#endif /* CONFIG_IPW_DEBUG */
224 223
225#ifdef CONFIG_IPW_DEBUG 224#ifdef CONFIG_IPW_DEBUG
226static const char *command_types[] = { 225static const char *command_types[] = {
227 "undefined", 226 "undefined",
228 "unused", /* HOST_ATTENTION */ 227 "unused", /* HOST_ATTENTION */
229 "HOST_COMPLETE", 228 "HOST_COMPLETE",
230 "unused", /* SLEEP */ 229 "unused", /* SLEEP */
231 "unused", /* HOST_POWER_DOWN */ 230 "unused", /* HOST_POWER_DOWN */
232 "unused", 231 "unused",
233 "SYSTEM_CONFIG", 232 "SYSTEM_CONFIG",
234 "unused", /* SET_IMR */ 233 "unused", /* SET_IMR */
235 "SSID", 234 "SSID",
236 "MANDATORY_BSSID", 235 "MANDATORY_BSSID",
237 "AUTHENTICATION_TYPE", 236 "AUTHENTICATION_TYPE",
@@ -277,17 +276,16 @@ static const char *command_types[] = {
277 "GROUP_ORDINALS", 276 "GROUP_ORDINALS",
278 "SHORT_RETRY_LIMIT", 277 "SHORT_RETRY_LIMIT",
279 "LONG_RETRY_LIMIT", 278 "LONG_RETRY_LIMIT",
280 "unused", /* SAVE_CALIBRATION */ 279 "unused", /* SAVE_CALIBRATION */
281 "unused", /* RESTORE_CALIBRATION */ 280 "unused", /* RESTORE_CALIBRATION */
282 "undefined", 281 "undefined",
283 "undefined", 282 "undefined",
284 "undefined", 283 "undefined",
285 "HOST_PRE_POWER_DOWN", 284 "HOST_PRE_POWER_DOWN",
286 "unused", /* HOST_INTERRUPT_COALESCING */ 285 "unused", /* HOST_INTERRUPT_COALESCING */
287 "undefined", 286 "undefined",
288 "CARD_DISABLE_PHY_OFF", 287 "CARD_DISABLE_PHY_OFF",
289 "MSDU_TX_RATES" 288 "MSDU_TX_RATES" "undefined",
290 "undefined",
291 "undefined", 289 "undefined",
292 "SET_STATION_STAT_BITS", 290 "SET_STATION_STAT_BITS",
293 "CLEAR_STATIONS_STAT_BITS", 291 "CLEAR_STATIONS_STAT_BITS",
@@ -298,7 +296,6 @@ static const char *command_types[] = {
298}; 296};
299#endif 297#endif
300 298
301
302/* Pre-decl until we get the code solid and then we can clean it up */ 299/* Pre-decl until we get the code solid and then we can clean it up */
303static void ipw2100_tx_send_commands(struct ipw2100_priv *priv); 300static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
304static void ipw2100_tx_send_data(struct ipw2100_priv *priv); 301static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
@@ -321,11 +318,10 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
321static int ipw2100_ucode_download(struct ipw2100_priv *priv, 318static int ipw2100_ucode_download(struct ipw2100_priv *priv,
322 struct ipw2100_fw *fw); 319 struct ipw2100_fw *fw);
323static void ipw2100_wx_event_work(struct ipw2100_priv *priv); 320static void ipw2100_wx_event_work(struct ipw2100_priv *priv);
324static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev); 321static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev);
325static struct iw_handler_def ipw2100_wx_handler_def; 322static struct iw_handler_def ipw2100_wx_handler_def;
326 323
327 324static inline void read_register(struct net_device *dev, u32 reg, u32 * val)
328static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
329{ 325{
330 *val = readl((void __iomem *)(dev->base_addr + reg)); 326 *val = readl((void __iomem *)(dev->base_addr + reg));
331 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val); 327 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
@@ -337,13 +333,14 @@ static inline void write_register(struct net_device *dev, u32 reg, u32 val)
337 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val); 333 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
338} 334}
339 335
340static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val) 336static inline void read_register_word(struct net_device *dev, u32 reg,
337 u16 * val)
341{ 338{
342 *val = readw((void __iomem *)(dev->base_addr + reg)); 339 *val = readw((void __iomem *)(dev->base_addr + reg));
343 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val); 340 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
344} 341}
345 342
346static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val) 343static inline void read_register_byte(struct net_device *dev, u32 reg, u8 * val)
347{ 344{
348 *val = readb((void __iomem *)(dev->base_addr + reg)); 345 *val = readb((void __iomem *)(dev->base_addr + reg));
349 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val); 346 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
@@ -355,14 +352,13 @@ static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
355 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val); 352 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
356} 353}
357 354
358
359static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val) 355static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
360{ 356{
361 writeb(val, (void __iomem *)(dev->base_addr + reg)); 357 writeb(val, (void __iomem *)(dev->base_addr + reg));
362 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val); 358 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
363} 359}
364 360
365static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 *val) 361static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 * val)
366{ 362{
367 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 363 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
368 addr & IPW_REG_INDIRECT_ADDR_MASK); 364 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -376,7 +372,7 @@ static inline void write_nic_dword(struct net_device *dev, u32 addr, u32 val)
376 write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val); 372 write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
377} 373}
378 374
379static inline void read_nic_word(struct net_device *dev, u32 addr, u16 *val) 375static inline void read_nic_word(struct net_device *dev, u32 addr, u16 * val)
380{ 376{
381 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 377 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
382 addr & IPW_REG_INDIRECT_ADDR_MASK); 378 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -390,7 +386,7 @@ static inline void write_nic_word(struct net_device *dev, u32 addr, u16 val)
390 write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val); 386 write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
391} 387}
392 388
393static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 *val) 389static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 * val)
394{ 390{
395 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 391 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
396 addr & IPW_REG_INDIRECT_ADDR_MASK); 392 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -416,7 +412,7 @@ static inline void write_nic_dword_auto_inc(struct net_device *dev, u32 val)
416} 412}
417 413
418static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len, 414static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
419 const u8 *buf) 415 const u8 * buf)
420{ 416{
421 u32 aligned_addr; 417 u32 aligned_addr;
422 u32 aligned_len; 418 u32 aligned_len;
@@ -431,32 +427,30 @@ static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
431 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 427 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
432 aligned_addr); 428 aligned_addr);
433 for (i = dif_len; i < 4; i++, buf++) 429 for (i = dif_len; i < 4; i++, buf++)
434 write_register_byte( 430 write_register_byte(dev,
435 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, 431 IPW_REG_INDIRECT_ACCESS_DATA + i,
436 *buf); 432 *buf);
437 433
438 len -= dif_len; 434 len -= dif_len;
439 aligned_addr += 4; 435 aligned_addr += 4;
440 } 436 }
441 437
442 /* read DWs through autoincrement registers */ 438 /* read DWs through autoincrement registers */
443 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, 439 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, aligned_addr);
444 aligned_addr);
445 aligned_len = len & (~0x3); 440 aligned_len = len & (~0x3);
446 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) 441 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
447 write_register( 442 write_register(dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *) buf);
448 dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *)buf);
449 443
450 /* copy the last nibble */ 444 /* copy the last nibble */
451 dif_len = len - aligned_len; 445 dif_len = len - aligned_len;
452 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr); 446 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
453 for (i = 0; i < dif_len; i++, buf++) 447 for (i = 0; i < dif_len; i++, buf++)
454 write_register_byte( 448 write_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i,
455 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, *buf); 449 *buf);
456} 450}
457 451
458static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len, 452static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
459 u8 *buf) 453 u8 * buf)
460{ 454{
461 u32 aligned_addr; 455 u32 aligned_addr;
462 u32 aligned_len; 456 u32 aligned_len;
@@ -471,39 +465,38 @@ static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
471 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 465 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
472 aligned_addr); 466 aligned_addr);
473 for (i = dif_len; i < 4; i++, buf++) 467 for (i = dif_len; i < 4; i++, buf++)
474 read_register_byte( 468 read_register_byte(dev,
475 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf); 469 IPW_REG_INDIRECT_ACCESS_DATA + i,
470 buf);
476 471
477 len -= dif_len; 472 len -= dif_len;
478 aligned_addr += 4; 473 aligned_addr += 4;
479 } 474 }
480 475
481 /* read DWs through autoincrement registers */ 476 /* read DWs through autoincrement registers */
482 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, 477 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, aligned_addr);
483 aligned_addr);
484 aligned_len = len & (~0x3); 478 aligned_len = len & (~0x3);
485 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) 479 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
486 read_register(dev, IPW_REG_AUTOINCREMENT_DATA, 480 read_register(dev, IPW_REG_AUTOINCREMENT_DATA, (u32 *) buf);
487 (u32 *)buf);
488 481
489 /* copy the last nibble */ 482 /* copy the last nibble */
490 dif_len = len - aligned_len; 483 dif_len = len - aligned_len;
491 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 484 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
492 aligned_addr);
493 for (i = 0; i < dif_len; i++, buf++) 485 for (i = 0; i < dif_len; i++, buf++)
494 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + 486 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf);
495 i, buf);
496} 487}
497 488
498static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev) 489static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
499{ 490{
500 return (dev->base_addr && 491 return (dev->base_addr &&
501 (readl((void __iomem *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START)) 492 (readl
493 ((void __iomem *)(dev->base_addr +
494 IPW_REG_DOA_DEBUG_AREA_START))
502 == IPW_DATA_DOA_DEBUG_VALUE)); 495 == IPW_DATA_DOA_DEBUG_VALUE));
503} 496}
504 497
505static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord, 498static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
506 void *val, u32 *len) 499 void *val, u32 * len)
507{ 500{
508 struct ipw2100_ordinals *ordinals = &priv->ordinals; 501 struct ipw2100_ordinals *ordinals = &priv->ordinals;
509 u32 addr; 502 u32 addr;
@@ -529,8 +522,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
529 return -EINVAL; 522 return -EINVAL;
530 } 523 }
531 524
532 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2), 525 read_nic_dword(priv->net_dev,
533 &addr); 526 ordinals->table1_addr + (ord << 2), &addr);
534 read_nic_dword(priv->net_dev, addr, val); 527 read_nic_dword(priv->net_dev, addr, val);
535 528
536 *len = IPW_ORD_TAB_1_ENTRY_SIZE; 529 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
@@ -543,8 +536,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
543 ord -= IPW_START_ORD_TAB_2; 536 ord -= IPW_START_ORD_TAB_2;
544 537
545 /* get the address of statistic */ 538 /* get the address of statistic */
546 read_nic_dword(priv->net_dev, ordinals->table2_addr + (ord << 3), 539 read_nic_dword(priv->net_dev,
547 &addr); 540 ordinals->table2_addr + (ord << 3), &addr);
548 541
549 /* get the second DW of statistics ; 542 /* get the second DW of statistics ;
550 * two 16-bit words - first is length, second is count */ 543 * two 16-bit words - first is length, second is count */
@@ -553,10 +546,10 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
553 &field_info); 546 &field_info);
554 547
555 /* get each entry length */ 548 /* get each entry length */
556 field_len = *((u16 *)&field_info); 549 field_len = *((u16 *) & field_info);
557 550
558 /* get number of entries */ 551 /* get number of entries */
559 field_count = *(((u16 *)&field_info) + 1); 552 field_count = *(((u16 *) & field_info) + 1);
560 553
561 /* abort if no enought memory */ 554 /* abort if no enought memory */
562 total_length = field_len * field_count; 555 total_length = field_len * field_count;
@@ -581,8 +574,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
581 return -EINVAL; 574 return -EINVAL;
582} 575}
583 576
584static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val, 577static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 * val,
585 u32 *len) 578 u32 * len)
586{ 579{
587 struct ipw2100_ordinals *ordinals = &priv->ordinals; 580 struct ipw2100_ordinals *ordinals = &priv->ordinals;
588 u32 addr; 581 u32 addr;
@@ -594,8 +587,8 @@ static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
594 return -EINVAL; 587 return -EINVAL;
595 } 588 }
596 589
597 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2), 590 read_nic_dword(priv->net_dev,
598 &addr); 591 ordinals->table1_addr + (ord << 2), &addr);
599 592
600 write_nic_dword(priv->net_dev, addr, *val); 593 write_nic_dword(priv->net_dev, addr, *val);
601 594
@@ -612,7 +605,7 @@ static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
612} 605}
613 606
614static char *snprint_line(char *buf, size_t count, 607static char *snprint_line(char *buf, size_t count,
615 const u8 *data, u32 len, u32 ofs) 608 const u8 * data, u32 len, u32 ofs)
616{ 609{
617 int out, i, j, l; 610 int out, i, j, l;
618 char c; 611 char c;
@@ -646,7 +639,7 @@ static char *snprint_line(char *buf, size_t count,
646 return buf; 639 return buf;
647} 640}
648 641
649static void printk_buf(int level, const u8 *data, u32 len) 642static void printk_buf(int level, const u8 * data, u32 len)
650{ 643{
651 char line[81]; 644 char line[81];
652 u32 ofs = 0; 645 u32 ofs = 0;
@@ -662,8 +655,6 @@ static void printk_buf(int level, const u8 *data, u32 len)
662 } 655 }
663} 656}
664 657
665
666
667#define MAX_RESET_BACKOFF 10 658#define MAX_RESET_BACKOFF 10
668 659
669static inline void schedule_reset(struct ipw2100_priv *priv) 660static inline void schedule_reset(struct ipw2100_priv *priv)
@@ -703,7 +694,7 @@ static inline void schedule_reset(struct ipw2100_priv *priv)
703 694
704#define HOST_COMPLETE_TIMEOUT (2 * HZ) 695#define HOST_COMPLETE_TIMEOUT (2 * HZ)
705static int ipw2100_hw_send_command(struct ipw2100_priv *priv, 696static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
706 struct host_command * cmd) 697 struct host_command *cmd)
707{ 698{
708 struct list_head *element; 699 struct list_head *element;
709 struct ipw2100_tx_packet *packet; 700 struct ipw2100_tx_packet *packet;
@@ -713,25 +704,28 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
713 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", 704 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n",
714 command_types[cmd->host_command], cmd->host_command, 705 command_types[cmd->host_command], cmd->host_command,
715 cmd->host_command_length); 706 cmd->host_command_length);
716 printk_buf(IPW_DL_HC, (u8*)cmd->host_command_parameters, 707 printk_buf(IPW_DL_HC, (u8 *) cmd->host_command_parameters,
717 cmd->host_command_length); 708 cmd->host_command_length);
718 709
719 spin_lock_irqsave(&priv->low_lock, flags); 710 spin_lock_irqsave(&priv->low_lock, flags);
720 711
721 if (priv->fatal_error) { 712 if (priv->fatal_error) {
722 IPW_DEBUG_INFO("Attempt to send command while hardware in fatal error condition.\n"); 713 IPW_DEBUG_INFO
714 ("Attempt to send command while hardware in fatal error condition.\n");
723 err = -EIO; 715 err = -EIO;
724 goto fail_unlock; 716 goto fail_unlock;
725 } 717 }
726 718
727 if (!(priv->status & STATUS_RUNNING)) { 719 if (!(priv->status & STATUS_RUNNING)) {
728 IPW_DEBUG_INFO("Attempt to send command while hardware is not running.\n"); 720 IPW_DEBUG_INFO
721 ("Attempt to send command while hardware is not running.\n");
729 err = -EIO; 722 err = -EIO;
730 goto fail_unlock; 723 goto fail_unlock;
731 } 724 }
732 725
733 if (priv->status & STATUS_CMD_ACTIVE) { 726 if (priv->status & STATUS_CMD_ACTIVE) {
734 IPW_DEBUG_INFO("Attempt to send command while another command is pending.\n"); 727 IPW_DEBUG_INFO
728 ("Attempt to send command while another command is pending.\n");
735 err = -EBUSY; 729 err = -EBUSY;
736 goto fail_unlock; 730 goto fail_unlock;
737 } 731 }
@@ -752,7 +746,8 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
752 /* initialize the firmware command packet */ 746 /* initialize the firmware command packet */
753 packet->info.c_struct.cmd->host_command_reg = cmd->host_command; 747 packet->info.c_struct.cmd->host_command_reg = cmd->host_command;
754 packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1; 748 packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1;
755 packet->info.c_struct.cmd->host_command_len_reg = cmd->host_command_length; 749 packet->info.c_struct.cmd->host_command_len_reg =
750 cmd->host_command_length;
756 packet->info.c_struct.cmd->sequence = cmd->host_command_sequence; 751 packet->info.c_struct.cmd->sequence = cmd->host_command_sequence;
757 752
758 memcpy(packet->info.c_struct.cmd->host_command_params_reg, 753 memcpy(packet->info.c_struct.cmd->host_command_params_reg,
@@ -776,13 +771,15 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
776 * then there is a problem. 771 * then there is a problem.
777 */ 772 */
778 773
779 err = wait_event_interruptible_timeout( 774 err =
780 priv->wait_command_queue, !(priv->status & STATUS_CMD_ACTIVE), 775 wait_event_interruptible_timeout(priv->wait_command_queue,
781 HOST_COMPLETE_TIMEOUT); 776 !(priv->
777 status & STATUS_CMD_ACTIVE),
778 HOST_COMPLETE_TIMEOUT);
782 779
783 if (err == 0) { 780 if (err == 0) {
784 IPW_DEBUG_INFO("Command completion failed out after %dms.\n", 781 IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
785 HOST_COMPLETE_TIMEOUT / (HZ / 100)); 782 1000 * (HOST_COMPLETE_TIMEOUT / HZ));
786 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT; 783 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT;
787 priv->status &= ~STATUS_CMD_ACTIVE; 784 priv->status &= ~STATUS_CMD_ACTIVE;
788 schedule_reset(priv); 785 schedule_reset(priv);
@@ -804,13 +801,12 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
804 801
805 return 0; 802 return 0;
806 803
807 fail_unlock: 804 fail_unlock:
808 spin_unlock_irqrestore(&priv->low_lock, flags); 805 spin_unlock_irqrestore(&priv->low_lock, flags);
809 806
810 return err; 807 return err;
811} 808}
812 809
813
814/* 810/*
815 * Verify the values and data access of the hardware 811 * Verify the values and data access of the hardware
816 * No locks needed or used. No functions called. 812 * No locks needed or used. No functions called.
@@ -825,8 +821,7 @@ static int ipw2100_verify(struct ipw2100_priv *priv)
825 821
826 /* Domain 0 check - all values should be DOA_DEBUG */ 822 /* Domain 0 check - all values should be DOA_DEBUG */
827 for (address = IPW_REG_DOA_DEBUG_AREA_START; 823 for (address = IPW_REG_DOA_DEBUG_AREA_START;
828 address < IPW_REG_DOA_DEBUG_AREA_END; 824 address < IPW_REG_DOA_DEBUG_AREA_END; address += sizeof(u32)) {
829 address += sizeof(u32)) {
830 read_register(priv->net_dev, address, &data1); 825 read_register(priv->net_dev, address, &data1);
831 if (data1 != IPW_DATA_DOA_DEBUG_VALUE) 826 if (data1 != IPW_DATA_DOA_DEBUG_VALUE)
832 return -EIO; 827 return -EIO;
@@ -898,7 +893,6 @@ static int ipw2100_wait_for_card_state(struct ipw2100_priv *priv, int state)
898 return -EIO; 893 return -EIO;
899} 894}
900 895
901
902/********************************************************************* 896/*********************************************************************
903 Procedure : sw_reset_and_clock 897 Procedure : sw_reset_and_clock
904 Purpose : Asserts s/w reset, asserts clock initialization 898 Purpose : Asserts s/w reset, asserts clock initialization
@@ -975,17 +969,16 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
975 969
976 if (priv->fatal_error) { 970 if (priv->fatal_error) {
977 IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after " 971 IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after "
978 "fatal error %d. Interface must be brought down.\n", 972 "fatal error %d. Interface must be brought down.\n",
979 priv->net_dev->name, priv->fatal_error); 973 priv->net_dev->name, priv->fatal_error);
980 return -EINVAL; 974 return -EINVAL;
981 } 975 }
982
983#ifdef CONFIG_PM 976#ifdef CONFIG_PM
984 if (!ipw2100_firmware.version) { 977 if (!ipw2100_firmware.version) {
985 err = ipw2100_get_firmware(priv, &ipw2100_firmware); 978 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
986 if (err) { 979 if (err) {
987 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n", 980 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
988 priv->net_dev->name, err); 981 priv->net_dev->name, err);
989 priv->fatal_error = IPW2100_ERR_FW_LOAD; 982 priv->fatal_error = IPW2100_ERR_FW_LOAD;
990 goto fail; 983 goto fail;
991 } 984 }
@@ -994,7 +987,7 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
994 err = ipw2100_get_firmware(priv, &ipw2100_firmware); 987 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
995 if (err) { 988 if (err) {
996 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n", 989 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
997 priv->net_dev->name, err); 990 priv->net_dev->name, err);
998 priv->fatal_error = IPW2100_ERR_FW_LOAD; 991 priv->fatal_error = IPW2100_ERR_FW_LOAD;
999 goto fail; 992 goto fail;
1000 } 993 }
@@ -1005,21 +998,20 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1005 err = sw_reset_and_clock(priv); 998 err = sw_reset_and_clock(priv);
1006 if (err) { 999 if (err) {
1007 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n", 1000 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n",
1008 priv->net_dev->name, err); 1001 priv->net_dev->name, err);
1009 goto fail; 1002 goto fail;
1010 } 1003 }
1011 1004
1012 err = ipw2100_verify(priv); 1005 err = ipw2100_verify(priv);
1013 if (err) { 1006 if (err) {
1014 IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n", 1007 IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n",
1015 priv->net_dev->name, err); 1008 priv->net_dev->name, err);
1016 goto fail; 1009 goto fail;
1017 } 1010 }
1018 1011
1019 /* Hold ARC */ 1012 /* Hold ARC */
1020 write_nic_dword(priv->net_dev, 1013 write_nic_dword(priv->net_dev,
1021 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 1014 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 0x80000000);
1022 0x80000000);
1023 1015
1024 /* allow ARC to run */ 1016 /* allow ARC to run */
1025 write_register(priv->net_dev, IPW_REG_RESET_REG, 0); 1017 write_register(priv->net_dev, IPW_REG_RESET_REG, 0);
@@ -1034,13 +1026,13 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1034 1026
1035 /* release ARC */ 1027 /* release ARC */
1036 write_nic_dword(priv->net_dev, 1028 write_nic_dword(priv->net_dev,
1037 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 1029 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 0x00000000);
1038 0x00000000);
1039 1030
1040 /* s/w reset and clock stabilization (again!!!) */ 1031 /* s/w reset and clock stabilization (again!!!) */
1041 err = sw_reset_and_clock(priv); 1032 err = sw_reset_and_clock(priv);
1042 if (err) { 1033 if (err) {
1043 printk(KERN_ERR DRV_NAME ": %s: sw_reset_and_clock failed: %d\n", 1034 printk(KERN_ERR DRV_NAME
1035 ": %s: sw_reset_and_clock failed: %d\n",
1044 priv->net_dev->name, err); 1036 priv->net_dev->name, err);
1045 goto fail; 1037 goto fail;
1046 } 1038 }
@@ -1049,10 +1041,9 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1049 err = ipw2100_fw_download(priv, &ipw2100_firmware); 1041 err = ipw2100_fw_download(priv, &ipw2100_firmware);
1050 if (err) { 1042 if (err) {
1051 IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n", 1043 IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n",
1052 priv->net_dev->name, err); 1044 priv->net_dev->name, err);
1053 goto fail; 1045 goto fail;
1054 } 1046 }
1055
1056#ifndef CONFIG_PM 1047#ifndef CONFIG_PM
1057 /* 1048 /*
1058 * When the .resume method of the driver is called, the other 1049 * When the .resume method of the driver is called, the other
@@ -1084,7 +1075,7 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1084 1075
1085 return 0; 1076 return 0;
1086 1077
1087 fail: 1078 fail:
1088 ipw2100_release_firmware(priv, &ipw2100_firmware); 1079 ipw2100_release_firmware(priv, &ipw2100_firmware);
1089 return err; 1080 return err;
1090} 1081}
@@ -1105,7 +1096,6 @@ static inline void ipw2100_disable_interrupts(struct ipw2100_priv *priv)
1105 write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0); 1096 write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0);
1106} 1097}
1107 1098
1108
1109static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv) 1099static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv)
1110{ 1100{
1111 struct ipw2100_ordinals *ord = &priv->ordinals; 1101 struct ipw2100_ordinals *ord = &priv->ordinals;
@@ -1177,11 +1167,10 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1177 * EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1 1167 * EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1
1178 */ 1168 */
1179 len = sizeof(addr); 1169 len = sizeof(addr);
1180 if (ipw2100_get_ordinal( 1170 if (ipw2100_get_ordinal
1181 priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS, 1171 (priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS, &addr, &len)) {
1182 &addr, &len)) {
1183 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1172 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1184 __LINE__); 1173 __LINE__);
1185 return -EIO; 1174 return -EIO;
1186 } 1175 }
1187 1176
@@ -1194,7 +1183,7 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1194 priv->eeprom_version = (val >> 24) & 0xFF; 1183 priv->eeprom_version = (val >> 24) & 0xFF;
1195 IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version); 1184 IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version);
1196 1185
1197 /* 1186 /*
1198 * HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware 1187 * HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware
1199 * 1188 *
1200 * notice that the EEPROM bit is reverse polarity, i.e. 1189 * notice that the EEPROM bit is reverse polarity, i.e.
@@ -1206,8 +1195,7 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1206 priv->hw_features |= HW_FEATURE_RFKILL; 1195 priv->hw_features |= HW_FEATURE_RFKILL;
1207 1196
1208 IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n", 1197 IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n",
1209 (priv->hw_features & HW_FEATURE_RFKILL) ? 1198 (priv->hw_features & HW_FEATURE_RFKILL) ? "" : "not ");
1210 "" : "not ");
1211 1199
1212 return 0; 1200 return 0;
1213} 1201}
@@ -1234,7 +1222,8 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
1234 * fw & dino ucode 1222 * fw & dino ucode
1235 */ 1223 */
1236 if (ipw2100_download_firmware(priv)) { 1224 if (ipw2100_download_firmware(priv)) {
1237 printk(KERN_ERR DRV_NAME ": %s: Failed to power on the adapter.\n", 1225 printk(KERN_ERR DRV_NAME
1226 ": %s: Failed to power on the adapter.\n",
1238 priv->net_dev->name); 1227 priv->net_dev->name);
1239 return -EIO; 1228 return -EIO;
1240 } 1229 }
@@ -1293,7 +1282,8 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
1293 i ? "SUCCESS" : "FAILED"); 1282 i ? "SUCCESS" : "FAILED");
1294 1283
1295 if (!i) { 1284 if (!i) {
1296 printk(KERN_WARNING DRV_NAME ": %s: Firmware did not initialize.\n", 1285 printk(KERN_WARNING DRV_NAME
1286 ": %s: Firmware did not initialize.\n",
1297 priv->net_dev->name); 1287 priv->net_dev->name);
1298 return -EIO; 1288 return -EIO;
1299 } 1289 }
@@ -1326,7 +1316,6 @@ static inline void ipw2100_reset_fatalerror(struct ipw2100_priv *priv)
1326 priv->fatal_error = 0; 1316 priv->fatal_error = 0;
1327} 1317}
1328 1318
1329
1330/* NOTE: Our interrupt is disabled when this method is called */ 1319/* NOTE: Our interrupt is disabled when this method is called */
1331static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv) 1320static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
1332{ 1321{
@@ -1350,19 +1339,19 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
1350 1339
1351 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED) 1340 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
1352 break; 1341 break;
1353 } while(i--); 1342 } while (i--);
1354 1343
1355 priv->status &= ~STATUS_RESET_PENDING; 1344 priv->status &= ~STATUS_RESET_PENDING;
1356 1345
1357 if (!i) { 1346 if (!i) {
1358 IPW_DEBUG_INFO("exit - waited too long for master assert stop\n"); 1347 IPW_DEBUG_INFO
1348 ("exit - waited too long for master assert stop\n");
1359 return -EIO; 1349 return -EIO;
1360 } 1350 }
1361 1351
1362 write_register(priv->net_dev, IPW_REG_RESET_REG, 1352 write_register(priv->net_dev, IPW_REG_RESET_REG,
1363 IPW_AUX_HOST_RESET_REG_SW_RESET); 1353 IPW_AUX_HOST_RESET_REG_SW_RESET);
1364 1354
1365
1366 /* Reset any fatal_error conditions */ 1355 /* Reset any fatal_error conditions */
1367 ipw2100_reset_fatalerror(priv); 1356 ipw2100_reset_fatalerror(priv);
1368 1357
@@ -1415,7 +1404,6 @@ static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
1415 return -EIO; 1404 return -EIO;
1416} 1405}
1417 1406
1418
1419static int ipw2100_enable_adapter(struct ipw2100_priv *priv) 1407static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1420{ 1408{
1421 struct host_command cmd = { 1409 struct host_command cmd = {
@@ -1445,9 +1433,8 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1445 1433
1446 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED); 1434 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED);
1447 if (err) { 1435 if (err) {
1448 IPW_DEBUG_INFO( 1436 IPW_DEBUG_INFO("%s: card not responding to init command.\n",
1449 "%s: card not responding to init command.\n", 1437 priv->net_dev->name);
1450 priv->net_dev->name);
1451 goto fail_up; 1438 goto fail_up;
1452 } 1439 }
1453 1440
@@ -1456,7 +1443,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1456 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2); 1443 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
1457 } 1444 }
1458 1445
1459fail_up: 1446 fail_up:
1460 up(&priv->adapter_sem); 1447 up(&priv->adapter_sem);
1461 return err; 1448 return err;
1462} 1449}
@@ -1488,7 +1475,8 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
1488 1475
1489 err = ipw2100_hw_phy_off(priv); 1476 err = ipw2100_hw_phy_off(priv);
1490 if (err) 1477 if (err)
1491 printk(KERN_WARNING DRV_NAME ": Error disabling radio %d\n", err); 1478 printk(KERN_WARNING DRV_NAME
1479 ": Error disabling radio %d\n", err);
1492 1480
1493 /* 1481 /*
1494 * If in D0-standby mode going directly to D3 may cause a 1482 * If in D0-standby mode going directly to D3 may cause a
@@ -1566,7 +1554,6 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
1566 return 0; 1554 return 0;
1567} 1555}
1568 1556
1569
1570static int ipw2100_disable_adapter(struct ipw2100_priv *priv) 1557static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1571{ 1558{
1572 struct host_command cmd = { 1559 struct host_command cmd = {
@@ -1593,19 +1580,21 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1593 1580
1594 err = ipw2100_hw_send_command(priv, &cmd); 1581 err = ipw2100_hw_send_command(priv, &cmd);
1595 if (err) { 1582 if (err) {
1596 printk(KERN_WARNING DRV_NAME ": exit - failed to send CARD_DISABLE command\n"); 1583 printk(KERN_WARNING DRV_NAME
1584 ": exit - failed to send CARD_DISABLE command\n");
1597 goto fail_up; 1585 goto fail_up;
1598 } 1586 }
1599 1587
1600 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED); 1588 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED);
1601 if (err) { 1589 if (err) {
1602 printk(KERN_WARNING DRV_NAME ": exit - card failed to change to DISABLED\n"); 1590 printk(KERN_WARNING DRV_NAME
1591 ": exit - card failed to change to DISABLED\n");
1603 goto fail_up; 1592 goto fail_up;
1604 } 1593 }
1605 1594
1606 IPW_DEBUG_INFO("TODO: implement scan state machine\n"); 1595 IPW_DEBUG_INFO("TODO: implement scan state machine\n");
1607 1596
1608fail_up: 1597 fail_up:
1609 up(&priv->adapter_sem); 1598 up(&priv->adapter_sem);
1610 return err; 1599 return err;
1611} 1600}
@@ -1627,7 +1616,7 @@ static int ipw2100_set_scan_options(struct ipw2100_priv *priv)
1627 1616
1628 if (!(priv->config & CFG_ASSOCIATE)) 1617 if (!(priv->config & CFG_ASSOCIATE))
1629 cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE; 1618 cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE;
1630 if ((priv->sec.flags & SEC_ENABLED) && priv->sec.enabled) 1619 if ((priv->ieee->sec.flags & SEC_ENABLED) && priv->ieee->sec.enabled)
1631 cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL; 1620 cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL;
1632 if (priv->config & CFG_PASSIVE_SCAN) 1621 if (priv->config & CFG_PASSIVE_SCAN)
1633 cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE; 1622 cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE;
@@ -1709,8 +1698,9 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1709 (priv->status & STATUS_RESET_PENDING)) { 1698 (priv->status & STATUS_RESET_PENDING)) {
1710 /* Power cycle the card ... */ 1699 /* Power cycle the card ... */
1711 if (ipw2100_power_cycle_adapter(priv)) { 1700 if (ipw2100_power_cycle_adapter(priv)) {
1712 printk(KERN_WARNING DRV_NAME ": %s: Could not cycle adapter.\n", 1701 printk(KERN_WARNING DRV_NAME
1713 priv->net_dev->name); 1702 ": %s: Could not cycle adapter.\n",
1703 priv->net_dev->name);
1714 rc = 1; 1704 rc = 1;
1715 goto exit; 1705 goto exit;
1716 } 1706 }
@@ -1719,8 +1709,9 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1719 1709
1720 /* Load the firmware, start the clocks, etc. */ 1710 /* Load the firmware, start the clocks, etc. */
1721 if (ipw2100_start_adapter(priv)) { 1711 if (ipw2100_start_adapter(priv)) {
1722 printk(KERN_ERR DRV_NAME ": %s: Failed to start the firmware.\n", 1712 printk(KERN_ERR DRV_NAME
1723 priv->net_dev->name); 1713 ": %s: Failed to start the firmware.\n",
1714 priv->net_dev->name);
1724 rc = 1; 1715 rc = 1;
1725 goto exit; 1716 goto exit;
1726 } 1717 }
@@ -1729,16 +1720,18 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1729 1720
1730 /* Determine capabilities of this particular HW configuration */ 1721 /* Determine capabilities of this particular HW configuration */
1731 if (ipw2100_get_hw_features(priv)) { 1722 if (ipw2100_get_hw_features(priv)) {
1732 printk(KERN_ERR DRV_NAME ": %s: Failed to determine HW features.\n", 1723 printk(KERN_ERR DRV_NAME
1733 priv->net_dev->name); 1724 ": %s: Failed to determine HW features.\n",
1725 priv->net_dev->name);
1734 rc = 1; 1726 rc = 1;
1735 goto exit; 1727 goto exit;
1736 } 1728 }
1737 1729
1738 lock = LOCK_NONE; 1730 lock = LOCK_NONE;
1739 if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) { 1731 if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
1740 printk(KERN_ERR DRV_NAME ": %s: Failed to clear ordinal lock.\n", 1732 printk(KERN_ERR DRV_NAME
1741 priv->net_dev->name); 1733 ": %s: Failed to clear ordinal lock.\n",
1734 priv->net_dev->name);
1742 rc = 1; 1735 rc = 1;
1743 goto exit; 1736 goto exit;
1744 } 1737 }
@@ -1764,7 +1757,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1764 * HOST_COMPLETE */ 1757 * HOST_COMPLETE */
1765 if (ipw2100_adapter_setup(priv)) { 1758 if (ipw2100_adapter_setup(priv)) {
1766 printk(KERN_ERR DRV_NAME ": %s: Failed to start the card.\n", 1759 printk(KERN_ERR DRV_NAME ": %s: Failed to start the card.\n",
1767 priv->net_dev->name); 1760 priv->net_dev->name);
1768 rc = 1; 1761 rc = 1;
1769 goto exit; 1762 goto exit;
1770 } 1763 }
@@ -1773,20 +1766,19 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1773 /* Enable the adapter - sends HOST_COMPLETE */ 1766 /* Enable the adapter - sends HOST_COMPLETE */
1774 if (ipw2100_enable_adapter(priv)) { 1767 if (ipw2100_enable_adapter(priv)) {
1775 printk(KERN_ERR DRV_NAME ": " 1768 printk(KERN_ERR DRV_NAME ": "
1776 "%s: failed in call to enable adapter.\n", 1769 "%s: failed in call to enable adapter.\n",
1777 priv->net_dev->name); 1770 priv->net_dev->name);
1778 ipw2100_hw_stop_adapter(priv); 1771 ipw2100_hw_stop_adapter(priv);
1779 rc = 1; 1772 rc = 1;
1780 goto exit; 1773 goto exit;
1781 } 1774 }
1782 1775
1783
1784 /* Start a scan . . . */ 1776 /* Start a scan . . . */
1785 ipw2100_set_scan_options(priv); 1777 ipw2100_set_scan_options(priv);
1786 ipw2100_start_scan(priv); 1778 ipw2100_start_scan(priv);
1787 } 1779 }
1788 1780
1789 exit: 1781 exit:
1790 return rc; 1782 return rc;
1791} 1783}
1792 1784
@@ -1802,8 +1794,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1802 unsigned long flags; 1794 unsigned long flags;
1803 union iwreq_data wrqu = { 1795 union iwreq_data wrqu = {
1804 .ap_addr = { 1796 .ap_addr = {
1805 .sa_family = ARPHRD_ETHER 1797 .sa_family = ARPHRD_ETHER}
1806 }
1807 }; 1798 };
1808 int associated = priv->status & STATUS_ASSOCIATED; 1799 int associated = priv->status & STATUS_ASSOCIATED;
1809 1800
@@ -1842,7 +1833,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1842 1833
1843#ifdef ACPI_CSTATE_LIMIT_DEFINED 1834#ifdef ACPI_CSTATE_LIMIT_DEFINED
1844 if (priv->config & CFG_C3_DISABLED) { 1835 if (priv->config & CFG_C3_DISABLED) {
1845 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n"); 1836 IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
1846 acpi_set_cstate_limit(priv->cstate_limit); 1837 acpi_set_cstate_limit(priv->cstate_limit);
1847 priv->config &= ~CFG_C3_DISABLED; 1838 priv->config &= ~CFG_C3_DISABLED;
1848 } 1839 }
@@ -1862,14 +1853,12 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1862 unsigned long flags; 1853 unsigned long flags;
1863 union iwreq_data wrqu = { 1854 union iwreq_data wrqu = {
1864 .ap_addr = { 1855 .ap_addr = {
1865 .sa_family = ARPHRD_ETHER 1856 .sa_family = ARPHRD_ETHER}
1866 }
1867 }; 1857 };
1868 int associated = priv->status & STATUS_ASSOCIATED; 1858 int associated = priv->status & STATUS_ASSOCIATED;
1869 1859
1870 spin_lock_irqsave(&priv->low_lock, flags); 1860 spin_lock_irqsave(&priv->low_lock, flags);
1871 IPW_DEBUG_INFO(DRV_NAME ": %s: Restarting adapter.\n", 1861 IPW_DEBUG_INFO(": %s: Restarting adapter.\n", priv->net_dev->name);
1872 priv->net_dev->name);
1873 priv->resets++; 1862 priv->resets++;
1874 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); 1863 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1875 priv->status |= STATUS_SECURITY_UPDATED; 1864 priv->status |= STATUS_SECURITY_UPDATED;
@@ -1894,7 +1883,6 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1894 1883
1895} 1884}
1896 1885
1897
1898static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) 1886static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1899{ 1887{
1900 1888
@@ -1904,7 +1892,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1904 u32 txrate; 1892 u32 txrate;
1905 u32 chan; 1893 u32 chan;
1906 char *txratename; 1894 char *txratename;
1907 u8 bssid[ETH_ALEN]; 1895 u8 bssid[ETH_ALEN];
1908 1896
1909 /* 1897 /*
1910 * TBD: BSSID is usually 00:00:00:00:00:00 here and not 1898 * TBD: BSSID is usually 00:00:00:00:00:00 here and not
@@ -1918,16 +1906,15 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1918 essid, &essid_len); 1906 essid, &essid_len);
1919 if (ret) { 1907 if (ret) {
1920 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1908 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1921 __LINE__); 1909 __LINE__);
1922 return; 1910 return;
1923 } 1911 }
1924 1912
1925 len = sizeof(u32); 1913 len = sizeof(u32);
1926 ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, 1914 ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, &txrate, &len);
1927 &txrate, &len);
1928 if (ret) { 1915 if (ret) {
1929 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1916 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1930 __LINE__); 1917 __LINE__);
1931 return; 1918 return;
1932 } 1919 }
1933 1920
@@ -1935,19 +1922,18 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1935 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len); 1922 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len);
1936 if (ret) { 1923 if (ret) {
1937 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1924 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1938 __LINE__); 1925 __LINE__);
1939 return; 1926 return;
1940 } 1927 }
1941 len = ETH_ALEN; 1928 len = ETH_ALEN;
1942 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len); 1929 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len);
1943 if (ret) { 1930 if (ret) {
1944 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1931 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1945 __LINE__); 1932 __LINE__);
1946 return; 1933 return;
1947 } 1934 }
1948 memcpy(priv->ieee->bssid, bssid, ETH_ALEN); 1935 memcpy(priv->ieee->bssid, bssid, ETH_ALEN);
1949 1936
1950
1951 switch (txrate) { 1937 switch (txrate) {
1952 case TX_RATE_1_MBIT: 1938 case TX_RATE_1_MBIT:
1953 txratename = "1Mbps"; 1939 txratename = "1Mbps";
@@ -1974,7 +1960,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1974 1960
1975 /* now we copy read ssid into dev */ 1961 /* now we copy read ssid into dev */
1976 if (!(priv->config & CFG_STATIC_ESSID)) { 1962 if (!(priv->config & CFG_STATIC_ESSID)) {
1977 priv->essid_len = min((u8)essid_len, (u8)IW_ESSID_MAX_SIZE); 1963 priv->essid_len = min((u8) essid_len, (u8) IW_ESSID_MAX_SIZE);
1978 memcpy(priv->essid, essid, priv->essid_len); 1964 memcpy(priv->essid, essid, priv->essid_len);
1979 } 1965 }
1980 priv->channel = chan; 1966 priv->channel = chan;
@@ -1986,7 +1972,6 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1986 queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10); 1972 queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10);
1987} 1973}
1988 1974
1989
1990static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, 1975static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
1991 int length, int batch_mode) 1976 int length, int batch_mode)
1992{ 1977{
@@ -2001,8 +1986,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2001 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len)); 1986 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len));
2002 1987
2003 if (ssid_len) 1988 if (ssid_len)
2004 memcpy((char*)cmd.host_command_parameters, 1989 memcpy(cmd.host_command_parameters, essid, ssid_len);
2005 essid, ssid_len);
2006 1990
2007 if (!batch_mode) { 1991 if (!batch_mode) {
2008 err = ipw2100_disable_adapter(priv); 1992 err = ipw2100_disable_adapter(priv);
@@ -2014,7 +1998,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2014 * disable auto association -- so we cheat by setting a bogus SSID */ 1998 * disable auto association -- so we cheat by setting a bogus SSID */
2015 if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) { 1999 if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) {
2016 int i; 2000 int i;
2017 u8 *bogus = (u8*)cmd.host_command_parameters; 2001 u8 *bogus = (u8 *) cmd.host_command_parameters;
2018 for (i = 0; i < IW_ESSID_MAX_SIZE; i++) 2002 for (i = 0; i < IW_ESSID_MAX_SIZE; i++)
2019 bogus[i] = 0x18 + i; 2003 bogus[i] = 0x18 + i;
2020 cmd.host_command_length = IW_ESSID_MAX_SIZE; 2004 cmd.host_command_length = IW_ESSID_MAX_SIZE;
@@ -2025,8 +2009,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2025 2009
2026 err = ipw2100_hw_send_command(priv, &cmd); 2010 err = ipw2100_hw_send_command(priv, &cmd);
2027 if (!err) { 2011 if (!err) {
2028 memset(priv->essid + ssid_len, 0, 2012 memset(priv->essid + ssid_len, 0, IW_ESSID_MAX_SIZE - ssid_len);
2029 IW_ESSID_MAX_SIZE - ssid_len);
2030 memcpy(priv->essid, essid, ssid_len); 2013 memcpy(priv->essid, essid, ssid_len);
2031 priv->essid_len = ssid_len; 2014 priv->essid_len = ssid_len;
2032 } 2015 }
@@ -2071,14 +2054,14 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
2071static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) 2054static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
2072{ 2055{
2073 IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n", 2056 IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n",
2074 priv->net_dev->name); 2057 priv->net_dev->name);
2075 2058
2076 /* RF_KILL is now enabled (else we wouldn't be here) */ 2059 /* RF_KILL is now enabled (else we wouldn't be here) */
2077 priv->status |= STATUS_RF_KILL_HW; 2060 priv->status |= STATUS_RF_KILL_HW;
2078 2061
2079#ifdef ACPI_CSTATE_LIMIT_DEFINED 2062#ifdef ACPI_CSTATE_LIMIT_DEFINED
2080 if (priv->config & CFG_C3_DISABLED) { 2063 if (priv->config & CFG_C3_DISABLED) {
2081 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n"); 2064 IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
2082 acpi_set_cstate_limit(priv->cstate_limit); 2065 acpi_set_cstate_limit(priv->cstate_limit);
2083 priv->config &= ~CFG_C3_DISABLED; 2066 priv->config &= ~CFG_C3_DISABLED;
2084 } 2067 }
@@ -2102,16 +2085,16 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
2102#define IPW2100_HANDLER(v, f) { v, f, # v } 2085#define IPW2100_HANDLER(v, f) { v, f, # v }
2103struct ipw2100_status_indicator { 2086struct ipw2100_status_indicator {
2104 int status; 2087 int status;
2105 void (*cb)(struct ipw2100_priv *priv, u32 status); 2088 void (*cb) (struct ipw2100_priv * priv, u32 status);
2106 char *name; 2089 char *name;
2107}; 2090};
2108#else 2091#else
2109#define IPW2100_HANDLER(v, f) { v, f } 2092#define IPW2100_HANDLER(v, f) { v, f }
2110struct ipw2100_status_indicator { 2093struct ipw2100_status_indicator {
2111 int status; 2094 int status;
2112 void (*cb)(struct ipw2100_priv *priv, u32 status); 2095 void (*cb) (struct ipw2100_priv * priv, u32 status);
2113}; 2096};
2114#endif /* CONFIG_IPW_DEBUG */ 2097#endif /* CONFIG_IPW_DEBUG */
2115 2098
2116static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status) 2099static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
2117{ 2100{
@@ -2135,7 +2118,6 @@ static const struct ipw2100_status_indicator status_handlers[] = {
2135 IPW2100_HANDLER(-1, NULL) 2118 IPW2100_HANDLER(-1, NULL)
2136}; 2119};
2137 2120
2138
2139static void isr_status_change(struct ipw2100_priv *priv, int status) 2121static void isr_status_change(struct ipw2100_priv *priv, int status)
2140{ 2122{
2141 int i; 2123 int i;
@@ -2153,7 +2135,7 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
2153 for (i = 0; status_handlers[i].status != -1; i++) { 2135 for (i = 0; status_handlers[i].status != -1; i++) {
2154 if (status == status_handlers[i].status) { 2136 if (status == status_handlers[i].status) {
2155 IPW_DEBUG_NOTIF("Status change: %s\n", 2137 IPW_DEBUG_NOTIF("Status change: %s\n",
2156 status_handlers[i].name); 2138 status_handlers[i].name);
2157 if (status_handlers[i].cb) 2139 if (status_handlers[i].cb)
2158 status_handlers[i].cb(priv, status); 2140 status_handlers[i].cb(priv, status);
2159 priv->wstats.status = status; 2141 priv->wstats.status = status;
@@ -2164,9 +2146,8 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
2164 IPW_DEBUG_NOTIF("unknown status received: %04x\n", status); 2146 IPW_DEBUG_NOTIF("unknown status received: %04x\n", status);
2165} 2147}
2166 2148
2167static void isr_rx_complete_command( 2149static void isr_rx_complete_command(struct ipw2100_priv *priv,
2168 struct ipw2100_priv *priv, 2150 struct ipw2100_cmd_header *cmd)
2169 struct ipw2100_cmd_header *cmd)
2170{ 2151{
2171#ifdef CONFIG_IPW_DEBUG 2152#ifdef CONFIG_IPW_DEBUG
2172 if (cmd->host_command_reg < ARRAY_SIZE(command_types)) { 2153 if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
@@ -2196,10 +2177,8 @@ static const char *frame_types[] = {
2196}; 2177};
2197#endif 2178#endif
2198 2179
2199 2180static inline int ipw2100_alloc_skb(struct ipw2100_priv *priv,
2200static inline int ipw2100_alloc_skb( 2181 struct ipw2100_rx_packet *packet)
2201 struct ipw2100_priv *priv,
2202 struct ipw2100_rx_packet *packet)
2203{ 2182{
2204 packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx)); 2183 packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx));
2205 if (!packet->skb) 2184 if (!packet->skb)
@@ -2215,7 +2194,6 @@ static inline int ipw2100_alloc_skb(
2215 return 0; 2194 return 0;
2216} 2195}
2217 2196
2218
2219#define SEARCH_ERROR 0xffffffff 2197#define SEARCH_ERROR 0xffffffff
2220#define SEARCH_FAIL 0xfffffffe 2198#define SEARCH_FAIL 0xfffffffe
2221#define SEARCH_SUCCESS 0xfffffff0 2199#define SEARCH_SUCCESS 0xfffffff0
@@ -2229,10 +2207,10 @@ static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
2229 if (priv->snapshot[0]) 2207 if (priv->snapshot[0])
2230 return 1; 2208 return 1;
2231 for (i = 0; i < 0x30; i++) { 2209 for (i = 0; i < 0x30; i++) {
2232 priv->snapshot[i] = (u8*)kmalloc(0x1000, GFP_ATOMIC); 2210 priv->snapshot[i] = (u8 *) kmalloc(0x1000, GFP_ATOMIC);
2233 if (!priv->snapshot[i]) { 2211 if (!priv->snapshot[i]) {
2234 IPW_DEBUG_INFO("%s: Error allocating snapshot " 2212 IPW_DEBUG_INFO("%s: Error allocating snapshot "
2235 "buffer %d\n", priv->net_dev->name, i); 2213 "buffer %d\n", priv->net_dev->name, i);
2236 while (i > 0) 2214 while (i > 0)
2237 kfree(priv->snapshot[--i]); 2215 kfree(priv->snapshot[--i]);
2238 priv->snapshot[0] = NULL; 2216 priv->snapshot[0] = NULL;
@@ -2253,7 +2231,7 @@ static inline void ipw2100_snapshot_free(struct ipw2100_priv *priv)
2253 priv->snapshot[0] = NULL; 2231 priv->snapshot[0] = NULL;
2254} 2232}
2255 2233
2256static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf, 2234static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
2257 size_t len, int mode) 2235 size_t len, int mode)
2258{ 2236{
2259 u32 i, j; 2237 u32 i, j;
@@ -2270,9 +2248,9 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
2270 for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) { 2248 for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) {
2271 read_nic_dword(priv->net_dev, i, &tmp); 2249 read_nic_dword(priv->net_dev, i, &tmp);
2272 if (mode == SEARCH_SNAPSHOT) 2250 if (mode == SEARCH_SNAPSHOT)
2273 *(u32 *)SNAPSHOT_ADDR(i) = tmp; 2251 *(u32 *) SNAPSHOT_ADDR(i) = tmp;
2274 if (ret == SEARCH_FAIL) { 2252 if (ret == SEARCH_FAIL) {
2275 d = (u8*)&tmp; 2253 d = (u8 *) & tmp;
2276 for (j = 0; j < 4; j++) { 2254 for (j = 0; j < 4; j++) {
2277 if (*s != *d) { 2255 if (*s != *d) {
2278 s = in_buf; 2256 s = in_buf;
@@ -2310,8 +2288,7 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
2310static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH]; 2288static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
2311#endif 2289#endif
2312 2290
2313static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, 2291static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
2314 int i)
2315{ 2292{
2316#ifdef CONFIG_IPW_DEBUG_C3 2293#ifdef CONFIG_IPW_DEBUG_C3
2317 struct ipw2100_status *status = &priv->status_queue.drv[i]; 2294 struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2322,11 +2299,11 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2322 int limit; 2299 int limit;
2323#endif 2300#endif
2324 2301
2325 IPW_DEBUG_INFO(DRV_NAME ": PCI latency error detected at " 2302 IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n",
2326 "0x%04zX.\n", i * sizeof(struct ipw2100_status)); 2303 i * sizeof(struct ipw2100_status));
2327 2304
2328#ifdef ACPI_CSTATE_LIMIT_DEFINED 2305#ifdef ACPI_CSTATE_LIMIT_DEFINED
2329 IPW_DEBUG_INFO(DRV_NAME ": Disabling C3 transitions.\n"); 2306 IPW_DEBUG_INFO(": Disabling C3 transitions.\n");
2330 limit = acpi_get_cstate_limit(); 2307 limit = acpi_get_cstate_limit();
2331 if (limit > 2) { 2308 if (limit > 2) {
2332 priv->cstate_limit = limit; 2309 priv->cstate_limit = limit;
@@ -2346,9 +2323,9 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2346 2323
2347 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED) 2324 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
2348 break; 2325 break;
2349 } while (j--); 2326 } while (j--);
2350 2327
2351 match = ipw2100_match_buf(priv, (u8*)status, 2328 match = ipw2100_match_buf(priv, (u8 *) status,
2352 sizeof(struct ipw2100_status), 2329 sizeof(struct ipw2100_status),
2353 SEARCH_SNAPSHOT); 2330 SEARCH_SNAPSHOT);
2354 if (match < SEARCH_SUCCESS) 2331 if (match < SEARCH_SUCCESS)
@@ -2360,7 +2337,7 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2360 IPW_DEBUG_INFO("%s: No DMA status match in " 2337 IPW_DEBUG_INFO("%s: No DMA status match in "
2361 "Firmware.\n", priv->net_dev->name); 2338 "Firmware.\n", priv->net_dev->name);
2362 2339
2363 printk_buf((u8*)priv->status_queue.drv, 2340 printk_buf((u8 *) priv->status_queue.drv,
2364 sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH); 2341 sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH);
2365#endif 2342#endif
2366 2343
@@ -2392,26 +2369,26 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
2392 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n"); 2369 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
2393 return; 2370 return;
2394 } 2371 }
2395 2372#ifdef CONFIG_IPW2100_MONITOR
2396 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR && 2373 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
2374 priv->config & CFG_CRC_CHECK &&
2397 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) { 2375 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
2398 IPW_DEBUG_RX("CRC error in packet. Dropping.\n"); 2376 IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
2399 priv->ieee->stats.rx_errors++; 2377 priv->ieee->stats.rx_errors++;
2400 return; 2378 return;
2401 } 2379 }
2380#endif
2402 2381
2403 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR && 2382 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
2404 !(priv->status & STATUS_ASSOCIATED))) { 2383 !(priv->status & STATUS_ASSOCIATED))) {
2405 IPW_DEBUG_DROP("Dropping packet while not associated.\n"); 2384 IPW_DEBUG_DROP("Dropping packet while not associated.\n");
2406 priv->wstats.discard.misc++; 2385 priv->wstats.discard.misc++;
2407 return; 2386 return;
2408 } 2387 }
2409 2388
2410
2411 pci_unmap_single(priv->pci_dev, 2389 pci_unmap_single(priv->pci_dev,
2412 packet->dma_addr, 2390 packet->dma_addr,
2413 sizeof(struct ipw2100_rx), 2391 sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE);
2414 PCI_DMA_FROMDEVICE);
2415 2392
2416 skb_put(packet->skb, status->frame_size); 2393 skb_put(packet->skb, status->frame_size);
2417 2394
@@ -2438,8 +2415,8 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
2438 /* We need to allocate a new SKB and attach it to the RDB. */ 2415 /* We need to allocate a new SKB and attach it to the RDB. */
2439 if (unlikely(ipw2100_alloc_skb(priv, packet))) { 2416 if (unlikely(ipw2100_alloc_skb(priv, packet))) {
2440 printk(KERN_WARNING DRV_NAME ": " 2417 printk(KERN_WARNING DRV_NAME ": "
2441 "%s: Unable to allocate SKB onto RBD ring - disabling " 2418 "%s: Unable to allocate SKB onto RBD ring - disabling "
2442 "adapter.\n", priv->net_dev->name); 2419 "adapter.\n", priv->net_dev->name);
2443 /* TODO: schedule adapter shutdown */ 2420 /* TODO: schedule adapter shutdown */
2444 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n"); 2421 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
2445 } 2422 }
@@ -2534,11 +2511,11 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2534 2511
2535 /* Sync the DMA for the STATUS buffer so CPU is sure to get 2512 /* Sync the DMA for the STATUS buffer so CPU is sure to get
2536 * the correct values */ 2513 * the correct values */
2537 pci_dma_sync_single_for_cpu( 2514 pci_dma_sync_single_for_cpu(priv->pci_dev,
2538 priv->pci_dev, 2515 sq->nic +
2539 sq->nic + sizeof(struct ipw2100_status) * i, 2516 sizeof(struct ipw2100_status) * i,
2540 sizeof(struct ipw2100_status), 2517 sizeof(struct ipw2100_status),
2541 PCI_DMA_FROMDEVICE); 2518 PCI_DMA_FROMDEVICE);
2542 2519
2543 /* Sync the DMA for the RX buffer so CPU is sure to get 2520 /* Sync the DMA for the RX buffer so CPU is sure to get
2544 * the correct values */ 2521 * the correct values */
@@ -2552,8 +2529,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2552 } 2529 }
2553 2530
2554 u = packet->rxp; 2531 u = packet->rxp;
2555 frame_type = sq->drv[i].status_fields & 2532 frame_type = sq->drv[i].status_fields & STATUS_TYPE_MASK;
2556 STATUS_TYPE_MASK;
2557 stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM; 2533 stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM;
2558 stats.len = sq->drv[i].frame_size; 2534 stats.len = sq->drv[i].frame_size;
2559 2535
@@ -2562,16 +2538,14 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2562 stats.mask |= IEEE80211_STATMASK_RSSI; 2538 stats.mask |= IEEE80211_STATMASK_RSSI;
2563 stats.freq = IEEE80211_24GHZ_BAND; 2539 stats.freq = IEEE80211_24GHZ_BAND;
2564 2540
2565 IPW_DEBUG_RX( 2541 IPW_DEBUG_RX("%s: '%s' frame type received (%d).\n",
2566 "%s: '%s' frame type received (%d).\n", 2542 priv->net_dev->name, frame_types[frame_type],
2567 priv->net_dev->name, frame_types[frame_type], 2543 stats.len);
2568 stats.len);
2569 2544
2570 switch (frame_type) { 2545 switch (frame_type) {
2571 case COMMAND_STATUS_VAL: 2546 case COMMAND_STATUS_VAL:
2572 /* Reset Rx watchdog */ 2547 /* Reset Rx watchdog */
2573 isr_rx_complete_command( 2548 isr_rx_complete_command(priv, &u->rx_data.command);
2574 priv, &u->rx_data.command);
2575 break; 2549 break;
2576 2550
2577 case STATUS_CHANGE_VAL: 2551 case STATUS_CHANGE_VAL:
@@ -2588,12 +2562,10 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2588#endif 2562#endif
2589 if (stats.len < sizeof(u->rx_data.header)) 2563 if (stats.len < sizeof(u->rx_data.header))
2590 break; 2564 break;
2591 switch (WLAN_FC_GET_TYPE(u->rx_data.header. 2565 switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
2592 frame_ctl)) {
2593 case IEEE80211_FTYPE_MGMT: 2566 case IEEE80211_FTYPE_MGMT:
2594 ieee80211_rx_mgt(priv->ieee, 2567 ieee80211_rx_mgt(priv->ieee,
2595 &u->rx_data.header, 2568 &u->rx_data.header, &stats);
2596 &stats);
2597 break; 2569 break;
2598 2570
2599 case IEEE80211_FTYPE_CTL: 2571 case IEEE80211_FTYPE_CTL:
@@ -2607,7 +2579,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2607 break; 2579 break;
2608 } 2580 }
2609 2581
2610 increment: 2582 increment:
2611 /* clear status field associated with this RBD */ 2583 /* clear status field associated with this RBD */
2612 rxq->drv[i].status.info.field = 0; 2584 rxq->drv[i].status.info.field = 0;
2613 2585
@@ -2619,12 +2591,10 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2619 rxq->next = (i ? i : rxq->entries) - 1; 2591 rxq->next = (i ? i : rxq->entries) - 1;
2620 2592
2621 write_register(priv->net_dev, 2593 write_register(priv->net_dev,
2622 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, 2594 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, rxq->next);
2623 rxq->next);
2624 } 2595 }
2625} 2596}
2626 2597
2627
2628/* 2598/*
2629 * __ipw2100_tx_process 2599 * __ipw2100_tx_process
2630 * 2600 *
@@ -2667,7 +2637,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2667static inline int __ipw2100_tx_process(struct ipw2100_priv *priv) 2637static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2668{ 2638{
2669 struct ipw2100_bd_queue *txq = &priv->tx_queue; 2639 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2670 struct ipw2100_bd *tbd; 2640 struct ipw2100_bd *tbd;
2671 struct list_head *element; 2641 struct list_head *element;
2672 struct ipw2100_tx_packet *packet; 2642 struct ipw2100_tx_packet *packet;
2673 int descriptors_used; 2643 int descriptors_used;
@@ -2680,7 +2650,7 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2680 element = priv->fw_pend_list.next; 2650 element = priv->fw_pend_list.next;
2681 2651
2682 packet = list_entry(element, struct ipw2100_tx_packet, list); 2652 packet = list_entry(element, struct ipw2100_tx_packet, list);
2683 tbd = &txq->drv[packet->index]; 2653 tbd = &txq->drv[packet->index];
2684 2654
2685 /* Determine how many TBD entries must be finished... */ 2655 /* Determine how many TBD entries must be finished... */
2686 switch (packet->type) { 2656 switch (packet->type) {
@@ -2693,14 +2663,14 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2693 case DATA: 2663 case DATA:
2694 /* DATA uses two slots; advance and loop position. */ 2664 /* DATA uses two slots; advance and loop position. */
2695 descriptors_used = tbd->num_fragments; 2665 descriptors_used = tbd->num_fragments;
2696 frag_num = tbd->num_fragments - 1; 2666 frag_num = tbd->num_fragments - 1;
2697 e = txq->oldest + frag_num; 2667 e = txq->oldest + frag_num;
2698 e %= txq->entries; 2668 e %= txq->entries;
2699 break; 2669 break;
2700 2670
2701 default: 2671 default:
2702 printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n", 2672 printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n",
2703 priv->net_dev->name); 2673 priv->net_dev->name);
2704 return 0; 2674 return 0;
2705 } 2675 }
2706 2676
@@ -2716,13 +2686,12 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2716 printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n", 2686 printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n",
2717 priv->net_dev->name); 2687 priv->net_dev->name);
2718 2688
2719 /* 2689 /*
2720 * txq->next is the index of the last packet written txq->oldest is 2690 * txq->next is the index of the last packet written txq->oldest is
2721 * the index of the r is the index of the next packet to be read by 2691 * the index of the r is the index of the next packet to be read by
2722 * firmware 2692 * firmware
2723 */ 2693 */
2724 2694
2725
2726 /* 2695 /*
2727 * Quick graphic to help you visualize the following 2696 * Quick graphic to help you visualize the following
2728 * if / else statement 2697 * if / else statement
@@ -2750,23 +2719,20 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2750#ifdef CONFIG_IPW_DEBUG 2719#ifdef CONFIG_IPW_DEBUG
2751 { 2720 {
2752 int i = txq->oldest; 2721 int i = txq->oldest;
2753 IPW_DEBUG_TX( 2722 IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
2754 "TX%d V=%p P=%04X T=%04X L=%d\n", i, 2723 &txq->drv[i],
2755 &txq->drv[i], 2724 (u32) (txq->nic + i * sizeof(struct ipw2100_bd)),
2756 (u32)(txq->nic + i * sizeof(struct ipw2100_bd)), 2725 txq->drv[i].host_addr, txq->drv[i].buf_length);
2757 txq->drv[i].host_addr,
2758 txq->drv[i].buf_length);
2759 2726
2760 if (packet->type == DATA) { 2727 if (packet->type == DATA) {
2761 i = (i + 1) % txq->entries; 2728 i = (i + 1) % txq->entries;
2762 2729
2763 IPW_DEBUG_TX( 2730 IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
2764 "TX%d V=%p P=%04X T=%04X L=%d\n", i, 2731 &txq->drv[i],
2765 &txq->drv[i], 2732 (u32) (txq->nic + i *
2766 (u32)(txq->nic + i * 2733 sizeof(struct ipw2100_bd)),
2767 sizeof(struct ipw2100_bd)), 2734 (u32) txq->drv[i].host_addr,
2768 (u32)txq->drv[i].host_addr, 2735 txq->drv[i].buf_length);
2769 txq->drv[i].buf_length);
2770 } 2736 }
2771 } 2737 }
2772#endif 2738#endif
@@ -2780,23 +2746,18 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2780 priv->net_dev->name, txq->oldest, packet->index); 2746 priv->net_dev->name, txq->oldest, packet->index);
2781 2747
2782 /* DATA packet; we have to unmap and free the SKB */ 2748 /* DATA packet; we have to unmap and free the SKB */
2783 priv->ieee->stats.tx_packets++;
2784 for (i = 0; i < frag_num; i++) { 2749 for (i = 0; i < frag_num; i++) {
2785 tbd = &txq->drv[(packet->index + 1 + i) % 2750 tbd = &txq->drv[(packet->index + 1 + i) % txq->entries];
2786 txq->entries];
2787 2751
2788 IPW_DEBUG_TX( 2752 IPW_DEBUG_TX("TX%d P=%08x L=%d\n",
2789 "TX%d P=%08x L=%d\n", 2753 (packet->index + 1 + i) % txq->entries,
2790 (packet->index + 1 + i) % txq->entries, 2754 tbd->host_addr, tbd->buf_length);
2791 tbd->host_addr, tbd->buf_length);
2792 2755
2793 pci_unmap_single(priv->pci_dev, 2756 pci_unmap_single(priv->pci_dev,
2794 tbd->host_addr, 2757 tbd->host_addr,
2795 tbd->buf_length, 2758 tbd->buf_length, PCI_DMA_TODEVICE);
2796 PCI_DMA_TODEVICE);
2797 } 2759 }
2798 2760
2799 priv->ieee->stats.tx_bytes += packet->info.d_struct.txb->payload_size;
2800 ieee80211_txb_free(packet->info.d_struct.txb); 2761 ieee80211_txb_free(packet->info.d_struct.txb);
2801 packet->info.d_struct.txb = NULL; 2762 packet->info.d_struct.txb = NULL;
2802 2763
@@ -2805,13 +2766,8 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2805 2766
2806 /* We have a free slot in the Tx queue, so wake up the 2767 /* We have a free slot in the Tx queue, so wake up the
2807 * transmit layer if it is stopped. */ 2768 * transmit layer if it is stopped. */
2808 if (priv->status & STATUS_ASSOCIATED && 2769 if (priv->status & STATUS_ASSOCIATED)
2809 netif_queue_stopped(priv->net_dev)) {
2810 IPW_DEBUG_INFO(KERN_INFO
2811 "%s: Waking net queue.\n",
2812 priv->net_dev->name);
2813 netif_wake_queue(priv->net_dev); 2770 netif_wake_queue(priv->net_dev);
2814 }
2815 2771
2816 /* A packet was processed by the hardware, so update the 2772 /* A packet was processed by the hardware, so update the
2817 * watchdog */ 2773 * watchdog */
@@ -2829,11 +2785,12 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2829#ifdef CONFIG_IPW_DEBUG 2785#ifdef CONFIG_IPW_DEBUG
2830 if (packet->info.c_struct.cmd->host_command_reg < 2786 if (packet->info.c_struct.cmd->host_command_reg <
2831 sizeof(command_types) / sizeof(*command_types)) 2787 sizeof(command_types) / sizeof(*command_types))
2832 IPW_DEBUG_TX( 2788 IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",
2833 "Command '%s (%d)' processed: %d.\n", 2789 command_types[packet->info.c_struct.cmd->
2834 command_types[packet->info.c_struct.cmd->host_command_reg], 2790 host_command_reg],
2835 packet->info.c_struct.cmd->host_command_reg, 2791 packet->info.c_struct.cmd->
2836 packet->info.c_struct.cmd->cmd_status_reg); 2792 host_command_reg,
2793 packet->info.c_struct.cmd->cmd_status_reg);
2837#endif 2794#endif
2838 2795
2839 list_add_tail(element, &priv->msg_free_list); 2796 list_add_tail(element, &priv->msg_free_list);
@@ -2848,17 +2805,17 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2848 SET_STAT(&priv->txq_stat, txq->available); 2805 SET_STAT(&priv->txq_stat, txq->available);
2849 2806
2850 IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n", 2807 IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n",
2851 jiffies - packet->jiffy_start); 2808 jiffies - packet->jiffy_start);
2852 2809
2853 return (!list_empty(&priv->fw_pend_list)); 2810 return (!list_empty(&priv->fw_pend_list));
2854} 2811}
2855 2812
2856
2857static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv) 2813static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
2858{ 2814{
2859 int i = 0; 2815 int i = 0;
2860 2816
2861 while (__ipw2100_tx_process(priv) && i < 200) i++; 2817 while (__ipw2100_tx_process(priv) && i < 200)
2818 i++;
2862 2819
2863 if (i == 200) { 2820 if (i == 200) {
2864 printk(KERN_WARNING DRV_NAME ": " 2821 printk(KERN_WARNING DRV_NAME ": "
@@ -2867,7 +2824,6 @@ static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
2867 } 2824 }
2868} 2825}
2869 2826
2870
2871static void ipw2100_tx_send_commands(struct ipw2100_priv *priv) 2827static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2872{ 2828{
2873 struct list_head *element; 2829 struct list_head *element;
@@ -2892,13 +2848,12 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2892 list_del(element); 2848 list_del(element);
2893 DEC_STAT(&priv->msg_pend_stat); 2849 DEC_STAT(&priv->msg_pend_stat);
2894 2850
2895 packet = list_entry(element, 2851 packet = list_entry(element, struct ipw2100_tx_packet, list);
2896 struct ipw2100_tx_packet, list);
2897 2852
2898 IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n", 2853 IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n",
2899 &txq->drv[txq->next], 2854 &txq->drv[txq->next],
2900 (void*)(txq->nic + txq->next * 2855 (void *)(txq->nic + txq->next *
2901 sizeof(struct ipw2100_bd))); 2856 sizeof(struct ipw2100_bd)));
2902 2857
2903 packet->index = txq->next; 2858 packet->index = txq->next;
2904 2859
@@ -2911,8 +2866,8 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2911 * with f/w debug version */ 2866 * with f/w debug version */
2912 tbd->num_fragments = 1; 2867 tbd->num_fragments = 1;
2913 tbd->status.info.field = 2868 tbd->status.info.field =
2914 IPW_BD_STATUS_TX_FRAME_COMMAND | 2869 IPW_BD_STATUS_TX_FRAME_COMMAND |
2915 IPW_BD_STATUS_TX_INTERRUPT_ENABLE; 2870 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
2916 2871
2917 /* update TBD queue counters */ 2872 /* update TBD queue counters */
2918 txq->next++; 2873 txq->next++;
@@ -2934,7 +2889,6 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2934 } 2889 }
2935} 2890}
2936 2891
2937
2938/* 2892/*
2939 * ipw2100_tx_send_data 2893 * ipw2100_tx_send_data
2940 * 2894 *
@@ -2946,7 +2900,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2946 struct ipw2100_bd_queue *txq = &priv->tx_queue; 2900 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2947 struct ipw2100_bd *tbd; 2901 struct ipw2100_bd *tbd;
2948 int next = txq->next; 2902 int next = txq->next;
2949 int i = 0; 2903 int i = 0;
2950 struct ipw2100_data_header *ipw_hdr; 2904 struct ipw2100_data_header *ipw_hdr;
2951 struct ieee80211_hdr_3addr *hdr; 2905 struct ieee80211_hdr_3addr *hdr;
2952 2906
@@ -2958,20 +2912,18 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2958 * maintained between the r and w indexes 2912 * maintained between the r and w indexes
2959 */ 2913 */
2960 element = priv->tx_pend_list.next; 2914 element = priv->tx_pend_list.next;
2961 packet = list_entry(element, struct ipw2100_tx_packet, list); 2915 packet = list_entry(element, struct ipw2100_tx_packet, list);
2962 2916
2963 if (unlikely(1 + packet->info.d_struct.txb->nr_frags > 2917 if (unlikely(1 + packet->info.d_struct.txb->nr_frags >
2964 IPW_MAX_BDS)) { 2918 IPW_MAX_BDS)) {
2965 /* TODO: Support merging buffers if more than 2919 /* TODO: Support merging buffers if more than
2966 * IPW_MAX_BDS are used */ 2920 * IPW_MAX_BDS are used */
2967 IPW_DEBUG_INFO( 2921 IPW_DEBUG_INFO("%s: Maximum BD theshold exceeded. "
2968 "%s: Maximum BD theshold exceeded. " 2922 "Increase fragmentation level.\n",
2969 "Increase fragmentation level.\n", 2923 priv->net_dev->name);
2970 priv->net_dev->name);
2971 } 2924 }
2972 2925
2973 if (txq->available <= 3 + 2926 if (txq->available <= 3 + packet->info.d_struct.txb->nr_frags) {
2974 packet->info.d_struct.txb->nr_frags) {
2975 IPW_DEBUG_TX("no room in tx_queue\n"); 2927 IPW_DEBUG_TX("no room in tx_queue\n");
2976 break; 2928 break;
2977 } 2929 }
@@ -2985,7 +2937,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2985 2937
2986 ipw_hdr = packet->info.d_struct.data; 2938 ipw_hdr = packet->info.d_struct.data;
2987 hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb-> 2939 hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
2988 fragments[0]->data; 2940 fragments[0]->data;
2989 2941
2990 if (priv->ieee->iw_mode == IW_MODE_INFRA) { 2942 if (priv->ieee->iw_mode == IW_MODE_INFRA) {
2991 /* To DS: Addr1 = BSSID, Addr2 = SA, 2943 /* To DS: Addr1 = BSSID, Addr2 = SA,
@@ -3007,7 +2959,8 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3007 ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted; 2959 ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted;
3008 if (packet->info.d_struct.txb->nr_frags > 1) 2960 if (packet->info.d_struct.txb->nr_frags > 1)
3009 ipw_hdr->fragment_size = 2961 ipw_hdr->fragment_size =
3010 packet->info.d_struct.txb->frag_size - IEEE80211_3ADDR_LEN; 2962 packet->info.d_struct.txb->frag_size -
2963 IEEE80211_3ADDR_LEN;
3011 else 2964 else
3012 ipw_hdr->fragment_size = 0; 2965 ipw_hdr->fragment_size = 0;
3013 2966
@@ -3015,54 +2968,53 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3015 tbd->buf_length = sizeof(struct ipw2100_data_header); 2968 tbd->buf_length = sizeof(struct ipw2100_data_header);
3016 tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags; 2969 tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags;
3017 tbd->status.info.field = 2970 tbd->status.info.field =
3018 IPW_BD_STATUS_TX_FRAME_802_3 | 2971 IPW_BD_STATUS_TX_FRAME_802_3 |
3019 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT; 2972 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3020 txq->next++; 2973 txq->next++;
3021 txq->next %= txq->entries; 2974 txq->next %= txq->entries;
3022 2975
3023 IPW_DEBUG_TX( 2976 IPW_DEBUG_TX("data header tbd TX%d P=%08x L=%d\n",
3024 "data header tbd TX%d P=%08x L=%d\n", 2977 packet->index, tbd->host_addr, tbd->buf_length);
3025 packet->index, tbd->host_addr,
3026 tbd->buf_length);
3027#ifdef CONFIG_IPW_DEBUG 2978#ifdef CONFIG_IPW_DEBUG
3028 if (packet->info.d_struct.txb->nr_frags > 1) 2979 if (packet->info.d_struct.txb->nr_frags > 1)
3029 IPW_DEBUG_FRAG("fragment Tx: %d frames\n", 2980 IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
3030 packet->info.d_struct.txb->nr_frags); 2981 packet->info.d_struct.txb->nr_frags);
3031#endif 2982#endif
3032 2983
3033 for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) { 2984 for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) {
3034 tbd = &txq->drv[txq->next]; 2985 tbd = &txq->drv[txq->next];
3035 if (i == packet->info.d_struct.txb->nr_frags - 1) 2986 if (i == packet->info.d_struct.txb->nr_frags - 1)
3036 tbd->status.info.field = 2987 tbd->status.info.field =
3037 IPW_BD_STATUS_TX_FRAME_802_3 | 2988 IPW_BD_STATUS_TX_FRAME_802_3 |
3038 IPW_BD_STATUS_TX_INTERRUPT_ENABLE; 2989 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
3039 else 2990 else
3040 tbd->status.info.field = 2991 tbd->status.info.field =
3041 IPW_BD_STATUS_TX_FRAME_802_3 | 2992 IPW_BD_STATUS_TX_FRAME_802_3 |
3042 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT; 2993 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3043 2994
3044 tbd->buf_length = packet->info.d_struct.txb-> 2995 tbd->buf_length = packet->info.d_struct.txb->
3045 fragments[i]->len - IEEE80211_3ADDR_LEN; 2996 fragments[i]->len - IEEE80211_3ADDR_LEN;
3046 2997
3047 tbd->host_addr = pci_map_single( 2998 tbd->host_addr = pci_map_single(priv->pci_dev,
3048 priv->pci_dev, 2999 packet->info.d_struct.
3049 packet->info.d_struct.txb->fragments[i]->data + 3000 txb->fragments[i]->
3050 IEEE80211_3ADDR_LEN, 3001 data +
3051 tbd->buf_length, 3002 IEEE80211_3ADDR_LEN,
3052 PCI_DMA_TODEVICE); 3003 tbd->buf_length,
3004 PCI_DMA_TODEVICE);
3053 3005
3054 IPW_DEBUG_TX( 3006 IPW_DEBUG_TX("data frag tbd TX%d P=%08x L=%d\n",
3055 "data frag tbd TX%d P=%08x L=%d\n", 3007 txq->next, tbd->host_addr,
3056 txq->next, tbd->host_addr, tbd->buf_length); 3008 tbd->buf_length);
3057 3009
3058 pci_dma_sync_single_for_device( 3010 pci_dma_sync_single_for_device(priv->pci_dev,
3059 priv->pci_dev, tbd->host_addr, 3011 tbd->host_addr,
3060 tbd->buf_length, 3012 tbd->buf_length,
3061 PCI_DMA_TODEVICE); 3013 PCI_DMA_TODEVICE);
3062 3014
3063 txq->next++; 3015 txq->next++;
3064 txq->next %= txq->entries; 3016 txq->next %= txq->entries;
3065 } 3017 }
3066 3018
3067 txq->available -= 1 + packet->info.d_struct.txb->nr_frags; 3019 txq->available -= 1 + packet->info.d_struct.txb->nr_frags;
3068 SET_STAT(&priv->txq_stat, txq->available); 3020 SET_STAT(&priv->txq_stat, txq->available);
@@ -3078,7 +3030,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3078 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX, 3030 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
3079 txq->next); 3031 txq->next);
3080 } 3032 }
3081 return; 3033 return;
3082} 3034}
3083 3035
3084static void ipw2100_irq_tasklet(struct ipw2100_priv *priv) 3036static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
@@ -3106,11 +3058,9 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3106 3058
3107 if (inta & IPW2100_INTA_FATAL_ERROR) { 3059 if (inta & IPW2100_INTA_FATAL_ERROR) {
3108 printk(KERN_WARNING DRV_NAME 3060 printk(KERN_WARNING DRV_NAME
3109 ": Fatal interrupt. Scheduling firmware restart.\n"); 3061 ": Fatal interrupt. Scheduling firmware restart.\n");
3110 priv->inta_other++; 3062 priv->inta_other++;
3111 write_register( 3063 write_register(dev, IPW_REG_INTA, IPW2100_INTA_FATAL_ERROR);
3112 dev, IPW_REG_INTA,
3113 IPW2100_INTA_FATAL_ERROR);
3114 3064
3115 read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error); 3065 read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error);
3116 IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n", 3066 IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n",
@@ -3125,11 +3075,10 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3125 } 3075 }
3126 3076
3127 if (inta & IPW2100_INTA_PARITY_ERROR) { 3077 if (inta & IPW2100_INTA_PARITY_ERROR) {
3128 printk(KERN_ERR DRV_NAME ": ***** PARITY ERROR INTERRUPT !!!! \n"); 3078 printk(KERN_ERR DRV_NAME
3079 ": ***** PARITY ERROR INTERRUPT !!!! \n");
3129 priv->inta_other++; 3080 priv->inta_other++;
3130 write_register( 3081 write_register(dev, IPW_REG_INTA, IPW2100_INTA_PARITY_ERROR);
3131 dev, IPW_REG_INTA,
3132 IPW2100_INTA_PARITY_ERROR);
3133 } 3082 }
3134 3083
3135 if (inta & IPW2100_INTA_RX_TRANSFER) { 3084 if (inta & IPW2100_INTA_RX_TRANSFER) {
@@ -3137,9 +3086,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3137 3086
3138 priv->rx_interrupts++; 3087 priv->rx_interrupts++;
3139 3088
3140 write_register( 3089 write_register(dev, IPW_REG_INTA, IPW2100_INTA_RX_TRANSFER);
3141 dev, IPW_REG_INTA,
3142 IPW2100_INTA_RX_TRANSFER);
3143 3090
3144 __ipw2100_rx_process(priv); 3091 __ipw2100_rx_process(priv);
3145 __ipw2100_tx_complete(priv); 3092 __ipw2100_tx_complete(priv);
@@ -3150,8 +3097,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3150 3097
3151 priv->tx_interrupts++; 3098 priv->tx_interrupts++;
3152 3099
3153 write_register(dev, IPW_REG_INTA, 3100 write_register(dev, IPW_REG_INTA, IPW2100_INTA_TX_TRANSFER);
3154 IPW2100_INTA_TX_TRANSFER);
3155 3101
3156 __ipw2100_tx_complete(priv); 3102 __ipw2100_tx_complete(priv);
3157 ipw2100_tx_send_commands(priv); 3103 ipw2100_tx_send_commands(priv);
@@ -3161,9 +3107,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3161 if (inta & IPW2100_INTA_TX_COMPLETE) { 3107 if (inta & IPW2100_INTA_TX_COMPLETE) {
3162 IPW_DEBUG_ISR("TX complete\n"); 3108 IPW_DEBUG_ISR("TX complete\n");
3163 priv->inta_other++; 3109 priv->inta_other++;
3164 write_register( 3110 write_register(dev, IPW_REG_INTA, IPW2100_INTA_TX_COMPLETE);
3165 dev, IPW_REG_INTA,
3166 IPW2100_INTA_TX_COMPLETE);
3167 3111
3168 __ipw2100_tx_complete(priv); 3112 __ipw2100_tx_complete(priv);
3169 } 3113 }
@@ -3171,9 +3115,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3171 if (inta & IPW2100_INTA_EVENT_INTERRUPT) { 3115 if (inta & IPW2100_INTA_EVENT_INTERRUPT) {
3172 /* ipw2100_handle_event(dev); */ 3116 /* ipw2100_handle_event(dev); */
3173 priv->inta_other++; 3117 priv->inta_other++;
3174 write_register( 3118 write_register(dev, IPW_REG_INTA, IPW2100_INTA_EVENT_INTERRUPT);
3175 dev, IPW_REG_INTA,
3176 IPW2100_INTA_EVENT_INTERRUPT);
3177 } 3119 }
3178 3120
3179 if (inta & IPW2100_INTA_FW_INIT_DONE) { 3121 if (inta & IPW2100_INTA_FW_INIT_DONE) {
@@ -3183,30 +3125,25 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3183 read_register(dev, IPW_REG_INTA, &tmp); 3125 read_register(dev, IPW_REG_INTA, &tmp);
3184 if (tmp & (IPW2100_INTA_FATAL_ERROR | 3126 if (tmp & (IPW2100_INTA_FATAL_ERROR |
3185 IPW2100_INTA_PARITY_ERROR)) { 3127 IPW2100_INTA_PARITY_ERROR)) {
3186 write_register( 3128 write_register(dev, IPW_REG_INTA,
3187 dev, IPW_REG_INTA, 3129 IPW2100_INTA_FATAL_ERROR |
3188 IPW2100_INTA_FATAL_ERROR | 3130 IPW2100_INTA_PARITY_ERROR);
3189 IPW2100_INTA_PARITY_ERROR);
3190 } 3131 }
3191 3132
3192 write_register(dev, IPW_REG_INTA, 3133 write_register(dev, IPW_REG_INTA, IPW2100_INTA_FW_INIT_DONE);
3193 IPW2100_INTA_FW_INIT_DONE);
3194 } 3134 }
3195 3135
3196 if (inta & IPW2100_INTA_STATUS_CHANGE) { 3136 if (inta & IPW2100_INTA_STATUS_CHANGE) {
3197 IPW_DEBUG_ISR("Status change interrupt\n"); 3137 IPW_DEBUG_ISR("Status change interrupt\n");
3198 priv->inta_other++; 3138 priv->inta_other++;
3199 write_register( 3139 write_register(dev, IPW_REG_INTA, IPW2100_INTA_STATUS_CHANGE);
3200 dev, IPW_REG_INTA,
3201 IPW2100_INTA_STATUS_CHANGE);
3202 } 3140 }
3203 3141
3204 if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) { 3142 if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) {
3205 IPW_DEBUG_ISR("slave host mode interrupt\n"); 3143 IPW_DEBUG_ISR("slave host mode interrupt\n");
3206 priv->inta_other++; 3144 priv->inta_other++;
3207 write_register( 3145 write_register(dev, IPW_REG_INTA,
3208 dev, IPW_REG_INTA, 3146 IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
3209 IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
3210 } 3147 }
3211 3148
3212 priv->in_isr--; 3149 priv->in_isr--;
@@ -3217,9 +3154,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3217 IPW_DEBUG_ISR("exit\n"); 3154 IPW_DEBUG_ISR("exit\n");
3218} 3155}
3219 3156
3220 3157static irqreturn_t ipw2100_interrupt(int irq, void *data, struct pt_regs *regs)
3221static irqreturn_t ipw2100_interrupt(int irq, void *data,
3222 struct pt_regs *regs)
3223{ 3158{
3224 struct ipw2100_priv *priv = data; 3159 struct ipw2100_priv *priv = data;
3225 u32 inta, inta_mask; 3160 u32 inta, inta_mask;
@@ -3227,7 +3162,7 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
3227 if (!data) 3162 if (!data)
3228 return IRQ_NONE; 3163 return IRQ_NONE;
3229 3164
3230 spin_lock(&priv->low_lock); 3165 spin_lock(&priv->low_lock);
3231 3166
3232 /* We check to see if we should be ignoring interrupts before 3167 /* We check to see if we should be ignoring interrupts before
3233 * we touch the hardware. During ucode load if we try and handle 3168 * we touch the hardware. During ucode load if we try and handle
@@ -3261,10 +3196,10 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
3261 ipw2100_disable_interrupts(priv); 3196 ipw2100_disable_interrupts(priv);
3262 3197
3263 tasklet_schedule(&priv->irq_tasklet); 3198 tasklet_schedule(&priv->irq_tasklet);
3264 spin_unlock(&priv->low_lock); 3199 spin_unlock(&priv->low_lock);
3265 3200
3266 return IRQ_HANDLED; 3201 return IRQ_HANDLED;
3267 none: 3202 none:
3268 spin_unlock(&priv->low_lock); 3203 spin_unlock(&priv->low_lock);
3269 return IRQ_NONE; 3204 return IRQ_NONE;
3270} 3205}
@@ -3294,10 +3229,8 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
3294 3229
3295 packet->info.d_struct.txb = txb; 3230 packet->info.d_struct.txb = txb;
3296 3231
3297 IPW_DEBUG_TX("Sending fragment (%d bytes):\n", 3232 IPW_DEBUG_TX("Sending fragment (%d bytes):\n", txb->fragments[0]->len);
3298 txb->fragments[0]->len); 3233 printk_buf(IPW_DL_TX, txb->fragments[0]->data, txb->fragments[0]->len);
3299 printk_buf(IPW_DL_TX, txb->fragments[0]->data,
3300 txb->fragments[0]->len);
3301 3234
3302 packet->jiffy_start = jiffies; 3235 packet->jiffy_start = jiffies;
3303 3236
@@ -3312,22 +3245,23 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
3312 spin_unlock_irqrestore(&priv->low_lock, flags); 3245 spin_unlock_irqrestore(&priv->low_lock, flags);
3313 return 0; 3246 return 0;
3314 3247
3315 fail_unlock: 3248 fail_unlock:
3316 netif_stop_queue(dev); 3249 netif_stop_queue(dev);
3317 spin_unlock_irqrestore(&priv->low_lock, flags); 3250 spin_unlock_irqrestore(&priv->low_lock, flags);
3318 return 1; 3251 return 1;
3319} 3252}
3320 3253
3321
3322static int ipw2100_msg_allocate(struct ipw2100_priv *priv) 3254static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3323{ 3255{
3324 int i, j, err = -EINVAL; 3256 int i, j, err = -EINVAL;
3325 void *v; 3257 void *v;
3326 dma_addr_t p; 3258 dma_addr_t p;
3327 3259
3328 priv->msg_buffers = (struct ipw2100_tx_packet *)kmalloc( 3260 priv->msg_buffers =
3329 IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet), 3261 (struct ipw2100_tx_packet *)kmalloc(IPW_COMMAND_POOL_SIZE *
3330 GFP_KERNEL); 3262 sizeof(struct
3263 ipw2100_tx_packet),
3264 GFP_KERNEL);
3331 if (!priv->msg_buffers) { 3265 if (!priv->msg_buffers) {
3332 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg " 3266 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg "
3333 "buffers.\n", priv->net_dev->name); 3267 "buffers.\n", priv->net_dev->name);
@@ -3335,15 +3269,12 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3335 } 3269 }
3336 3270
3337 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) { 3271 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
3338 v = pci_alloc_consistent( 3272 v = pci_alloc_consistent(priv->pci_dev,
3339 priv->pci_dev, 3273 sizeof(struct ipw2100_cmd_header), &p);
3340 sizeof(struct ipw2100_cmd_header),
3341 &p);
3342 if (!v) { 3274 if (!v) {
3343 printk(KERN_ERR DRV_NAME ": " 3275 printk(KERN_ERR DRV_NAME ": "
3344 "%s: PCI alloc failed for msg " 3276 "%s: PCI alloc failed for msg "
3345 "buffers.\n", 3277 "buffers.\n", priv->net_dev->name);
3346 priv->net_dev->name);
3347 err = -ENOMEM; 3278 err = -ENOMEM;
3348 break; 3279 break;
3349 } 3280 }
@@ -3352,7 +3283,7 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3352 3283
3353 priv->msg_buffers[i].type = COMMAND; 3284 priv->msg_buffers[i].type = COMMAND;
3354 priv->msg_buffers[i].info.c_struct.cmd = 3285 priv->msg_buffers[i].info.c_struct.cmd =
3355 (struct ipw2100_cmd_header*)v; 3286 (struct ipw2100_cmd_header *)v;
3356 priv->msg_buffers[i].info.c_struct.cmd_phys = p; 3287 priv->msg_buffers[i].info.c_struct.cmd_phys = p;
3357 } 3288 }
3358 3289
@@ -3360,11 +3291,11 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3360 return 0; 3291 return 0;
3361 3292
3362 for (j = 0; j < i; j++) { 3293 for (j = 0; j < i; j++) {
3363 pci_free_consistent( 3294 pci_free_consistent(priv->pci_dev,
3364 priv->pci_dev, 3295 sizeof(struct ipw2100_cmd_header),
3365 sizeof(struct ipw2100_cmd_header), 3296 priv->msg_buffers[j].info.c_struct.cmd,
3366 priv->msg_buffers[j].info.c_struct.cmd, 3297 priv->msg_buffers[j].info.c_struct.
3367 priv->msg_buffers[j].info.c_struct.cmd_phys); 3298 cmd_phys);
3368 } 3299 }
3369 3300
3370 kfree(priv->msg_buffers); 3301 kfree(priv->msg_buffers);
@@ -3398,7 +3329,8 @@ static void ipw2100_msg_free(struct ipw2100_priv *priv)
3398 pci_free_consistent(priv->pci_dev, 3329 pci_free_consistent(priv->pci_dev,
3399 sizeof(struct ipw2100_cmd_header), 3330 sizeof(struct ipw2100_cmd_header),
3400 priv->msg_buffers[i].info.c_struct.cmd, 3331 priv->msg_buffers[i].info.c_struct.cmd,
3401 priv->msg_buffers[i].info.c_struct.cmd_phys); 3332 priv->msg_buffers[i].info.c_struct.
3333 cmd_phys);
3402 } 3334 }
3403 3335
3404 kfree(priv->msg_buffers); 3336 kfree(priv->msg_buffers);
@@ -3424,6 +3356,7 @@ static ssize_t show_pci(struct device *d, struct device_attribute *attr,
3424 3356
3425 return out - buf; 3357 return out - buf;
3426} 3358}
3359
3427static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL); 3360static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
3428 3361
3429static ssize_t show_cfg(struct device *d, struct device_attribute *attr, 3362static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
@@ -3432,209 +3365,269 @@ static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
3432 struct ipw2100_priv *p = d->driver_data; 3365 struct ipw2100_priv *p = d->driver_data;
3433 return sprintf(buf, "0x%08x\n", (int)p->config); 3366 return sprintf(buf, "0x%08x\n", (int)p->config);
3434} 3367}
3368
3435static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); 3369static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
3436 3370
3437static ssize_t show_status(struct device *d, struct device_attribute *attr, 3371static ssize_t show_status(struct device *d, struct device_attribute *attr,
3438 char *buf) 3372 char *buf)
3439{ 3373{
3440 struct ipw2100_priv *p = d->driver_data; 3374 struct ipw2100_priv *p = d->driver_data;
3441 return sprintf(buf, "0x%08x\n", (int)p->status); 3375 return sprintf(buf, "0x%08x\n", (int)p->status);
3442} 3376}
3377
3443static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 3378static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
3444 3379
3445static ssize_t show_capability(struct device *d, struct device_attribute *attr, 3380static ssize_t show_capability(struct device *d, struct device_attribute *attr,
3446 char *buf) 3381 char *buf)
3447{ 3382{
3448 struct ipw2100_priv *p = d->driver_data; 3383 struct ipw2100_priv *p = d->driver_data;
3449 return sprintf(buf, "0x%08x\n", (int)p->capability); 3384 return sprintf(buf, "0x%08x\n", (int)p->capability);
3450} 3385}
3451static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
3452 3386
3387static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
3453 3388
3454#define IPW2100_REG(x) { IPW_ ##x, #x } 3389#define IPW2100_REG(x) { IPW_ ##x, #x }
3455static const struct { 3390static const struct {
3456 u32 addr; 3391 u32 addr;
3457 const char *name; 3392 const char *name;
3458} hw_data[] = { 3393} hw_data[] = {
3459 IPW2100_REG(REG_GP_CNTRL), 3394IPW2100_REG(REG_GP_CNTRL),
3460 IPW2100_REG(REG_GPIO), 3395 IPW2100_REG(REG_GPIO),
3461 IPW2100_REG(REG_INTA), 3396 IPW2100_REG(REG_INTA),
3462 IPW2100_REG(REG_INTA_MASK), 3397 IPW2100_REG(REG_INTA_MASK), IPW2100_REG(REG_RESET_REG),};
3463 IPW2100_REG(REG_RESET_REG),
3464};
3465#define IPW2100_NIC(x, s) { x, #x, s } 3398#define IPW2100_NIC(x, s) { x, #x, s }
3466static const struct { 3399static const struct {
3467 u32 addr; 3400 u32 addr;
3468 const char *name; 3401 const char *name;
3469 size_t size; 3402 size_t size;
3470} nic_data[] = { 3403} nic_data[] = {
3471 IPW2100_NIC(IPW2100_CONTROL_REG, 2), 3404IPW2100_NIC(IPW2100_CONTROL_REG, 2),
3472 IPW2100_NIC(0x210014, 1), 3405 IPW2100_NIC(0x210014, 1), IPW2100_NIC(0x210000, 1),};
3473 IPW2100_NIC(0x210000, 1),
3474};
3475#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d } 3406#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d }
3476static const struct { 3407static const struct {
3477 u8 index; 3408 u8 index;
3478 const char *name; 3409 const char *name;
3479 const char *desc; 3410 const char *desc;
3480} ord_data[] = { 3411} ord_data[] = {
3481 IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"), 3412IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"),
3482 IPW2100_ORD(STAT_TX_HOST_COMPLETE, "successful Host Tx's (MSDU)"), 3413 IPW2100_ORD(STAT_TX_HOST_COMPLETE,
3483 IPW2100_ORD(STAT_TX_DIR_DATA, "successful Directed Tx's (MSDU)"), 3414 "successful Host Tx's (MSDU)"),
3484 IPW2100_ORD(STAT_TX_DIR_DATA1, "successful Directed Tx's (MSDU) @ 1MB"), 3415 IPW2100_ORD(STAT_TX_DIR_DATA,
3485 IPW2100_ORD(STAT_TX_DIR_DATA2, "successful Directed Tx's (MSDU) @ 2MB"), 3416 "successful Directed Tx's (MSDU)"),
3486 IPW2100_ORD(STAT_TX_DIR_DATA5_5, "successful Directed Tx's (MSDU) @ 5_5MB"), 3417 IPW2100_ORD(STAT_TX_DIR_DATA1,
3487 IPW2100_ORD(STAT_TX_DIR_DATA11, "successful Directed Tx's (MSDU) @ 11MB"), 3418 "successful Directed Tx's (MSDU) @ 1MB"),
3488 IPW2100_ORD(STAT_TX_NODIR_DATA1, "successful Non_Directed Tx's (MSDU) @ 1MB"), 3419 IPW2100_ORD(STAT_TX_DIR_DATA2,
3489 IPW2100_ORD(STAT_TX_NODIR_DATA2, "successful Non_Directed Tx's (MSDU) @ 2MB"), 3420 "successful Directed Tx's (MSDU) @ 2MB"),
3490 IPW2100_ORD(STAT_TX_NODIR_DATA5_5, "successful Non_Directed Tx's (MSDU) @ 5.5MB"), 3421 IPW2100_ORD(STAT_TX_DIR_DATA5_5,
3491 IPW2100_ORD(STAT_TX_NODIR_DATA11, "successful Non_Directed Tx's (MSDU) @ 11MB"), 3422 "successful Directed Tx's (MSDU) @ 5_5MB"),
3492 IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"), 3423 IPW2100_ORD(STAT_TX_DIR_DATA11,
3493 IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"), 3424 "successful Directed Tx's (MSDU) @ 11MB"),
3494 IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"), 3425 IPW2100_ORD(STAT_TX_NODIR_DATA1,
3495 IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"), 3426 "successful Non_Directed Tx's (MSDU) @ 1MB"),
3496 IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"), 3427 IPW2100_ORD(STAT_TX_NODIR_DATA2,
3497 IPW2100_ORD(STAT_TX_ASSN_RESP, "successful Association response Tx's"), 3428 "successful Non_Directed Tx's (MSDU) @ 2MB"),
3498 IPW2100_ORD(STAT_TX_REASSN, "successful Reassociation Tx's"), 3429 IPW2100_ORD(STAT_TX_NODIR_DATA5_5,
3499 IPW2100_ORD(STAT_TX_REASSN_RESP, "successful Reassociation response Tx's"), 3430 "successful Non_Directed Tx's (MSDU) @ 5.5MB"),
3500 IPW2100_ORD(STAT_TX_PROBE, "probes successfully transmitted"), 3431 IPW2100_ORD(STAT_TX_NODIR_DATA11,
3501 IPW2100_ORD(STAT_TX_PROBE_RESP, "probe responses successfully transmitted"), 3432 "successful Non_Directed Tx's (MSDU) @ 11MB"),
3502 IPW2100_ORD(STAT_TX_BEACON, "tx beacon"), 3433 IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"),
3503 IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"), 3434 IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"),
3504 IPW2100_ORD(STAT_TX_DISASSN, "successful Disassociation TX"), 3435 IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"),
3505 IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"), 3436 IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"),
3506 IPW2100_ORD(STAT_TX_DEAUTH, "successful Deauthentication TX"), 3437 IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"),
3507 IPW2100_ORD(STAT_TX_TOTAL_BYTES, "Total successful Tx data bytes"), 3438 IPW2100_ORD(STAT_TX_ASSN_RESP,
3508 IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"), 3439 "successful Association response Tx's"),
3509 IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"), 3440 IPW2100_ORD(STAT_TX_REASSN,
3510 IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"), 3441 "successful Reassociation Tx's"),
3511 IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"), 3442 IPW2100_ORD(STAT_TX_REASSN_RESP,
3512 IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"), 3443 "successful Reassociation response Tx's"),
3513 IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"), 3444 IPW2100_ORD(STAT_TX_PROBE,
3514 IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,"times max tries in a hop failed"), 3445 "probes successfully transmitted"),
3515 IPW2100_ORD(STAT_TX_DISASSN_FAIL, "times disassociation failed"), 3446 IPW2100_ORD(STAT_TX_PROBE_RESP,
3516 IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"), 3447 "probe responses successfully transmitted"),
3517 IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"), 3448 IPW2100_ORD(STAT_TX_BEACON, "tx beacon"),
3518 IPW2100_ORD(STAT_RX_HOST, "packets passed to host"), 3449 IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"),
3519 IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"), 3450 IPW2100_ORD(STAT_TX_DISASSN,
3520 IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"), 3451 "successful Disassociation TX"),
3521 IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"), 3452 IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"),
3522 IPW2100_ORD(STAT_RX_DIR_DATA5_5, "directed packets at 5.5MB"), 3453 IPW2100_ORD(STAT_TX_DEAUTH,
3523 IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"), 3454 "successful Deauthentication TX"),
3524 IPW2100_ORD(STAT_RX_NODIR_DATA,"nondirected packets"), 3455 IPW2100_ORD(STAT_TX_TOTAL_BYTES,
3525 IPW2100_ORD(STAT_RX_NODIR_DATA1, "nondirected packets at 1MB"), 3456 "Total successful Tx data bytes"),
3526 IPW2100_ORD(STAT_RX_NODIR_DATA2, "nondirected packets at 2MB"), 3457 IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"),
3527 IPW2100_ORD(STAT_RX_NODIR_DATA5_5, "nondirected packets at 5.5MB"), 3458 IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"),
3528 IPW2100_ORD(STAT_RX_NODIR_DATA11, "nondirected packets at 11MB"), 3459 IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"),
3529 IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"), 3460 IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"),
3530 IPW2100_ORD(STAT_RX_RTS, "Rx RTS"), 3461 IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"),
3531 IPW2100_ORD(STAT_RX_CTS, "Rx CTS"), 3462 IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"),
3532 IPW2100_ORD(STAT_RX_ACK, "Rx ACK"), 3463 IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,
3533 IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"), 3464 "times max tries in a hop failed"),
3534 IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"), 3465 IPW2100_ORD(STAT_TX_DISASSN_FAIL,
3535 IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"), 3466 "times disassociation failed"),
3536 IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"), 3467 IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"),
3537 IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"), 3468 IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"),
3538 IPW2100_ORD(STAT_RX_REASSN_RESP, "Reassociation response Rx's"), 3469 IPW2100_ORD(STAT_RX_HOST, "packets passed to host"),
3539 IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"), 3470 IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"),
3540 IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"), 3471 IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"),
3541 IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"), 3472 IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"),
3542 IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"), 3473 IPW2100_ORD(STAT_RX_DIR_DATA5_5,
3543 IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"), 3474 "directed packets at 5.5MB"),
3544 IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"), 3475 IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"),
3545 IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"), 3476 IPW2100_ORD(STAT_RX_NODIR_DATA, "nondirected packets"),
3546 IPW2100_ORD(STAT_RX_TOTAL_BYTES,"Total rx data bytes received"), 3477 IPW2100_ORD(STAT_RX_NODIR_DATA1,
3547 IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"), 3478 "nondirected packets at 1MB"),
3548 IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"), 3479 IPW2100_ORD(STAT_RX_NODIR_DATA2,
3549 IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"), 3480 "nondirected packets at 2MB"),
3550 IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"), 3481 IPW2100_ORD(STAT_RX_NODIR_DATA5_5,
3551 IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"), 3482 "nondirected packets at 5.5MB"),
3552 IPW2100_ORD(STAT_RX_DUPLICATE1, "duplicate rx packets at 1MB"), 3483 IPW2100_ORD(STAT_RX_NODIR_DATA11,
3553 IPW2100_ORD(STAT_RX_DUPLICATE2, "duplicate rx packets at 2MB"), 3484 "nondirected packets at 11MB"),
3554 IPW2100_ORD(STAT_RX_DUPLICATE5_5, "duplicate rx packets at 5.5MB"), 3485 IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"),
3555 IPW2100_ORD(STAT_RX_DUPLICATE11, "duplicate rx packets at 11MB"), 3486 IPW2100_ORD(STAT_RX_RTS, "Rx RTS"), IPW2100_ORD(STAT_RX_CTS,
3556 IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"), 3487 "Rx CTS"),
3557 IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"), 3488 IPW2100_ORD(STAT_RX_ACK, "Rx ACK"),
3558 IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"), 3489 IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"),
3559 IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"), 3490 IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"),
3560 IPW2100_ORD(STAT_RX_INVALID_PROTOCOL, "rx frames with invalid protocol"), 3491 IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"),
3561 IPW2100_ORD(SYS_BOOT_TIME, "Boot time"), 3492 IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"),
3562 IPW2100_ORD(STAT_RX_NO_BUFFER, "rx frames rejected due to no buffer"), 3493 IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"),
3563 IPW2100_ORD(STAT_RX_MISSING_FRAG, "rx frames dropped due to missing fragment"), 3494 IPW2100_ORD(STAT_RX_REASSN_RESP,
3564 IPW2100_ORD(STAT_RX_ORPHAN_FRAG, "rx frames dropped due to non-sequential fragment"), 3495 "Reassociation response Rx's"),
3565 IPW2100_ORD(STAT_RX_ORPHAN_FRAME, "rx frames dropped due to unmatched 1st frame"), 3496 IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"),
3566 IPW2100_ORD(STAT_RX_FRAG_AGEOUT, "rx frames dropped due to uncompleted frame"), 3497 IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"),
3567 IPW2100_ORD(STAT_RX_ICV_ERRORS, "ICV errors during decryption"), 3498 IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"),
3568 IPW2100_ORD(STAT_PSP_SUSPENSION,"times adapter suspended"), 3499 IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"),
3569 IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"), 3500 IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"),
3570 IPW2100_ORD(STAT_PSP_POLL_TIMEOUT, "poll response timeouts"), 3501 IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"),
3571 IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT, "timeouts waiting for last {broad,multi}cast pkt"), 3502 IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"),
3572 IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"), 3503 IPW2100_ORD(STAT_RX_TOTAL_BYTES,
3573 IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"), 3504 "Total rx data bytes received"),
3574 IPW2100_ORD(STAT_PSP_STATION_ID,"PSP Station ID"), 3505 IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"),
3575 IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"), 3506 IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"),
3576 IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,"current calculation of % missed beacons"), 3507 IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"),
3577 IPW2100_ORD(STAT_PERCENT_RETRIES,"current calculation of % missed tx retries"), 3508 IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"),
3578 IPW2100_ORD(ASSOCIATED_AP_PTR, "0 if not associated, else pointer to AP table entry"), 3509 IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"),
3579 IPW2100_ORD(AVAILABLE_AP_CNT, "AP's decsribed in the AP table"), 3510 IPW2100_ORD(STAT_RX_DUPLICATE1,
3580 IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"), 3511 "duplicate rx packets at 1MB"),
3581 IPW2100_ORD(STAT_AP_ASSNS, "associations"), 3512 IPW2100_ORD(STAT_RX_DUPLICATE2,
3582 IPW2100_ORD(STAT_ASSN_FAIL, "association failures"), 3513 "duplicate rx packets at 2MB"),
3583 IPW2100_ORD(STAT_ASSN_RESP_FAIL,"failures due to response fail"), 3514 IPW2100_ORD(STAT_RX_DUPLICATE5_5,
3584 IPW2100_ORD(STAT_FULL_SCANS, "full scans"), 3515 "duplicate rx packets at 5.5MB"),
3585 IPW2100_ORD(CARD_DISABLED, "Card Disabled"), 3516 IPW2100_ORD(STAT_RX_DUPLICATE11,
3586 IPW2100_ORD(STAT_ROAM_INHIBIT, "times roaming was inhibited due to activity"), 3517 "duplicate rx packets at 11MB"),
3587 IPW2100_ORD(RSSI_AT_ASSN, "RSSI of associated AP at time of association"), 3518 IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"),
3588 IPW2100_ORD(STAT_ASSN_CAUSE1, "reassociation: no probe response or TX on hop"), 3519 IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"),
3589 IPW2100_ORD(STAT_ASSN_CAUSE2, "reassociation: poor tx/rx quality"), 3520 IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"),
3590 IPW2100_ORD(STAT_ASSN_CAUSE3, "reassociation: tx/rx quality (excessive AP load"), 3521 IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"),
3591 IPW2100_ORD(STAT_ASSN_CAUSE4, "reassociation: AP RSSI level"), 3522 IPW2100_ORD(STAT_RX_INVALID_PROTOCOL,
3592 IPW2100_ORD(STAT_ASSN_CAUSE5, "reassociations due to load leveling"), 3523 "rx frames with invalid protocol"),
3593 IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"), 3524 IPW2100_ORD(SYS_BOOT_TIME, "Boot time"),
3594 IPW2100_ORD(STAT_AUTH_RESP_FAIL,"times authentication response failed"), 3525 IPW2100_ORD(STAT_RX_NO_BUFFER,
3595 IPW2100_ORD(STATION_TABLE_CNT, "entries in association table"), 3526 "rx frames rejected due to no buffer"),
3596 IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"), 3527 IPW2100_ORD(STAT_RX_MISSING_FRAG,
3597 IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"), 3528 "rx frames dropped due to missing fragment"),
3598 IPW2100_ORD(COUNTRY_CODE, "IEEE country code as recv'd from beacon"), 3529 IPW2100_ORD(STAT_RX_ORPHAN_FRAG,
3599 IPW2100_ORD(COUNTRY_CHANNELS, "channels suported by country"), 3530 "rx frames dropped due to non-sequential fragment"),
3600 IPW2100_ORD(RESET_CNT, "adapter resets (warm)"), 3531 IPW2100_ORD(STAT_RX_ORPHAN_FRAME,
3601 IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"), 3532 "rx frames dropped due to unmatched 1st frame"),
3602 IPW2100_ORD(ANTENNA_DIVERSITY, "TRUE if antenna diversity is disabled"), 3533 IPW2100_ORD(STAT_RX_FRAG_AGEOUT,
3603 IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"), 3534 "rx frames dropped due to uncompleted frame"),
3604 IPW2100_ORD(OUR_FREQ, "current radio freq lower digits - channel ID"), 3535 IPW2100_ORD(STAT_RX_ICV_ERRORS,
3605 IPW2100_ORD(RTC_TIME, "current RTC time"), 3536 "ICV errors during decryption"),
3606 IPW2100_ORD(PORT_TYPE, "operating mode"), 3537 IPW2100_ORD(STAT_PSP_SUSPENSION, "times adapter suspended"),
3607 IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"), 3538 IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"),
3608 IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"), 3539 IPW2100_ORD(STAT_PSP_POLL_TIMEOUT,
3609 IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"), 3540 "poll response timeouts"),
3610 IPW2100_ORD(BASIC_RATES, "basic tx rates"), 3541 IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT,
3611 IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"), 3542 "timeouts waiting for last {broad,multi}cast pkt"),
3612 IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"), 3543 IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"),
3613 IPW2100_ORD(CAPABILITIES, "Management frame capability field"), 3544 IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"),
3614 IPW2100_ORD(AUTH_TYPE, "Type of authentication"), 3545 IPW2100_ORD(STAT_PSP_STATION_ID, "PSP Station ID"),
3615 IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"), 3546 IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"),
3616 IPW2100_ORD(RTS_THRESHOLD, "Min packet length for RTS handshaking"), 3547 IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,
3617 IPW2100_ORD(INT_MODE, "International mode"), 3548 "current calculation of % missed beacons"),
3618 IPW2100_ORD(FRAGMENTATION_THRESHOLD, "protocol frag threshold"), 3549 IPW2100_ORD(STAT_PERCENT_RETRIES,
3619 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS, "EEPROM offset in SRAM"), 3550 "current calculation of % missed tx retries"),
3620 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE, "EEPROM size in SRAM"), 3551 IPW2100_ORD(ASSOCIATED_AP_PTR,
3621 IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"), 3552 "0 if not associated, else pointer to AP table entry"),
3622 IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS, "EEPROM IBSS 11b channel set"), 3553 IPW2100_ORD(AVAILABLE_AP_CNT,
3623 IPW2100_ORD(MAC_VERSION, "MAC Version"), 3554 "AP's decsribed in the AP table"),
3624 IPW2100_ORD(MAC_REVISION, "MAC Revision"), 3555 IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"),
3625 IPW2100_ORD(RADIO_VERSION, "Radio Version"), 3556 IPW2100_ORD(STAT_AP_ASSNS, "associations"),
3626 IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"), 3557 IPW2100_ORD(STAT_ASSN_FAIL, "association failures"),
3627 IPW2100_ORD(UCODE_VERSION, "Ucode Version"), 3558 IPW2100_ORD(STAT_ASSN_RESP_FAIL,
3628}; 3559 "failures due to response fail"),
3629 3560 IPW2100_ORD(STAT_FULL_SCANS, "full scans"),
3561 IPW2100_ORD(CARD_DISABLED, "Card Disabled"),
3562 IPW2100_ORD(STAT_ROAM_INHIBIT,
3563 "times roaming was inhibited due to activity"),
3564 IPW2100_ORD(RSSI_AT_ASSN,
3565 "RSSI of associated AP at time of association"),
3566 IPW2100_ORD(STAT_ASSN_CAUSE1,
3567 "reassociation: no probe response or TX on hop"),
3568 IPW2100_ORD(STAT_ASSN_CAUSE2,
3569 "reassociation: poor tx/rx quality"),
3570 IPW2100_ORD(STAT_ASSN_CAUSE3,
3571 "reassociation: tx/rx quality (excessive AP load"),
3572 IPW2100_ORD(STAT_ASSN_CAUSE4,
3573 "reassociation: AP RSSI level"),
3574 IPW2100_ORD(STAT_ASSN_CAUSE5,
3575 "reassociations due to load leveling"),
3576 IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"),
3577 IPW2100_ORD(STAT_AUTH_RESP_FAIL,
3578 "times authentication response failed"),
3579 IPW2100_ORD(STATION_TABLE_CNT,
3580 "entries in association table"),
3581 IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"),
3582 IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"),
3583 IPW2100_ORD(COUNTRY_CODE,
3584 "IEEE country code as recv'd from beacon"),
3585 IPW2100_ORD(COUNTRY_CHANNELS,
3586 "channels suported by country"),
3587 IPW2100_ORD(RESET_CNT, "adapter resets (warm)"),
3588 IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"),
3589 IPW2100_ORD(ANTENNA_DIVERSITY,
3590 "TRUE if antenna diversity is disabled"),
3591 IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"),
3592 IPW2100_ORD(OUR_FREQ,
3593 "current radio freq lower digits - channel ID"),
3594 IPW2100_ORD(RTC_TIME, "current RTC time"),
3595 IPW2100_ORD(PORT_TYPE, "operating mode"),
3596 IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"),
3597 IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"),
3598 IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"),
3599 IPW2100_ORD(BASIC_RATES, "basic tx rates"),
3600 IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"),
3601 IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"),
3602 IPW2100_ORD(CAPABILITIES,
3603 "Management frame capability field"),
3604 IPW2100_ORD(AUTH_TYPE, "Type of authentication"),
3605 IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"),
3606 IPW2100_ORD(RTS_THRESHOLD,
3607 "Min packet length for RTS handshaking"),
3608 IPW2100_ORD(INT_MODE, "International mode"),
3609 IPW2100_ORD(FRAGMENTATION_THRESHOLD,
3610 "protocol frag threshold"),
3611 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS,
3612 "EEPROM offset in SRAM"),
3613 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE,
3614 "EEPROM size in SRAM"),
3615 IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"),
3616 IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS,
3617 "EEPROM IBSS 11b channel set"),
3618 IPW2100_ORD(MAC_VERSION, "MAC Version"),
3619 IPW2100_ORD(MAC_REVISION, "MAC Revision"),
3620 IPW2100_ORD(RADIO_VERSION, "Radio Version"),
3621 IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"),
3622 IPW2100_ORD(UCODE_VERSION, "Ucode Version"),};
3630 3623
3631static ssize_t show_registers(struct device *d, struct device_attribute *attr, 3624static ssize_t show_registers(struct device *d, struct device_attribute *attr,
3632 char *buf) 3625 char *buf)
3633{ 3626{
3634 int i; 3627 int i;
3635 struct ipw2100_priv *priv = dev_get_drvdata(d); 3628 struct ipw2100_priv *priv = dev_get_drvdata(d);
3636 struct net_device *dev = priv->net_dev; 3629 struct net_device *dev = priv->net_dev;
3637 char * out = buf; 3630 char *out = buf;
3638 u32 val = 0; 3631 u32 val = 0;
3639 3632
3640 out += sprintf(out, "%30s [Address ] : Hex\n", "Register"); 3633 out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
@@ -3647,15 +3640,15 @@ static ssize_t show_registers(struct device *d, struct device_attribute *attr,
3647 3640
3648 return out - buf; 3641 return out - buf;
3649} 3642}
3650static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
3651 3643
3644static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
3652 3645
3653static ssize_t show_hardware(struct device *d, struct device_attribute *attr, 3646static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
3654 char *buf) 3647 char *buf)
3655{ 3648{
3656 struct ipw2100_priv *priv = dev_get_drvdata(d); 3649 struct ipw2100_priv *priv = dev_get_drvdata(d);
3657 struct net_device *dev = priv->net_dev; 3650 struct net_device *dev = priv->net_dev;
3658 char * out = buf; 3651 char *out = buf;
3659 int i; 3652 int i;
3660 3653
3661 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry"); 3654 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
@@ -3688,11 +3681,11 @@ static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
3688 } 3681 }
3689 return out - buf; 3682 return out - buf;
3690} 3683}
3691static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
3692 3684
3685static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
3693 3686
3694static ssize_t show_memory(struct device *d, struct device_attribute *attr, 3687static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3695 char *buf) 3688 char *buf)
3696{ 3689{
3697 struct ipw2100_priv *priv = dev_get_drvdata(d); 3690 struct ipw2100_priv *priv = dev_get_drvdata(d);
3698 struct net_device *dev = priv->net_dev; 3691 struct net_device *dev = priv->net_dev;
@@ -3708,10 +3701,13 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3708 /* sysfs provides us PAGE_SIZE buffer */ 3701 /* sysfs provides us PAGE_SIZE buffer */
3709 while (len < PAGE_SIZE - 128 && loop < 0x30000) { 3702 while (len < PAGE_SIZE - 128 && loop < 0x30000) {
3710 3703
3711 if (priv->snapshot[0]) for (i = 0; i < 4; i++) 3704 if (priv->snapshot[0])
3712 buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4); 3705 for (i = 0; i < 4; i++)
3713 else for (i = 0; i < 4; i++) 3706 buffer[i] =
3714 read_nic_dword(dev, loop + i * 4, &buffer[i]); 3707 *(u32 *) SNAPSHOT_ADDR(loop + i * 4);
3708 else
3709 for (i = 0; i < 4; i++)
3710 read_nic_dword(dev, loop + i * 4, &buffer[i]);
3715 3711
3716 if (priv->dump_raw) 3712 if (priv->dump_raw)
3717 len += sprintf(buf + len, 3713 len += sprintf(buf + len,
@@ -3719,26 +3715,26 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3719 "%c%c%c%c" 3715 "%c%c%c%c"
3720 "%c%c%c%c" 3716 "%c%c%c%c"
3721 "%c%c%c%c", 3717 "%c%c%c%c",
3722 ((u8*)buffer)[0x0], 3718 ((u8 *) buffer)[0x0],
3723 ((u8*)buffer)[0x1], 3719 ((u8 *) buffer)[0x1],
3724 ((u8*)buffer)[0x2], 3720 ((u8 *) buffer)[0x2],
3725 ((u8*)buffer)[0x3], 3721 ((u8 *) buffer)[0x3],
3726 ((u8*)buffer)[0x4], 3722 ((u8 *) buffer)[0x4],
3727 ((u8*)buffer)[0x5], 3723 ((u8 *) buffer)[0x5],
3728 ((u8*)buffer)[0x6], 3724 ((u8 *) buffer)[0x6],
3729 ((u8*)buffer)[0x7], 3725 ((u8 *) buffer)[0x7],
3730 ((u8*)buffer)[0x8], 3726 ((u8 *) buffer)[0x8],
3731 ((u8*)buffer)[0x9], 3727 ((u8 *) buffer)[0x9],
3732 ((u8*)buffer)[0xa], 3728 ((u8 *) buffer)[0xa],
3733 ((u8*)buffer)[0xb], 3729 ((u8 *) buffer)[0xb],
3734 ((u8*)buffer)[0xc], 3730 ((u8 *) buffer)[0xc],
3735 ((u8*)buffer)[0xd], 3731 ((u8 *) buffer)[0xd],
3736 ((u8*)buffer)[0xe], 3732 ((u8 *) buffer)[0xe],
3737 ((u8*)buffer)[0xf]); 3733 ((u8 *) buffer)[0xf]);
3738 else 3734 else
3739 len += sprintf(buf + len, "%s\n", 3735 len += sprintf(buf + len, "%s\n",
3740 snprint_line(line, sizeof(line), 3736 snprint_line(line, sizeof(line),
3741 (u8*)buffer, 16, loop)); 3737 (u8 *) buffer, 16, loop));
3742 loop += 16; 3738 loop += 16;
3743 } 3739 }
3744 3740
@@ -3746,44 +3742,44 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3746} 3742}
3747 3743
3748static ssize_t store_memory(struct device *d, struct device_attribute *attr, 3744static ssize_t store_memory(struct device *d, struct device_attribute *attr,
3749 const char *buf, size_t count) 3745 const char *buf, size_t count)
3750{ 3746{
3751 struct ipw2100_priv *priv = dev_get_drvdata(d); 3747 struct ipw2100_priv *priv = dev_get_drvdata(d);
3752 struct net_device *dev = priv->net_dev; 3748 struct net_device *dev = priv->net_dev;
3753 const char *p = buf; 3749 const char *p = buf;
3754 3750
3751 (void) dev; /* kill unused-var warning for debug-only code */
3752
3755 if (count < 1) 3753 if (count < 1)
3756 return count; 3754 return count;
3757 3755
3758 if (p[0] == '1' || 3756 if (p[0] == '1' ||
3759 (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) { 3757 (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
3760 IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n", 3758 IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n",
3761 dev->name); 3759 dev->name);
3762 priv->dump_raw = 1; 3760 priv->dump_raw = 1;
3763 3761
3764 } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' && 3762 } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
3765 tolower(p[1]) == 'f')) { 3763 tolower(p[1]) == 'f')) {
3766 IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n", 3764 IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n",
3767 dev->name); 3765 dev->name);
3768 priv->dump_raw = 0; 3766 priv->dump_raw = 0;
3769 3767
3770 } else if (tolower(p[0]) == 'r') { 3768 } else if (tolower(p[0]) == 'r') {
3771 IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n", 3769 IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n", dev->name);
3772 dev->name);
3773 ipw2100_snapshot_free(priv); 3770 ipw2100_snapshot_free(priv);
3774 3771
3775 } else 3772 } else
3776 IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, " 3773 IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, "
3777 "reset = clear memory snapshot\n", 3774 "reset = clear memory snapshot\n", dev->name);
3778 dev->name);
3779 3775
3780 return count; 3776 return count;
3781} 3777}
3782static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
3783 3778
3779static DEVICE_ATTR(memory, S_IWUSR | S_IRUGO, show_memory, store_memory);
3784 3780
3785static ssize_t show_ordinals(struct device *d, struct device_attribute *attr, 3781static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3786 char *buf) 3782 char *buf)
3787{ 3783{
3788 struct ipw2100_priv *priv = dev_get_drvdata(d); 3784 struct ipw2100_priv *priv = dev_get_drvdata(d);
3789 u32 val = 0; 3785 u32 val = 0;
@@ -3791,6 +3787,9 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3791 u32 val_len; 3787 u32 val_len;
3792 static int loop = 0; 3788 static int loop = 0;
3793 3789
3790 if (priv->status & STATUS_RF_KILL_MASK)
3791 return 0;
3792
3794 if (loop >= sizeof(ord_data) / sizeof(*ord_data)) 3793 if (loop >= sizeof(ord_data) / sizeof(*ord_data))
3795 loop = 0; 3794 loop = 0;
3796 3795
@@ -3814,14 +3813,14 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3814 3813
3815 return len; 3814 return len;
3816} 3815}
3817static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
3818 3816
3817static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
3819 3818
3820static ssize_t show_stats(struct device *d, struct device_attribute *attr, 3819static ssize_t show_stats(struct device *d, struct device_attribute *attr,
3821 char *buf) 3820 char *buf)
3822{ 3821{
3823 struct ipw2100_priv *priv = dev_get_drvdata(d); 3822 struct ipw2100_priv *priv = dev_get_drvdata(d);
3824 char * out = buf; 3823 char *out = buf;
3825 3824
3826 out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n", 3825 out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
3827 priv->interrupts, priv->tx_interrupts, 3826 priv->interrupts, priv->tx_interrupts,
@@ -3835,8 +3834,8 @@ static ssize_t show_stats(struct device *d, struct device_attribute *attr,
3835 3834
3836 return out - buf; 3835 return out - buf;
3837} 3836}
3838static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
3839 3837
3838static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
3840 3839
3841static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode) 3840static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3842{ 3841{
@@ -3864,19 +3863,18 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3864 priv->last_mode = priv->ieee->iw_mode; 3863 priv->last_mode = priv->ieee->iw_mode;
3865 priv->net_dev->type = ARPHRD_IEEE80211; 3864 priv->net_dev->type = ARPHRD_IEEE80211;
3866 break; 3865 break;
3867#endif /* CONFIG_IPW2100_MONITOR */ 3866#endif /* CONFIG_IPW2100_MONITOR */
3868 } 3867 }
3869 3868
3870 priv->ieee->iw_mode = mode; 3869 priv->ieee->iw_mode = mode;
3871 3870
3872#ifdef CONFIG_PM 3871#ifdef CONFIG_PM
3873 /* Indicate ipw2100_download_firmware download firmware 3872 /* Indicate ipw2100_download_firmware download firmware
3874 * from disk instead of memory. */ 3873 * from disk instead of memory. */
3875 ipw2100_firmware.version = 0; 3874 ipw2100_firmware.version = 0;
3876#endif 3875#endif
3877 3876
3878 printk(KERN_INFO "%s: Reseting on mode change.\n", 3877 printk(KERN_INFO "%s: Reseting on mode change.\n", priv->net_dev->name);
3879 priv->net_dev->name);
3880 priv->reset_backoff = 0; 3878 priv->reset_backoff = 0;
3881 schedule_reset(priv); 3879 schedule_reset(priv);
3882 3880
@@ -3884,12 +3882,12 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3884} 3882}
3885 3883
3886static ssize_t show_internals(struct device *d, struct device_attribute *attr, 3884static ssize_t show_internals(struct device *d, struct device_attribute *attr,
3887 char *buf) 3885 char *buf)
3888{ 3886{
3889 struct ipw2100_priv *priv = dev_get_drvdata(d); 3887 struct ipw2100_priv *priv = dev_get_drvdata(d);
3890 int len = 0; 3888 int len = 0;
3891 3889
3892#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" # y "\n", priv-> x) 3890#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" y "\n", priv-> x)
3893 3891
3894 if (priv->status & STATUS_ASSOCIATED) 3892 if (priv->status & STATUS_ASSOCIATED)
3895 len += sprintf(buf + len, "connected: %lu\n", 3893 len += sprintf(buf + len, "connected: %lu\n",
@@ -3897,55 +3895,60 @@ static ssize_t show_internals(struct device *d, struct device_attribute *attr,
3897 else 3895 else
3898 len += sprintf(buf + len, "not connected\n"); 3896 len += sprintf(buf + len, "not connected\n");
3899 3897
3900 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], p); 3898 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], "p");
3901 DUMP_VAR(status, 08lx); 3899 DUMP_VAR(status, "08lx");
3902 DUMP_VAR(config, 08lx); 3900 DUMP_VAR(config, "08lx");
3903 DUMP_VAR(capability, 08lx); 3901 DUMP_VAR(capability, "08lx");
3904 3902
3905 len += sprintf(buf + len, "last_rtc: %lu\n", (unsigned long)priv->last_rtc); 3903 len +=
3904 sprintf(buf + len, "last_rtc: %lu\n",
3905 (unsigned long)priv->last_rtc);
3906 3906
3907 DUMP_VAR(fatal_error, d); 3907 DUMP_VAR(fatal_error, "d");
3908 DUMP_VAR(stop_hang_check, d); 3908 DUMP_VAR(stop_hang_check, "d");
3909 DUMP_VAR(stop_rf_kill, d); 3909 DUMP_VAR(stop_rf_kill, "d");
3910 DUMP_VAR(messages_sent, d); 3910 DUMP_VAR(messages_sent, "d");
3911 3911
3912 DUMP_VAR(tx_pend_stat.value, d); 3912 DUMP_VAR(tx_pend_stat.value, "d");
3913 DUMP_VAR(tx_pend_stat.hi, d); 3913 DUMP_VAR(tx_pend_stat.hi, "d");
3914 3914
3915 DUMP_VAR(tx_free_stat.value, d); 3915 DUMP_VAR(tx_free_stat.value, "d");
3916 DUMP_VAR(tx_free_stat.lo, d); 3916 DUMP_VAR(tx_free_stat.lo, "d");
3917 3917
3918 DUMP_VAR(msg_free_stat.value, d); 3918 DUMP_VAR(msg_free_stat.value, "d");
3919 DUMP_VAR(msg_free_stat.lo, d); 3919 DUMP_VAR(msg_free_stat.lo, "d");
3920 3920
3921 DUMP_VAR(msg_pend_stat.value, d); 3921 DUMP_VAR(msg_pend_stat.value, "d");
3922 DUMP_VAR(msg_pend_stat.hi, d); 3922 DUMP_VAR(msg_pend_stat.hi, "d");
3923 3923
3924 DUMP_VAR(fw_pend_stat.value, d); 3924 DUMP_VAR(fw_pend_stat.value, "d");
3925 DUMP_VAR(fw_pend_stat.hi, d); 3925 DUMP_VAR(fw_pend_stat.hi, "d");
3926 3926
3927 DUMP_VAR(txq_stat.value, d); 3927 DUMP_VAR(txq_stat.value, "d");
3928 DUMP_VAR(txq_stat.lo, d); 3928 DUMP_VAR(txq_stat.lo, "d");
3929 3929
3930 DUMP_VAR(ieee->scans, d); 3930 DUMP_VAR(ieee->scans, "d");
3931 DUMP_VAR(reset_backoff, d); 3931 DUMP_VAR(reset_backoff, "d");
3932 3932
3933 return len; 3933 return len;
3934} 3934}
3935static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
3936 3935
3936static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
3937 3937
3938static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, 3938static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
3939 char *buf) 3939 char *buf)
3940{ 3940{
3941 struct ipw2100_priv *priv = dev_get_drvdata(d); 3941 struct ipw2100_priv *priv = dev_get_drvdata(d);
3942 char essid[IW_ESSID_MAX_SIZE + 1]; 3942 char essid[IW_ESSID_MAX_SIZE + 1];
3943 u8 bssid[ETH_ALEN]; 3943 u8 bssid[ETH_ALEN];
3944 u32 chan = 0; 3944 u32 chan = 0;
3945 char * out = buf; 3945 char *out = buf;
3946 int length; 3946 int length;
3947 int ret; 3947 int ret;
3948 3948
3949 if (priv->status & STATUS_RF_KILL_MASK)
3950 return 0;
3951
3949 memset(essid, 0, sizeof(essid)); 3952 memset(essid, 0, sizeof(essid));
3950 memset(bssid, 0, sizeof(bssid)); 3953 memset(bssid, 0, sizeof(bssid));
3951 3954
@@ -3976,8 +3979,8 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
3976 3979
3977 return out - buf; 3980 return out - buf;
3978} 3981}
3979static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
3980 3982
3983static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
3981 3984
3982#ifdef CONFIG_IPW_DEBUG 3985#ifdef CONFIG_IPW_DEBUG
3983static ssize_t show_debug_level(struct device_driver *d, char *buf) 3986static ssize_t show_debug_level(struct device_driver *d, char *buf)
@@ -3985,8 +3988,8 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
3985 return sprintf(buf, "0x%08X\n", ipw2100_debug_level); 3988 return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
3986} 3989}
3987 3990
3988static ssize_t store_debug_level(struct device_driver *d, const char *buf, 3991static ssize_t store_debug_level(struct device_driver *d,
3989 size_t count) 3992 const char *buf, size_t count)
3990{ 3993{
3991 char *p = (char *)buf; 3994 char *p = (char *)buf;
3992 u32 val; 3995 u32 val;
@@ -3999,28 +4002,26 @@ static ssize_t store_debug_level(struct device_driver *d, const char *buf,
3999 } else 4002 } else
4000 val = simple_strtoul(p, &p, 10); 4003 val = simple_strtoul(p, &p, 10);
4001 if (p == buf) 4004 if (p == buf)
4002 IPW_DEBUG_INFO(DRV_NAME 4005 IPW_DEBUG_INFO(": %s is not in hex or decimal form.\n", buf);
4003 ": %s is not in hex or decimal form.\n", buf);
4004 else 4006 else
4005 ipw2100_debug_level = val; 4007 ipw2100_debug_level = val;
4006 4008
4007 return strnlen(buf, count); 4009 return strnlen(buf, count);
4008} 4010}
4011
4009static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level, 4012static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
4010 store_debug_level); 4013 store_debug_level);
4011#endif /* CONFIG_IPW_DEBUG */ 4014#endif /* CONFIG_IPW_DEBUG */
4012
4013 4015
4014static ssize_t show_fatal_error(struct device *d, 4016static ssize_t show_fatal_error(struct device *d,
4015 struct device_attribute *attr, char *buf) 4017 struct device_attribute *attr, char *buf)
4016{ 4018{
4017 struct ipw2100_priv *priv = dev_get_drvdata(d); 4019 struct ipw2100_priv *priv = dev_get_drvdata(d);
4018 char *out = buf; 4020 char *out = buf;
4019 int i; 4021 int i;
4020 4022
4021 if (priv->fatal_error) 4023 if (priv->fatal_error)
4022 out += sprintf(out, "0x%08X\n", 4024 out += sprintf(out, "0x%08X\n", priv->fatal_error);
4023 priv->fatal_error);
4024 else 4025 else
4025 out += sprintf(out, "0\n"); 4026 out += sprintf(out, "0\n");
4026 4027
@@ -4038,24 +4039,26 @@ static ssize_t show_fatal_error(struct device *d,
4038} 4039}
4039 4040
4040static ssize_t store_fatal_error(struct device *d, 4041static ssize_t store_fatal_error(struct device *d,
4041 struct device_attribute *attr, const char *buf, size_t count) 4042 struct device_attribute *attr, const char *buf,
4043 size_t count)
4042{ 4044{
4043 struct ipw2100_priv *priv = dev_get_drvdata(d); 4045 struct ipw2100_priv *priv = dev_get_drvdata(d);
4044 schedule_reset(priv); 4046 schedule_reset(priv);
4045 return count; 4047 return count;
4046} 4048}
4047static DEVICE_ATTR(fatal_error, S_IWUSR|S_IRUGO, show_fatal_error, store_fatal_error);
4048 4049
4050static DEVICE_ATTR(fatal_error, S_IWUSR | S_IRUGO, show_fatal_error,
4051 store_fatal_error);
4049 4052
4050static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, 4053static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
4051 char *buf) 4054 char *buf)
4052{ 4055{
4053 struct ipw2100_priv *priv = dev_get_drvdata(d); 4056 struct ipw2100_priv *priv = dev_get_drvdata(d);
4054 return sprintf(buf, "%d\n", priv->ieee->scan_age); 4057 return sprintf(buf, "%d\n", priv->ieee->scan_age);
4055} 4058}
4056 4059
4057static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, 4060static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4058 const char *buf, size_t count) 4061 const char *buf, size_t count)
4059{ 4062{
4060 struct ipw2100_priv *priv = dev_get_drvdata(d); 4063 struct ipw2100_priv *priv = dev_get_drvdata(d);
4061 struct net_device *dev = priv->net_dev; 4064 struct net_device *dev = priv->net_dev;
@@ -4065,6 +4068,8 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4065 unsigned long val; 4068 unsigned long val;
4066 char *p = buffer; 4069 char *p = buffer;
4067 4070
4071 (void) dev; /* kill unused-var warning for debug-only code */
4072
4068 IPW_DEBUG_INFO("enter\n"); 4073 IPW_DEBUG_INFO("enter\n");
4069 4074
4070 strncpy(buffer, buf, len); 4075 strncpy(buffer, buf, len);
@@ -4078,8 +4083,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4078 } else 4083 } else
4079 val = simple_strtoul(p, &p, 10); 4084 val = simple_strtoul(p, &p, 10);
4080 if (p == buffer) { 4085 if (p == buffer) {
4081 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", 4086 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
4082 dev->name);
4083 } else { 4087 } else {
4084 priv->ieee->scan_age = val; 4088 priv->ieee->scan_age = val;
4085 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age); 4089 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
@@ -4088,11 +4092,11 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4088 IPW_DEBUG_INFO("exit\n"); 4092 IPW_DEBUG_INFO("exit\n");
4089 return len; 4093 return len;
4090} 4094}
4091static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
4092 4095
4096static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
4093 4097
4094static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, 4098static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
4095 char *buf) 4099 char *buf)
4096{ 4100{
4097 /* 0 - RF kill not enabled 4101 /* 0 - RF kill not enabled
4098 1 - SW based RF kill active (sysfs) 4102 1 - SW based RF kill active (sysfs)
@@ -4100,7 +4104,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
4100 3 - Both HW and SW baed RF kill active */ 4104 3 - Both HW and SW baed RF kill active */
4101 struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data; 4105 struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
4102 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) | 4106 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
4103 (rf_kill_active(priv) ? 0x2 : 0x0); 4107 (rf_kill_active(priv) ? 0x2 : 0x0);
4104 return sprintf(buf, "%i\n", val); 4108 return sprintf(buf, "%i\n", val);
4105} 4109}
4106 4110
@@ -4108,7 +4112,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4108{ 4112{
4109 if ((disable_radio ? 1 : 0) == 4113 if ((disable_radio ? 1 : 0) ==
4110 (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) 4114 (priv->status & STATUS_RF_KILL_SW ? 1 : 0))
4111 return 0 ; 4115 return 0;
4112 4116
4113 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", 4117 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
4114 disable_radio ? "OFF" : "ON"); 4118 disable_radio ? "OFF" : "ON");
@@ -4126,8 +4130,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4126 /* Make sure the RF_KILL check timer is running */ 4130 /* Make sure the RF_KILL check timer is running */
4127 priv->stop_rf_kill = 0; 4131 priv->stop_rf_kill = 0;
4128 cancel_delayed_work(&priv->rf_kill); 4132 cancel_delayed_work(&priv->rf_kill);
4129 queue_delayed_work(priv->workqueue, &priv->rf_kill, 4133 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
4130 HZ);
4131 } else 4134 } else
4132 schedule_reset(priv); 4135 schedule_reset(priv);
4133 } 4136 }
@@ -4137,14 +4140,14 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4137} 4140}
4138 4141
4139static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, 4142static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
4140 const char *buf, size_t count) 4143 const char *buf, size_t count)
4141{ 4144{
4142 struct ipw2100_priv *priv = dev_get_drvdata(d); 4145 struct ipw2100_priv *priv = dev_get_drvdata(d);
4143 ipw_radio_kill_sw(priv, buf[0] == '1'); 4146 ipw_radio_kill_sw(priv, buf[0] == '1');
4144 return count; 4147 return count;
4145} 4148}
4146static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill);
4147 4149
4150static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
4148 4151
4149static struct attribute *ipw2100_sysfs_entries[] = { 4152static struct attribute *ipw2100_sysfs_entries[] = {
4150 &dev_attr_hardware.attr, 4153 &dev_attr_hardware.attr,
@@ -4168,7 +4171,6 @@ static struct attribute_group ipw2100_attribute_group = {
4168 .attrs = ipw2100_sysfs_entries, 4171 .attrs = ipw2100_sysfs_entries,
4169}; 4172};
4170 4173
4171
4172static int status_queue_allocate(struct ipw2100_priv *priv, int entries) 4174static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
4173{ 4175{
4174 struct ipw2100_status_queue *q = &priv->status_queue; 4176 struct ipw2100_status_queue *q = &priv->status_queue;
@@ -4176,11 +4178,11 @@ static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
4176 IPW_DEBUG_INFO("enter\n"); 4178 IPW_DEBUG_INFO("enter\n");
4177 4179
4178 q->size = entries * sizeof(struct ipw2100_status); 4180 q->size = entries * sizeof(struct ipw2100_status);
4179 q->drv = (struct ipw2100_status *)pci_alloc_consistent( 4181 q->drv =
4180 priv->pci_dev, q->size, &q->nic); 4182 (struct ipw2100_status *)pci_alloc_consistent(priv->pci_dev,
4183 q->size, &q->nic);
4181 if (!q->drv) { 4184 if (!q->drv) {
4182 IPW_DEBUG_WARNING( 4185 IPW_DEBUG_WARNING("Can not allocate status queue.\n");
4183 "Can not allocate status queue.\n");
4184 return -ENOMEM; 4186 return -ENOMEM;
4185 } 4187 }
4186 4188
@@ -4196,9 +4198,9 @@ static void status_queue_free(struct ipw2100_priv *priv)
4196 IPW_DEBUG_INFO("enter\n"); 4198 IPW_DEBUG_INFO("enter\n");
4197 4199
4198 if (priv->status_queue.drv) { 4200 if (priv->status_queue.drv) {
4199 pci_free_consistent( 4201 pci_free_consistent(priv->pci_dev, priv->status_queue.size,
4200 priv->pci_dev, priv->status_queue.size, 4202 priv->status_queue.drv,
4201 priv->status_queue.drv, priv->status_queue.nic); 4203 priv->status_queue.nic);
4202 priv->status_queue.drv = NULL; 4204 priv->status_queue.drv = NULL;
4203 } 4205 }
4204 4206
@@ -4216,7 +4218,8 @@ static int bd_queue_allocate(struct ipw2100_priv *priv,
4216 q->size = entries * sizeof(struct ipw2100_bd); 4218 q->size = entries * sizeof(struct ipw2100_bd);
4217 q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic); 4219 q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic);
4218 if (!q->drv) { 4220 if (!q->drv) {
4219 IPW_DEBUG_INFO("can't allocate shared memory for buffer descriptors\n"); 4221 IPW_DEBUG_INFO
4222 ("can't allocate shared memory for buffer descriptors\n");
4220 return -ENOMEM; 4223 return -ENOMEM;
4221 } 4224 }
4222 memset(q->drv, 0, q->size); 4225 memset(q->drv, 0, q->size);
@@ -4226,8 +4229,7 @@ static int bd_queue_allocate(struct ipw2100_priv *priv,
4226 return 0; 4229 return 0;
4227} 4230}
4228 4231
4229static void bd_queue_free(struct ipw2100_priv *priv, 4232static void bd_queue_free(struct ipw2100_priv *priv, struct ipw2100_bd_queue *q)
4230 struct ipw2100_bd_queue *q)
4231{ 4233{
4232 IPW_DEBUG_INFO("enter\n"); 4234 IPW_DEBUG_INFO("enter\n");
4233 4235
@@ -4235,21 +4237,21 @@ static void bd_queue_free(struct ipw2100_priv *priv,
4235 return; 4237 return;
4236 4238
4237 if (q->drv) { 4239 if (q->drv) {
4238 pci_free_consistent(priv->pci_dev, 4240 pci_free_consistent(priv->pci_dev, q->size, q->drv, q->nic);
4239 q->size, q->drv, q->nic);
4240 q->drv = NULL; 4241 q->drv = NULL;
4241 } 4242 }
4242 4243
4243 IPW_DEBUG_INFO("exit\n"); 4244 IPW_DEBUG_INFO("exit\n");
4244} 4245}
4245 4246
4246static void bd_queue_initialize( 4247static void bd_queue_initialize(struct ipw2100_priv *priv,
4247 struct ipw2100_priv *priv, struct ipw2100_bd_queue * q, 4248 struct ipw2100_bd_queue *q, u32 base, u32 size,
4248 u32 base, u32 size, u32 r, u32 w) 4249 u32 r, u32 w)
4249{ 4250{
4250 IPW_DEBUG_INFO("enter\n"); 4251 IPW_DEBUG_INFO("enter\n");
4251 4252
4252 IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv, (u32)q->nic); 4253 IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv,
4254 (u32) q->nic);
4253 4255
4254 write_register(priv->net_dev, base, q->nic); 4256 write_register(priv->net_dev, base, q->nic);
4255 write_register(priv->net_dev, size, q->entries); 4257 write_register(priv->net_dev, size, q->entries);
@@ -4285,32 +4287,38 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4285 err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH); 4287 err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH);
4286 if (err) { 4288 if (err) {
4287 IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n", 4289 IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n",
4288 priv->net_dev->name); 4290 priv->net_dev->name);
4289 return err; 4291 return err;
4290 } 4292 }
4291 4293
4292 priv->tx_buffers = (struct ipw2100_tx_packet *)kmalloc( 4294 priv->tx_buffers =
4293 TX_PENDED_QUEUE_LENGTH * sizeof(struct ipw2100_tx_packet), 4295 (struct ipw2100_tx_packet *)kmalloc(TX_PENDED_QUEUE_LENGTH *
4294 GFP_ATOMIC); 4296 sizeof(struct
4297 ipw2100_tx_packet),
4298 GFP_ATOMIC);
4295 if (!priv->tx_buffers) { 4299 if (!priv->tx_buffers) {
4296 printk(KERN_ERR DRV_NAME ": %s: alloc failed form tx buffers.\n", 4300 printk(KERN_ERR DRV_NAME
4301 ": %s: alloc failed form tx buffers.\n",
4297 priv->net_dev->name); 4302 priv->net_dev->name);
4298 bd_queue_free(priv, &priv->tx_queue); 4303 bd_queue_free(priv, &priv->tx_queue);
4299 return -ENOMEM; 4304 return -ENOMEM;
4300 } 4305 }
4301 4306
4302 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) { 4307 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4303 v = pci_alloc_consistent( 4308 v = pci_alloc_consistent(priv->pci_dev,
4304 priv->pci_dev, sizeof(struct ipw2100_data_header), &p); 4309 sizeof(struct ipw2100_data_header),
4310 &p);
4305 if (!v) { 4311 if (!v) {
4306 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for tx " 4312 printk(KERN_ERR DRV_NAME
4307 "buffers.\n", priv->net_dev->name); 4313 ": %s: PCI alloc failed for tx " "buffers.\n",
4314 priv->net_dev->name);
4308 err = -ENOMEM; 4315 err = -ENOMEM;
4309 break; 4316 break;
4310 } 4317 }
4311 4318
4312 priv->tx_buffers[i].type = DATA; 4319 priv->tx_buffers[i].type = DATA;
4313 priv->tx_buffers[i].info.d_struct.data = (struct ipw2100_data_header*)v; 4320 priv->tx_buffers[i].info.d_struct.data =
4321 (struct ipw2100_data_header *)v;
4314 priv->tx_buffers[i].info.d_struct.data_phys = p; 4322 priv->tx_buffers[i].info.d_struct.data_phys = p;
4315 priv->tx_buffers[i].info.d_struct.txb = NULL; 4323 priv->tx_buffers[i].info.d_struct.txb = NULL;
4316 } 4324 }
@@ -4319,11 +4327,11 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4319 return 0; 4327 return 0;
4320 4328
4321 for (j = 0; j < i; j++) { 4329 for (j = 0; j < i; j++) {
4322 pci_free_consistent( 4330 pci_free_consistent(priv->pci_dev,
4323 priv->pci_dev, 4331 sizeof(struct ipw2100_data_header),
4324 sizeof(struct ipw2100_data_header), 4332 priv->tx_buffers[j].info.d_struct.data,
4325 priv->tx_buffers[j].info.d_struct.data, 4333 priv->tx_buffers[j].info.d_struct.
4326 priv->tx_buffers[j].info.d_struct.data_phys); 4334 data_phys);
4327 } 4335 }
4328 4336
4329 kfree(priv->tx_buffers); 4337 kfree(priv->tx_buffers);
@@ -4356,7 +4364,8 @@ static void ipw2100_tx_initialize(struct ipw2100_priv *priv)
4356 /* We simply drop any SKBs that have been queued for 4364 /* We simply drop any SKBs that have been queued for
4357 * transmit */ 4365 * transmit */
4358 if (priv->tx_buffers[i].info.d_struct.txb) { 4366 if (priv->tx_buffers[i].info.d_struct.txb) {
4359 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb); 4367 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
4368 txb);
4360 priv->tx_buffers[i].info.d_struct.txb = NULL; 4369 priv->tx_buffers[i].info.d_struct.txb = NULL;
4361 } 4370 }
4362 4371
@@ -4394,15 +4403,17 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
4394 4403
4395 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) { 4404 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4396 if (priv->tx_buffers[i].info.d_struct.txb) { 4405 if (priv->tx_buffers[i].info.d_struct.txb) {
4397 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb); 4406 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
4407 txb);
4398 priv->tx_buffers[i].info.d_struct.txb = NULL; 4408 priv->tx_buffers[i].info.d_struct.txb = NULL;
4399 } 4409 }
4400 if (priv->tx_buffers[i].info.d_struct.data) 4410 if (priv->tx_buffers[i].info.d_struct.data)
4401 pci_free_consistent( 4411 pci_free_consistent(priv->pci_dev,
4402 priv->pci_dev, 4412 sizeof(struct ipw2100_data_header),
4403 sizeof(struct ipw2100_data_header), 4413 priv->tx_buffers[i].info.d_struct.
4404 priv->tx_buffers[i].info.d_struct.data, 4414 data,
4405 priv->tx_buffers[i].info.d_struct.data_phys); 4415 priv->tx_buffers[i].info.d_struct.
4416 data_phys);
4406 } 4417 }
4407 4418
4408 kfree(priv->tx_buffers); 4419 kfree(priv->tx_buffers);
@@ -4411,8 +4422,6 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
4411 IPW_DEBUG_INFO("exit\n"); 4422 IPW_DEBUG_INFO("exit\n");
4412} 4423}
4413 4424
4414
4415
4416static int ipw2100_rx_allocate(struct ipw2100_priv *priv) 4425static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
4417{ 4426{
4418 int i, j, err = -EINVAL; 4427 int i, j, err = -EINVAL;
@@ -4542,14 +4551,13 @@ static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
4542 4551
4543 int err; 4552 int err;
4544 4553
4545 err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC, 4554 err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC, mac, &length);
4546 mac, &length);
4547 if (err) { 4555 if (err) {
4548 IPW_DEBUG_INFO("MAC address read failed\n"); 4556 IPW_DEBUG_INFO("MAC address read failed\n");
4549 return -EIO; 4557 return -EIO;
4550 } 4558 }
4551 IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n", 4559 IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n",
4552 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 4560 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4553 4561
4554 memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN); 4562 memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN);
4555 4563
@@ -4576,8 +4584,7 @@ static int ipw2100_set_mac_address(struct ipw2100_priv *priv, int batch_mode)
4576 IPW_DEBUG_INFO("enter\n"); 4584 IPW_DEBUG_INFO("enter\n");
4577 4585
4578 if (priv->config & CFG_CUSTOM_MAC) { 4586 if (priv->config & CFG_CUSTOM_MAC) {
4579 memcpy(cmd.host_command_parameters, priv->mac_addr, 4587 memcpy(cmd.host_command_parameters, priv->mac_addr, ETH_ALEN);
4580 ETH_ALEN);
4581 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); 4588 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
4582 } else 4589 } else
4583 memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr, 4590 memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr,
@@ -4614,7 +4621,8 @@ static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
4614 if (!batch_mode) { 4621 if (!batch_mode) {
4615 err = ipw2100_disable_adapter(priv); 4622 err = ipw2100_disable_adapter(priv);
4616 if (err) { 4623 if (err) {
4617 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 4624 printk(KERN_ERR DRV_NAME
4625 ": %s: Could not disable adapter %d\n",
4618 priv->net_dev->name, err); 4626 priv->net_dev->name, err);
4619 return err; 4627 return err;
4620 } 4628 }
@@ -4629,7 +4637,6 @@ static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
4629 return err; 4637 return err;
4630} 4638}
4631 4639
4632
4633static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel, 4640static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
4634 int batch_mode) 4641 int batch_mode)
4635{ 4642{
@@ -4660,8 +4667,7 @@ static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
4660 4667
4661 err = ipw2100_hw_send_command(priv, &cmd); 4668 err = ipw2100_hw_send_command(priv, &cmd);
4662 if (err) { 4669 if (err) {
4663 IPW_DEBUG_INFO("Failed to set channel to %d", 4670 IPW_DEBUG_INFO("Failed to set channel to %d", channel);
4664 channel);
4665 return err; 4671 return err;
4666 } 4672 }
4667 4673
@@ -4703,15 +4709,14 @@ static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
4703 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START; 4709 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START;
4704 4710
4705 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK | 4711 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK |
4706 IPW_CFG_BSS_MASK | 4712 IPW_CFG_BSS_MASK | IPW_CFG_802_1x_ENABLE;
4707 IPW_CFG_802_1x_ENABLE;
4708 4713
4709 if (!(priv->config & CFG_LONG_PREAMBLE)) 4714 if (!(priv->config & CFG_LONG_PREAMBLE))
4710 cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO; 4715 cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO;
4711 4716
4712 err = ipw2100_get_ordinal(priv, 4717 err = ipw2100_get_ordinal(priv,
4713 IPW_ORD_EEPROM_IBSS_11B_CHANNELS, 4718 IPW_ORD_EEPROM_IBSS_11B_CHANNELS,
4714 &ibss_mask, &len); 4719 &ibss_mask, &len);
4715 if (err) 4720 if (err)
4716 ibss_mask = IPW_IBSS_11B_DEFAULT_MASK; 4721 ibss_mask = IPW_IBSS_11B_DEFAULT_MASK;
4717 4722
@@ -4719,7 +4724,7 @@ static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
4719 cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask; 4724 cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask;
4720 4725
4721 /* 11b only */ 4726 /* 11b only */
4722 /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A;*/ 4727 /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A; */
4723 4728
4724 err = ipw2100_hw_send_command(priv, &cmd); 4729 err = ipw2100_hw_send_command(priv, &cmd);
4725 if (err) 4730 if (err)
@@ -4783,8 +4788,7 @@ static int ipw2100_set_tx_rates(struct ipw2100_priv *priv, u32 rate,
4783 return 0; 4788 return 0;
4784} 4789}
4785 4790
4786static int ipw2100_set_power_mode(struct ipw2100_priv *priv, 4791static int ipw2100_set_power_mode(struct ipw2100_priv *priv, int power_level)
4787 int power_level)
4788{ 4792{
4789 struct host_command cmd = { 4793 struct host_command cmd = {
4790 .host_command = POWER_MODE, 4794 .host_command = POWER_MODE,
@@ -4805,11 +4809,10 @@ static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
4805 priv->power_mode = IPW_POWER_ENABLED | power_level; 4809 priv->power_mode = IPW_POWER_ENABLED | power_level;
4806 4810
4807#ifdef CONFIG_IPW2100_TX_POWER 4811#ifdef CONFIG_IPW2100_TX_POWER
4808 if (priv->port_type == IBSS && 4812 if (priv->port_type == IBSS && priv->adhoc_power != DFTL_IBSS_TX_POWER) {
4809 priv->adhoc_power != DFTL_IBSS_TX_POWER) {
4810 /* Set beacon interval */ 4813 /* Set beacon interval */
4811 cmd.host_command = TX_POWER_INDEX; 4814 cmd.host_command = TX_POWER_INDEX;
4812 cmd.host_command_parameters[0] = (u32)priv->adhoc_power; 4815 cmd.host_command_parameters[0] = (u32) priv->adhoc_power;
4813 4816
4814 err = ipw2100_hw_send_command(priv, &cmd); 4817 err = ipw2100_hw_send_command(priv, &cmd);
4815 if (err) 4818 if (err)
@@ -4820,7 +4823,6 @@ static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
4820 return 0; 4823 return 0;
4821} 4824}
4822 4825
4823
4824static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold) 4826static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold)
4825{ 4827{
4826 struct host_command cmd = { 4828 struct host_command cmd = {
@@ -4925,8 +4927,7 @@ static int ipw2100_set_long_retry(struct ipw2100_priv *priv, u32 retry)
4925 return 0; 4927 return 0;
4926} 4928}
4927 4929
4928 4930static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid,
4929static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4930 int batch_mode) 4931 int batch_mode)
4931{ 4932{
4932 struct host_command cmd = { 4933 struct host_command cmd = {
@@ -4938,16 +4939,15 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4938 4939
4939#ifdef CONFIG_IPW_DEBUG 4940#ifdef CONFIG_IPW_DEBUG
4940 if (bssid != NULL) 4941 if (bssid != NULL)
4941 IPW_DEBUG_HC( 4942 IPW_DEBUG_HC("MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
4942 "MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", 4943 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
4943 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], 4944 bssid[5]);
4944 bssid[5]);
4945 else 4945 else
4946 IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n"); 4946 IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n");
4947#endif 4947#endif
4948 /* if BSSID is empty then we disable mandatory bssid mode */ 4948 /* if BSSID is empty then we disable mandatory bssid mode */
4949 if (bssid != NULL) 4949 if (bssid != NULL)
4950 memcpy((u8 *)cmd.host_command_parameters, bssid, ETH_ALEN); 4950 memcpy(cmd.host_command_parameters, bssid, ETH_ALEN);
4951 4951
4952 if (!batch_mode) { 4952 if (!batch_mode) {
4953 err = ipw2100_disable_adapter(priv); 4953 err = ipw2100_disable_adapter(priv);
@@ -4963,7 +4963,6 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4963 return err; 4963 return err;
4964} 4964}
4965 4965
4966#ifdef CONFIG_IEEE80211_WPA
4967static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv) 4966static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4968{ 4967{
4969 struct host_command cmd = { 4968 struct host_command cmd = {
@@ -4987,42 +4986,10 @@ static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4987 4986
4988 return err; 4987 return err;
4989} 4988}
4990#endif
4991
4992/*
4993 * Pseudo code for setting up wpa_frame:
4994 */
4995#if 0
4996void x(struct ieee80211_assoc_frame *wpa_assoc)
4997{
4998 struct ipw2100_wpa_assoc_frame frame;
4999 frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
5000 IPW_WPA_LISTENINTERVAL |
5001 IPW_WPA_AP_ADDRESS;
5002 frame->capab_info = wpa_assoc->capab_info;
5003 frame->lisen_interval = wpa_assoc->listent_interval;
5004 memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
5005
5006 /* UNKNOWN -- I'm not postivive about this part; don't have any WPA
5007 * setup here to test it with.
5008 *
5009 * Walk the IEs in the wpa_assoc and figure out the total size of all
5010 * that data. Stick that into frame->var_ie_len. Then memcpy() all of
5011 * the IEs from wpa_frame into frame.
5012 */
5013 frame->var_ie_len = calculate_ie_len(wpa_assoc);
5014 memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
5015
5016 ipw2100_set_wpa_ie(priv, &frame, 0);
5017}
5018#endif
5019
5020
5021
5022 4989
5023static int ipw2100_set_wpa_ie(struct ipw2100_priv *, 4990static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
5024 struct ipw2100_wpa_assoc_frame *, int) 4991 struct ipw2100_wpa_assoc_frame *, int)
5025__attribute__ ((unused)); 4992 __attribute__ ((unused));
5026 4993
5027static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv, 4994static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv,
5028 struct ipw2100_wpa_assoc_frame *wpa_frame, 4995 struct ipw2100_wpa_assoc_frame *wpa_frame,
@@ -5076,7 +5043,7 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5076 .host_command_length = sizeof(struct security_info_params) 5043 .host_command_length = sizeof(struct security_info_params)
5077 }; 5044 };
5078 struct security_info_params *security = 5045 struct security_info_params *security =
5079 (struct security_info_params *)&cmd.host_command_parameters; 5046 (struct security_info_params *)&cmd.host_command_parameters;
5080 int err; 5047 int err;
5081 memset(security, 0, sizeof(*security)); 5048 memset(security, 0, sizeof(*security));
5082 5049
@@ -5094,25 +5061,25 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5094 break; 5061 break;
5095 case SEC_LEVEL_1: 5062 case SEC_LEVEL_1:
5096 security->allowed_ciphers = IPW_WEP40_CIPHER | 5063 security->allowed_ciphers = IPW_WEP40_CIPHER |
5097 IPW_WEP104_CIPHER; 5064 IPW_WEP104_CIPHER;
5098 break; 5065 break;
5099 case SEC_LEVEL_2: 5066 case SEC_LEVEL_2:
5100 security->allowed_ciphers = IPW_WEP40_CIPHER | 5067 security->allowed_ciphers = IPW_WEP40_CIPHER |
5101 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER; 5068 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER;
5102 break; 5069 break;
5103 case SEC_LEVEL_2_CKIP: 5070 case SEC_LEVEL_2_CKIP:
5104 security->allowed_ciphers = IPW_WEP40_CIPHER | 5071 security->allowed_ciphers = IPW_WEP40_CIPHER |
5105 IPW_WEP104_CIPHER | IPW_CKIP_CIPHER; 5072 IPW_WEP104_CIPHER | IPW_CKIP_CIPHER;
5106 break; 5073 break;
5107 case SEC_LEVEL_3: 5074 case SEC_LEVEL_3:
5108 security->allowed_ciphers = IPW_WEP40_CIPHER | 5075 security->allowed_ciphers = IPW_WEP40_CIPHER |
5109 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER; 5076 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER;
5110 break; 5077 break;
5111 } 5078 }
5112 5079
5113 IPW_DEBUG_HC( 5080 IPW_DEBUG_HC
5114 "SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n", 5081 ("SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n",
5115 security->auth_mode, security->allowed_ciphers, security_level); 5082 security->auth_mode, security->allowed_ciphers, security_level);
5116 5083
5117 security->replay_counters_number = 0; 5084 security->replay_counters_number = 0;
5118 5085
@@ -5130,8 +5097,7 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5130 return err; 5097 return err;
5131} 5098}
5132 5099
5133static int ipw2100_set_tx_power(struct ipw2100_priv *priv, 5100static int ipw2100_set_tx_power(struct ipw2100_priv *priv, u32 tx_power)
5134 u32 tx_power)
5135{ 5101{
5136 struct host_command cmd = { 5102 struct host_command cmd = {
5137 .host_command = TX_POWER_INDEX, 5103 .host_command = TX_POWER_INDEX,
@@ -5140,6 +5106,10 @@ static int ipw2100_set_tx_power(struct ipw2100_priv *priv,
5140 }; 5106 };
5141 int err = 0; 5107 int err = 0;
5142 5108
5109 if (tx_power != IPW_TX_POWER_DEFAULT)
5110 tx_power = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 /
5111 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
5112
5143 cmd.host_command_parameters[0] = tx_power; 5113 cmd.host_command_parameters[0] = tx_power;
5144 5114
5145 if (priv->ieee->iw_mode == IW_MODE_ADHOC) 5115 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
@@ -5185,7 +5155,6 @@ static int ipw2100_set_ibss_beacon_interval(struct ipw2100_priv *priv,
5185 return 0; 5155 return 0;
5186} 5156}
5187 5157
5188
5189void ipw2100_queues_initialize(struct ipw2100_priv *priv) 5158void ipw2100_queues_initialize(struct ipw2100_priv *priv)
5190{ 5159{
5191 ipw2100_tx_initialize(priv); 5160 ipw2100_tx_initialize(priv);
@@ -5203,13 +5172,12 @@ void ipw2100_queues_free(struct ipw2100_priv *priv)
5203int ipw2100_queues_allocate(struct ipw2100_priv *priv) 5172int ipw2100_queues_allocate(struct ipw2100_priv *priv)
5204{ 5173{
5205 if (ipw2100_tx_allocate(priv) || 5174 if (ipw2100_tx_allocate(priv) ||
5206 ipw2100_rx_allocate(priv) || 5175 ipw2100_rx_allocate(priv) || ipw2100_msg_allocate(priv))
5207 ipw2100_msg_allocate(priv))
5208 goto fail; 5176 goto fail;
5209 5177
5210 return 0; 5178 return 0;
5211 5179
5212 fail: 5180 fail:
5213 ipw2100_tx_free(priv); 5181 ipw2100_tx_free(priv);
5214 ipw2100_rx_free(priv); 5182 ipw2100_rx_free(priv);
5215 ipw2100_msg_free(priv); 5183 ipw2100_msg_free(priv);
@@ -5235,7 +5203,8 @@ static int ipw2100_set_wep_flags(struct ipw2100_priv *priv, u32 flags,
5235 if (!batch_mode) { 5203 if (!batch_mode) {
5236 err = ipw2100_disable_adapter(priv); 5204 err = ipw2100_disable_adapter(priv);
5237 if (err) { 5205 if (err) {
5238 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5206 printk(KERN_ERR DRV_NAME
5207 ": %s: Could not disable adapter %d\n",
5239 priv->net_dev->name, err); 5208 priv->net_dev->name, err);
5240 return err; 5209 return err;
5241 } 5210 }
@@ -5262,7 +5231,6 @@ struct ipw2100_wep_key {
5262#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4] 5231#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4]
5263#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10] 5232#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10]
5264 5233
5265
5266/** 5234/**
5267 * Set a the wep key 5235 * Set a the wep key
5268 * 5236 *
@@ -5287,11 +5255,11 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
5287 .host_command_sequence = 0, 5255 .host_command_sequence = 0,
5288 .host_command_length = sizeof(struct ipw2100_wep_key), 5256 .host_command_length = sizeof(struct ipw2100_wep_key),
5289 }; 5257 };
5290 struct ipw2100_wep_key *wep_key = (void*)cmd.host_command_parameters; 5258 struct ipw2100_wep_key *wep_key = (void *)cmd.host_command_parameters;
5291 int err; 5259 int err;
5292 5260
5293 IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n", 5261 IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n",
5294 idx, keylen, len); 5262 idx, keylen, len);
5295 5263
5296 /* NOTE: We don't check cached values in case the firmware was reset 5264 /* NOTE: We don't check cached values in case the firmware was reset
5297 * or some other problem is occuring. If the user is setting the key, 5265 * or some other problem is occuring. If the user is setting the key,
@@ -5308,22 +5276,23 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
5308 /* Will be optimized out on debug not being configured in */ 5276 /* Will be optimized out on debug not being configured in */
5309 if (keylen == 0) 5277 if (keylen == 0)
5310 IPW_DEBUG_WEP("%s: Clearing key %d\n", 5278 IPW_DEBUG_WEP("%s: Clearing key %d\n",
5311 priv->net_dev->name, wep_key->idx); 5279 priv->net_dev->name, wep_key->idx);
5312 else if (keylen == 5) 5280 else if (keylen == 5)
5313 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n", 5281 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n",
5314 priv->net_dev->name, wep_key->idx, wep_key->len, 5282 priv->net_dev->name, wep_key->idx, wep_key->len,
5315 WEP_STR_64(wep_key->key)); 5283 WEP_STR_64(wep_key->key));
5316 else 5284 else
5317 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128 5285 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128
5318 "\n", 5286 "\n",
5319 priv->net_dev->name, wep_key->idx, wep_key->len, 5287 priv->net_dev->name, wep_key->idx, wep_key->len,
5320 WEP_STR_128(wep_key->key)); 5288 WEP_STR_128(wep_key->key));
5321 5289
5322 if (!batch_mode) { 5290 if (!batch_mode) {
5323 err = ipw2100_disable_adapter(priv); 5291 err = ipw2100_disable_adapter(priv);
5324 /* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */ 5292 /* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */
5325 if (err) { 5293 if (err) {
5326 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5294 printk(KERN_ERR DRV_NAME
5295 ": %s: Could not disable adapter %d\n",
5327 priv->net_dev->name, err); 5296 priv->net_dev->name, err);
5328 return err; 5297 return err;
5329 } 5298 }
@@ -5347,7 +5316,7 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5347 .host_command = WEP_KEY_INDEX, 5316 .host_command = WEP_KEY_INDEX,
5348 .host_command_sequence = 0, 5317 .host_command_sequence = 0,
5349 .host_command_length = 4, 5318 .host_command_length = 4,
5350 .host_command_parameters = { idx }, 5319 .host_command_parameters = {idx},
5351 }; 5320 };
5352 int err; 5321 int err;
5353 5322
@@ -5359,7 +5328,8 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5359 if (!batch_mode) { 5328 if (!batch_mode) {
5360 err = ipw2100_disable_adapter(priv); 5329 err = ipw2100_disable_adapter(priv);
5361 if (err) { 5330 if (err) {
5362 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5331 printk(KERN_ERR DRV_NAME
5332 ": %s: Could not disable adapter %d\n",
5363 priv->net_dev->name, err); 5333 priv->net_dev->name, err);
5364 return err; 5334 return err;
5365 } 5335 }
@@ -5374,9 +5344,7 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5374 return err; 5344 return err;
5375} 5345}
5376 5346
5377 5347static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
5378static int ipw2100_configure_security(struct ipw2100_priv *priv,
5379 int batch_mode)
5380{ 5348{
5381 int i, err, auth_mode, sec_level, use_group; 5349 int i, err, auth_mode, sec_level, use_group;
5382 5350
@@ -5389,40 +5357,42 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv,
5389 return err; 5357 return err;
5390 } 5358 }
5391 5359
5392 if (!priv->sec.enabled) { 5360 if (!priv->ieee->sec.enabled) {
5393 err = ipw2100_set_security_information( 5361 err =
5394 priv, IPW_AUTH_OPEN, SEC_LEVEL_0, 0, 1); 5362 ipw2100_set_security_information(priv, IPW_AUTH_OPEN,
5363 SEC_LEVEL_0, 0, 1);
5395 } else { 5364 } else {
5396 auth_mode = IPW_AUTH_OPEN; 5365 auth_mode = IPW_AUTH_OPEN;
5397 if ((priv->sec.flags & SEC_AUTH_MODE) && 5366 if ((priv->ieee->sec.flags & SEC_AUTH_MODE) &&
5398 (priv->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) 5367 (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
5399 auth_mode = IPW_AUTH_SHARED; 5368 auth_mode = IPW_AUTH_SHARED;
5400 5369
5401 sec_level = SEC_LEVEL_0; 5370 sec_level = SEC_LEVEL_0;
5402 if (priv->sec.flags & SEC_LEVEL) 5371 if (priv->ieee->sec.flags & SEC_LEVEL)
5403 sec_level = priv->sec.level; 5372 sec_level = priv->ieee->sec.level;
5404 5373
5405 use_group = 0; 5374 use_group = 0;
5406 if (priv->sec.flags & SEC_UNICAST_GROUP) 5375 if (priv->ieee->sec.flags & SEC_UNICAST_GROUP)
5407 use_group = priv->sec.unicast_uses_group; 5376 use_group = priv->ieee->sec.unicast_uses_group;
5408 5377
5409 err = ipw2100_set_security_information( 5378 err =
5410 priv, auth_mode, sec_level, use_group, 1); 5379 ipw2100_set_security_information(priv, auth_mode, sec_level,
5380 use_group, 1);
5411 } 5381 }
5412 5382
5413 if (err) 5383 if (err)
5414 goto exit; 5384 goto exit;
5415 5385
5416 if (priv->sec.enabled) { 5386 if (priv->ieee->sec.enabled) {
5417 for (i = 0; i < 4; i++) { 5387 for (i = 0; i < 4; i++) {
5418 if (!(priv->sec.flags & (1 << i))) { 5388 if (!(priv->ieee->sec.flags & (1 << i))) {
5419 memset(priv->sec.keys[i], 0, WEP_KEY_LEN); 5389 memset(priv->ieee->sec.keys[i], 0, WEP_KEY_LEN);
5420 priv->sec.key_sizes[i] = 0; 5390 priv->ieee->sec.key_sizes[i] = 0;
5421 } else { 5391 } else {
5422 err = ipw2100_set_key(priv, i, 5392 err = ipw2100_set_key(priv, i,
5423 priv->sec.keys[i], 5393 priv->ieee->sec.keys[i],
5424 priv->sec.key_sizes[i], 5394 priv->ieee->sec.
5425 1); 5395 key_sizes[i], 1);
5426 if (err) 5396 if (err)
5427 goto exit; 5397 goto exit;
5428 } 5398 }
@@ -5433,14 +5403,16 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv,
5433 5403
5434 /* Always enable privacy so the Host can filter WEP packets if 5404 /* Always enable privacy so the Host can filter WEP packets if
5435 * encrypted data is sent up */ 5405 * encrypted data is sent up */
5436 err = ipw2100_set_wep_flags( 5406 err =
5437 priv, priv->sec.enabled ? IPW_PRIVACY_CAPABLE : 0, 1); 5407 ipw2100_set_wep_flags(priv,
5408 priv->ieee->sec.
5409 enabled ? IPW_PRIVACY_CAPABLE : 0, 1);
5438 if (err) 5410 if (err)
5439 goto exit; 5411 goto exit;
5440 5412
5441 priv->status &= ~STATUS_SECURITY_UPDATED; 5413 priv->status &= ~STATUS_SECURITY_UPDATED;
5442 5414
5443 exit: 5415 exit:
5444 if (!batch_mode) 5416 if (!batch_mode)
5445 ipw2100_enable_adapter(priv); 5417 ipw2100_enable_adapter(priv);
5446 5418
@@ -5469,60 +5441,64 @@ static void shim__set_security(struct net_device *dev,
5469 5441
5470 for (i = 0; i < 4; i++) { 5442 for (i = 0; i < 4; i++) {
5471 if (sec->flags & (1 << i)) { 5443 if (sec->flags & (1 << i)) {
5472 priv->sec.key_sizes[i] = sec->key_sizes[i]; 5444 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
5473 if (sec->key_sizes[i] == 0) 5445 if (sec->key_sizes[i] == 0)
5474 priv->sec.flags &= ~(1 << i); 5446 priv->ieee->sec.flags &= ~(1 << i);
5475 else 5447 else
5476 memcpy(priv->sec.keys[i], sec->keys[i], 5448 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
5477 sec->key_sizes[i]); 5449 sec->key_sizes[i]);
5478 priv->sec.flags |= (1 << i); 5450 if (sec->level == SEC_LEVEL_1) {
5479 priv->status |= STATUS_SECURITY_UPDATED; 5451 priv->ieee->sec.flags |= (1 << i);
5452 priv->status |= STATUS_SECURITY_UPDATED;
5453 } else
5454 priv->ieee->sec.flags &= ~(1 << i);
5480 } 5455 }
5481 } 5456 }
5482 5457
5483 if ((sec->flags & SEC_ACTIVE_KEY) && 5458 if ((sec->flags & SEC_ACTIVE_KEY) &&
5484 priv->sec.active_key != sec->active_key) { 5459 priv->ieee->sec.active_key != sec->active_key) {
5485 if (sec->active_key <= 3) { 5460 if (sec->active_key <= 3) {
5486 priv->sec.active_key = sec->active_key; 5461 priv->ieee->sec.active_key = sec->active_key;
5487 priv->sec.flags |= SEC_ACTIVE_KEY; 5462 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
5488 } else 5463 } else
5489 priv->sec.flags &= ~SEC_ACTIVE_KEY; 5464 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
5490 5465
5491 priv->status |= STATUS_SECURITY_UPDATED; 5466 priv->status |= STATUS_SECURITY_UPDATED;
5492 } 5467 }
5493 5468
5494 if ((sec->flags & SEC_AUTH_MODE) && 5469 if ((sec->flags & SEC_AUTH_MODE) &&
5495 (priv->sec.auth_mode != sec->auth_mode)) { 5470 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
5496 priv->sec.auth_mode = sec->auth_mode; 5471 priv->ieee->sec.auth_mode = sec->auth_mode;
5497 priv->sec.flags |= SEC_AUTH_MODE; 5472 priv->ieee->sec.flags |= SEC_AUTH_MODE;
5498 priv->status |= STATUS_SECURITY_UPDATED; 5473 priv->status |= STATUS_SECURITY_UPDATED;
5499 } 5474 }
5500 5475
5501 if (sec->flags & SEC_ENABLED && 5476 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
5502 priv->sec.enabled != sec->enabled) { 5477 priv->ieee->sec.flags |= SEC_ENABLED;
5503 priv->sec.flags |= SEC_ENABLED; 5478 priv->ieee->sec.enabled = sec->enabled;
5504 priv->sec.enabled = sec->enabled;
5505 priv->status |= STATUS_SECURITY_UPDATED; 5479 priv->status |= STATUS_SECURITY_UPDATED;
5506 force_update = 1; 5480 force_update = 1;
5507 } 5481 }
5508 5482
5509 if (sec->flags & SEC_LEVEL && 5483 if (sec->flags & SEC_ENCRYPT)
5510 priv->sec.level != sec->level) { 5484 priv->ieee->sec.encrypt = sec->encrypt;
5511 priv->sec.level = sec->level; 5485
5512 priv->sec.flags |= SEC_LEVEL; 5486 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
5487 priv->ieee->sec.level = sec->level;
5488 priv->ieee->sec.flags |= SEC_LEVEL;
5513 priv->status |= STATUS_SECURITY_UPDATED; 5489 priv->status |= STATUS_SECURITY_UPDATED;
5514 } 5490 }
5515 5491
5516 IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n", 5492 IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n",
5517 priv->sec.flags & (1<<8) ? '1' : '0', 5493 priv->ieee->sec.flags & (1 << 8) ? '1' : '0',
5518 priv->sec.flags & (1<<7) ? '1' : '0', 5494 priv->ieee->sec.flags & (1 << 7) ? '1' : '0',
5519 priv->sec.flags & (1<<6) ? '1' : '0', 5495 priv->ieee->sec.flags & (1 << 6) ? '1' : '0',
5520 priv->sec.flags & (1<<5) ? '1' : '0', 5496 priv->ieee->sec.flags & (1 << 5) ? '1' : '0',
5521 priv->sec.flags & (1<<4) ? '1' : '0', 5497 priv->ieee->sec.flags & (1 << 4) ? '1' : '0',
5522 priv->sec.flags & (1<<3) ? '1' : '0', 5498 priv->ieee->sec.flags & (1 << 3) ? '1' : '0',
5523 priv->sec.flags & (1<<2) ? '1' : '0', 5499 priv->ieee->sec.flags & (1 << 2) ? '1' : '0',
5524 priv->sec.flags & (1<<1) ? '1' : '0', 5500 priv->ieee->sec.flags & (1 << 1) ? '1' : '0',
5525 priv->sec.flags & (1<<0) ? '1' : '0'); 5501 priv->ieee->sec.flags & (1 << 0) ? '1' : '0');
5526 5502
5527/* As a temporary work around to enable WPA until we figure out why 5503/* As a temporary work around to enable WPA until we figure out why
5528 * wpa_supplicant toggles the security capability of the driver, which 5504 * wpa_supplicant toggles the security capability of the driver, which
@@ -5531,7 +5507,7 @@ static void shim__set_security(struct net_device *dev,
5531 * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/ 5507 * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/
5532 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) 5508 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
5533 ipw2100_configure_security(priv, 0); 5509 ipw2100_configure_security(priv, 0);
5534done: 5510 done:
5535 up(&priv->action_sem); 5511 up(&priv->action_sem);
5536} 5512}
5537 5513
@@ -5556,7 +5532,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5556 5532
5557 return 0; 5533 return 0;
5558 } 5534 }
5559#endif /* CONFIG_IPW2100_MONITOR */ 5535#endif /* CONFIG_IPW2100_MONITOR */
5560 5536
5561 err = ipw2100_read_mac_address(priv); 5537 err = ipw2100_read_mac_address(priv);
5562 if (err) 5538 if (err)
@@ -5576,7 +5552,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5576 return err; 5552 return err;
5577 } 5553 }
5578 5554
5579 err = ipw2100_system_config(priv, batch_mode); 5555 err = ipw2100_system_config(priv, batch_mode);
5580 if (err) 5556 if (err)
5581 return err; 5557 return err;
5582 5558
@@ -5614,8 +5590,10 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5614 return err; 5590 return err;
5615 5591
5616 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 5592 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5617 err = ipw2100_set_ibss_beacon_interval( 5593 err =
5618 priv, priv->beacon_interval, batch_mode); 5594 ipw2100_set_ibss_beacon_interval(priv,
5595 priv->beacon_interval,
5596 batch_mode);
5619 if (err) 5597 if (err)
5620 return err; 5598 return err;
5621 5599
@@ -5625,18 +5603,17 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5625 } 5603 }
5626 5604
5627 /* 5605 /*
5628 err = ipw2100_set_fragmentation_threshold( 5606 err = ipw2100_set_fragmentation_threshold(
5629 priv, priv->frag_threshold, batch_mode); 5607 priv, priv->frag_threshold, batch_mode);
5630 if (err) 5608 if (err)
5631 return err; 5609 return err;
5632 */ 5610 */
5633 5611
5634 IPW_DEBUG_INFO("exit\n"); 5612 IPW_DEBUG_INFO("exit\n");
5635 5613
5636 return 0; 5614 return 0;
5637} 5615}
5638 5616
5639
5640/************************************************************************* 5617/*************************************************************************
5641 * 5618 *
5642 * EXTERNALLY CALLED METHODS 5619 * EXTERNALLY CALLED METHODS
@@ -5669,7 +5646,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
5669 ipw2100_reset_adapter(priv); 5646 ipw2100_reset_adapter(priv);
5670 return 0; 5647 return 0;
5671 5648
5672 done: 5649 done:
5673 up(&priv->action_sem); 5650 up(&priv->action_sem);
5674 return err; 5651 return err;
5675} 5652}
@@ -5708,7 +5685,7 @@ static int ipw2100_close(struct net_device *dev)
5708 /* Flush the TX queue ... */ 5685 /* Flush the TX queue ... */
5709 while (!list_empty(&priv->tx_pend_list)) { 5686 while (!list_empty(&priv->tx_pend_list)) {
5710 element = priv->tx_pend_list.next; 5687 element = priv->tx_pend_list.next;
5711 packet = list_entry(element, struct ipw2100_tx_packet, list); 5688 packet = list_entry(element, struct ipw2100_tx_packet, list);
5712 5689
5713 list_del(element); 5690 list_del(element);
5714 DEC_STAT(&priv->tx_pend_stat); 5691 DEC_STAT(&priv->tx_pend_stat);
@@ -5726,8 +5703,6 @@ static int ipw2100_close(struct net_device *dev)
5726 return 0; 5703 return 0;
5727} 5704}
5728 5705
5729
5730
5731/* 5706/*
5732 * TODO: Fix this function... its just wrong 5707 * TODO: Fix this function... its just wrong
5733 */ 5708 */
@@ -5747,7 +5722,6 @@ static void ipw2100_tx_timeout(struct net_device *dev)
5747 schedule_reset(priv); 5722 schedule_reset(priv);
5748} 5723}
5749 5724
5750
5751/* 5725/*
5752 * TODO: reimplement it so that it reads statistics 5726 * TODO: reimplement it so that it reads statistics
5753 * from the adapter using ordinal tables 5727 * from the adapter using ordinal tables
@@ -5761,11 +5735,10 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5761 return &priv->ieee->stats; 5735 return &priv->ieee->stats;
5762} 5736}
5763 5737
5764/* Support for wpa_supplicant. Will be replaced with WEXT once 5738#if WIRELESS_EXT < 18
5765 * they get WPA support. */ 5739/* Support for wpa_supplicant before WE-18, deprecated. */
5766#ifdef CONFIG_IEEE80211_WPA
5767 5740
5768/* following definitions must match definitions in driver_ipw2100.c */ 5741/* following definitions must match definitions in driver_ipw.c */
5769 5742
5770#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 5743#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
5771 5744
@@ -5796,25 +5769,26 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5796struct ipw2100_param { 5769struct ipw2100_param {
5797 u32 cmd; 5770 u32 cmd;
5798 u8 sta_addr[ETH_ALEN]; 5771 u8 sta_addr[ETH_ALEN];
5799 union { 5772 union {
5800 struct { 5773 struct {
5801 u8 name; 5774 u8 name;
5802 u32 value; 5775 u32 value;
5803 } wpa_param; 5776 } wpa_param;
5804 struct { 5777 struct {
5805 u32 len; 5778 u32 len;
5806 u8 *data; 5779 u8 reserved[32];
5780 u8 data[0];
5807 } wpa_ie; 5781 } wpa_ie;
5808 struct{ 5782 struct {
5809 int command; 5783 u32 command;
5810 int reason_code; 5784 u32 reason_code;
5811 } mlme; 5785 } mlme;
5812 struct { 5786 struct {
5813 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN]; 5787 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
5814 u8 set_tx; 5788 u8 set_tx;
5815 u32 err; 5789 u32 err;
5816 u8 idx; 5790 u8 idx;
5817 u8 seq[8]; /* sequence counter (set: RX, get: TX) */ 5791 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
5818 u16 key_len; 5792 u16 key_len;
5819 u8 key[0]; 5793 u8 key[0];
5820 } crypt; 5794 } crypt;
@@ -5822,38 +5796,24 @@ struct ipw2100_param {
5822 } u; 5796 } u;
5823}; 5797};
5824 5798
5825/* end of driver_ipw2100.c code */ 5799/* end of driver_ipw.c code */
5826 5800#endif /* WIRELESS_EXT < 18 */
5827static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value){
5828 5801
5829 struct ieee80211_device *ieee = priv->ieee; 5802static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
5830 struct ieee80211_security sec = { 5803{
5831 .flags = SEC_LEVEL | SEC_ENABLED, 5804 /* This is called when wpa_supplicant loads and closes the driver
5832 }; 5805 * interface. */
5833 int ret = 0; 5806 priv->ieee->wpa_enabled = value;
5834 5807 return 0;
5835 ieee->wpa_enabled = value;
5836
5837 if (value){
5838 sec.level = SEC_LEVEL_3;
5839 sec.enabled = 1;
5840 } else {
5841 sec.level = SEC_LEVEL_0;
5842 sec.enabled = 0;
5843 }
5844
5845 if (ieee->set_security)
5846 ieee->set_security(ieee->dev, &sec);
5847 else
5848 ret = -EOPNOTSUPP;
5849
5850 return ret;
5851} 5808}
5852 5809
5853#define AUTH_ALG_OPEN_SYSTEM 0x1 5810#if WIRELESS_EXT < 18
5854#define AUTH_ALG_SHARED_KEY 0x2 5811#define IW_AUTH_ALG_OPEN_SYSTEM 0x1
5812#define IW_AUTH_ALG_SHARED_KEY 0x2
5813#endif
5855 5814
5856static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){ 5815static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
5816{
5857 5817
5858 struct ieee80211_device *ieee = priv->ieee; 5818 struct ieee80211_device *ieee = priv->ieee;
5859 struct ieee80211_security sec = { 5819 struct ieee80211_security sec = {
@@ -5861,13 +5821,14 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
5861 }; 5821 };
5862 int ret = 0; 5822 int ret = 0;
5863 5823
5864 if (value & AUTH_ALG_SHARED_KEY){ 5824 if (value & IW_AUTH_ALG_SHARED_KEY) {
5865 sec.auth_mode = WLAN_AUTH_SHARED_KEY; 5825 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
5866 ieee->open_wep = 0; 5826 ieee->open_wep = 0;
5867 } else { 5827 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
5868 sec.auth_mode = WLAN_AUTH_OPEN; 5828 sec.auth_mode = WLAN_AUTH_OPEN;
5869 ieee->open_wep = 1; 5829 ieee->open_wep = 1;
5870 } 5830 } else
5831 return -EINVAL;
5871 5832
5872 if (ieee->set_security) 5833 if (ieee->set_security)
5873 ieee->set_security(ieee->dev, &sec); 5834 ieee->set_security(ieee->dev, &sec);
@@ -5877,103 +5838,135 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
5877 return ret; 5838 return ret;
5878} 5839}
5879 5840
5841void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
5842 char *wpa_ie, int wpa_ie_len)
5843{
5880 5844
5881static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value){ 5845 struct ipw2100_wpa_assoc_frame frame;
5882
5883 struct ipw2100_priv *priv = ieee80211_priv(dev);
5884 int ret=0;
5885 5846
5886 switch(name){ 5847 frame.fixed_ie_mask = 0;
5887 case IPW2100_PARAM_WPA_ENABLED:
5888 ret = ipw2100_wpa_enable(priv, value);
5889 break;
5890 5848
5891 case IPW2100_PARAM_TKIP_COUNTERMEASURES: 5849 /* copy WPA IE */
5892 priv->ieee->tkip_countermeasures=value; 5850 memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
5893 break; 5851 frame.var_ie_len = wpa_ie_len;
5894 5852
5895 case IPW2100_PARAM_DROP_UNENCRYPTED: 5853 /* make sure WPA is enabled */
5896 priv->ieee->drop_unencrypted=value; 5854 ipw2100_wpa_enable(priv, 1);
5897 break; 5855 ipw2100_set_wpa_ie(priv, &frame, 0);
5856}
5898 5857
5899 case IPW2100_PARAM_PRIVACY_INVOKED: 5858#if WIRELESS_EXT < 18
5900 priv->ieee->privacy_invoked=value; 5859static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5901 break; 5860{
5861 struct ipw2100_priv *priv = ieee80211_priv(dev);
5862 struct ieee80211_crypt_data *crypt;
5863 unsigned long flags;
5864 int ret = 0;
5902 5865
5903 case IPW2100_PARAM_AUTH_ALGS: 5866 switch (name) {
5904 ret = ipw2100_wpa_set_auth_algs(priv, value); 5867 case IPW2100_PARAM_WPA_ENABLED:
5905 break; 5868 ret = ipw2100_wpa_enable(priv, value);
5869 break;
5906 5870
5907 case IPW2100_PARAM_IEEE_802_1X: 5871 case IPW2100_PARAM_TKIP_COUNTERMEASURES:
5908 priv->ieee->ieee802_1x=value; 5872 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
5873 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
5909 break; 5874 break;
5910 5875
5911 default: 5876 flags = crypt->ops->get_flags(crypt->priv);
5912 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
5913 dev->name, name);
5914 ret = -EOPNOTSUPP;
5915 }
5916 5877
5917 return ret; 5878 if (value)
5918} 5879 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5880 else
5881 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5919 5882
5920static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason){ 5883 crypt->ops->set_flags(flags, crypt->priv);
5921 5884
5922 struct ipw2100_priv *priv = ieee80211_priv(dev); 5885 break;
5923 int ret=0;
5924 5886
5925 switch(command){ 5887 case IPW2100_PARAM_DROP_UNENCRYPTED:{
5926 case IPW2100_MLME_STA_DEAUTH: 5888 /* See IW_AUTH_DROP_UNENCRYPTED handling for details */
5927 // silently ignore 5889 struct ieee80211_security sec = {
5890 .flags = SEC_ENABLED,
5891 .enabled = value,
5892 };
5893 priv->ieee->drop_unencrypted = value;
5894 /* We only change SEC_LEVEL for open mode. Others
5895 * are set by ipw_wpa_set_encryption.
5896 */
5897 if (!value) {
5898 sec.flags |= SEC_LEVEL;
5899 sec.level = SEC_LEVEL_0;
5900 } else {
5901 sec.flags |= SEC_LEVEL;
5902 sec.level = SEC_LEVEL_1;
5903 }
5904 if (priv->ieee->set_security)
5905 priv->ieee->set_security(priv->ieee->dev, &sec);
5928 break; 5906 break;
5907 }
5929 5908
5930 case IPW2100_MLME_STA_DISASSOC: 5909 case IPW2100_PARAM_PRIVACY_INVOKED:
5931 ipw2100_disassociate_bssid(priv); 5910 priv->ieee->privacy_invoked = value;
5932 break; 5911 break;
5933 5912
5934 default: 5913 case IPW2100_PARAM_AUTH_ALGS:
5935 printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n", 5914 ret = ipw2100_wpa_set_auth_algs(priv, value);
5936 dev->name, command); 5915 break;
5937 ret = -EOPNOTSUPP; 5916
5917 case IPW2100_PARAM_IEEE_802_1X:
5918 priv->ieee->ieee802_1x = value;
5919 break;
5920
5921 default:
5922 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
5923 dev->name, name);
5924 ret = -EOPNOTSUPP;
5938 } 5925 }
5939 5926
5940 return ret; 5927 return ret;
5941} 5928}
5942 5929
5930static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason)
5931{
5943 5932
5944void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, 5933 struct ipw2100_priv *priv = ieee80211_priv(dev);
5945 char *wpa_ie, int wpa_ie_len){ 5934 int ret = 0;
5946 5935
5947 struct ipw2100_wpa_assoc_frame frame; 5936 switch (command) {
5937 case IPW2100_MLME_STA_DEAUTH:
5938 // silently ignore
5939 break;
5948 5940
5949 frame.fixed_ie_mask = 0; 5941 case IPW2100_MLME_STA_DISASSOC:
5942 ipw2100_disassociate_bssid(priv);
5943 break;
5950 5944
5951 /* copy WPA IE */ 5945 default:
5952 memcpy(frame.var_ie, wpa_ie, wpa_ie_len); 5946 printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
5953 frame.var_ie_len = wpa_ie_len; 5947 dev->name, command);
5948 ret = -EOPNOTSUPP;
5949 }
5954 5950
5955 /* make sure WPA is enabled */ 5951 return ret;
5956 ipw2100_wpa_enable(priv, 1);
5957 ipw2100_set_wpa_ie(priv, &frame, 0);
5958} 5952}
5959 5953
5960
5961static int ipw2100_wpa_set_wpa_ie(struct net_device *dev, 5954static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5962 struct ipw2100_param *param, int plen){ 5955 struct ipw2100_param *param, int plen)
5956{
5963 5957
5964 struct ipw2100_priv *priv = ieee80211_priv(dev); 5958 struct ipw2100_priv *priv = ieee80211_priv(dev);
5965 struct ieee80211_device *ieee = priv->ieee; 5959 struct ieee80211_device *ieee = priv->ieee;
5966 u8 *buf; 5960 u8 *buf;
5967 5961
5968 if (! ieee->wpa_enabled) 5962 if (!ieee->wpa_enabled)
5969 return -EOPNOTSUPP; 5963 return -EOPNOTSUPP;
5970 5964
5971 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || 5965 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
5972 (param->u.wpa_ie.len && 5966 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
5973 param->u.wpa_ie.data==NULL))
5974 return -EINVAL; 5967 return -EINVAL;
5975 5968
5976 if (param->u.wpa_ie.len){ 5969 if (param->u.wpa_ie.len) {
5977 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); 5970 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
5978 if (buf == NULL) 5971 if (buf == NULL)
5979 return -ENOMEM; 5972 return -ENOMEM;
@@ -5998,8 +5991,9 @@ static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5998/* implementation borrowed from hostap driver */ 5991/* implementation borrowed from hostap driver */
5999 5992
6000static int ipw2100_wpa_set_encryption(struct net_device *dev, 5993static int ipw2100_wpa_set_encryption(struct net_device *dev,
6001 struct ipw2100_param *param, int param_len){ 5994 struct ipw2100_param *param,
6002 5995 int param_len)
5996{
6003 int ret = 0; 5997 int ret = 0;
6004 struct ipw2100_priv *priv = ieee80211_priv(dev); 5998 struct ipw2100_priv *priv = ieee80211_priv(dev);
6005 struct ieee80211_device *ieee = priv->ieee; 5999 struct ieee80211_device *ieee = priv->ieee;
@@ -6014,9 +6008,10 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6014 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0'; 6008 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
6015 6009
6016 if (param_len != 6010 if (param_len !=
6017 (int) ((char *) param->u.crypt.key - (char *) param) + 6011 (int)((char *)param->u.crypt.key - (char *)param) +
6018 param->u.crypt.key_len){ 6012 param->u.crypt.key_len) {
6019 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, param->u.crypt.key_len); 6013 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
6014 param->u.crypt.key_len);
6020 return -EINVAL; 6015 return -EINVAL;
6021 } 6016 }
6022 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 6017 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
@@ -6029,17 +6024,19 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6029 return -EINVAL; 6024 return -EINVAL;
6030 } 6025 }
6031 6026
6027 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
6032 if (strcmp(param->u.crypt.alg, "none") == 0) { 6028 if (strcmp(param->u.crypt.alg, "none") == 0) {
6033 if (crypt){ 6029 if (crypt) {
6034 sec.enabled = 0; 6030 sec.enabled = 0;
6031 sec.encrypt = 0;
6035 sec.level = SEC_LEVEL_0; 6032 sec.level = SEC_LEVEL_0;
6036 sec.flags |= SEC_ENABLED | SEC_LEVEL; 6033 sec.flags |= SEC_LEVEL;
6037 ieee80211_crypt_delayed_deinit(ieee, crypt); 6034 ieee80211_crypt_delayed_deinit(ieee, crypt);
6038 } 6035 }
6039 goto done; 6036 goto done;
6040 } 6037 }
6041 sec.enabled = 1; 6038 sec.enabled = 1;
6042 sec.flags |= SEC_ENABLED; 6039 sec.encrypt = 1;
6043 6040
6044 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 6041 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6045 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { 6042 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
@@ -6054,7 +6051,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6054 } 6051 }
6055 if (ops == NULL) { 6052 if (ops == NULL) {
6056 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n", 6053 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
6057 dev->name, param->u.crypt.alg); 6054 dev->name, param->u.crypt.alg);
6058 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG; 6055 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
6059 ret = -EINVAL; 6056 ret = -EINVAL;
6060 goto done; 6057 goto done;
@@ -6065,21 +6062,20 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6065 6062
6066 ieee80211_crypt_delayed_deinit(ieee, crypt); 6063 ieee80211_crypt_delayed_deinit(ieee, crypt);
6067 6064
6068 new_crypt = (struct ieee80211_crypt_data *) 6065 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6069 kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6070 if (new_crypt == NULL) { 6066 if (new_crypt == NULL) {
6071 ret = -ENOMEM; 6067 ret = -ENOMEM;
6072 goto done; 6068 goto done;
6073 } 6069 }
6074 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
6075 new_crypt->ops = ops; 6070 new_crypt->ops = ops;
6076 if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) 6071 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
6077 new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); 6072 new_crypt->priv =
6073 new_crypt->ops->init(param->u.crypt.idx);
6078 6074
6079 if (new_crypt->priv == NULL) { 6075 if (new_crypt->priv == NULL) {
6080 kfree(new_crypt); 6076 kfree(new_crypt);
6081 param->u.crypt.err = 6077 param->u.crypt.err =
6082 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED; 6078 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
6083 ret = -EINVAL; 6079 ret = -EINVAL;
6084 goto done; 6080 goto done;
6085 } 6081 }
@@ -6091,24 +6087,25 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6091 (*crypt)->ops->set_key(param->u.crypt.key, 6087 (*crypt)->ops->set_key(param->u.crypt.key,
6092 param->u.crypt.key_len, param->u.crypt.seq, 6088 param->u.crypt.key_len, param->u.crypt.seq,
6093 (*crypt)->priv) < 0) { 6089 (*crypt)->priv) < 0) {
6094 IPW_DEBUG_INFO("%s: key setting failed\n", 6090 IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
6095 dev->name);
6096 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED; 6091 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
6097 ret = -EINVAL; 6092 ret = -EINVAL;
6098 goto done; 6093 goto done;
6099 } 6094 }
6100 6095
6101 if (param->u.crypt.set_tx){ 6096 if (param->u.crypt.set_tx) {
6102 ieee->tx_keyidx = param->u.crypt.idx; 6097 ieee->tx_keyidx = param->u.crypt.idx;
6103 sec.active_key = param->u.crypt.idx; 6098 sec.active_key = param->u.crypt.idx;
6104 sec.flags |= SEC_ACTIVE_KEY; 6099 sec.flags |= SEC_ACTIVE_KEY;
6105 } 6100 }
6106 6101
6107 if (ops->name != NULL){ 6102 if (ops->name != NULL) {
6108 6103
6109 if (strcmp(ops->name, "WEP") == 0) { 6104 if (strcmp(ops->name, "WEP") == 0) {
6110 memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key, param->u.crypt.key_len); 6105 memcpy(sec.keys[param->u.crypt.idx],
6111 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; 6106 param->u.crypt.key, param->u.crypt.key_len);
6107 sec.key_sizes[param->u.crypt.idx] =
6108 param->u.crypt.key_len;
6112 sec.flags |= (1 << param->u.crypt.idx); 6109 sec.flags |= (1 << param->u.crypt.idx);
6113 sec.flags |= SEC_LEVEL; 6110 sec.flags |= SEC_LEVEL;
6114 sec.level = SEC_LEVEL_1; 6111 sec.level = SEC_LEVEL_1;
@@ -6120,7 +6117,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6120 sec.level = SEC_LEVEL_3; 6117 sec.level = SEC_LEVEL_3;
6121 } 6118 }
6122 } 6119 }
6123 done: 6120 done:
6124 if (ieee->set_security) 6121 if (ieee->set_security)
6125 ieee->set_security(ieee->dev, &sec); 6122 ieee->set_security(ieee->dev, &sec);
6126 6123
@@ -6131,8 +6128,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6131 * the callbacks structures used to initialize the 802.11 stack. */ 6128 * the callbacks structures used to initialize the 802.11 stack. */
6132 if (ieee->reset_on_keychange && 6129 if (ieee->reset_on_keychange &&
6133 ieee->iw_mode != IW_MODE_INFRA && 6130 ieee->iw_mode != IW_MODE_INFRA &&
6134 ieee->reset_port && 6131 ieee->reset_port && ieee->reset_port(dev)) {
6135 ieee->reset_port(dev)) {
6136 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name); 6132 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
6137 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED; 6133 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
6138 return -EINVAL; 6134 return -EINVAL;
@@ -6141,11 +6137,11 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6141 return ret; 6137 return ret;
6142} 6138}
6143 6139
6144 6140static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p)
6145static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){ 6141{
6146 6142
6147 struct ipw2100_param *param; 6143 struct ipw2100_param *param;
6148 int ret=0; 6144 int ret = 0;
6149 6145
6150 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length); 6146 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
6151 6147
@@ -6156,12 +6152,12 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6156 if (param == NULL) 6152 if (param == NULL)
6157 return -ENOMEM; 6153 return -ENOMEM;
6158 6154
6159 if (copy_from_user(param, p->pointer, p->length)){ 6155 if (copy_from_user(param, p->pointer, p->length)) {
6160 kfree(param); 6156 kfree(param);
6161 return -EFAULT; 6157 return -EFAULT;
6162 } 6158 }
6163 6159
6164 switch (param->cmd){ 6160 switch (param->cmd) {
6165 6161
6166 case IPW2100_CMD_SET_WPA_PARAM: 6162 case IPW2100_CMD_SET_WPA_PARAM:
6167 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name, 6163 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
@@ -6182,8 +6178,9 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6182 break; 6178 break;
6183 6179
6184 default: 6180 default:
6185 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA supplicant request: %d\n", 6181 printk(KERN_ERR DRV_NAME
6186 dev->name, param->cmd); 6182 ": %s: Unknown WPA supplicant request: %d\n", dev->name,
6183 param->cmd);
6187 ret = -EOPNOTSUPP; 6184 ret = -EOPNOTSUPP;
6188 6185
6189 } 6186 }
@@ -6194,27 +6191,23 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6194 kfree(param); 6191 kfree(param);
6195 return ret; 6192 return ret;
6196} 6193}
6197#endif /* CONFIG_IEEE80211_WPA */
6198 6194
6199static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 6195static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6200{ 6196{
6201#ifdef CONFIG_IEEE80211_WPA 6197 struct iwreq *wrq = (struct iwreq *)rq;
6202 struct iwreq *wrq = (struct iwreq *) rq; 6198 int ret = -1;
6203 int ret=-1; 6199 switch (cmd) {
6204 switch (cmd){ 6200 case IPW2100_IOCTL_WPA_SUPPLICANT:
6205 case IPW2100_IOCTL_WPA_SUPPLICANT:
6206 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data); 6201 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
6207 return ret; 6202 return ret;
6208 6203
6209 default: 6204 default:
6210 return -EOPNOTSUPP; 6205 return -EOPNOTSUPP;
6211 } 6206 }
6212 6207
6213#endif /* CONFIG_IEEE80211_WPA */
6214
6215 return -EOPNOTSUPP; 6208 return -EOPNOTSUPP;
6216} 6209}
6217 6210#endif /* WIRELESS_EXT < 18 */
6218 6211
6219static void ipw_ethtool_get_drvinfo(struct net_device *dev, 6212static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6220 struct ethtool_drvinfo *info) 6213 struct ethtool_drvinfo *info)
@@ -6236,14 +6229,13 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6236 6229
6237static u32 ipw2100_ethtool_get_link(struct net_device *dev) 6230static u32 ipw2100_ethtool_get_link(struct net_device *dev)
6238{ 6231{
6239 struct ipw2100_priv *priv = ieee80211_priv(dev); 6232 struct ipw2100_priv *priv = ieee80211_priv(dev);
6240 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0; 6233 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
6241} 6234}
6242 6235
6243
6244static struct ethtool_ops ipw2100_ethtool_ops = { 6236static struct ethtool_ops ipw2100_ethtool_ops = {
6245 .get_link = ipw2100_ethtool_get_link, 6237 .get_link = ipw2100_ethtool_get_link,
6246 .get_drvinfo = ipw_ethtool_get_drvinfo, 6238 .get_drvinfo = ipw_ethtool_get_drvinfo,
6247}; 6239};
6248 6240
6249static void ipw2100_hang_check(void *adapter) 6241static void ipw2100_hang_check(void *adapter)
@@ -6288,7 +6280,6 @@ static void ipw2100_hang_check(void *adapter)
6288 spin_unlock_irqrestore(&priv->low_lock, flags); 6280 spin_unlock_irqrestore(&priv->low_lock, flags);
6289} 6281}
6290 6282
6291
6292static void ipw2100_rf_kill(void *adapter) 6283static void ipw2100_rf_kill(void *adapter)
6293{ 6284{
6294 struct ipw2100_priv *priv = adapter; 6285 struct ipw2100_priv *priv = adapter;
@@ -6313,7 +6304,7 @@ static void ipw2100_rf_kill(void *adapter)
6313 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still " 6304 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
6314 "enabled\n"); 6305 "enabled\n");
6315 6306
6316 exit_unlock: 6307 exit_unlock:
6317 spin_unlock_irqrestore(&priv->low_lock, flags); 6308 spin_unlock_irqrestore(&priv->low_lock, flags);
6318} 6309}
6319 6310
@@ -6321,11 +6312,10 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
6321 6312
6322/* Look into using netdev destructor to shutdown ieee80211? */ 6313/* Look into using netdev destructor to shutdown ieee80211? */
6323 6314
6324static struct net_device *ipw2100_alloc_device( 6315static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6325 struct pci_dev *pci_dev, 6316 void __iomem * base_addr,
6326 void __iomem *base_addr, 6317 unsigned long mem_start,
6327 unsigned long mem_start, 6318 unsigned long mem_len)
6328 unsigned long mem_len)
6329{ 6319{
6330 struct ipw2100_priv *priv; 6320 struct ipw2100_priv *priv;
6331 struct net_device *dev; 6321 struct net_device *dev;
@@ -6341,17 +6331,22 @@ static struct net_device *ipw2100_alloc_device(
6341 priv->ieee->hard_start_xmit = ipw2100_tx; 6331 priv->ieee->hard_start_xmit = ipw2100_tx;
6342 priv->ieee->set_security = shim__set_security; 6332 priv->ieee->set_security = shim__set_security;
6343 6333
6334 priv->ieee->perfect_rssi = -20;
6335 priv->ieee->worst_rssi = -85;
6336
6344 dev->open = ipw2100_open; 6337 dev->open = ipw2100_open;
6345 dev->stop = ipw2100_close; 6338 dev->stop = ipw2100_close;
6346 dev->init = ipw2100_net_init; 6339 dev->init = ipw2100_net_init;
6340#if WIRELESS_EXT < 18
6347 dev->do_ioctl = ipw2100_ioctl; 6341 dev->do_ioctl = ipw2100_ioctl;
6342#endif
6348 dev->get_stats = ipw2100_stats; 6343 dev->get_stats = ipw2100_stats;
6349 dev->ethtool_ops = &ipw2100_ethtool_ops; 6344 dev->ethtool_ops = &ipw2100_ethtool_ops;
6350 dev->tx_timeout = ipw2100_tx_timeout; 6345 dev->tx_timeout = ipw2100_tx_timeout;
6351 dev->wireless_handlers = &ipw2100_wx_handler_def; 6346 dev->wireless_handlers = &ipw2100_wx_handler_def;
6352 dev->get_wireless_stats = ipw2100_wx_wireless_stats; 6347 dev->get_wireless_stats = ipw2100_wx_wireless_stats;
6353 dev->set_mac_address = ipw2100_set_address; 6348 dev->set_mac_address = ipw2100_set_address;
6354 dev->watchdog_timeo = 3*HZ; 6349 dev->watchdog_timeo = 3 * HZ;
6355 dev->irq = 0; 6350 dev->irq = 0;
6356 6351
6357 dev->base_addr = (unsigned long)base_addr; 6352 dev->base_addr = (unsigned long)base_addr;
@@ -6364,22 +6359,19 @@ static struct net_device *ipw2100_alloc_device(
6364 * ends up causing problems. So, we just handle 6359 * ends up causing problems. So, we just handle
6365 * the WX extensions through the ipw2100_ioctl interface */ 6360 * the WX extensions through the ipw2100_ioctl interface */
6366 6361
6367
6368 /* memset() puts everything to 0, so we only have explicitely set 6362 /* memset() puts everything to 0, so we only have explicitely set
6369 * those values that need to be something else */ 6363 * those values that need to be something else */
6370 6364
6371 /* If power management is turned on, default to AUTO mode */ 6365 /* If power management is turned on, default to AUTO mode */
6372 priv->power_mode = IPW_POWER_AUTO; 6366 priv->power_mode = IPW_POWER_AUTO;
6373 6367
6374 6368#ifdef CONFIG_IPW2100_MONITOR
6375 6369 priv->config |= CFG_CRC_CHECK;
6376#ifdef CONFIG_IEEE80211_WPA 6370#endif
6377 priv->ieee->wpa_enabled = 0; 6371 priv->ieee->wpa_enabled = 0;
6378 priv->ieee->tkip_countermeasures = 0;
6379 priv->ieee->drop_unencrypted = 0; 6372 priv->ieee->drop_unencrypted = 0;
6380 priv->ieee->privacy_invoked = 0; 6373 priv->ieee->privacy_invoked = 0;
6381 priv->ieee->ieee802_1x = 1; 6374 priv->ieee->ieee802_1x = 1;
6382#endif /* CONFIG_IEEE80211_WPA */
6383 6375
6384 /* Set module parameters */ 6376 /* Set module parameters */
6385 switch (mode) { 6377 switch (mode) {
@@ -6401,8 +6393,7 @@ static struct net_device *ipw2100_alloc_device(
6401 priv->status |= STATUS_RF_KILL_SW; 6393 priv->status |= STATUS_RF_KILL_SW;
6402 6394
6403 if (channel != 0 && 6395 if (channel != 0 &&
6404 ((channel >= REG_MIN_CHANNEL) && 6396 ((channel >= REG_MIN_CHANNEL) && (channel <= REG_MAX_CHANNEL))) {
6405 (channel <= REG_MAX_CHANNEL))) {
6406 priv->config |= CFG_STATIC_CHANNEL; 6397 priv->config |= CFG_STATIC_CHANNEL;
6407 priv->channel = channel; 6398 priv->channel = channel;
6408 } 6399 }
@@ -6441,12 +6432,8 @@ static struct net_device *ipw2100_alloc_device(
6441 INIT_LIST_HEAD(&priv->fw_pend_list); 6432 INIT_LIST_HEAD(&priv->fw_pend_list);
6442 INIT_STAT(&priv->fw_pend_stat); 6433 INIT_STAT(&priv->fw_pend_stat);
6443 6434
6444
6445#ifdef CONFIG_SOFTWARE_SUSPEND2
6446 priv->workqueue = create_workqueue(DRV_NAME, 0);
6447#else
6448 priv->workqueue = create_workqueue(DRV_NAME); 6435 priv->workqueue = create_workqueue(DRV_NAME);
6449#endif 6436
6450 INIT_WORK(&priv->reset_work, 6437 INIT_WORK(&priv->reset_work,
6451 (void (*)(void *))ipw2100_reset_adapter, priv); 6438 (void (*)(void *))ipw2100_reset_adapter, priv);
6452 INIT_WORK(&priv->security_work, 6439 INIT_WORK(&priv->security_work,
@@ -6535,7 +6522,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6535 return err; 6522 return err;
6536 } 6523 }
6537 6524
6538 /* We disable the RETRY_TIMEOUT register (0x41) to keep 6525 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6539 * PCI Tx retries from interfering with C3 CPU state */ 6526 * PCI Tx retries from interfering with C3 CPU state */
6540 pci_read_config_dword(pci_dev, 0x40, &val); 6527 pci_read_config_dword(pci_dev, 0x40, &val);
6541 if ((val & 0x0000ff00) != 0) 6528 if ((val & 0x0000ff00) != 0)
@@ -6566,12 +6553,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6566 ipw2100_queues_initialize(priv); 6553 ipw2100_queues_initialize(priv);
6567 6554
6568 err = request_irq(pci_dev->irq, 6555 err = request_irq(pci_dev->irq,
6569 ipw2100_interrupt, SA_SHIRQ, 6556 ipw2100_interrupt, SA_SHIRQ, dev->name, priv);
6570 dev->name, priv);
6571 if (err) { 6557 if (err) {
6572 printk(KERN_WARNING DRV_NAME 6558 printk(KERN_WARNING DRV_NAME
6573 "Error calling request_irq: %d.\n", 6559 "Error calling request_irq: %d.\n", pci_dev->irq);
6574 pci_dev->irq);
6575 goto fail; 6560 goto fail;
6576 } 6561 }
6577 dev->irq = pci_dev->irq; 6562 dev->irq = pci_dev->irq;
@@ -6606,7 +6591,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6606 6591
6607 /* perform this after register_netdev so that dev->name is set */ 6592 /* perform this after register_netdev so that dev->name is set */
6608 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6593 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6609 netif_carrier_off(dev);
6610 6594
6611 /* If the RF Kill switch is disabled, go ahead and complete the 6595 /* If the RF Kill switch is disabled, go ahead and complete the
6612 * startup sequence */ 6596 * startup sequence */
@@ -6634,10 +6618,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6634 6618
6635 return 0; 6619 return 0;
6636 6620
6637 fail_unlock: 6621 fail_unlock:
6638 up(&priv->action_sem); 6622 up(&priv->action_sem);
6639 6623
6640 fail: 6624 fail:
6641 if (dev) { 6625 if (dev) {
6642 if (registered) 6626 if (registered)
6643 unregister_netdev(dev); 6627 unregister_netdev(dev);
@@ -6653,7 +6637,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6653 6637
6654 /* These are safe to call even if they weren't allocated */ 6638 /* These are safe to call even if they weren't allocated */
6655 ipw2100_queues_free(priv); 6639 ipw2100_queues_free(priv);
6656 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6640 sysfs_remove_group(&pci_dev->dev.kobj,
6641 &ipw2100_attribute_group);
6657 6642
6658 free_ieee80211(dev); 6643 free_ieee80211(dev);
6659 pci_set_drvdata(pci_dev, NULL); 6644 pci_set_drvdata(pci_dev, NULL);
@@ -6679,7 +6664,8 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6679 priv->status &= ~STATUS_INITIALIZED; 6664 priv->status &= ~STATUS_INITIALIZED;
6680 6665
6681 dev = priv->net_dev; 6666 dev = priv->net_dev;
6682 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6667 sysfs_remove_group(&pci_dev->dev.kobj,
6668 &ipw2100_attribute_group);
6683 6669
6684#ifdef CONFIG_PM 6670#ifdef CONFIG_PM
6685 if (ipw2100_firmware.version) 6671 if (ipw2100_firmware.version)
@@ -6721,19 +6707,13 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6721 IPW_DEBUG_INFO("exit\n"); 6707 IPW_DEBUG_INFO("exit\n");
6722} 6708}
6723 6709
6724
6725#ifdef CONFIG_PM 6710#ifdef CONFIG_PM
6726#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
6727static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
6728#else
6729static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state) 6711static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6730#endif
6731{ 6712{
6732 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); 6713 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6733 struct net_device *dev = priv->net_dev; 6714 struct net_device *dev = priv->net_dev;
6734 6715
6735 IPW_DEBUG_INFO("%s: Going into suspend...\n", 6716 IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name);
6736 dev->name);
6737 6717
6738 down(&priv->action_sem); 6718 down(&priv->action_sem);
6739 if (priv->status & STATUS_INITIALIZED) { 6719 if (priv->status & STATUS_INITIALIZED) {
@@ -6745,7 +6725,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6745 netif_device_detach(dev); 6725 netif_device_detach(dev);
6746 6726
6747 pci_save_state(pci_dev); 6727 pci_save_state(pci_dev);
6748 pci_disable_device (pci_dev); 6728 pci_disable_device(pci_dev);
6749 pci_set_power_state(pci_dev, PCI_D3hot); 6729 pci_set_power_state(pci_dev, PCI_D3hot);
6750 6730
6751 up(&priv->action_sem); 6731 up(&priv->action_sem);
@@ -6764,8 +6744,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6764 6744
6765 down(&priv->action_sem); 6745 down(&priv->action_sem);
6766 6746
6767 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", 6747 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name);
6768 dev->name);
6769 6748
6770 pci_set_power_state(pci_dev, PCI_D0); 6749 pci_set_power_state(pci_dev, PCI_D0);
6771 pci_enable_device(pci_dev); 6750 pci_enable_device(pci_dev);
@@ -6785,9 +6764,9 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6785 * the queue of needed */ 6764 * the queue of needed */
6786 netif_device_attach(dev); 6765 netif_device_attach(dev);
6787 6766
6788 /* Bring the device back up */ 6767 /* Bring the device back up */
6789 if (!(priv->status & STATUS_RF_KILL_SW)) 6768 if (!(priv->status & STATUS_RF_KILL_SW))
6790 ipw2100_up(priv, 0); 6769 ipw2100_up(priv, 0);
6791 6770
6792 up(&priv->action_sem); 6771 up(&priv->action_sem);
6793 6772
@@ -6795,56 +6774,55 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6795} 6774}
6796#endif 6775#endif
6797 6776
6798
6799#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x } 6777#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
6800 6778
6801static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = { 6779static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
6802 IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */ 6780 IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */
6803 IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */ 6781 IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */
6804 IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */ 6782 IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */
6805 IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */ 6783 IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */
6806 IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */ 6784 IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */
6807 IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */ 6785 IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */
6808 IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */ 6786 IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */
6809 IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */ 6787 IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */
6810 IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */ 6788 IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */
6811 IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */ 6789 IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */
6812 IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */ 6790 IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */
6813 IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */ 6791 IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */
6814 IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */ 6792 IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */
6815 6793
6816 IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */ 6794 IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */
6817 IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */ 6795 IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */
6818 IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */ 6796 IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */
6819 IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */ 6797 IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */
6820 IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */ 6798 IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */
6821 6799
6822 IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */ 6800 IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */
6823 IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */ 6801 IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */
6824 IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */ 6802 IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */
6825 IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */ 6803 IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */
6826 IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */ 6804 IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */
6827 IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */ 6805 IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */
6828 IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */ 6806 IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */
6829 6807
6830 IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */ 6808 IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */
6831 6809
6832 IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */ 6810 IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */
6833 IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */ 6811 IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */
6834 IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */ 6812 IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */
6835 IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */ 6813 IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */
6836 IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */ 6814 IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */
6837 IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */ 6815 IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */
6838 IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */ 6816 IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */
6839 6817
6840 IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */ 6818 IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */
6841 IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */ 6819 IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */
6842 IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */ 6820 IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */
6843 IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */ 6821 IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */
6844 IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */ 6822 IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */
6845 IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */ 6823 IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */
6846 6824
6847 IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */ 6825 IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */
6848 {0,}, 6826 {0,},
6849}; 6827};
6850 6828
@@ -6861,7 +6839,6 @@ static struct pci_driver ipw2100_pci_driver = {
6861#endif 6839#endif
6862}; 6840};
6863 6841
6864
6865/** 6842/**
6866 * Initialize the ipw2100 driver/module 6843 * Initialize the ipw2100 driver/module
6867 * 6844 *
@@ -6878,10 +6855,6 @@ static int __init ipw2100_init(void)
6878 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); 6855 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
6879 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT); 6856 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
6880 6857
6881#ifdef CONFIG_IEEE80211_NOWEP
6882 IPW_DEBUG_INFO(DRV_NAME ": Compiled with WEP disabled.\n");
6883#endif
6884
6885 ret = pci_module_init(&ipw2100_pci_driver); 6858 ret = pci_module_init(&ipw2100_pci_driver);
6886 6859
6887#ifdef CONFIG_IPW_DEBUG 6860#ifdef CONFIG_IPW_DEBUG
@@ -6893,7 +6866,6 @@ static int __init ipw2100_init(void)
6893 return ret; 6866 return ret;
6894} 6867}
6895 6868
6896
6897/** 6869/**
6898 * Cleanup ipw2100 driver registration 6870 * Cleanup ipw2100 driver registration
6899 */ 6871 */
@@ -6949,7 +6921,6 @@ static int ipw2100_wx_get_name(struct net_device *dev,
6949 return 0; 6921 return 0;
6950} 6922}
6951 6923
6952
6953static int ipw2100_wx_set_freq(struct net_device *dev, 6924static int ipw2100_wx_set_freq(struct net_device *dev,
6954 struct iw_request_info *info, 6925 struct iw_request_info *info,
6955 union iwreq_data *wrqu, char *extra) 6926 union iwreq_data *wrqu, char *extra)
@@ -6969,8 +6940,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6969 6940
6970 /* if setting by freq convert to channel */ 6941 /* if setting by freq convert to channel */
6971 if (fwrq->e == 1) { 6942 if (fwrq->e == 1) {
6972 if ((fwrq->m >= (int) 2.412e8 && 6943 if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) {
6973 fwrq->m <= (int) 2.487e8)) {
6974 int f = fwrq->m / 100000; 6944 int f = fwrq->m / 100000;
6975 int c = 0; 6945 int c = 0;
6976 6946
@@ -6984,19 +6954,19 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6984 } 6954 }
6985 } 6955 }
6986 6956
6987 if (fwrq->e > 0 || fwrq->m > 1000) 6957 if (fwrq->e > 0 || fwrq->m > 1000) {
6988 return -EOPNOTSUPP; 6958 err = -EOPNOTSUPP;
6989 else { /* Set the channel */ 6959 goto done;
6960 } else { /* Set the channel */
6990 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 6961 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
6991 err = ipw2100_set_channel(priv, fwrq->m, 0); 6962 err = ipw2100_set_channel(priv, fwrq->m, 0);
6992 } 6963 }
6993 6964
6994 done: 6965 done:
6995 up(&priv->action_sem); 6966 up(&priv->action_sem);
6996 return err; 6967 return err;
6997} 6968}
6998 6969
6999
7000static int ipw2100_wx_get_freq(struct net_device *dev, 6970static int ipw2100_wx_get_freq(struct net_device *dev,
7001 struct iw_request_info *info, 6971 struct iw_request_info *info,
7002 union iwreq_data *wrqu, char *extra) 6972 union iwreq_data *wrqu, char *extra)
@@ -7045,7 +7015,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
7045 case IW_MODE_MONITOR: 7015 case IW_MODE_MONITOR:
7046 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR); 7016 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR);
7047 break; 7017 break;
7048#endif /* CONFIG_IPW2100_MONITOR */ 7018#endif /* CONFIG_IPW2100_MONITOR */
7049 case IW_MODE_ADHOC: 7019 case IW_MODE_ADHOC:
7050 err = ipw2100_switch_mode(priv, IW_MODE_ADHOC); 7020 err = ipw2100_switch_mode(priv, IW_MODE_ADHOC);
7051 break; 7021 break;
@@ -7056,9 +7026,9 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
7056 break; 7026 break;
7057 } 7027 }
7058 7028
7059done: 7029 done:
7060 up(&priv->action_sem); 7030 up(&priv->action_sem);
7061 return err; 7031 return err;
7062} 7032}
7063 7033
7064static int ipw2100_wx_get_mode(struct net_device *dev, 7034static int ipw2100_wx_get_mode(struct net_device *dev,
@@ -7077,7 +7047,6 @@ static int ipw2100_wx_get_mode(struct net_device *dev,
7077 return 0; 7047 return 0;
7078} 7048}
7079 7049
7080
7081#define POWER_MODES 5 7050#define POWER_MODES 5
7082 7051
7083/* Values are in microsecond */ 7052/* Values are in microsecond */
@@ -7124,19 +7093,19 @@ static int ipw2100_wx_get_range(struct net_device *dev,
7124 /* ~5 Mb/s real (802.11b) */ 7093 /* ~5 Mb/s real (802.11b) */
7125 range->throughput = 5 * 1000 * 1000; 7094 range->throughput = 5 * 1000 * 1000;
7126 7095
7127// range->sensitivity; /* signal level threshold range */ 7096// range->sensitivity; /* signal level threshold range */
7128 7097
7129 range->max_qual.qual = 100; 7098 range->max_qual.qual = 100;
7130 /* TODO: Find real max RSSI and stick here */ 7099 /* TODO: Find real max RSSI and stick here */
7131 range->max_qual.level = 0; 7100 range->max_qual.level = 0;
7132 range->max_qual.noise = 0; 7101 range->max_qual.noise = 0;
7133 range->max_qual.updated = 7; /* Updated all three */ 7102 range->max_qual.updated = 7; /* Updated all three */
7134 7103
7135 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */ 7104 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
7136 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ 7105 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
7137 range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM; 7106 range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM;
7138 range->avg_qual.noise = 0; 7107 range->avg_qual.noise = 0;
7139 range->avg_qual.updated = 7; /* Updated all three */ 7108 range->avg_qual.updated = 7; /* Updated all three */
7140 7109
7141 range->num_bitrates = RATE_COUNT; 7110 range->num_bitrates = RATE_COUNT;
7142 7111
@@ -7150,61 +7119,62 @@ static int ipw2100_wx_get_range(struct net_device *dev,
7150 range->max_frag = MAX_FRAG_THRESHOLD; 7119 range->max_frag = MAX_FRAG_THRESHOLD;
7151 7120
7152 range->min_pmp = period_duration[0]; /* Minimal PM period */ 7121 range->min_pmp = period_duration[0]; /* Minimal PM period */
7153 range->max_pmp = period_duration[POWER_MODES-1];/* Maximal PM period */ 7122 range->max_pmp = period_duration[POWER_MODES - 1]; /* Maximal PM period */
7154 range->min_pmt = timeout_duration[POWER_MODES-1]; /* Minimal PM timeout */ 7123 range->min_pmt = timeout_duration[POWER_MODES - 1]; /* Minimal PM timeout */
7155 range->max_pmt = timeout_duration[0];/* Maximal PM timeout */ 7124 range->max_pmt = timeout_duration[0]; /* Maximal PM timeout */
7156 7125
7157 /* How to decode max/min PM period */ 7126 /* How to decode max/min PM period */
7158 range->pmp_flags = IW_POWER_PERIOD; 7127 range->pmp_flags = IW_POWER_PERIOD;
7159 /* How to decode max/min PM period */ 7128 /* How to decode max/min PM period */
7160 range->pmt_flags = IW_POWER_TIMEOUT; 7129 range->pmt_flags = IW_POWER_TIMEOUT;
7161 /* What PM options are supported */ 7130 /* What PM options are supported */
7162 range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD; 7131 range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD;
7163 7132
7164 range->encoding_size[0] = 5; 7133 range->encoding_size[0] = 5;
7165 range->encoding_size[1] = 13; /* Different token sizes */ 7134 range->encoding_size[1] = 13; /* Different token sizes */
7166 range->num_encoding_sizes = 2; /* Number of entry in the list */ 7135 range->num_encoding_sizes = 2; /* Number of entry in the list */
7167 range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */ 7136 range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */
7168// range->encoding_login_index; /* token index for login token */ 7137// range->encoding_login_index; /* token index for login token */
7169 7138
7170 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 7139 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7171 range->txpower_capa = IW_TXPOW_DBM; 7140 range->txpower_capa = IW_TXPOW_DBM;
7172 range->num_txpower = IW_MAX_TXPOWER; 7141 range->num_txpower = IW_MAX_TXPOWER;
7173 for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16); i < IW_MAX_TXPOWER; 7142 for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16);
7174 i++, level -= ((IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM) * 16) / 7143 i < IW_MAX_TXPOWER;
7175 (IW_MAX_TXPOWER - 1)) 7144 i++, level -=
7145 ((IPW_TX_POWER_MAX_DBM -
7146 IPW_TX_POWER_MIN_DBM) * 16) / (IW_MAX_TXPOWER - 1))
7176 range->txpower[i] = level / 16; 7147 range->txpower[i] = level / 16;
7177 } else { 7148 } else {
7178 range->txpower_capa = 0; 7149 range->txpower_capa = 0;
7179 range->num_txpower = 0; 7150 range->num_txpower = 0;
7180 } 7151 }
7181 7152
7182
7183 /* Set the Wireless Extension versions */ 7153 /* Set the Wireless Extension versions */
7184 range->we_version_compiled = WIRELESS_EXT; 7154 range->we_version_compiled = WIRELESS_EXT;
7185 range->we_version_source = 16; 7155 range->we_version_source = 16;
7186 7156
7187// range->retry_capa; /* What retry options are supported */ 7157// range->retry_capa; /* What retry options are supported */
7188// range->retry_flags; /* How to decode max/min retry limit */ 7158// range->retry_flags; /* How to decode max/min retry limit */
7189// range->r_time_flags; /* How to decode max/min retry life */ 7159// range->r_time_flags; /* How to decode max/min retry life */
7190// range->min_retry; /* Minimal number of retries */ 7160// range->min_retry; /* Minimal number of retries */
7191// range->max_retry; /* Maximal number of retries */ 7161// range->max_retry; /* Maximal number of retries */
7192// range->min_r_time; /* Minimal retry lifetime */ 7162// range->min_r_time; /* Minimal retry lifetime */
7193// range->max_r_time; /* Maximal retry lifetime */ 7163// range->max_r_time; /* Maximal retry lifetime */
7194 7164
7195 range->num_channels = FREQ_COUNT; 7165 range->num_channels = FREQ_COUNT;
7196 7166
7197 val = 0; 7167 val = 0;
7198 for (i = 0; i < FREQ_COUNT; i++) { 7168 for (i = 0; i < FREQ_COUNT; i++) {
7199 // TODO: Include only legal frequencies for some countries 7169 // TODO: Include only legal frequencies for some countries
7200// if (local->channel_mask & (1 << i)) { 7170// if (local->channel_mask & (1 << i)) {
7201 range->freq[val].i = i + 1; 7171 range->freq[val].i = i + 1;
7202 range->freq[val].m = ipw2100_frequencies[i] * 100000; 7172 range->freq[val].m = ipw2100_frequencies[i] * 100000;
7203 range->freq[val].e = 1; 7173 range->freq[val].e = 1;
7204 val++; 7174 val++;
7205// } 7175// }
7206 if (val == IW_MAX_FREQUENCIES) 7176 if (val == IW_MAX_FREQUENCIES)
7207 break; 7177 break;
7208 } 7178 }
7209 range->num_frequency = val; 7179 range->num_frequency = val;
7210 7180
@@ -7259,7 +7229,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
7259 wrqu->ap_addr.sa_data[4] & 0xff, 7229 wrqu->ap_addr.sa_data[4] & 0xff,
7260 wrqu->ap_addr.sa_data[5] & 0xff); 7230 wrqu->ap_addr.sa_data[5] & 0xff);
7261 7231
7262 done: 7232 done:
7263 up(&priv->action_sem); 7233 up(&priv->action_sem);
7264 return err; 7234 return err;
7265} 7235}
@@ -7276,10 +7246,9 @@ static int ipw2100_wx_get_wap(struct net_device *dev,
7276 7246
7277 /* If we are associated, trying to associate, or have a statically 7247 /* If we are associated, trying to associate, or have a statically
7278 * configured BSSID then return that; otherwise return ANY */ 7248 * configured BSSID then return that; otherwise return ANY */
7279 if (priv->config & CFG_STATIC_BSSID || 7249 if (priv->config & CFG_STATIC_BSSID || priv->status & STATUS_ASSOCIATED) {
7280 priv->status & STATUS_ASSOCIATED) {
7281 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 7250 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
7282 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN); 7251 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
7283 } else 7252 } else
7284 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 7253 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
7285 7254
@@ -7293,7 +7262,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
7293 union iwreq_data *wrqu, char *extra) 7262 union iwreq_data *wrqu, char *extra)
7294{ 7263{
7295 struct ipw2100_priv *priv = ieee80211_priv(dev); 7264 struct ipw2100_priv *priv = ieee80211_priv(dev);
7296 char *essid = ""; /* ANY */ 7265 char *essid = ""; /* ANY */
7297 int length = 0; 7266 int length = 0;
7298 int err = 0; 7267 int err = 0;
7299 7268
@@ -7333,7 +7302,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
7333 7302
7334 err = ipw2100_set_essid(priv, essid, length, 0); 7303 err = ipw2100_set_essid(priv, essid, length, 0);
7335 7304
7336 done: 7305 done:
7337 up(&priv->action_sem); 7306 up(&priv->action_sem);
7338 return err; 7307 return err;
7339} 7308}
@@ -7350,17 +7319,16 @@ static int ipw2100_wx_get_essid(struct net_device *dev,
7350 7319
7351 /* If we are associated, trying to associate, or have a statically 7320 /* If we are associated, trying to associate, or have a statically
7352 * configured ESSID then return that; otherwise return ANY */ 7321 * configured ESSID then return that; otherwise return ANY */
7353 if (priv->config & CFG_STATIC_ESSID || 7322 if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) {
7354 priv->status & STATUS_ASSOCIATED) {
7355 IPW_DEBUG_WX("Getting essid: '%s'\n", 7323 IPW_DEBUG_WX("Getting essid: '%s'\n",
7356 escape_essid(priv->essid, priv->essid_len)); 7324 escape_essid(priv->essid, priv->essid_len));
7357 memcpy(extra, priv->essid, priv->essid_len); 7325 memcpy(extra, priv->essid, priv->essid_len);
7358 wrqu->essid.length = priv->essid_len; 7326 wrqu->essid.length = priv->essid_len;
7359 wrqu->essid.flags = 1; /* active */ 7327 wrqu->essid.flags = 1; /* active */
7360 } else { 7328 } else {
7361 IPW_DEBUG_WX("Getting essid: ANY\n"); 7329 IPW_DEBUG_WX("Getting essid: ANY\n");
7362 wrqu->essid.length = 0; 7330 wrqu->essid.length = 0;
7363 wrqu->essid.flags = 0; /* active */ 7331 wrqu->essid.flags = 0; /* active */
7364 } 7332 }
7365 7333
7366 return 0; 7334 return 0;
@@ -7379,9 +7347,9 @@ static int ipw2100_wx_set_nick(struct net_device *dev,
7379 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 7347 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
7380 return -E2BIG; 7348 return -E2BIG;
7381 7349
7382 wrqu->data.length = min((size_t)wrqu->data.length, sizeof(priv->nick)); 7350 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
7383 memset(priv->nick, 0, sizeof(priv->nick)); 7351 memset(priv->nick, 0, sizeof(priv->nick));
7384 memcpy(priv->nick, extra, wrqu->data.length); 7352 memcpy(priv->nick, extra, wrqu->data.length);
7385 7353
7386 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick); 7354 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick);
7387 7355
@@ -7400,7 +7368,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
7400 7368
7401 wrqu->data.length = strlen(priv->nick) + 1; 7369 wrqu->data.length = strlen(priv->nick) + 1;
7402 memcpy(extra, priv->nick, wrqu->data.length); 7370 memcpy(extra, priv->nick, wrqu->data.length);
7403 wrqu->data.flags = 1; /* active */ 7371 wrqu->data.flags = 1; /* active */
7404 7372
7405 IPW_DEBUG_WX("GET Nickname -> %s \n", extra); 7373 IPW_DEBUG_WX("GET Nickname -> %s \n", extra);
7406 7374
@@ -7442,12 +7410,11 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
7442 err = ipw2100_set_tx_rates(priv, rate, 0); 7410 err = ipw2100_set_tx_rates(priv, rate, 0);
7443 7411
7444 IPW_DEBUG_WX("SET Rate -> %04X \n", rate); 7412 IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
7445 done: 7413 done:
7446 up(&priv->action_sem); 7414 up(&priv->action_sem);
7447 return err; 7415 return err;
7448} 7416}
7449 7417
7450
7451static int ipw2100_wx_get_rate(struct net_device *dev, 7418static int ipw2100_wx_get_rate(struct net_device *dev,
7452 struct iw_request_info *info, 7419 struct iw_request_info *info,
7453 union iwreq_data *wrqu, char *extra) 7420 union iwreq_data *wrqu, char *extra)
@@ -7495,7 +7462,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
7495 7462
7496 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 7463 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
7497 7464
7498 done: 7465 done:
7499 up(&priv->action_sem); 7466 up(&priv->action_sem);
7500 return err; 7467 return err;
7501} 7468}
@@ -7520,8 +7487,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7520 if (wrqu->rts.disabled) 7487 if (wrqu->rts.disabled)
7521 value = priv->rts_threshold | RTS_DISABLED; 7488 value = priv->rts_threshold | RTS_DISABLED;
7522 else { 7489 else {
7523 if (wrqu->rts.value < 1 || 7490 if (wrqu->rts.value < 1 || wrqu->rts.value > 2304) {
7524 wrqu->rts.value > 2304) {
7525 err = -EINVAL; 7491 err = -EINVAL;
7526 goto done; 7492 goto done;
7527 } 7493 }
@@ -7531,7 +7497,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7531 err = ipw2100_set_rts_threshold(priv, value); 7497 err = ipw2100_set_rts_threshold(priv, value);
7532 7498
7533 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value); 7499 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
7534 done: 7500 done:
7535 up(&priv->action_sem); 7501 up(&priv->action_sem);
7536 return err; 7502 return err;
7537} 7503}
@@ -7547,7 +7513,7 @@ static int ipw2100_wx_get_rts(struct net_device *dev,
7547 struct ipw2100_priv *priv = ieee80211_priv(dev); 7513 struct ipw2100_priv *priv = ieee80211_priv(dev);
7548 7514
7549 wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED; 7515 wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED;
7550 wrqu->rts.fixed = 1; /* no auto select */ 7516 wrqu->rts.fixed = 1; /* no auto select */
7551 7517
7552 /* If RTS is set to the default value, then it is disabled */ 7518 /* If RTS is set to the default value, then it is disabled */
7553 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0; 7519 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0;
@@ -7574,8 +7540,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7574 wrqu->txpower.value > IPW_TX_POWER_MAX_DBM) 7540 wrqu->txpower.value > IPW_TX_POWER_MAX_DBM)
7575 return -EINVAL; 7541 return -EINVAL;
7576 7542
7577 value = (wrqu->txpower.value - IPW_TX_POWER_MIN_DBM) * 16 / 7543 value = wrqu->txpower.value;
7578 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
7579 } 7544 }
7580 7545
7581 down(&priv->action_sem); 7546 down(&priv->action_sem);
@@ -7588,7 +7553,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7588 7553
7589 IPW_DEBUG_WX("SET TX Power -> %d \n", value); 7554 IPW_DEBUG_WX("SET TX Power -> %d \n", value);
7590 7555
7591 done: 7556 done:
7592 up(&priv->action_sem); 7557 up(&priv->action_sem);
7593 return err; 7558 return err;
7594} 7559}
@@ -7615,11 +7580,7 @@ static int ipw2100_wx_get_txpow(struct net_device *dev,
7615 } else { 7580 } else {
7616 wrqu->power.disabled = 0; 7581 wrqu->power.disabled = 0;
7617 wrqu->power.fixed = 1; 7582 wrqu->power.fixed = 1;
7618 wrqu->power.value = 7583 wrqu->power.value = priv->tx_power;
7619 (priv->tx_power *
7620 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM)) /
7621 (IPW_TX_POWER_MAX - IPW_TX_POWER_MIN) +
7622 IPW_TX_POWER_MIN_DBM;
7623 } 7584 }
7624 7585
7625 wrqu->power.flags = IW_TXPOW_DBM; 7586 wrqu->power.flags = IW_TXPOW_DBM;
@@ -7684,8 +7645,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7684 struct ipw2100_priv *priv = ieee80211_priv(dev); 7645 struct ipw2100_priv *priv = ieee80211_priv(dev);
7685 int err = 0; 7646 int err = 0;
7686 7647
7687 if (wrqu->retry.flags & IW_RETRY_LIFETIME || 7648 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
7688 wrqu->retry.disabled)
7689 return -EINVAL; 7649 return -EINVAL;
7690 7650
7691 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) 7651 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
@@ -7700,14 +7660,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7700 if (wrqu->retry.flags & IW_RETRY_MIN) { 7660 if (wrqu->retry.flags & IW_RETRY_MIN) {
7701 err = ipw2100_set_short_retry(priv, wrqu->retry.value); 7661 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7702 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n", 7662 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
7703 wrqu->retry.value); 7663 wrqu->retry.value);
7704 goto done; 7664 goto done;
7705 } 7665 }
7706 7666
7707 if (wrqu->retry.flags & IW_RETRY_MAX) { 7667 if (wrqu->retry.flags & IW_RETRY_MAX) {
7708 err = ipw2100_set_long_retry(priv, wrqu->retry.value); 7668 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7709 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n", 7669 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
7710 wrqu->retry.value); 7670 wrqu->retry.value);
7711 goto done; 7671 goto done;
7712 } 7672 }
7713 7673
@@ -7717,7 +7677,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7717 7677
7718 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value); 7678 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
7719 7679
7720 done: 7680 done:
7721 up(&priv->action_sem); 7681 up(&priv->action_sem);
7722 return err; 7682 return err;
7723} 7683}
@@ -7732,20 +7692,19 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
7732 7692
7733 struct ipw2100_priv *priv = ieee80211_priv(dev); 7693 struct ipw2100_priv *priv = ieee80211_priv(dev);
7734 7694
7735 wrqu->retry.disabled = 0; /* can't be disabled */ 7695 wrqu->retry.disabled = 0; /* can't be disabled */
7736 7696
7737 if ((wrqu->retry.flags & IW_RETRY_TYPE) == 7697 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
7738 IW_RETRY_LIFETIME)
7739 return -EINVAL; 7698 return -EINVAL;
7740 7699
7741 if (wrqu->retry.flags & IW_RETRY_MAX) { 7700 if (wrqu->retry.flags & IW_RETRY_MAX) {
7742 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; 7701 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
7743 wrqu->retry.value = priv->long_retry_limit; 7702 wrqu->retry.value = priv->long_retry_limit;
7744 } else { 7703 } else {
7745 wrqu->retry.flags = 7704 wrqu->retry.flags =
7746 (priv->short_retry_limit != 7705 (priv->short_retry_limit !=
7747 priv->long_retry_limit) ? 7706 priv->long_retry_limit) ?
7748 IW_RETRY_LIMIT & IW_RETRY_MIN : IW_RETRY_LIMIT; 7707 IW_RETRY_LIMIT | IW_RETRY_MIN : IW_RETRY_LIMIT;
7749 7708
7750 wrqu->retry.value = priv->short_retry_limit; 7709 wrqu->retry.value = priv->short_retry_limit;
7751 } 7710 }
@@ -7769,15 +7728,14 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
7769 } 7728 }
7770 7729
7771 IPW_DEBUG_WX("Initiating scan...\n"); 7730 IPW_DEBUG_WX("Initiating scan...\n");
7772 if (ipw2100_set_scan_options(priv) || 7731 if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
7773 ipw2100_start_scan(priv)) {
7774 IPW_DEBUG_WX("Start scan failed.\n"); 7732 IPW_DEBUG_WX("Start scan failed.\n");
7775 7733
7776 /* TODO: Mark a scan as pending so when hardware initialized 7734 /* TODO: Mark a scan as pending so when hardware initialized
7777 * a scan starts */ 7735 * a scan starts */
7778 } 7736 }
7779 7737
7780 done: 7738 done:
7781 up(&priv->action_sem); 7739 up(&priv->action_sem);
7782 return err; 7740 return err;
7783} 7741}
@@ -7794,7 +7752,6 @@ static int ipw2100_wx_get_scan(struct net_device *dev,
7794 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra); 7752 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
7795} 7753}
7796 7754
7797
7798/* 7755/*
7799 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c 7756 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c
7800 */ 7757 */
@@ -7823,8 +7780,8 @@ static int ipw2100_wx_get_encode(struct net_device *dev,
7823} 7780}
7824 7781
7825static int ipw2100_wx_set_power(struct net_device *dev, 7782static int ipw2100_wx_set_power(struct net_device *dev,
7826 struct iw_request_info *info, 7783 struct iw_request_info *info,
7827 union iwreq_data *wrqu, char *extra) 7784 union iwreq_data *wrqu, char *extra)
7828{ 7785{
7829 struct ipw2100_priv *priv = ieee80211_priv(dev); 7786 struct ipw2100_priv *priv = ieee80211_priv(dev);
7830 int err = 0; 7787 int err = 0;
@@ -7843,11 +7800,11 @@ static int ipw2100_wx_set_power(struct net_device *dev,
7843 } 7800 }
7844 7801
7845 switch (wrqu->power.flags & IW_POWER_MODE) { 7802 switch (wrqu->power.flags & IW_POWER_MODE) {
7846 case IW_POWER_ON: /* If not specified */ 7803 case IW_POWER_ON: /* If not specified */
7847 case IW_POWER_MODE: /* If set all mask */ 7804 case IW_POWER_MODE: /* If set all mask */
7848 case IW_POWER_ALL_R: /* If explicitely state all */ 7805 case IW_POWER_ALL_R: /* If explicitely state all */
7849 break; 7806 break;
7850 default: /* Otherwise we don't support it */ 7807 default: /* Otherwise we don't support it */
7851 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", 7808 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
7852 wrqu->power.flags); 7809 wrqu->power.flags);
7853 err = -EOPNOTSUPP; 7810 err = -EOPNOTSUPP;
@@ -7859,18 +7816,17 @@ static int ipw2100_wx_set_power(struct net_device *dev,
7859 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode; 7816 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
7860 err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); 7817 err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
7861 7818
7862 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", 7819 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
7863 priv->power_mode);
7864 7820
7865 done: 7821 done:
7866 up(&priv->action_sem); 7822 up(&priv->action_sem);
7867 return err; 7823 return err;
7868 7824
7869} 7825}
7870 7826
7871static int ipw2100_wx_get_power(struct net_device *dev, 7827static int ipw2100_wx_get_power(struct net_device *dev,
7872 struct iw_request_info *info, 7828 struct iw_request_info *info,
7873 union iwreq_data *wrqu, char *extra) 7829 union iwreq_data *wrqu, char *extra)
7874{ 7830{
7875 /* 7831 /*
7876 * This can be called at any time. No action lock required 7832 * This can be called at any time. No action lock required
@@ -7878,9 +7834,9 @@ static int ipw2100_wx_get_power(struct net_device *dev,
7878 7834
7879 struct ipw2100_priv *priv = ieee80211_priv(dev); 7835 struct ipw2100_priv *priv = ieee80211_priv(dev);
7880 7836
7881 if (!(priv->power_mode & IPW_POWER_ENABLED)) { 7837 if (!(priv->power_mode & IPW_POWER_ENABLED))
7882 wrqu->power.disabled = 1; 7838 wrqu->power.disabled = 1;
7883 } else { 7839 else {
7884 wrqu->power.disabled = 0; 7840 wrqu->power.disabled = 0;
7885 wrqu->power.flags = 0; 7841 wrqu->power.flags = 0;
7886 } 7842 }
@@ -7890,6 +7846,269 @@ static int ipw2100_wx_get_power(struct net_device *dev,
7890 return 0; 7846 return 0;
7891} 7847}
7892 7848
7849#if WIRELESS_EXT > 17
7850/*
7851 * WE-18 WPA support
7852 */
7853
7854/* SIOCSIWGENIE */
7855static int ipw2100_wx_set_genie(struct net_device *dev,
7856 struct iw_request_info *info,
7857 union iwreq_data *wrqu, char *extra)
7858{
7859
7860 struct ipw2100_priv *priv = ieee80211_priv(dev);
7861 struct ieee80211_device *ieee = priv->ieee;
7862 u8 *buf;
7863
7864 if (!ieee->wpa_enabled)
7865 return -EOPNOTSUPP;
7866
7867 if (wrqu->data.length > MAX_WPA_IE_LEN ||
7868 (wrqu->data.length && extra == NULL))
7869 return -EINVAL;
7870
7871 if (wrqu->data.length) {
7872 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
7873 if (buf == NULL)
7874 return -ENOMEM;
7875
7876 memcpy(buf, extra, wrqu->data.length);
7877 kfree(ieee->wpa_ie);
7878 ieee->wpa_ie = buf;
7879 ieee->wpa_ie_len = wrqu->data.length;
7880 } else {
7881 kfree(ieee->wpa_ie);
7882 ieee->wpa_ie = NULL;
7883 ieee->wpa_ie_len = 0;
7884 }
7885
7886 ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
7887
7888 return 0;
7889}
7890
7891/* SIOCGIWGENIE */
7892static int ipw2100_wx_get_genie(struct net_device *dev,
7893 struct iw_request_info *info,
7894 union iwreq_data *wrqu, char *extra)
7895{
7896 struct ipw2100_priv *priv = ieee80211_priv(dev);
7897 struct ieee80211_device *ieee = priv->ieee;
7898
7899 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
7900 wrqu->data.length = 0;
7901 return 0;
7902 }
7903
7904 if (wrqu->data.length < ieee->wpa_ie_len)
7905 return -E2BIG;
7906
7907 wrqu->data.length = ieee->wpa_ie_len;
7908 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
7909
7910 return 0;
7911}
7912
7913/* SIOCSIWAUTH */
7914static int ipw2100_wx_set_auth(struct net_device *dev,
7915 struct iw_request_info *info,
7916 union iwreq_data *wrqu, char *extra)
7917{
7918 struct ipw2100_priv *priv = ieee80211_priv(dev);
7919 struct ieee80211_device *ieee = priv->ieee;
7920 struct iw_param *param = &wrqu->param;
7921 struct ieee80211_crypt_data *crypt;
7922 unsigned long flags;
7923 int ret = 0;
7924
7925 switch (param->flags & IW_AUTH_INDEX) {
7926 case IW_AUTH_WPA_VERSION:
7927 case IW_AUTH_CIPHER_PAIRWISE:
7928 case IW_AUTH_CIPHER_GROUP:
7929 case IW_AUTH_KEY_MGMT:
7930 /*
7931 * ipw2200 does not use these parameters
7932 */
7933 break;
7934
7935 case IW_AUTH_TKIP_COUNTERMEASURES:
7936 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
7937 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
7938 break;
7939
7940 flags = crypt->ops->get_flags(crypt->priv);
7941
7942 if (param->value)
7943 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
7944 else
7945 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
7946
7947 crypt->ops->set_flags(flags, crypt->priv);
7948
7949 break;
7950
7951 case IW_AUTH_DROP_UNENCRYPTED:{
7952 /* HACK:
7953 *
7954 * wpa_supplicant calls set_wpa_enabled when the driver
7955 * is loaded and unloaded, regardless of if WPA is being
7956 * used. No other calls are made which can be used to
7957 * determine if encryption will be used or not prior to
7958 * association being expected. If encryption is not being
7959 * used, drop_unencrypted is set to false, else true -- we
7960 * can use this to determine if the CAP_PRIVACY_ON bit should
7961 * be set.
7962 */
7963 struct ieee80211_security sec = {
7964 .flags = SEC_ENABLED,
7965 .enabled = param->value,
7966 };
7967 priv->ieee->drop_unencrypted = param->value;
7968 /* We only change SEC_LEVEL for open mode. Others
7969 * are set by ipw_wpa_set_encryption.
7970 */
7971 if (!param->value) {
7972 sec.flags |= SEC_LEVEL;
7973 sec.level = SEC_LEVEL_0;
7974 } else {
7975 sec.flags |= SEC_LEVEL;
7976 sec.level = SEC_LEVEL_1;
7977 }
7978 if (priv->ieee->set_security)
7979 priv->ieee->set_security(priv->ieee->dev, &sec);
7980 break;
7981 }
7982
7983 case IW_AUTH_80211_AUTH_ALG:
7984 ret = ipw2100_wpa_set_auth_algs(priv, param->value);
7985 break;
7986
7987 case IW_AUTH_WPA_ENABLED:
7988 ret = ipw2100_wpa_enable(priv, param->value);
7989 break;
7990
7991 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
7992 ieee->ieee802_1x = param->value;
7993 break;
7994
7995 //case IW_AUTH_ROAMING_CONTROL:
7996 case IW_AUTH_PRIVACY_INVOKED:
7997 ieee->privacy_invoked = param->value;
7998 break;
7999
8000 default:
8001 return -EOPNOTSUPP;
8002 }
8003 return ret;
8004}
8005
8006/* SIOCGIWAUTH */
8007static int ipw2100_wx_get_auth(struct net_device *dev,
8008 struct iw_request_info *info,
8009 union iwreq_data *wrqu, char *extra)
8010{
8011 struct ipw2100_priv *priv = ieee80211_priv(dev);
8012 struct ieee80211_device *ieee = priv->ieee;
8013 struct ieee80211_crypt_data *crypt;
8014 struct iw_param *param = &wrqu->param;
8015 int ret = 0;
8016
8017 switch (param->flags & IW_AUTH_INDEX) {
8018 case IW_AUTH_WPA_VERSION:
8019 case IW_AUTH_CIPHER_PAIRWISE:
8020 case IW_AUTH_CIPHER_GROUP:
8021 case IW_AUTH_KEY_MGMT:
8022 /*
8023 * wpa_supplicant will control these internally
8024 */
8025 ret = -EOPNOTSUPP;
8026 break;
8027
8028 case IW_AUTH_TKIP_COUNTERMEASURES:
8029 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
8030 if (!crypt || !crypt->ops->get_flags) {
8031 IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
8032 "crypt not set!\n");
8033 break;
8034 }
8035
8036 param->value = (crypt->ops->get_flags(crypt->priv) &
8037 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
8038
8039 break;
8040
8041 case IW_AUTH_DROP_UNENCRYPTED:
8042 param->value = ieee->drop_unencrypted;
8043 break;
8044
8045 case IW_AUTH_80211_AUTH_ALG:
8046 param->value = priv->ieee->sec.auth_mode;
8047 break;
8048
8049 case IW_AUTH_WPA_ENABLED:
8050 param->value = ieee->wpa_enabled;
8051 break;
8052
8053 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
8054 param->value = ieee->ieee802_1x;
8055 break;
8056
8057 case IW_AUTH_ROAMING_CONTROL:
8058 case IW_AUTH_PRIVACY_INVOKED:
8059 param->value = ieee->privacy_invoked;
8060 break;
8061
8062 default:
8063 return -EOPNOTSUPP;
8064 }
8065 return 0;
8066}
8067
8068/* SIOCSIWENCODEEXT */
8069static int ipw2100_wx_set_encodeext(struct net_device *dev,
8070 struct iw_request_info *info,
8071 union iwreq_data *wrqu, char *extra)
8072{
8073 struct ipw2100_priv *priv = ieee80211_priv(dev);
8074 return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
8075}
8076
8077/* SIOCGIWENCODEEXT */
8078static int ipw2100_wx_get_encodeext(struct net_device *dev,
8079 struct iw_request_info *info,
8080 union iwreq_data *wrqu, char *extra)
8081{
8082 struct ipw2100_priv *priv = ieee80211_priv(dev);
8083 return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
8084}
8085
8086/* SIOCSIWMLME */
8087static int ipw2100_wx_set_mlme(struct net_device *dev,
8088 struct iw_request_info *info,
8089 union iwreq_data *wrqu, char *extra)
8090{
8091 struct ipw2100_priv *priv = ieee80211_priv(dev);
8092 struct iw_mlme *mlme = (struct iw_mlme *)extra;
8093 u16 reason;
8094
8095 reason = cpu_to_le16(mlme->reason_code);
8096
8097 switch (mlme->cmd) {
8098 case IW_MLME_DEAUTH:
8099 // silently ignore
8100 break;
8101
8102 case IW_MLME_DISASSOC:
8103 ipw2100_disassociate_bssid(priv);
8104 break;
8105
8106 default:
8107 return -EOPNOTSUPP;
8108 }
8109 return 0;
8110}
8111#endif /* WIRELESS_EXT > 17 */
7893 8112
7894/* 8113/*
7895 * 8114 *
@@ -7923,7 +8142,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
7923 if (priv->ieee->iw_mode == IW_MODE_MONITOR) 8142 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
7924 err = ipw2100_switch_mode(priv, priv->last_mode); 8143 err = ipw2100_switch_mode(priv, priv->last_mode);
7925 } 8144 }
7926 done: 8145 done:
7927 up(&priv->action_sem); 8146 up(&priv->action_sem);
7928 return err; 8147 return err;
7929} 8148}
@@ -7958,7 +8177,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
7958 8177
7959 if (priv->power_mode != mode) 8178 if (priv->power_mode != mode)
7960 err = ipw2100_set_power_mode(priv, mode); 8179 err = ipw2100_set_power_mode(priv, mode);
7961 done: 8180 done:
7962 up(&priv->action_sem); 8181 up(&priv->action_sem);
7963 return err; 8182 return err;
7964} 8183}
@@ -7986,8 +8205,8 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
7986 "Power save level: %d (None)", level); 8205 "Power save level: %d (None)", level);
7987 break; 8206 break;
7988 case IPW_POWER_AUTO: 8207 case IPW_POWER_AUTO:
7989 snprintf(extra, MAX_POWER_STRING, 8208 snprintf(extra, MAX_POWER_STRING,
7990 "Power save level: %d (Auto)", 0); 8209 "Power save level: %d (Auto)", 0);
7991 break; 8210 break;
7992 default: 8211 default:
7993 timeout = timeout_duration[level - 1] / 1000; 8212 timeout = timeout_duration[level - 1] / 1000;
@@ -8004,7 +8223,6 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
8004 return 0; 8223 return 0;
8005} 8224}
8006 8225
8007
8008static int ipw2100_wx_set_preamble(struct net_device *dev, 8226static int ipw2100_wx_set_preamble(struct net_device *dev,
8009 struct iw_request_info *info, 8227 struct iw_request_info *info,
8010 union iwreq_data *wrqu, char *extra) 8228 union iwreq_data *wrqu, char *extra)
@@ -8029,14 +8247,14 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
8029 8247
8030 err = ipw2100_system_config(priv, 0); 8248 err = ipw2100_system_config(priv, 0);
8031 8249
8032done: 8250 done:
8033 up(&priv->action_sem); 8251 up(&priv->action_sem);
8034 return err; 8252 return err;
8035} 8253}
8036 8254
8037static int ipw2100_wx_get_preamble(struct net_device *dev, 8255static int ipw2100_wx_get_preamble(struct net_device *dev,
8038 struct iw_request_info *info, 8256 struct iw_request_info *info,
8039 union iwreq_data *wrqu, char *extra) 8257 union iwreq_data *wrqu, char *extra)
8040{ 8258{
8041 /* 8259 /*
8042 * This can be called at any time. No action lock required 8260 * This can be called at any time. No action lock required
@@ -8052,54 +8270,116 @@ static int ipw2100_wx_get_preamble(struct net_device *dev,
8052 return 0; 8270 return 0;
8053} 8271}
8054 8272
8055static iw_handler ipw2100_wx_handlers[] = 8273#ifdef CONFIG_IPW2100_MONITOR
8056{ 8274static int ipw2100_wx_set_crc_check(struct net_device *dev,
8057 NULL, /* SIOCSIWCOMMIT */ 8275 struct iw_request_info *info,
8058 ipw2100_wx_get_name, /* SIOCGIWNAME */ 8276 union iwreq_data *wrqu, char *extra)
8059 NULL, /* SIOCSIWNWID */ 8277{
8060 NULL, /* SIOCGIWNWID */ 8278 struct ipw2100_priv *priv = ieee80211_priv(dev);
8061 ipw2100_wx_set_freq, /* SIOCSIWFREQ */ 8279 int err, mode = *(int *)extra;
8062 ipw2100_wx_get_freq, /* SIOCGIWFREQ */ 8280
8063 ipw2100_wx_set_mode, /* SIOCSIWMODE */ 8281 down(&priv->action_sem);
8064 ipw2100_wx_get_mode, /* SIOCGIWMODE */ 8282 if (!(priv->status & STATUS_INITIALIZED)) {
8065 NULL, /* SIOCSIWSENS */ 8283 err = -EIO;
8066 NULL, /* SIOCGIWSENS */ 8284 goto done;
8067 NULL, /* SIOCSIWRANGE */ 8285 }
8068 ipw2100_wx_get_range, /* SIOCGIWRANGE */ 8286
8069 NULL, /* SIOCSIWPRIV */ 8287 if (mode == 1)
8070 NULL, /* SIOCGIWPRIV */ 8288 priv->config |= CFG_CRC_CHECK;
8071 NULL, /* SIOCSIWSTATS */ 8289 else if (mode == 0)
8072 NULL, /* SIOCGIWSTATS */ 8290 priv->config &= ~CFG_CRC_CHECK;
8073 NULL, /* SIOCSIWSPY */ 8291 else {
8074 NULL, /* SIOCGIWSPY */ 8292 err = -EINVAL;
8075 NULL, /* SIOCGIWTHRSPY */ 8293 goto done;
8076 NULL, /* SIOCWIWTHRSPY */ 8294 }
8077 ipw2100_wx_set_wap, /* SIOCSIWAP */ 8295 err = 0;
8078 ipw2100_wx_get_wap, /* SIOCGIWAP */ 8296
8079 NULL, /* -- hole -- */ 8297 done:
8080 NULL, /* SIOCGIWAPLIST -- deprecated */ 8298 up(&priv->action_sem);
8081 ipw2100_wx_set_scan, /* SIOCSIWSCAN */ 8299 return err;
8082 ipw2100_wx_get_scan, /* SIOCGIWSCAN */ 8300}
8083 ipw2100_wx_set_essid, /* SIOCSIWESSID */ 8301
8084 ipw2100_wx_get_essid, /* SIOCGIWESSID */ 8302static int ipw2100_wx_get_crc_check(struct net_device *dev,
8085 ipw2100_wx_set_nick, /* SIOCSIWNICKN */ 8303 struct iw_request_info *info,
8086 ipw2100_wx_get_nick, /* SIOCGIWNICKN */ 8304 union iwreq_data *wrqu, char *extra)
8087 NULL, /* -- hole -- */ 8305{
8088 NULL, /* -- hole -- */ 8306 /*
8089 ipw2100_wx_set_rate, /* SIOCSIWRATE */ 8307 * This can be called at any time. No action lock required
8090 ipw2100_wx_get_rate, /* SIOCGIWRATE */ 8308 */
8091 ipw2100_wx_set_rts, /* SIOCSIWRTS */ 8309
8092 ipw2100_wx_get_rts, /* SIOCGIWRTS */ 8310 struct ipw2100_priv *priv = ieee80211_priv(dev);
8093 ipw2100_wx_set_frag, /* SIOCSIWFRAG */ 8311
8094 ipw2100_wx_get_frag, /* SIOCGIWFRAG */ 8312 if (priv->config & CFG_CRC_CHECK)
8095 ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */ 8313 snprintf(wrqu->name, IFNAMSIZ, "CRC checked (1)");
8096 ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */ 8314 else
8097 ipw2100_wx_set_retry, /* SIOCSIWRETRY */ 8315 snprintf(wrqu->name, IFNAMSIZ, "CRC ignored (0)");
8098 ipw2100_wx_get_retry, /* SIOCGIWRETRY */ 8316
8099 ipw2100_wx_set_encode, /* SIOCSIWENCODE */ 8317 return 0;
8100 ipw2100_wx_get_encode, /* SIOCGIWENCODE */ 8318}
8101 ipw2100_wx_set_power, /* SIOCSIWPOWER */ 8319#endif /* CONFIG_IPW2100_MONITOR */
8102 ipw2100_wx_get_power, /* SIOCGIWPOWER */ 8320
8321static iw_handler ipw2100_wx_handlers[] = {
8322 NULL, /* SIOCSIWCOMMIT */
8323 ipw2100_wx_get_name, /* SIOCGIWNAME */
8324 NULL, /* SIOCSIWNWID */
8325 NULL, /* SIOCGIWNWID */
8326 ipw2100_wx_set_freq, /* SIOCSIWFREQ */
8327 ipw2100_wx_get_freq, /* SIOCGIWFREQ */
8328 ipw2100_wx_set_mode, /* SIOCSIWMODE */
8329 ipw2100_wx_get_mode, /* SIOCGIWMODE */
8330 NULL, /* SIOCSIWSENS */
8331 NULL, /* SIOCGIWSENS */
8332 NULL, /* SIOCSIWRANGE */
8333 ipw2100_wx_get_range, /* SIOCGIWRANGE */
8334 NULL, /* SIOCSIWPRIV */
8335 NULL, /* SIOCGIWPRIV */
8336 NULL, /* SIOCSIWSTATS */
8337 NULL, /* SIOCGIWSTATS */
8338 NULL, /* SIOCSIWSPY */
8339 NULL, /* SIOCGIWSPY */
8340 NULL, /* SIOCGIWTHRSPY */
8341 NULL, /* SIOCWIWTHRSPY */
8342 ipw2100_wx_set_wap, /* SIOCSIWAP */
8343 ipw2100_wx_get_wap, /* SIOCGIWAP */
8344#if WIRELESS_EXT > 17
8345 ipw2100_wx_set_mlme, /* SIOCSIWMLME */
8346#else
8347 NULL, /* -- hole -- */
8348#endif
8349 NULL, /* SIOCGIWAPLIST -- deprecated */
8350 ipw2100_wx_set_scan, /* SIOCSIWSCAN */
8351 ipw2100_wx_get_scan, /* SIOCGIWSCAN */
8352 ipw2100_wx_set_essid, /* SIOCSIWESSID */
8353 ipw2100_wx_get_essid, /* SIOCGIWESSID */
8354 ipw2100_wx_set_nick, /* SIOCSIWNICKN */
8355 ipw2100_wx_get_nick, /* SIOCGIWNICKN */
8356 NULL, /* -- hole -- */
8357 NULL, /* -- hole -- */
8358 ipw2100_wx_set_rate, /* SIOCSIWRATE */
8359 ipw2100_wx_get_rate, /* SIOCGIWRATE */
8360 ipw2100_wx_set_rts, /* SIOCSIWRTS */
8361 ipw2100_wx_get_rts, /* SIOCGIWRTS */
8362 ipw2100_wx_set_frag, /* SIOCSIWFRAG */
8363 ipw2100_wx_get_frag, /* SIOCGIWFRAG */
8364 ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */
8365 ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */
8366 ipw2100_wx_set_retry, /* SIOCSIWRETRY */
8367 ipw2100_wx_get_retry, /* SIOCGIWRETRY */
8368 ipw2100_wx_set_encode, /* SIOCSIWENCODE */
8369 ipw2100_wx_get_encode, /* SIOCGIWENCODE */
8370 ipw2100_wx_set_power, /* SIOCSIWPOWER */
8371 ipw2100_wx_get_power, /* SIOCGIWPOWER */
8372#if WIRELESS_EXT > 17
8373 NULL, /* -- hole -- */
8374 NULL, /* -- hole -- */
8375 ipw2100_wx_set_genie, /* SIOCSIWGENIE */
8376 ipw2100_wx_get_genie, /* SIOCGIWGENIE */
8377 ipw2100_wx_set_auth, /* SIOCSIWAUTH */
8378 ipw2100_wx_get_auth, /* SIOCGIWAUTH */
8379 ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */
8380 ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */
8381 NULL, /* SIOCSIWPMKSA */
8382#endif
8103}; 8383};
8104 8384
8105#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV 8385#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV
@@ -8108,60 +8388,71 @@ static iw_handler ipw2100_wx_handlers[] =
8108#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3 8388#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3
8109#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4 8389#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4
8110#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5 8390#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5
8391#define IPW2100_PRIV_SET_CRC_CHECK SIOCIWFIRSTPRIV+6
8392#define IPW2100_PRIV_GET_CRC_CHECK SIOCIWFIRSTPRIV+7
8111 8393
8112static const struct iw_priv_args ipw2100_private_args[] = { 8394static const struct iw_priv_args ipw2100_private_args[] = {
8113 8395
8114#ifdef CONFIG_IPW2100_MONITOR 8396#ifdef CONFIG_IPW2100_MONITOR
8115 { 8397 {
8116 IPW2100_PRIV_SET_MONITOR, 8398 IPW2100_PRIV_SET_MONITOR,
8117 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor" 8399 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
8118 },
8119 { 8400 {
8120 IPW2100_PRIV_RESET, 8401 IPW2100_PRIV_RESET,
8121 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset" 8402 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
8122 }, 8403#endif /* CONFIG_IPW2100_MONITOR */
8123#endif /* CONFIG_IPW2100_MONITOR */
8124 8404
8125 { 8405 {
8126 IPW2100_PRIV_SET_POWER, 8406 IPW2100_PRIV_SET_POWER,
8127 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power" 8407 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power"},
8128 },
8129 { 8408 {
8130 IPW2100_PRIV_GET_POWER, 8409 IPW2100_PRIV_GET_POWER,
8131 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING, "get_power" 8410 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING,
8132 }, 8411 "get_power"},
8133 { 8412 {
8134 IPW2100_PRIV_SET_LONGPREAMBLE, 8413 IPW2100_PRIV_SET_LONGPREAMBLE,
8135 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble" 8414 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
8136 },
8137 { 8415 {
8138 IPW2100_PRIV_GET_LONGPREAMBLE, 8416 IPW2100_PRIV_GET_LONGPREAMBLE,
8139 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble" 8417 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"},
8140 }, 8418#ifdef CONFIG_IPW2100_MONITOR
8419 {
8420 IPW2100_PRIV_SET_CRC_CHECK,
8421 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_crc_check"},
8422 {
8423 IPW2100_PRIV_GET_CRC_CHECK,
8424 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_crc_check"},
8425#endif /* CONFIG_IPW2100_MONITOR */
8141}; 8426};
8142 8427
8143static iw_handler ipw2100_private_handler[] = { 8428static iw_handler ipw2100_private_handler[] = {
8144#ifdef CONFIG_IPW2100_MONITOR 8429#ifdef CONFIG_IPW2100_MONITOR
8145 ipw2100_wx_set_promisc, 8430 ipw2100_wx_set_promisc,
8146 ipw2100_wx_reset, 8431 ipw2100_wx_reset,
8147#else /* CONFIG_IPW2100_MONITOR */ 8432#else /* CONFIG_IPW2100_MONITOR */
8148 NULL, 8433 NULL,
8149 NULL, 8434 NULL,
8150#endif /* CONFIG_IPW2100_MONITOR */ 8435#endif /* CONFIG_IPW2100_MONITOR */
8151 ipw2100_wx_set_powermode, 8436 ipw2100_wx_set_powermode,
8152 ipw2100_wx_get_powermode, 8437 ipw2100_wx_get_powermode,
8153 ipw2100_wx_set_preamble, 8438 ipw2100_wx_set_preamble,
8154 ipw2100_wx_get_preamble, 8439 ipw2100_wx_get_preamble,
8440#ifdef CONFIG_IPW2100_MONITOR
8441 ipw2100_wx_set_crc_check,
8442 ipw2100_wx_get_crc_check,
8443#else /* CONFIG_IPW2100_MONITOR */
8444 NULL,
8445 NULL,
8446#endif /* CONFIG_IPW2100_MONITOR */
8155}; 8447};
8156 8448
8157static struct iw_handler_def ipw2100_wx_handler_def = 8449static struct iw_handler_def ipw2100_wx_handler_def = {
8158{
8159 .standard = ipw2100_wx_handlers, 8450 .standard = ipw2100_wx_handlers,
8160 .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler), 8451 .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
8161 .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler), 8452 .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
8162 .num_private_args = sizeof(ipw2100_private_args) / 8453 .num_private_args = sizeof(ipw2100_private_args) /
8163 sizeof(struct iw_priv_args), 8454 sizeof(struct iw_priv_args),
8164 .private = (iw_handler *)ipw2100_private_handler, 8455 .private = (iw_handler *) ipw2100_private_handler,
8165 .private_args = (struct iw_priv_args *)ipw2100_private_args, 8456 .private_args = (struct iw_priv_args *)ipw2100_private_args,
8166}; 8457};
8167 8458
@@ -8170,7 +8461,7 @@ static struct iw_handler_def ipw2100_wx_handler_def =
8170 * Called by /proc/net/wireless 8461 * Called by /proc/net/wireless
8171 * Also called by SIOCGIWSTATS 8462 * Also called by SIOCGIWSTATS
8172 */ 8463 */
8173static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev) 8464static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
8174{ 8465{
8175 enum { 8466 enum {
8176 POOR = 30, 8467 POOR = 30,
@@ -8190,7 +8481,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8190 u32 ord_len = sizeof(u32); 8481 u32 ord_len = sizeof(u32);
8191 8482
8192 if (!priv) 8483 if (!priv)
8193 return (struct iw_statistics *) NULL; 8484 return (struct iw_statistics *)NULL;
8194 8485
8195 wstats = &priv->wstats; 8486 wstats = &priv->wstats;
8196 8487
@@ -8207,7 +8498,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8207 wstats->qual.noise = 0; 8498 wstats->qual.noise = 0;
8208 wstats->qual.updated = 7; 8499 wstats->qual.updated = 7;
8209 wstats->qual.updated |= IW_QUAL_NOISE_INVALID | 8500 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
8210 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; 8501 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
8211 return wstats; 8502 return wstats;
8212 } 8503 }
8213 8504
@@ -8215,7 +8506,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8215 &missed_beacons, &ord_len)) 8506 &missed_beacons, &ord_len))
8216 goto fail_get_ordinal; 8507 goto fail_get_ordinal;
8217 8508
8218 /* If we don't have a connection the quality and level is 0*/ 8509 /* If we don't have a connection the quality and level is 0 */
8219 if (!(priv->status & STATUS_ASSOCIATED)) { 8510 if (!(priv->status & STATUS_ASSOCIATED)) {
8220 wstats->qual.qual = 0; 8511 wstats->qual.qual = 0;
8221 wstats->qual.level = 0; 8512 wstats->qual.level = 0;
@@ -8232,10 +8523,10 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8232 rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR; 8523 rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR;
8233 else if (rssi < 30) 8524 else if (rssi < 30)
8234 rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) / 8525 rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) /
8235 10 + GOOD; 8526 10 + GOOD;
8236 else 8527 else
8237 rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) / 8528 rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) /
8238 10 + VERY_GOOD; 8529 10 + VERY_GOOD;
8239 8530
8240 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES, 8531 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES,
8241 &tx_retries, &ord_len)) 8532 &tx_retries, &ord_len))
@@ -8249,25 +8540,25 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8249 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR; 8540 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
8250 else if (tx_retries > 50) 8541 else if (tx_retries > 50)
8251 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) / 8542 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
8252 15 + GOOD; 8543 15 + GOOD;
8253 else 8544 else
8254 tx_qual = (50 - tx_retries) * 8545 tx_qual = (50 - tx_retries) *
8255 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD; 8546 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
8256 8547
8257 if (missed_beacons > 50) 8548 if (missed_beacons > 50)
8258 beacon_qual = (60 - missed_beacons) * POOR / 10; 8549 beacon_qual = (60 - missed_beacons) * POOR / 10;
8259 else if (missed_beacons > 40) 8550 else if (missed_beacons > 40)
8260 beacon_qual = (50 - missed_beacons) * (FAIR - POOR) / 8551 beacon_qual = (50 - missed_beacons) * (FAIR - POOR) /
8261 10 + POOR; 8552 10 + POOR;
8262 else if (missed_beacons > 32) 8553 else if (missed_beacons > 32)
8263 beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) / 8554 beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) /
8264 18 + FAIR; 8555 18 + FAIR;
8265 else if (missed_beacons > 20) 8556 else if (missed_beacons > 20)
8266 beacon_qual = (32 - missed_beacons) * 8557 beacon_qual = (32 - missed_beacons) *
8267 (VERY_GOOD - GOOD) / 20 + GOOD; 8558 (VERY_GOOD - GOOD) / 20 + GOOD;
8268 else 8559 else
8269 beacon_qual = (20 - missed_beacons) * 8560 beacon_qual = (20 - missed_beacons) *
8270 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD; 8561 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
8271 8562
8272 quality = min(beacon_qual, min(tx_qual, rssi_qual)); 8563 quality = min(beacon_qual, min(tx_qual, rssi_qual));
8273 8564
@@ -8290,7 +8581,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8290 wstats->qual.updated = 7; 8581 wstats->qual.updated = 7;
8291 wstats->qual.updated |= IW_QUAL_NOISE_INVALID; 8582 wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
8292 8583
8293 /* FIXME: this is percent and not a # */ 8584 /* FIXME: this is percent and not a # */
8294 wstats->miss.beacon = missed_beacons; 8585 wstats->miss.beacon = missed_beacons;
8295 8586
8296 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES, 8587 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES,
@@ -8300,10 +8591,10 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8300 8591
8301 return wstats; 8592 return wstats;
8302 8593
8303 fail_get_ordinal: 8594 fail_get_ordinal:
8304 IPW_DEBUG_WX("failed querying ordinals.\n"); 8595 IPW_DEBUG_WX("failed querying ordinals.\n");
8305 8596
8306 return (struct iw_statistics *) NULL; 8597 return (struct iw_statistics *)NULL;
8307} 8598}
8308 8599
8309static void ipw2100_wx_event_work(struct ipw2100_priv *priv) 8600static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
@@ -8326,23 +8617,17 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8326 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) || 8617 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) ||
8327 priv->status & STATUS_RF_KILL_MASK || 8618 priv->status & STATUS_RF_KILL_MASK ||
8328 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, 8619 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID,
8329 &priv->bssid, &len)) { 8620 &priv->bssid, &len)) {
8330 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 8621 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
8331 } else { 8622 } else {
8332 /* We now have the BSSID, so can finish setting to the full 8623 /* We now have the BSSID, so can finish setting to the full
8333 * associated state */ 8624 * associated state */
8334 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN); 8625 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
8335 memcpy(&priv->ieee->bssid, priv->bssid, ETH_ALEN); 8626 memcpy(priv->ieee->bssid, priv->bssid, ETH_ALEN);
8336 priv->status &= ~STATUS_ASSOCIATING; 8627 priv->status &= ~STATUS_ASSOCIATING;
8337 priv->status |= STATUS_ASSOCIATED; 8628 priv->status |= STATUS_ASSOCIATED;
8338 netif_carrier_on(priv->net_dev); 8629 netif_carrier_on(priv->net_dev);
8339 if (netif_queue_stopped(priv->net_dev)) { 8630 netif_wake_queue(priv->net_dev);
8340 IPW_DEBUG_INFO("Waking net queue.\n");
8341 netif_wake_queue(priv->net_dev);
8342 } else {
8343 IPW_DEBUG_INFO("Starting net queue.\n");
8344 netif_start_queue(priv->net_dev);
8345 }
8346 } 8631 }
8347 8632
8348 if (!(priv->status & STATUS_ASSOCIATED)) { 8633 if (!(priv->status & STATUS_ASSOCIATED)) {
@@ -8351,7 +8636,8 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8351 /* This is a disassociation event, so kick the firmware to 8636 /* This is a disassociation event, so kick the firmware to
8352 * look for another AP */ 8637 * look for another AP */
8353 if (priv->config & CFG_STATIC_ESSID) 8638 if (priv->config & CFG_STATIC_ESSID)
8354 ipw2100_set_essid(priv, priv->essid, priv->essid_len, 0); 8639 ipw2100_set_essid(priv, priv->essid, priv->essid_len,
8640 0);
8355 else 8641 else
8356 ipw2100_set_essid(priv, NULL, 0, 0); 8642 ipw2100_set_essid(priv, NULL, 0, 0);
8357 up(&priv->action_sem); 8643 up(&priv->action_sem);
@@ -8374,7 +8660,6 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8374 8660
8375#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw" 8661#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw"
8376 8662
8377
8378/* 8663/*
8379 8664
8380BINARY FIRMWARE HEADER FORMAT 8665BINARY FIRMWARE HEADER FORMAT
@@ -8396,12 +8681,10 @@ struct ipw2100_fw_header {
8396 unsigned int uc_size; 8681 unsigned int uc_size;
8397} __attribute__ ((packed)); 8682} __attribute__ ((packed));
8398 8683
8399
8400
8401static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw) 8684static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
8402{ 8685{
8403 struct ipw2100_fw_header *h = 8686 struct ipw2100_fw_header *h =
8404 (struct ipw2100_fw_header *)fw->fw_entry->data; 8687 (struct ipw2100_fw_header *)fw->fw_entry->data;
8405 8688
8406 if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) { 8689 if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) {
8407 printk(KERN_WARNING DRV_NAME ": Firmware image not compatible " 8690 printk(KERN_WARNING DRV_NAME ": Firmware image not compatible "
@@ -8420,7 +8703,6 @@ static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
8420 return 0; 8703 return 0;
8421} 8704}
8422 8705
8423
8424static int ipw2100_get_firmware(struct ipw2100_priv *priv, 8706static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8425 struct ipw2100_fw *fw) 8707 struct ipw2100_fw *fw)
8426{ 8708{
@@ -8428,7 +8710,7 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8428 int rc; 8710 int rc;
8429 8711
8430 IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n", 8712 IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n",
8431 priv->net_dev->name); 8713 priv->net_dev->name);
8432 8714
8433 switch (priv->ieee->iw_mode) { 8715 switch (priv->ieee->iw_mode) {
8434 case IW_MODE_ADHOC: 8716 case IW_MODE_ADHOC:
@@ -8454,7 +8736,7 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8454 return rc; 8736 return rc;
8455 } 8737 }
8456 IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data, 8738 IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data,
8457 fw->fw_entry->size); 8739 fw->fw_entry->size);
8458 8740
8459 ipw2100_mod_firmware_load(fw); 8741 ipw2100_mod_firmware_load(fw);
8460 8742
@@ -8470,7 +8752,6 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
8470 fw->fw_entry = NULL; 8752 fw->fw_entry = NULL;
8471} 8753}
8472 8754
8473
8474static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf, 8755static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
8475 size_t max) 8756 size_t max)
8476{ 8757{
@@ -8479,8 +8760,7 @@ static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
8479 u32 tmp; 8760 u32 tmp;
8480 int i; 8761 int i;
8481 /* firmware version is an ascii string (max len of 14) */ 8762 /* firmware version is an ascii string (max len of 14) */
8482 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM, 8763 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM, ver, &len))
8483 ver, &len))
8484 return -EIO; 8764 return -EIO;
8485 tmp = max; 8765 tmp = max;
8486 if (len >= max) 8766 if (len >= max)
@@ -8497,8 +8777,7 @@ static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
8497 u32 ver; 8777 u32 ver;
8498 u32 len = sizeof(ver); 8778 u32 len = sizeof(ver);
8499 /* microcode version is a 32 bit integer */ 8779 /* microcode version is a 32 bit integer */
8500 if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION, 8780 if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION, &ver, &len))
8501 &ver, &len))
8502 return -EIO; 8781 return -EIO;
8503 return snprintf(buf, max, "%08X", ver); 8782 return snprintf(buf, max, "%08X", ver);
8504} 8783}
@@ -8506,8 +8785,7 @@ static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
8506/* 8785/*
8507 * On exit, the firmware will have been freed from the fw list 8786 * On exit, the firmware will have been freed from the fw list
8508 */ 8787 */
8509static int ipw2100_fw_download(struct ipw2100_priv *priv, 8788static int ipw2100_fw_download(struct ipw2100_priv *priv, struct ipw2100_fw *fw)
8510 struct ipw2100_fw *fw)
8511{ 8789{
8512 /* firmware is constructed of N contiguous entries, each entry is 8790 /* firmware is constructed of N contiguous entries, each entry is
8513 * structured as: 8791 * structured as:
@@ -8515,7 +8793,7 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8515 * offset sie desc 8793 * offset sie desc
8516 * 0 4 address to write to 8794 * 0 4 address to write to
8517 * 4 2 length of data run 8795 * 4 2 length of data run
8518 * 6 length data 8796 * 6 length data
8519 */ 8797 */
8520 unsigned int addr; 8798 unsigned int addr;
8521 unsigned short len; 8799 unsigned short len;
@@ -8524,12 +8802,12 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8524 unsigned int firmware_data_left = fw->fw.size; 8802 unsigned int firmware_data_left = fw->fw.size;
8525 8803
8526 while (firmware_data_left > 0) { 8804 while (firmware_data_left > 0) {
8527 addr = *(u32 *)(firmware_data); 8805 addr = *(u32 *) (firmware_data);
8528 firmware_data += 4; 8806 firmware_data += 4;
8529 firmware_data_left -= 4; 8807 firmware_data_left -= 4;
8530 8808
8531 len = *(u16 *)(firmware_data); 8809 len = *(u16 *) (firmware_data);
8532 firmware_data += 2; 8810 firmware_data += 2;
8533 firmware_data_left -= 2; 8811 firmware_data_left -= 2;
8534 8812
8535 if (len > 32) { 8813 if (len > 32) {
@@ -8540,7 +8818,7 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8540 } 8818 }
8541 8819
8542 write_nic_memory(priv->net_dev, addr, len, firmware_data); 8820 write_nic_memory(priv->net_dev, addr, len, firmware_data);
8543 firmware_data += len; 8821 firmware_data += len;
8544 firmware_data_left -= len; 8822 firmware_data_left -= len;
8545 } 8823 }
8546 8824
@@ -8654,21 +8932,19 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
8654 for (i = 0; i < 30; i++) { 8932 for (i = 0; i < 30; i++) {
8655 /* Read alive response structure */ 8933 /* Read alive response structure */
8656 for (j = 0; 8934 for (j = 0;
8657 j < (sizeof(struct symbol_alive_response) >> 1); 8935 j < (sizeof(struct symbol_alive_response) >> 1); j++)
8658 j++) 8936 read_nic_word(dev, 0x210004, ((u16 *) & response) + j);
8659 read_nic_word(dev, 0x210004,
8660 ((u16 *)&response) + j);
8661 8937
8662 if ((response.cmd_id == 1) && 8938 if ((response.cmd_id == 1) && (response.ucode_valid == 0x1))
8663 (response.ucode_valid == 0x1))
8664 break; 8939 break;
8665 udelay(10); 8940 udelay(10);
8666 } 8941 }
8667 8942
8668 if (i == 30) { 8943 if (i == 30) {
8669 printk(KERN_ERR DRV_NAME ": %s: No response from Symbol - hw not alive\n", 8944 printk(KERN_ERR DRV_NAME
8945 ": %s: No response from Symbol - hw not alive\n",
8670 dev->name); 8946 dev->name);
8671 printk_buf(IPW_DL_ERROR, (u8*)&response, sizeof(response)); 8947 printk_buf(IPW_DL_ERROR, (u8 *) & response, sizeof(response));
8672 return -EIO; 8948 return -EIO;
8673 } 8949 }
8674 8950
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index c9e99ce15d66..140fdf2a0a09 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -37,7 +37,6 @@
37#include <linux/socket.h> 37#include <linux/socket.h>
38#include <linux/if_arp.h> 38#include <linux/if_arp.h>
39#include <linux/wireless.h> 39#include <linux/wireless.h>
40#include <linux/version.h>
41#include <net/iw_handler.h> // new driver API 40#include <net/iw_handler.h> // new driver API
42 41
43#include <net/ieee80211.h> 42#include <net/ieee80211.h>
@@ -93,7 +92,6 @@ struct ipw2100_rx_packet;
93#define IPW_DL_IOCTL (1<<14) 92#define IPW_DL_IOCTL (1<<14)
94#define IPW_DL_RF_KILL (1<<17) 93#define IPW_DL_RF_KILL (1<<17)
95 94
96
97#define IPW_DL_MANAGE (1<<15) 95#define IPW_DL_MANAGE (1<<15)
98#define IPW_DL_FW (1<<16) 96#define IPW_DL_FW (1<<16)
99 97
@@ -156,7 +154,9 @@ extern const char *band_str[];
156 154
157struct bd_status { 155struct bd_status {
158 union { 156 union {
159 struct { u8 nlf:1, txType:2, intEnabled:1, reserved:4;} fields; 157 struct {
158 u8 nlf:1, txType:2, intEnabled:1, reserved:4;
159 } fields;
160 u8 field; 160 u8 field;
161 } info; 161 } info;
162} __attribute__ ((packed)); 162} __attribute__ ((packed));
@@ -165,7 +165,7 @@ struct ipw2100_bd {
165 u32 host_addr; 165 u32 host_addr;
166 u32 buf_length; 166 u32 buf_length;
167 struct bd_status status; 167 struct bd_status status;
168 /* number of fragments for frame (should be set only for 168 /* number of fragments for frame (should be set only for
169 * 1st TBD) */ 169 * 1st TBD) */
170 u8 num_fragments; 170 u8 num_fragments;
171 u8 reserved[6]; 171 u8 reserved[6];
@@ -293,10 +293,10 @@ struct ipw2100_cmd_header {
293struct ipw2100_data_header { 293struct ipw2100_data_header {
294 u32 host_command_reg; 294 u32 host_command_reg;
295 u32 host_command_reg1; 295 u32 host_command_reg1;
296 u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver 296 u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver
297 u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC 297 u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC
298 u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key 298 u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key
299 u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV 299 u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV
300 u8 key[16]; 300 u8 key[16];
301 u8 reserved[10]; // f/w reserved 301 u8 reserved[10]; // f/w reserved
302 u8 src_addr[ETH_ALEN]; 302 u8 src_addr[ETH_ALEN];
@@ -306,14 +306,13 @@ struct ipw2100_data_header {
306 306
307/* Host command data structure */ 307/* Host command data structure */
308struct host_command { 308struct host_command {
309 u32 host_command; // COMMAND ID 309 u32 host_command; // COMMAND ID
310 u32 host_command1; // COMMAND ID 310 u32 host_command1; // COMMAND ID
311 u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID) 311 u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID)
312 u32 host_command_length; // LENGTH 312 u32 host_command_length; // LENGTH
313 u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS 313 u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS
314} __attribute__ ((packed)); 314} __attribute__ ((packed));
315 315
316
317typedef enum { 316typedef enum {
318 POWER_ON_RESET, 317 POWER_ON_RESET,
319 EXIT_POWER_DOWN_RESET, 318 EXIT_POWER_DOWN_RESET,
@@ -328,17 +327,16 @@ enum {
328 RX 327 RX
329}; 328};
330 329
331
332struct ipw2100_tx_packet { 330struct ipw2100_tx_packet {
333 int type; 331 int type;
334 int index; 332 int index;
335 union { 333 union {
336 struct { /* COMMAND */ 334 struct { /* COMMAND */
337 struct ipw2100_cmd_header* cmd; 335 struct ipw2100_cmd_header *cmd;
338 dma_addr_t cmd_phys; 336 dma_addr_t cmd_phys;
339 } c_struct; 337 } c_struct;
340 struct { /* DATA */ 338 struct { /* DATA */
341 struct ipw2100_data_header* data; 339 struct ipw2100_data_header *data;
342 dma_addr_t data_phys; 340 dma_addr_t data_phys;
343 struct ieee80211_txb *txb; 341 struct ieee80211_txb *txb;
344 } d_struct; 342 } d_struct;
@@ -348,7 +346,6 @@ struct ipw2100_tx_packet {
348 struct list_head list; 346 struct list_head list;
349}; 347};
350 348
351
352struct ipw2100_rx_packet { 349struct ipw2100_rx_packet {
353 struct ipw2100_rx *rxp; 350 struct ipw2100_rx *rxp;
354 dma_addr_t dma_addr; 351 dma_addr_t dma_addr;
@@ -432,13 +429,13 @@ enum {
432}; 429};
433 430
434#define STATUS_POWERED (1<<0) 431#define STATUS_POWERED (1<<0)
435#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */ 432#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */
436#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */ 433#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */
437#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */ 434#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */
438#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */ 435#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */
439#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */ 436#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */
440#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */ 437#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */
441#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */ 438#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */
442#define STATUS_INT_ENABLED (1<<11) 439#define STATUS_INT_ENABLED (1<<11)
443#define STATUS_RF_KILL_HW (1<<12) 440#define STATUS_RF_KILL_HW (1<<12)
444#define STATUS_RF_KILL_SW (1<<13) 441#define STATUS_RF_KILL_SW (1<<13)
@@ -451,9 +448,7 @@ enum {
451#define STATUS_SCAN_COMPLETE (1<<26) 448#define STATUS_SCAN_COMPLETE (1<<26)
452#define STATUS_WX_EVENT_PENDING (1<<27) 449#define STATUS_WX_EVENT_PENDING (1<<27)
453#define STATUS_RESET_PENDING (1<<29) 450#define STATUS_RESET_PENDING (1<<29)
454#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */ 451#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */
455
456
457 452
458/* Internal NIC states */ 453/* Internal NIC states */
459#define IPW_STATE_INITIALIZED (1<<0) 454#define IPW_STATE_INITIALIZED (1<<0)
@@ -469,11 +464,9 @@ enum {
469#define IPW_STATE_POWER_DOWN (1<<10) 464#define IPW_STATE_POWER_DOWN (1<<10)
470#define IPW_STATE_SCANNING (1<<11) 465#define IPW_STATE_SCANNING (1<<11)
471 466
472 467#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */
473 468#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
474#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */ 469#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
475#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
476#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
477#define CFG_CUSTOM_MAC (1<<3) 470#define CFG_CUSTOM_MAC (1<<3)
478#define CFG_LONG_PREAMBLE (1<<4) 471#define CFG_LONG_PREAMBLE (1<<4)
479#define CFG_ASSOCIATE (1<<6) 472#define CFG_ASSOCIATE (1<<6)
@@ -481,14 +474,17 @@ enum {
481#define CFG_ADHOC_CREATE (1<<8) 474#define CFG_ADHOC_CREATE (1<<8)
482#define CFG_C3_DISABLED (1<<9) 475#define CFG_C3_DISABLED (1<<9)
483#define CFG_PASSIVE_SCAN (1<<10) 476#define CFG_PASSIVE_SCAN (1<<10)
477#ifdef CONFIG_IPW2100_MONITOR
478#define CFG_CRC_CHECK (1<<11)
479#endif
484 480
485#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ 481#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
486#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ 482#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
487 483
488struct ipw2100_priv { 484struct ipw2100_priv {
489 485
490 int stop_hang_check; /* Set 1 when shutting down to kill hang_check */ 486 int stop_hang_check; /* Set 1 when shutting down to kill hang_check */
491 int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */ 487 int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */
492 488
493 struct ieee80211_device *ieee; 489 struct ieee80211_device *ieee;
494 unsigned long status; 490 unsigned long status;
@@ -519,19 +515,16 @@ struct ipw2100_priv {
519 unsigned long hw_features; 515 unsigned long hw_features;
520 int hangs; 516 int hangs;
521 u32 last_rtc; 517 u32 last_rtc;
522 int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */ 518 int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */
523 u8* snapshot[0x30]; 519 u8 *snapshot[0x30];
524 520
525 u8 mandatory_bssid_mac[ETH_ALEN]; 521 u8 mandatory_bssid_mac[ETH_ALEN];
526 u8 mac_addr[ETH_ALEN]; 522 u8 mac_addr[ETH_ALEN];
527 523
528 int power_mode; 524 int power_mode;
529 525
530 /* WEP data */
531 struct ieee80211_security sec;
532 int messages_sent; 526 int messages_sent;
533 527
534
535 int short_retry_limit; 528 int short_retry_limit;
536 int long_retry_limit; 529 int long_retry_limit;
537 530
@@ -599,7 +592,6 @@ struct ipw2100_priv {
599 wait_queue_head_t wait_command_queue; 592 wait_queue_head_t wait_command_queue;
600}; 593};
601 594
602
603/********************************************************* 595/*********************************************************
604 * Host Command -> From Driver to FW 596 * Host Command -> From Driver to FW
605 *********************************************************/ 597 *********************************************************/
@@ -646,7 +638,6 @@ struct ipw2100_priv {
646#define CARD_DISABLE_PHY_OFF 61 638#define CARD_DISABLE_PHY_OFF 61
647#define MSDU_TX_RATES 62 639#define MSDU_TX_RATES 62
648 640
649
650/* Rogue AP Detection */ 641/* Rogue AP Detection */
651#define SET_STATION_STAT_BITS 64 642#define SET_STATION_STAT_BITS 64
652#define CLEAR_STATIONS_STAT_BITS 65 643#define CLEAR_STATIONS_STAT_BITS 65
@@ -655,8 +646,6 @@ struct ipw2100_priv {
655#define DISASSOCIATION_BSSID 68 646#define DISASSOCIATION_BSSID 68
656#define SET_WPA_IE 69 647#define SET_WPA_IE 69
657 648
658
659
660/* system configuration bit mask: */ 649/* system configuration bit mask: */
661#define IPW_CFG_MONITOR 0x00004 650#define IPW_CFG_MONITOR 0x00004
662#define IPW_CFG_PREAMBLE_AUTO 0x00010 651#define IPW_CFG_PREAMBLE_AUTO 0x00010
@@ -704,7 +693,7 @@ struct ipw2100_priv {
704#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB) 693#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB)
705#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1 694#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1
706#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2 695#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2
707#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3 696#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3
708#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4 697#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4
709#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5 698#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5
710#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16 699#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16
@@ -784,9 +773,6 @@ struct ipw2100_priv {
784#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli 773#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli
785#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli 774#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli
786 775
787
788
789
790#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr) 776#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr)
791#define IPW_MAX_80211_PAYLOAD_SIZE 2304U 777#define IPW_MAX_80211_PAYLOAD_SIZE 2304U
792#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312 778#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312
@@ -843,8 +829,8 @@ struct ipw2100_rx {
843#define IPW_TX_POWER_MIN_DBM (-12) 829#define IPW_TX_POWER_MIN_DBM (-12)
844#define IPW_TX_POWER_MAX_DBM 16 830#define IPW_TX_POWER_MAX_DBM 16
845 831
846#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan 832#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan
847#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan 833#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan
848 834
849#define REG_MIN_CHANNEL 0 835#define REG_MIN_CHANNEL 0
850#define REG_MAX_CHANNEL 14 836#define REG_MAX_CHANNEL 14
@@ -856,7 +842,6 @@ struct ipw2100_rx {
856#define DIVERSITY_ANTENNA_A 1 // Use antenna A 842#define DIVERSITY_ANTENNA_A 1 // Use antenna A
857#define DIVERSITY_ANTENNA_B 2 // Use antenna B 843#define DIVERSITY_ANTENNA_B 2 // Use antenna B
858 844
859
860#define HOST_COMMAND_WAIT 0 845#define HOST_COMMAND_WAIT 0
861#define HOST_COMMAND_NO_WAIT 1 846#define HOST_COMMAND_NO_WAIT 1
862 847
@@ -873,10 +858,9 @@ struct ipw2100_rx {
873#define TYPE_ASSOCIATION_REQUEST 0x0013 858#define TYPE_ASSOCIATION_REQUEST 0x0013
874#define TYPE_REASSOCIATION_REQUEST 0x0014 859#define TYPE_REASSOCIATION_REQUEST 0x0014
875 860
876 861#define HW_FEATURE_RFKILL 0x0001
877#define HW_FEATURE_RFKILL (0x0001) 862#define RF_KILLSWITCH_OFF 1
878#define RF_KILLSWITCH_OFF (1) 863#define RF_KILLSWITCH_ON 0
879#define RF_KILLSWITCH_ON (0)
880 864
881#define IPW_COMMAND_POOL_SIZE 40 865#define IPW_COMMAND_POOL_SIZE 40
882 866
@@ -895,7 +879,7 @@ struct ipw2100_rx {
895// Fixed size data: Ordinal Table 1 879// Fixed size data: Ordinal Table 1
896typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW 880typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
897// Transmit statistics 881// Transmit statistics
898 IPW_ORD_STAT_TX_HOST_REQUESTS = 1,// # of requested Host Tx's (MSDU) 882 IPW_ORD_STAT_TX_HOST_REQUESTS = 1, // # of requested Host Tx's (MSDU)
899 IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU) 883 IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU)
900 IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU) 884 IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU)
901 885
@@ -905,42 +889,42 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
905 IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB 889 IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB
906 IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB 890 IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB
907 891
908 IPW_ORD_STAT_TX_NODIR_DATA1 = 13,// # of successful Non_Directed Tx's (MSDU) @ 1MB 892 IPW_ORD_STAT_TX_NODIR_DATA1 = 13, // # of successful Non_Directed Tx's (MSDU) @ 1MB
909 IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB 893 IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB
910 IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB 894 IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB
911 IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB 895 IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB
912 896
913 IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's 897 IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's
914 IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS 898 IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS
915 IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS 899 IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS
916 IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK 900 IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK
917 IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's 901 IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's
918 IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's 902 IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's
919 IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's 903 IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's
920 IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's 904 IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's
921 IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted 905 IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted
922 IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted 906 IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted
923 IPW_ORD_STAT_TX_BEACON, // # of tx beacon 907 IPW_ORD_STAT_TX_BEACON, // # of tx beacon
924 IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM 908 IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM
925 IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX 909 IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX
926 IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx 910 IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx
927 IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX 911 IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX
928 912
929 IPW_ORD_STAT_TX_TOTAL_BYTES = 41,// Total successful Tx data bytes 913 IPW_ORD_STAT_TX_TOTAL_BYTES = 41, // Total successful Tx data bytes
930 IPW_ORD_STAT_TX_RETRIES, // # of Tx retries 914 IPW_ORD_STAT_TX_RETRIES, // # of Tx retries
931 IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS 915 IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS
932 IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS 916 IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS
933 IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS 917 IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS
934 IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS 918 IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS
935 919
936 IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures 920 IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures
937 IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time 921 IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time
938 IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP,// # of times max tries in a hop failed 922 IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP, // # of times max tries in a hop failed
939 IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup 923 IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup
940 IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted 924 IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted
941 IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed 925 IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed
942 IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames 926 IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames
943 IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent 927 IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent
944 IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks 928 IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks
945 929
946 // Receive statistics 930 // Receive statistics
@@ -952,7 +936,7 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
952 IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB 936 IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB
953 IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB 937 IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB
954 938
955 IPW_ORD_STAT_RX_NODIR_DATA = 71,// # of nondirected packets 939 IPW_ORD_STAT_RX_NODIR_DATA = 71, // # of nondirected packets
956 IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB 940 IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB
957 IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB 941 IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB
958 IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB 942 IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB
@@ -977,18 +961,18 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
977 IPW_ORD_STAT_RX_AUTH, // # of authentication Rx 961 IPW_ORD_STAT_RX_AUTH, // # of authentication Rx
978 IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx 962 IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx
979 963
980 IPW_ORD_STAT_RX_TOTAL_BYTES = 101,// Total rx data bytes received 964 IPW_ORD_STAT_RX_TOTAL_BYTES = 101, // Total rx data bytes received
981 IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error 965 IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error
982 IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB 966 IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB
983 IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB 967 IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB
984 IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB 968 IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB
985 IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB 969 IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB
986 970
987 IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB 971 IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB
988 IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB 972 IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB
989 IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB 973 IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB
990 IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB 974 IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB
991 IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets 975 IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets
992 976
993 IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db 977 IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db
994 IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db 978 IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db
@@ -1006,17 +990,17 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
1006 IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption 990 IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption
1007 991
1008// PSP Statistics 992// PSP Statistics
1009 IPW_ORD_STAT_PSP_SUSPENSION = 137,// # of times adapter suspended 993 IPW_ORD_STAT_PSP_SUSPENSION = 137, // # of times adapter suspended
1010 IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout 994 IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout
1011 IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts 995 IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts
1012 IPW_ORD_STAT_PSP_NONDIR_TIMEOUT,// # of timeouts waiting for last broadcast/muticast pkt 996 IPW_ORD_STAT_PSP_NONDIR_TIMEOUT, // # of timeouts waiting for last broadcast/muticast pkt
1013 IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received 997 IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received
1014 IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received 998 IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received
1015 IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID 999 IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID
1016 1000
1017// Association and roaming 1001// Association and roaming
1018 IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association 1002 IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association
1019 IPW_ORD_STAT_PERCENT_MISSED_BCNS,// current calculation of % missed beacons 1003 IPW_ORD_STAT_PERCENT_MISSED_BCNS, // current calculation of % missed beacons
1020 IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries 1004 IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries
1021 IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated 1005 IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated
1022 // AP table entry. set to 0 if not associated 1006 // AP table entry. set to 0 if not associated
@@ -1151,7 +1135,7 @@ struct ipw2100_fw_chunk {
1151}; 1135};
1152 1136
1153struct ipw2100_fw_chunk_set { 1137struct ipw2100_fw_chunk_set {
1154 const void *data; 1138 const void *data;
1155 unsigned long size; 1139 unsigned long size;
1156}; 1140};
1157 1141
@@ -1164,4 +1148,4 @@ struct ipw2100_fw {
1164 1148
1165#define MAX_FW_VERSION_LEN 14 1149#define MAX_FW_VERSION_LEN 14
1166 1150
1167#endif /* _IPW2100_H */ 1151#endif /* _IPW2100_H */
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 3db0c32afe82..b0d195d1721a 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4 4
5 802.11 status code portion of this file from ethereal-0.10.6: 5 802.11 status code portion of this file from ethereal-0.10.6:
6 Copyright 2000, Axis Communications AB 6 Copyright 2000, Axis Communications AB
@@ -31,30 +31,103 @@
31******************************************************************************/ 31******************************************************************************/
32 32
33#include "ipw2200.h" 33#include "ipw2200.h"
34#include <linux/version.h>
34 35
35#define IPW2200_VERSION "1.0.0" 36#define IPW2200_VERSION "git-1.0.8"
36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" 37#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
37#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" 38#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
38#define DRV_VERSION IPW2200_VERSION 39#define DRV_VERSION IPW2200_VERSION
39 40
41#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
42
40MODULE_DESCRIPTION(DRV_DESCRIPTION); 43MODULE_DESCRIPTION(DRV_DESCRIPTION);
41MODULE_VERSION(DRV_VERSION); 44MODULE_VERSION(DRV_VERSION);
42MODULE_AUTHOR(DRV_COPYRIGHT); 45MODULE_AUTHOR(DRV_COPYRIGHT);
43MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
44 47
48static int cmdlog = 0;
45static int debug = 0; 49static int debug = 0;
46static int channel = 0; 50static int channel = 0;
47static char *ifname;
48static int mode = 0; 51static int mode = 0;
49 52
50static u32 ipw_debug_level; 53static u32 ipw_debug_level;
51static int associate = 1; 54static int associate = 1;
52static int auto_create = 1; 55static int auto_create = 1;
56static int led = 0;
53static int disable = 0; 57static int disable = 0;
58static int hwcrypto = 1;
54static const char ipw_modes[] = { 59static const char ipw_modes[] = {
55 'a', 'b', 'g', '?' 60 'a', 'b', 'g', '?'
56}; 61};
57 62
63#ifdef CONFIG_IPW_QOS
64static int qos_enable = 0;
65static int qos_burst_enable = 0;
66static int qos_no_ack_mask = 0;
67static int burst_duration_CCK = 0;
68static int burst_duration_OFDM = 0;
69
70static struct ieee80211_qos_parameters def_qos_parameters_OFDM = {
71 {QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,
72 QOS_TX3_CW_MIN_OFDM},
73 {QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,
74 QOS_TX3_CW_MAX_OFDM},
75 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
76 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
77 {QOS_TX0_TXOP_LIMIT_OFDM, QOS_TX1_TXOP_LIMIT_OFDM,
78 QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}
79};
80
81static struct ieee80211_qos_parameters def_qos_parameters_CCK = {
82 {QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,
83 QOS_TX3_CW_MIN_CCK},
84 {QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,
85 QOS_TX3_CW_MAX_CCK},
86 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
87 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
88 {QOS_TX0_TXOP_LIMIT_CCK, QOS_TX1_TXOP_LIMIT_CCK, QOS_TX2_TXOP_LIMIT_CCK,
89 QOS_TX3_TXOP_LIMIT_CCK}
90};
91
92static struct ieee80211_qos_parameters def_parameters_OFDM = {
93 {DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,
94 DEF_TX3_CW_MIN_OFDM},
95 {DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,
96 DEF_TX3_CW_MAX_OFDM},
97 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
98 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
99 {DEF_TX0_TXOP_LIMIT_OFDM, DEF_TX1_TXOP_LIMIT_OFDM,
100 DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}
101};
102
103static struct ieee80211_qos_parameters def_parameters_CCK = {
104 {DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,
105 DEF_TX3_CW_MIN_CCK},
106 {DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,
107 DEF_TX3_CW_MAX_CCK},
108 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
109 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
110 {DEF_TX0_TXOP_LIMIT_CCK, DEF_TX1_TXOP_LIMIT_CCK, DEF_TX2_TXOP_LIMIT_CCK,
111 DEF_TX3_TXOP_LIMIT_CCK}
112};
113
114static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
115
116static int from_priority_to_tx_queue[] = {
117 IPW_TX_QUEUE_1, IPW_TX_QUEUE_2, IPW_TX_QUEUE_2, IPW_TX_QUEUE_1,
118 IPW_TX_QUEUE_3, IPW_TX_QUEUE_3, IPW_TX_QUEUE_4, IPW_TX_QUEUE_4
119};
120
121static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);
122
123static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
124 *qos_param);
125static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
126 *qos_param);
127#endif /* CONFIG_IPW_QOS */
128
129static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev);
130static void ipw_remove_current_network(struct ipw_priv *priv);
58static void ipw_rx(struct ipw_priv *priv); 131static void ipw_rx(struct ipw_priv *priv);
59static int ipw_queue_tx_reclaim(struct ipw_priv *priv, 132static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
60 struct clx2_tx_queue *txq, int qindex); 133 struct clx2_tx_queue *txq, int qindex);
@@ -68,42 +141,24 @@ static void ipw_tx_queue_free(struct ipw_priv *);
68static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *); 141static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
69static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *); 142static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
70static void ipw_rx_queue_replenish(void *); 143static void ipw_rx_queue_replenish(void *);
71
72static int ipw_up(struct ipw_priv *); 144static int ipw_up(struct ipw_priv *);
145static void ipw_bg_up(void *);
73static void ipw_down(struct ipw_priv *); 146static void ipw_down(struct ipw_priv *);
147static void ipw_bg_down(void *);
74static int ipw_config(struct ipw_priv *); 148static int ipw_config(struct ipw_priv *);
75static int init_supported_rates(struct ipw_priv *priv, 149static int init_supported_rates(struct ipw_priv *priv,
76 struct ipw_supported_rates *prates); 150 struct ipw_supported_rates *prates);
151static void ipw_set_hwcrypto_keys(struct ipw_priv *);
152static void ipw_send_wep_keys(struct ipw_priv *, int);
77 153
78static u8 band_b_active_channel[MAX_B_CHANNELS] = { 154static int ipw_is_valid_channel(struct ieee80211_device *, u8);
79 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0 155static int ipw_channel_to_index(struct ieee80211_device *, u8);
80}; 156static u8 ipw_freq_to_channel(struct ieee80211_device *, u32);
81static u8 band_a_active_channel[MAX_A_CHANNELS] = { 157static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *);
82 36, 40, 44, 48, 149, 153, 157, 161, 165, 52, 56, 60, 64, 0 158static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *);
83};
84 159
85static int is_valid_channel(int mode_mask, int channel) 160static int snprint_line(char *buf, size_t count,
86{ 161 const u8 * data, u32 len, u32 ofs)
87 int i;
88
89 if (!channel)
90 return 0;
91
92 if (mode_mask & IEEE_A)
93 for (i = 0; i < MAX_A_CHANNELS; i++)
94 if (band_a_active_channel[i] == channel)
95 return IEEE_A;
96
97 if (mode_mask & (IEEE_B | IEEE_G))
98 for (i = 0; i < MAX_B_CHANNELS; i++)
99 if (band_b_active_channel[i] == channel)
100 return mode_mask & (IEEE_B | IEEE_G);
101
102 return 0;
103}
104
105static char *snprint_line(char *buf, size_t count,
106 const u8 * data, u32 len, u32 ofs)
107{ 162{
108 int out, i, j, l; 163 int out, i, j, l;
109 char c; 164 char c;
@@ -134,7 +189,7 @@ static char *snprint_line(char *buf, size_t count,
134 out += snprintf(buf + out, count - out, " "); 189 out += snprintf(buf + out, count - out, " ");
135 } 190 }
136 191
137 return buf; 192 return out;
138} 193}
139 194
140static void printk_buf(int level, const u8 * data, u32 len) 195static void printk_buf(int level, const u8 * data, u32 len)
@@ -145,14 +200,33 @@ static void printk_buf(int level, const u8 * data, u32 len)
145 return; 200 return;
146 201
147 while (len) { 202 while (len) {
148 printk(KERN_DEBUG "%s\n", 203 snprint_line(line, sizeof(line), &data[ofs],
149 snprint_line(line, sizeof(line), &data[ofs], 204 min(len, 16U), ofs);
150 min(len, 16U), ofs)); 205 printk(KERN_DEBUG "%s\n", line);
151 ofs += 16; 206 ofs += 16;
152 len -= min(len, 16U); 207 len -= min(len, 16U);
153 } 208 }
154} 209}
155 210
211static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)
212{
213 size_t out = size;
214 u32 ofs = 0;
215 int total = 0;
216
217 while (size && len) {
218 out = snprint_line(output, size, &data[ofs],
219 min_t(size_t, len, 16U), ofs);
220
221 ofs += 16;
222 output += out;
223 size -= out;
224 len -= min_t(size_t, len, 16U);
225 total += out;
226 }
227 return total;
228}
229
156static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg); 230static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
157#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b) 231#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
158 232
@@ -226,38 +300,42 @@ static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
226#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs) 300#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
227 301
228static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int); 302static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
229#define ipw_read_indirect(a, b, c, d) \ 303static inline void __ipw_read_indirect(const char *f, int l,
230 IPW_DEBUG_IO("%s %d: read_inddirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ 304 struct ipw_priv *a, u32 b, u8 * c, int d)
231 _ipw_read_indirect(a, b, c, d) 305{
306 IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", f, l, (u32) (b),
307 d);
308 _ipw_read_indirect(a, b, c, d);
309}
310
311#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
232 312
233static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data, 313static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
234 int num); 314 int num);
235#define ipw_write_indirect(a, b, c, d) \ 315#define ipw_write_indirect(a, b, c, d) \
236 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ 316 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
237 _ipw_write_indirect(a, b, c, d) 317 _ipw_write_indirect(a, b, c, d)
238 318
239/* indirect write s */ 319/* indirect write s */
240static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value) 320static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
241{ 321{
242 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value); 322 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
243 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg); 323 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
244 _ipw_write32(priv, CX2_INDIRECT_DATA, value); 324 _ipw_write32(priv, IPW_INDIRECT_DATA, value);
245} 325}
246 326
247static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value) 327static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
248{ 328{
249 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); 329 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
250 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 330 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
251 _ipw_write8(priv, CX2_INDIRECT_DATA, value); 331 _ipw_write8(priv, IPW_INDIRECT_DATA, value);
252 IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n",
253 (unsigned long)(priv->hw_base + CX2_INDIRECT_DATA), value);
254} 332}
255 333
256static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value) 334static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
257{ 335{
258 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); 336 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
259 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 337 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
260 _ipw_write16(priv, CX2_INDIRECT_DATA, value); 338 _ipw_write16(priv, IPW_INDIRECT_DATA, value);
261} 339}
262 340
263/* indirect read s */ 341/* indirect read s */
@@ -265,9 +343,9 @@ static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
265static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg) 343static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
266{ 344{
267 u32 word; 345 u32 word;
268 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 346 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
269 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg); 347 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg);
270 word = _ipw_read32(priv, CX2_INDIRECT_DATA); 348 word = _ipw_read32(priv, IPW_INDIRECT_DATA);
271 return (word >> ((reg & 0x3) * 8)) & 0xff; 349 return (word >> ((reg & 0x3) * 8)) & 0xff;
272} 350}
273 351
@@ -277,8 +355,8 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
277 355
278 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg); 356 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);
279 357
280 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg); 358 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
281 value = _ipw_read32(priv, CX2_INDIRECT_DATA); 359 value = _ipw_read32(priv, IPW_INDIRECT_DATA);
282 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value); 360 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value);
283 return value; 361 return value;
284} 362}
@@ -287,67 +365,69 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
287static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, 365static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
288 int num) 366 int num)
289{ 367{
290 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; 368 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
291 u32 dif_len = addr - aligned_addr; 369 u32 dif_len = addr - aligned_addr;
292 u32 aligned_len;
293 u32 i; 370 u32 i;
294 371
295 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); 372 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
296 373
374 if (num <= 0) {
375 return;
376 }
377
297 /* Read the first nibble byte by byte */ 378 /* Read the first nibble byte by byte */
298 if (unlikely(dif_len)) { 379 if (unlikely(dif_len)) {
380 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
299 /* Start reading at aligned_addr + dif_len */ 381 /* Start reading at aligned_addr + dif_len */
300 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 382 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
301 for (i = dif_len; i < 4; i++, buf++) 383 *buf++ = _ipw_read8(priv, IPW_INDIRECT_DATA + i);
302 *buf = _ipw_read8(priv, CX2_INDIRECT_DATA + i);
303 num -= dif_len;
304 aligned_addr += 4; 384 aligned_addr += 4;
305 } 385 }
306 386
307 /* Read DWs through autoinc register */ 387 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
308 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); 388 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
309 aligned_len = num & CX2_INDIRECT_ADDR_MASK; 389 *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
310 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
311 *(u32 *) buf = ipw_read32(priv, CX2_AUTOINC_DATA);
312 390
313 /* Copy the last nibble */ 391 /* Copy the last nibble */
314 dif_len = num - aligned_len; 392 if (unlikely(num)) {
315 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 393 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
316 for (i = 0; i < dif_len; i++, buf++) 394 for (i = 0; num > 0; i++, num--)
317 *buf = ipw_read8(priv, CX2_INDIRECT_DATA + i); 395 *buf++ = ipw_read8(priv, IPW_INDIRECT_DATA + i);
396 }
318} 397}
319 398
320static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, 399static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
321 int num) 400 int num)
322{ 401{
323 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; 402 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
324 u32 dif_len = addr - aligned_addr; 403 u32 dif_len = addr - aligned_addr;
325 u32 aligned_len;
326 u32 i; 404 u32 i;
327 405
328 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); 406 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
329 407
408 if (num <= 0) {
409 return;
410 }
411
330 /* Write the first nibble byte by byte */ 412 /* Write the first nibble byte by byte */
331 if (unlikely(dif_len)) { 413 if (unlikely(dif_len)) {
332 /* Start writing at aligned_addr + dif_len */ 414 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
333 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 415 /* Start reading at aligned_addr + dif_len */
334 for (i = dif_len; i < 4; i++, buf++) 416 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
335 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf); 417 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
336 num -= dif_len;
337 aligned_addr += 4; 418 aligned_addr += 4;
338 } 419 }
339 420
340 /* Write DWs through autoinc register */ 421 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
341 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); 422 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
342 aligned_len = num & CX2_INDIRECT_ADDR_MASK; 423 _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
343 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
344 _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32 *) buf);
345 424
346 /* Copy the last nibble */ 425 /* Copy the last nibble */
347 dif_len = num - aligned_len; 426 if (unlikely(num)) {
348 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 427 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
349 for (i = 0; i < dif_len; i++, buf++) 428 for (i = 0; num > 0; i++, num--, buf++)
350 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf); 429 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
430 }
351} 431}
352 432
353static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf, 433static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
@@ -371,7 +451,7 @@ static inline void ipw_enable_interrupts(struct ipw_priv *priv)
371 if (priv->status & STATUS_INT_ENABLED) 451 if (priv->status & STATUS_INT_ENABLED)
372 return; 452 return;
373 priv->status |= STATUS_INT_ENABLED; 453 priv->status |= STATUS_INT_ENABLED;
374 ipw_write32(priv, CX2_INTA_MASK_R, CX2_INTA_MASK_ALL); 454 ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);
375} 455}
376 456
377static inline void ipw_disable_interrupts(struct ipw_priv *priv) 457static inline void ipw_disable_interrupts(struct ipw_priv *priv)
@@ -379,9 +459,10 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv)
379 if (!(priv->status & STATUS_INT_ENABLED)) 459 if (!(priv->status & STATUS_INT_ENABLED))
380 return; 460 return;
381 priv->status &= ~STATUS_INT_ENABLED; 461 priv->status &= ~STATUS_INT_ENABLED;
382 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 462 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
383} 463}
384 464
465#ifdef CONFIG_IPW_DEBUG
385static char *ipw_error_desc(u32 val) 466static char *ipw_error_desc(u32 val)
386{ 467{
387 switch (val) { 468 switch (val) {
@@ -394,81 +475,65 @@ static char *ipw_error_desc(u32 val)
394 case IPW_FW_ERROR_MEMORY_OVERFLOW: 475 case IPW_FW_ERROR_MEMORY_OVERFLOW:
395 return "MEMORY_OVERFLOW"; 476 return "MEMORY_OVERFLOW";
396 case IPW_FW_ERROR_BAD_PARAM: 477 case IPW_FW_ERROR_BAD_PARAM:
397 return "ERROR_BAD_PARAM"; 478 return "BAD_PARAM";
398 case IPW_FW_ERROR_BAD_CHECKSUM: 479 case IPW_FW_ERROR_BAD_CHECKSUM:
399 return "ERROR_BAD_CHECKSUM"; 480 return "BAD_CHECKSUM";
400 case IPW_FW_ERROR_NMI_INTERRUPT: 481 case IPW_FW_ERROR_NMI_INTERRUPT:
401 return "ERROR_NMI_INTERRUPT"; 482 return "NMI_INTERRUPT";
402 case IPW_FW_ERROR_BAD_DATABASE: 483 case IPW_FW_ERROR_BAD_DATABASE:
403 return "ERROR_BAD_DATABASE"; 484 return "BAD_DATABASE";
404 case IPW_FW_ERROR_ALLOC_FAIL: 485 case IPW_FW_ERROR_ALLOC_FAIL:
405 return "ERROR_ALLOC_FAIL"; 486 return "ALLOC_FAIL";
406 case IPW_FW_ERROR_DMA_UNDERRUN: 487 case IPW_FW_ERROR_DMA_UNDERRUN:
407 return "ERROR_DMA_UNDERRUN"; 488 return "DMA_UNDERRUN";
408 case IPW_FW_ERROR_DMA_STATUS: 489 case IPW_FW_ERROR_DMA_STATUS:
409 return "ERROR_DMA_STATUS"; 490 return "DMA_STATUS";
410 case IPW_FW_ERROR_DINOSTATUS_ERROR: 491 case IPW_FW_ERROR_DINO_ERROR:
411 return "ERROR_DINOSTATUS_ERROR"; 492 return "DINO_ERROR";
412 case IPW_FW_ERROR_EEPROMSTATUS_ERROR: 493 case IPW_FW_ERROR_EEPROM_ERROR:
413 return "ERROR_EEPROMSTATUS_ERROR"; 494 return "EEPROM_ERROR";
414 case IPW_FW_ERROR_SYSASSERT: 495 case IPW_FW_ERROR_SYSASSERT:
415 return "ERROR_SYSASSERT"; 496 return "SYSASSERT";
416 case IPW_FW_ERROR_FATAL_ERROR: 497 case IPW_FW_ERROR_FATAL_ERROR:
417 return "ERROR_FATALSTATUS_ERROR"; 498 return "FATAL_ERROR";
418 default: 499 default:
419 return "UNKNOWNSTATUS_ERROR"; 500 return "UNKNOWN_ERROR";
420 } 501 }
421} 502}
422 503
423static void ipw_dump_nic_error_log(struct ipw_priv *priv) 504static void ipw_dump_error_log(struct ipw_priv *priv,
505 struct ipw_fw_error *error)
424{ 506{
425 u32 desc, time, blink1, blink2, ilink1, ilink2, idata, i, count, base; 507 u32 i;
426
427 base = ipw_read32(priv, IPWSTATUS_ERROR_LOG);
428 count = ipw_read_reg32(priv, base);
429 508
430 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { 509 if (!error) {
431 IPW_ERROR("Start IPW Error Log Dump:\n"); 510 IPW_ERROR("Error allocating and capturing error log. "
432 IPW_ERROR("Status: 0x%08X, Config: %08X\n", 511 "Nothing to dump.\n");
433 priv->status, priv->config); 512 return;
434 } 513 }
435 514
436 for (i = ERROR_START_OFFSET; 515 IPW_ERROR("Start IPW Error Log Dump:\n");
437 i <= count * ERROR_ELEM_SIZE; i += ERROR_ELEM_SIZE) { 516 IPW_ERROR("Status: 0x%08X, Config: %08X\n",
438 desc = ipw_read_reg32(priv, base + i); 517 error->status, error->config);
439 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
440 blink1 = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
441 blink2 = ipw_read_reg32(priv, base + i + 3 * sizeof(u32));
442 ilink1 = ipw_read_reg32(priv, base + i + 4 * sizeof(u32));
443 ilink2 = ipw_read_reg32(priv, base + i + 5 * sizeof(u32));
444 idata = ipw_read_reg32(priv, base + i + 6 * sizeof(u32));
445 518
519 for (i = 0; i < error->elem_len; i++)
446 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", 520 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
447 ipw_error_desc(desc), time, blink1, blink2, 521 ipw_error_desc(error->elem[i].desc),
448 ilink1, ilink2, idata); 522 error->elem[i].time,
449 } 523 error->elem[i].blink1,
524 error->elem[i].blink2,
525 error->elem[i].link1,
526 error->elem[i].link2, error->elem[i].data);
527 for (i = 0; i < error->log_len; i++)
528 IPW_ERROR("%i\t0x%08x\t%i\n",
529 error->log[i].time,
530 error->log[i].data, error->log[i].event);
450} 531}
532#endif
451 533
452static void ipw_dump_nic_event_log(struct ipw_priv *priv) 534static inline int ipw_is_init(struct ipw_priv *priv)
453{ 535{
454 u32 ev, time, data, i, count, base; 536 return (priv->status & STATUS_INIT) ? 1 : 0;
455
456 base = ipw_read32(priv, IPW_EVENT_LOG);
457 count = ipw_read_reg32(priv, base);
458
459 if (EVENT_START_OFFSET <= count * EVENT_ELEM_SIZE)
460 IPW_ERROR("Start IPW Event Log Dump:\n");
461
462 for (i = EVENT_START_OFFSET;
463 i <= count * EVENT_ELEM_SIZE; i += EVENT_ELEM_SIZE) {
464 ev = ipw_read_reg32(priv, base + i);
465 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
466 data = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
467
468#ifdef CONFIG_IPW_DEBUG
469 IPW_ERROR("%i\t0x%08x\t%i\n", time, data, ev);
470#endif
471 }
472} 537}
473 538
474static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len) 539static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
@@ -636,6 +701,340 @@ static void ipw_init_ordinals(struct ipw_priv *priv)
636 701
637} 702}
638 703
704u32 ipw_register_toggle(u32 reg)
705{
706 reg &= ~IPW_START_STANDBY;
707 if (reg & IPW_GATE_ODMA)
708 reg &= ~IPW_GATE_ODMA;
709 if (reg & IPW_GATE_IDMA)
710 reg &= ~IPW_GATE_IDMA;
711 if (reg & IPW_GATE_ADMA)
712 reg &= ~IPW_GATE_ADMA;
713 return reg;
714}
715
716/*
717 * LED behavior:
718 * - On radio ON, turn on any LEDs that require to be on during start
719 * - On initialization, start unassociated blink
720 * - On association, disable unassociated blink
721 * - On disassociation, start unassociated blink
722 * - On radio OFF, turn off any LEDs started during radio on
723 *
724 */
725#define LD_TIME_LINK_ON 300
726#define LD_TIME_LINK_OFF 2700
727#define LD_TIME_ACT_ON 250
728
729void ipw_led_link_on(struct ipw_priv *priv)
730{
731 unsigned long flags;
732 u32 led;
733
734 /* If configured to not use LEDs, or nic_type is 1,
735 * then we don't toggle a LINK led */
736 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
737 return;
738
739 spin_lock_irqsave(&priv->lock, flags);
740
741 if (!(priv->status & STATUS_RF_KILL_MASK) &&
742 !(priv->status & STATUS_LED_LINK_ON)) {
743 IPW_DEBUG_LED("Link LED On\n");
744 led = ipw_read_reg32(priv, IPW_EVENT_REG);
745 led |= priv->led_association_on;
746
747 led = ipw_register_toggle(led);
748
749 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
750 ipw_write_reg32(priv, IPW_EVENT_REG, led);
751
752 priv->status |= STATUS_LED_LINK_ON;
753
754 /* If we aren't associated, schedule turning the LED off */
755 if (!(priv->status & STATUS_ASSOCIATED))
756 queue_delayed_work(priv->workqueue,
757 &priv->led_link_off,
758 LD_TIME_LINK_ON);
759 }
760
761 spin_unlock_irqrestore(&priv->lock, flags);
762}
763
764static void ipw_bg_led_link_on(void *data)
765{
766 struct ipw_priv *priv = data;
767 down(&priv->sem);
768 ipw_led_link_on(data);
769 up(&priv->sem);
770}
771
772void ipw_led_link_off(struct ipw_priv *priv)
773{
774 unsigned long flags;
775 u32 led;
776
777 /* If configured not to use LEDs, or nic type is 1,
778 * then we don't goggle the LINK led. */
779 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
780 return;
781
782 spin_lock_irqsave(&priv->lock, flags);
783
784 if (priv->status & STATUS_LED_LINK_ON) {
785 led = ipw_read_reg32(priv, IPW_EVENT_REG);
786 led &= priv->led_association_off;
787 led = ipw_register_toggle(led);
788
789 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
790 ipw_write_reg32(priv, IPW_EVENT_REG, led);
791
792 IPW_DEBUG_LED("Link LED Off\n");
793
794 priv->status &= ~STATUS_LED_LINK_ON;
795
796 /* If we aren't associated and the radio is on, schedule
797 * turning the LED on (blink while unassociated) */
798 if (!(priv->status & STATUS_RF_KILL_MASK) &&
799 !(priv->status & STATUS_ASSOCIATED))
800 queue_delayed_work(priv->workqueue, &priv->led_link_on,
801 LD_TIME_LINK_OFF);
802
803 }
804
805 spin_unlock_irqrestore(&priv->lock, flags);
806}
807
808static void ipw_bg_led_link_off(void *data)
809{
810 struct ipw_priv *priv = data;
811 down(&priv->sem);
812 ipw_led_link_off(data);
813 up(&priv->sem);
814}
815
816static inline void __ipw_led_activity_on(struct ipw_priv *priv)
817{
818 u32 led;
819
820 if (priv->config & CFG_NO_LED)
821 return;
822
823 if (priv->status & STATUS_RF_KILL_MASK)
824 return;
825
826 if (!(priv->status & STATUS_LED_ACT_ON)) {
827 led = ipw_read_reg32(priv, IPW_EVENT_REG);
828 led |= priv->led_activity_on;
829
830 led = ipw_register_toggle(led);
831
832 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
833 ipw_write_reg32(priv, IPW_EVENT_REG, led);
834
835 IPW_DEBUG_LED("Activity LED On\n");
836
837 priv->status |= STATUS_LED_ACT_ON;
838
839 cancel_delayed_work(&priv->led_act_off);
840 queue_delayed_work(priv->workqueue, &priv->led_act_off,
841 LD_TIME_ACT_ON);
842 } else {
843 /* Reschedule LED off for full time period */
844 cancel_delayed_work(&priv->led_act_off);
845 queue_delayed_work(priv->workqueue, &priv->led_act_off,
846 LD_TIME_ACT_ON);
847 }
848}
849
850void ipw_led_activity_on(struct ipw_priv *priv)
851{
852 unsigned long flags;
853 spin_lock_irqsave(&priv->lock, flags);
854 __ipw_led_activity_on(priv);
855 spin_unlock_irqrestore(&priv->lock, flags);
856}
857
858void ipw_led_activity_off(struct ipw_priv *priv)
859{
860 unsigned long flags;
861 u32 led;
862
863 if (priv->config & CFG_NO_LED)
864 return;
865
866 spin_lock_irqsave(&priv->lock, flags);
867
868 if (priv->status & STATUS_LED_ACT_ON) {
869 led = ipw_read_reg32(priv, IPW_EVENT_REG);
870 led &= priv->led_activity_off;
871
872 led = ipw_register_toggle(led);
873
874 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
875 ipw_write_reg32(priv, IPW_EVENT_REG, led);
876
877 IPW_DEBUG_LED("Activity LED Off\n");
878
879 priv->status &= ~STATUS_LED_ACT_ON;
880 }
881
882 spin_unlock_irqrestore(&priv->lock, flags);
883}
884
885static void ipw_bg_led_activity_off(void *data)
886{
887 struct ipw_priv *priv = data;
888 down(&priv->sem);
889 ipw_led_activity_off(data);
890 up(&priv->sem);
891}
892
893void ipw_led_band_on(struct ipw_priv *priv)
894{
895 unsigned long flags;
896 u32 led;
897
898 /* Only nic type 1 supports mode LEDs */
899 if (priv->config & CFG_NO_LED ||
900 priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)
901 return;
902
903 spin_lock_irqsave(&priv->lock, flags);
904
905 led = ipw_read_reg32(priv, IPW_EVENT_REG);
906 if (priv->assoc_network->mode == IEEE_A) {
907 led |= priv->led_ofdm_on;
908 led &= priv->led_association_off;
909 IPW_DEBUG_LED("Mode LED On: 802.11a\n");
910 } else if (priv->assoc_network->mode == IEEE_G) {
911 led |= priv->led_ofdm_on;
912 led |= priv->led_association_on;
913 IPW_DEBUG_LED("Mode LED On: 802.11g\n");
914 } else {
915 led &= priv->led_ofdm_off;
916 led |= priv->led_association_on;
917 IPW_DEBUG_LED("Mode LED On: 802.11b\n");
918 }
919
920 led = ipw_register_toggle(led);
921
922 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
923 ipw_write_reg32(priv, IPW_EVENT_REG, led);
924
925 spin_unlock_irqrestore(&priv->lock, flags);
926}
927
928void ipw_led_band_off(struct ipw_priv *priv)
929{
930 unsigned long flags;
931 u32 led;
932
933 /* Only nic type 1 supports mode LEDs */
934 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
935 return;
936
937 spin_lock_irqsave(&priv->lock, flags);
938
939 led = ipw_read_reg32(priv, IPW_EVENT_REG);
940 led &= priv->led_ofdm_off;
941 led &= priv->led_association_off;
942
943 led = ipw_register_toggle(led);
944
945 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
946 ipw_write_reg32(priv, IPW_EVENT_REG, led);
947
948 spin_unlock_irqrestore(&priv->lock, flags);
949}
950
951void ipw_led_radio_on(struct ipw_priv *priv)
952{
953 ipw_led_link_on(priv);
954}
955
956void ipw_led_radio_off(struct ipw_priv *priv)
957{
958 ipw_led_activity_off(priv);
959 ipw_led_link_off(priv);
960}
961
962void ipw_led_link_up(struct ipw_priv *priv)
963{
964 /* Set the Link Led on for all nic types */
965 ipw_led_link_on(priv);
966}
967
968void ipw_led_link_down(struct ipw_priv *priv)
969{
970 ipw_led_activity_off(priv);
971 ipw_led_link_off(priv);
972
973 if (priv->status & STATUS_RF_KILL_MASK)
974 ipw_led_radio_off(priv);
975}
976
977void ipw_led_init(struct ipw_priv *priv)
978{
979 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
980
981 /* Set the default PINs for the link and activity leds */
982 priv->led_activity_on = IPW_ACTIVITY_LED;
983 priv->led_activity_off = ~(IPW_ACTIVITY_LED);
984
985 priv->led_association_on = IPW_ASSOCIATED_LED;
986 priv->led_association_off = ~(IPW_ASSOCIATED_LED);
987
988 /* Set the default PINs for the OFDM leds */
989 priv->led_ofdm_on = IPW_OFDM_LED;
990 priv->led_ofdm_off = ~(IPW_OFDM_LED);
991
992 switch (priv->nic_type) {
993 case EEPROM_NIC_TYPE_1:
994 /* In this NIC type, the LEDs are reversed.... */
995 priv->led_activity_on = IPW_ASSOCIATED_LED;
996 priv->led_activity_off = ~(IPW_ASSOCIATED_LED);
997 priv->led_association_on = IPW_ACTIVITY_LED;
998 priv->led_association_off = ~(IPW_ACTIVITY_LED);
999
1000 if (!(priv->config & CFG_NO_LED))
1001 ipw_led_band_on(priv);
1002
1003 /* And we don't blink link LEDs for this nic, so
1004 * just return here */
1005 return;
1006
1007 case EEPROM_NIC_TYPE_3:
1008 case EEPROM_NIC_TYPE_2:
1009 case EEPROM_NIC_TYPE_4:
1010 case EEPROM_NIC_TYPE_0:
1011 break;
1012
1013 default:
1014 IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
1015 priv->nic_type);
1016 priv->nic_type = EEPROM_NIC_TYPE_0;
1017 break;
1018 }
1019
1020 if (!(priv->config & CFG_NO_LED)) {
1021 if (priv->status & STATUS_ASSOCIATED)
1022 ipw_led_link_on(priv);
1023 else
1024 ipw_led_link_off(priv);
1025 }
1026}
1027
1028void ipw_led_shutdown(struct ipw_priv *priv)
1029{
1030 ipw_led_activity_off(priv);
1031 ipw_led_link_off(priv);
1032 ipw_led_band_off(priv);
1033 cancel_delayed_work(&priv->led_link_on);
1034 cancel_delayed_work(&priv->led_link_off);
1035 cancel_delayed_work(&priv->led_act_off);
1036}
1037
639/* 1038/*
640 * The following adds a new attribute to the sysfs representation 1039 * The following adds a new attribute to the sysfs representation
641 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/) 1040 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
@@ -647,8 +1046,9 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
647{ 1046{
648 return sprintf(buf, "0x%08X\n", ipw_debug_level); 1047 return sprintf(buf, "0x%08X\n", ipw_debug_level);
649} 1048}
650static ssize_t store_debug_level(struct device_driver *d, 1049
651 const char *buf, size_t count) 1050static ssize_t store_debug_level(struct device_driver *d, const char *buf,
1051 size_t count)
652{ 1052{
653 char *p = (char *)buf; 1053 char *p = (char *)buf;
654 u32 val; 1054 u32 val;
@@ -672,75 +1072,263 @@ static ssize_t store_debug_level(struct device_driver *d,
672static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, 1072static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
673 show_debug_level, store_debug_level); 1073 show_debug_level, store_debug_level);
674 1074
675static ssize_t show_status(struct device *d, 1075static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
676 struct device_attribute *attr, char *buf)
677{ 1076{
678 struct ipw_priv *p = d->driver_data; 1077 return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
679 return sprintf(buf, "0x%08x\n", (int)p->status);
680} 1078}
681 1079
682static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 1080static void ipw_capture_event_log(struct ipw_priv *priv,
1081 u32 log_len, struct ipw_event *log)
1082{
1083 u32 base;
683 1084
684static ssize_t show_cfg(struct device *d, struct device_attribute *attr, 1085 if (log_len) {
685 char *buf) 1086 base = ipw_read32(priv, IPW_EVENT_LOG);
1087 ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32),
1088 (u8 *) log, sizeof(*log) * log_len);
1089 }
1090}
1091
1092static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
686{ 1093{
687 struct ipw_priv *p = d->driver_data; 1094 struct ipw_fw_error *error;
688 return sprintf(buf, "0x%08x\n", (int)p->config); 1095 u32 log_len = ipw_get_event_log_len(priv);
1096 u32 base = ipw_read32(priv, IPW_ERROR_LOG);
1097 u32 elem_len = ipw_read_reg32(priv, base);
1098
1099 error = kmalloc(sizeof(*error) +
1100 sizeof(*error->elem) * elem_len +
1101 sizeof(*error->log) * log_len, GFP_ATOMIC);
1102 if (!error) {
1103 IPW_ERROR("Memory allocation for firmware error log "
1104 "failed.\n");
1105 return NULL;
1106 }
1107 error->jiffies = jiffies;
1108 error->status = priv->status;
1109 error->config = priv->config;
1110 error->elem_len = elem_len;
1111 error->log_len = log_len;
1112 error->elem = (struct ipw_error_elem *)error->payload;
1113 error->log = (struct ipw_event *)(error->elem +
1114 (sizeof(*error->elem) * elem_len));
1115
1116 ipw_capture_event_log(priv, log_len, error->log);
1117
1118 if (elem_len)
1119 ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem,
1120 sizeof(*error->elem) * elem_len);
1121
1122 return error;
689} 1123}
690 1124
691static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); 1125static void ipw_free_error_log(struct ipw_fw_error *error)
1126{
1127 if (error)
1128 kfree(error);
1129}
692 1130
693static ssize_t show_nic_type(struct device *d, 1131static ssize_t show_event_log(struct device *d,
694 struct device_attribute *attr, char *buf) 1132 struct device_attribute *attr, char *buf)
695{ 1133{
696 struct ipw_priv *p = d->driver_data; 1134 struct ipw_priv *priv = dev_get_drvdata(d);
697 u8 type = p->eeprom[EEPROM_NIC_TYPE]; 1135 u32 log_len = ipw_get_event_log_len(priv);
1136 struct ipw_event log[log_len];
1137 u32 len = 0, i;
1138
1139 ipw_capture_event_log(priv, log_len, log);
1140
1141 len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);
1142 for (i = 0; i < log_len; i++)
1143 len += snprintf(buf + len, PAGE_SIZE - len,
1144 "\n%08X%08X%08X",
1145 log[i].time, log[i].event, log[i].data);
1146 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1147 return len;
1148}
698 1149
699 switch (type) { 1150static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL);
700 case EEPROM_NIC_TYPE_STANDARD: 1151
701 return sprintf(buf, "STANDARD\n"); 1152static ssize_t show_error(struct device *d,
702 case EEPROM_NIC_TYPE_DELL: 1153 struct device_attribute *attr, char *buf)
703 return sprintf(buf, "DELL\n"); 1154{
704 case EEPROM_NIC_TYPE_FUJITSU: 1155 struct ipw_priv *priv = dev_get_drvdata(d);
705 return sprintf(buf, "FUJITSU\n"); 1156 u32 len = 0, i;
706 case EEPROM_NIC_TYPE_IBM: 1157 if (!priv->error)
707 return sprintf(buf, "IBM\n"); 1158 return 0;
708 case EEPROM_NIC_TYPE_HP: 1159 len += snprintf(buf + len, PAGE_SIZE - len,
709 return sprintf(buf, "HP\n"); 1160 "%08lX%08X%08X%08X",
1161 priv->error->jiffies,
1162 priv->error->status,
1163 priv->error->config, priv->error->elem_len);
1164 for (i = 0; i < priv->error->elem_len; i++)
1165 len += snprintf(buf + len, PAGE_SIZE - len,
1166 "\n%08X%08X%08X%08X%08X%08X%08X",
1167 priv->error->elem[i].time,
1168 priv->error->elem[i].desc,
1169 priv->error->elem[i].blink1,
1170 priv->error->elem[i].blink2,
1171 priv->error->elem[i].link1,
1172 priv->error->elem[i].link2,
1173 priv->error->elem[i].data);
1174
1175 len += snprintf(buf + len, PAGE_SIZE - len,
1176 "\n%08X", priv->error->log_len);
1177 for (i = 0; i < priv->error->log_len; i++)
1178 len += snprintf(buf + len, PAGE_SIZE - len,
1179 "\n%08X%08X%08X",
1180 priv->error->log[i].time,
1181 priv->error->log[i].event,
1182 priv->error->log[i].data);
1183 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1184 return len;
1185}
1186
1187static ssize_t clear_error(struct device *d,
1188 struct device_attribute *attr,
1189 const char *buf, size_t count)
1190{
1191 struct ipw_priv *priv = dev_get_drvdata(d);
1192 if (priv->error) {
1193 ipw_free_error_log(priv->error);
1194 priv->error = NULL;
710 } 1195 }
1196 return count;
1197}
1198
1199static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);
711 1200
712 return sprintf(buf, "UNKNOWN\n"); 1201static ssize_t show_cmd_log(struct device *d,
1202 struct device_attribute *attr, char *buf)
1203{
1204 struct ipw_priv *priv = dev_get_drvdata(d);
1205 u32 len = 0, i;
1206 if (!priv->cmdlog)
1207 return 0;
1208 for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len;
1209 (i != priv->cmdlog_pos) && (PAGE_SIZE - len);
1210 i = (i + 1) % priv->cmdlog_len) {
1211 len +=
1212 snprintf(buf + len, PAGE_SIZE - len,
1213 "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,
1214 priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,
1215 priv->cmdlog[i].cmd.len);
1216 len +=
1217 snprintk_buf(buf + len, PAGE_SIZE - len,
1218 (u8 *) priv->cmdlog[i].cmd.param,
1219 priv->cmdlog[i].cmd.len);
1220 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1221 }
1222 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1223 return len;
713} 1224}
714 1225
715static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL); 1226static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
716 1227
717static ssize_t dump_error_log(struct device *d, 1228static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
718 struct device_attribute *attr, const char *buf, 1229 char *buf)
719 size_t count)
720{ 1230{
721 char *p = (char *)buf; 1231 struct ipw_priv *priv = dev_get_drvdata(d);
1232 return sprintf(buf, "%d\n", priv->ieee->scan_age);
1233}
722 1234
723 if (p[0] == '1') 1235static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
724 ipw_dump_nic_error_log((struct ipw_priv *)d->driver_data); 1236 const char *buf, size_t count)
1237{
1238 struct ipw_priv *priv = dev_get_drvdata(d);
1239#ifdef CONFIG_IPW_DEBUG
1240 struct net_device *dev = priv->net_dev;
1241#endif
1242 char buffer[] = "00000000";
1243 unsigned long len =
1244 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
1245 unsigned long val;
1246 char *p = buffer;
725 1247
726 return strnlen(buf, count); 1248 IPW_DEBUG_INFO("enter\n");
1249
1250 strncpy(buffer, buf, len);
1251 buffer[len] = 0;
1252
1253 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1254 p++;
1255 if (p[0] == 'x' || p[0] == 'X')
1256 p++;
1257 val = simple_strtoul(p, &p, 16);
1258 } else
1259 val = simple_strtoul(p, &p, 10);
1260 if (p == buffer) {
1261 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
1262 } else {
1263 priv->ieee->scan_age = val;
1264 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
1265 }
1266
1267 IPW_DEBUG_INFO("exit\n");
1268 return len;
727} 1269}
728 1270
729static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log); 1271static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
730 1272
731static ssize_t dump_event_log(struct device *d, 1273static ssize_t show_led(struct device *d, struct device_attribute *attr,
732 struct device_attribute *attr, const char *buf, 1274 char *buf)
733 size_t count)
734{ 1275{
735 char *p = (char *)buf; 1276 struct ipw_priv *priv = dev_get_drvdata(d);
1277 return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
1278}
736 1279
737 if (p[0] == '1') 1280static ssize_t store_led(struct device *d, struct device_attribute *attr,
738 ipw_dump_nic_event_log((struct ipw_priv *)d->driver_data); 1281 const char *buf, size_t count)
1282{
1283 struct ipw_priv *priv = dev_get_drvdata(d);
739 1284
740 return strnlen(buf, count); 1285 IPW_DEBUG_INFO("enter\n");
1286
1287 if (count == 0)
1288 return 0;
1289
1290 if (*buf == 0) {
1291 IPW_DEBUG_LED("Disabling LED control.\n");
1292 priv->config |= CFG_NO_LED;
1293 ipw_led_shutdown(priv);
1294 } else {
1295 IPW_DEBUG_LED("Enabling LED control.\n");
1296 priv->config &= ~CFG_NO_LED;
1297 ipw_led_init(priv);
1298 }
1299
1300 IPW_DEBUG_INFO("exit\n");
1301 return count;
1302}
1303
1304static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
1305
1306static ssize_t show_status(struct device *d,
1307 struct device_attribute *attr, char *buf)
1308{
1309 struct ipw_priv *p = d->driver_data;
1310 return sprintf(buf, "0x%08x\n", (int)p->status);
741} 1311}
742 1312
743static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log); 1313static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
1314
1315static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
1316 char *buf)
1317{
1318 struct ipw_priv *p = d->driver_data;
1319 return sprintf(buf, "0x%08x\n", (int)p->config);
1320}
1321
1322static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
1323
1324static ssize_t show_nic_type(struct device *d,
1325 struct device_attribute *attr, char *buf)
1326{
1327 struct ipw_priv *priv = d->driver_data;
1328 return sprintf(buf, "TYPE: %d\n", priv->nic_type);
1329}
1330
1331static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
744 1332
745static ssize_t show_ucode_version(struct device *d, 1333static ssize_t show_ucode_version(struct device *d,
746 struct device_attribute *attr, char *buf) 1334 struct device_attribute *attr, char *buf)
@@ -798,7 +1386,7 @@ static ssize_t show_command_event_reg(struct device *d,
798 u32 reg = 0; 1386 u32 reg = 0;
799 struct ipw_priv *p = d->driver_data; 1387 struct ipw_priv *p = d->driver_data;
800 1388
801 reg = ipw_read_reg32(p, CX2_INTERNAL_CMD_EVENT); 1389 reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
802 return sprintf(buf, "0x%08x\n", reg); 1390 return sprintf(buf, "0x%08x\n", reg);
803} 1391}
804static ssize_t store_command_event_reg(struct device *d, 1392static ssize_t store_command_event_reg(struct device *d,
@@ -809,7 +1397,7 @@ static ssize_t store_command_event_reg(struct device *d,
809 struct ipw_priv *p = d->driver_data; 1397 struct ipw_priv *p = d->driver_data;
810 1398
811 sscanf(buf, "%x", &reg); 1399 sscanf(buf, "%x", &reg);
812 ipw_write_reg32(p, CX2_INTERNAL_CMD_EVENT, reg); 1400 ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
813 return strnlen(buf, count); 1401 return strnlen(buf, count);
814} 1402}
815 1403
@@ -845,6 +1433,7 @@ static ssize_t show_indirect_dword(struct device *d,
845{ 1433{
846 u32 reg = 0; 1434 u32 reg = 0;
847 struct ipw_priv *priv = d->driver_data; 1435 struct ipw_priv *priv = d->driver_data;
1436
848 if (priv->status & STATUS_INDIRECT_DWORD) 1437 if (priv->status & STATUS_INDIRECT_DWORD)
849 reg = ipw_read_reg32(priv, priv->indirect_dword); 1438 reg = ipw_read_reg32(priv, priv->indirect_dword);
850 else 1439 else
@@ -871,6 +1460,7 @@ static ssize_t show_indirect_byte(struct device *d,
871{ 1460{
872 u8 reg = 0; 1461 u8 reg = 0;
873 struct ipw_priv *priv = d->driver_data; 1462 struct ipw_priv *priv = d->driver_data;
1463
874 if (priv->status & STATUS_INDIRECT_BYTE) 1464 if (priv->status & STATUS_INDIRECT_BYTE)
875 reg = ipw_read_reg8(priv, priv->indirect_byte); 1465 reg = ipw_read_reg8(priv, priv->indirect_byte);
876 else 1466 else
@@ -945,7 +1535,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
945static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) 1535static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
946{ 1536{
947 if ((disable_radio ? 1 : 0) == 1537 if ((disable_radio ? 1 : 0) ==
948 (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) 1538 ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
949 return 0; 1539 return 0;
950 1540
951 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", 1541 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
@@ -954,10 +1544,8 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
954 if (disable_radio) { 1544 if (disable_radio) {
955 priv->status |= STATUS_RF_KILL_SW; 1545 priv->status |= STATUS_RF_KILL_SW;
956 1546
957 if (priv->workqueue) { 1547 if (priv->workqueue)
958 cancel_delayed_work(&priv->request_scan); 1548 cancel_delayed_work(&priv->request_scan);
959 }
960 wake_up_interruptible(&priv->wait_command_queue);
961 queue_work(priv->workqueue, &priv->down); 1549 queue_work(priv->workqueue, &priv->down);
962 } else { 1550 } else {
963 priv->status &= ~STATUS_RF_KILL_SW; 1551 priv->status &= ~STATUS_RF_KILL_SW;
@@ -987,6 +1575,93 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
987 1575
988static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); 1576static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
989 1577
1578static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
1579 char *buf)
1580{
1581 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1582 int pos = 0, len = 0;
1583 if (priv->config & CFG_SPEED_SCAN) {
1584 while (priv->speed_scan[pos] != 0)
1585 len += sprintf(&buf[len], "%d ",
1586 priv->speed_scan[pos++]);
1587 return len + sprintf(&buf[len], "\n");
1588 }
1589
1590 return sprintf(buf, "0\n");
1591}
1592
1593static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
1594 const char *buf, size_t count)
1595{
1596 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1597 int channel, pos = 0;
1598 const char *p = buf;
1599
1600 /* list of space separated channels to scan, optionally ending with 0 */
1601 while ((channel = simple_strtol(p, NULL, 0))) {
1602 if (pos == MAX_SPEED_SCAN - 1) {
1603 priv->speed_scan[pos] = 0;
1604 break;
1605 }
1606
1607 if (ipw_is_valid_channel(priv->ieee, channel))
1608 priv->speed_scan[pos++] = channel;
1609 else
1610 IPW_WARNING("Skipping invalid channel request: %d\n",
1611 channel);
1612 p = strchr(p, ' ');
1613 if (!p)
1614 break;
1615 while (*p == ' ' || *p == '\t')
1616 p++;
1617 }
1618
1619 if (pos == 0)
1620 priv->config &= ~CFG_SPEED_SCAN;
1621 else {
1622 priv->speed_scan_pos = 0;
1623 priv->config |= CFG_SPEED_SCAN;
1624 }
1625
1626 return count;
1627}
1628
1629static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
1630 store_speed_scan);
1631
1632static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
1633 char *buf)
1634{
1635 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1636 return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
1637}
1638
1639static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
1640 const char *buf, size_t count)
1641{
1642 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1643 if (buf[0] == '1')
1644 priv->config |= CFG_NET_STATS;
1645 else
1646 priv->config &= ~CFG_NET_STATS;
1647
1648 return count;
1649}
1650
1651static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,
1652 show_net_stats, store_net_stats);
1653
1654static void notify_wx_assoc_event(struct ipw_priv *priv)
1655{
1656 union iwreq_data wrqu;
1657 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1658 if (priv->status & STATUS_ASSOCIATED)
1659 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
1660 else
1661 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1662 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1663}
1664
990static void ipw_irq_tasklet(struct ipw_priv *priv) 1665static void ipw_irq_tasklet(struct ipw_priv *priv)
991{ 1666{
992 u32 inta, inta_mask, handled = 0; 1667 u32 inta, inta_mask, handled = 0;
@@ -995,102 +1670,135 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
995 1670
996 spin_lock_irqsave(&priv->lock, flags); 1671 spin_lock_irqsave(&priv->lock, flags);
997 1672
998 inta = ipw_read32(priv, CX2_INTA_RW); 1673 inta = ipw_read32(priv, IPW_INTA_RW);
999 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R); 1674 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
1000 inta &= (CX2_INTA_MASK_ALL & inta_mask); 1675 inta &= (IPW_INTA_MASK_ALL & inta_mask);
1001 1676
1002 /* Add any cached INTA values that need to be handled */ 1677 /* Add any cached INTA values that need to be handled */
1003 inta |= priv->isr_inta; 1678 inta |= priv->isr_inta;
1004 1679
1005 /* handle all the justifications for the interrupt */ 1680 /* handle all the justifications for the interrupt */
1006 if (inta & CX2_INTA_BIT_RX_TRANSFER) { 1681 if (inta & IPW_INTA_BIT_RX_TRANSFER) {
1007 ipw_rx(priv); 1682 ipw_rx(priv);
1008 handled |= CX2_INTA_BIT_RX_TRANSFER; 1683 handled |= IPW_INTA_BIT_RX_TRANSFER;
1009 } 1684 }
1010 1685
1011 if (inta & CX2_INTA_BIT_TX_CMD_QUEUE) { 1686 if (inta & IPW_INTA_BIT_TX_CMD_QUEUE) {
1012 IPW_DEBUG_HC("Command completed.\n"); 1687 IPW_DEBUG_HC("Command completed.\n");
1013 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1); 1688 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);
1014 priv->status &= ~STATUS_HCMD_ACTIVE; 1689 priv->status &= ~STATUS_HCMD_ACTIVE;
1015 wake_up_interruptible(&priv->wait_command_queue); 1690 wake_up_interruptible(&priv->wait_command_queue);
1016 handled |= CX2_INTA_BIT_TX_CMD_QUEUE; 1691 handled |= IPW_INTA_BIT_TX_CMD_QUEUE;
1017 } 1692 }
1018 1693
1019 if (inta & CX2_INTA_BIT_TX_QUEUE_1) { 1694 if (inta & IPW_INTA_BIT_TX_QUEUE_1) {
1020 IPW_DEBUG_TX("TX_QUEUE_1\n"); 1695 IPW_DEBUG_TX("TX_QUEUE_1\n");
1021 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0); 1696 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);
1022 handled |= CX2_INTA_BIT_TX_QUEUE_1; 1697 handled |= IPW_INTA_BIT_TX_QUEUE_1;
1023 } 1698 }
1024 1699
1025 if (inta & CX2_INTA_BIT_TX_QUEUE_2) { 1700 if (inta & IPW_INTA_BIT_TX_QUEUE_2) {
1026 IPW_DEBUG_TX("TX_QUEUE_2\n"); 1701 IPW_DEBUG_TX("TX_QUEUE_2\n");
1027 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1); 1702 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);
1028 handled |= CX2_INTA_BIT_TX_QUEUE_2; 1703 handled |= IPW_INTA_BIT_TX_QUEUE_2;
1029 } 1704 }
1030 1705
1031 if (inta & CX2_INTA_BIT_TX_QUEUE_3) { 1706 if (inta & IPW_INTA_BIT_TX_QUEUE_3) {
1032 IPW_DEBUG_TX("TX_QUEUE_3\n"); 1707 IPW_DEBUG_TX("TX_QUEUE_3\n");
1033 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2); 1708 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);
1034 handled |= CX2_INTA_BIT_TX_QUEUE_3; 1709 handled |= IPW_INTA_BIT_TX_QUEUE_3;
1035 } 1710 }
1036 1711
1037 if (inta & CX2_INTA_BIT_TX_QUEUE_4) { 1712 if (inta & IPW_INTA_BIT_TX_QUEUE_4) {
1038 IPW_DEBUG_TX("TX_QUEUE_4\n"); 1713 IPW_DEBUG_TX("TX_QUEUE_4\n");
1039 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3); 1714 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);
1040 handled |= CX2_INTA_BIT_TX_QUEUE_4; 1715 handled |= IPW_INTA_BIT_TX_QUEUE_4;
1041 } 1716 }
1042 1717
1043 if (inta & CX2_INTA_BIT_STATUS_CHANGE) { 1718 if (inta & IPW_INTA_BIT_STATUS_CHANGE) {
1044 IPW_WARNING("STATUS_CHANGE\n"); 1719 IPW_WARNING("STATUS_CHANGE\n");
1045 handled |= CX2_INTA_BIT_STATUS_CHANGE; 1720 handled |= IPW_INTA_BIT_STATUS_CHANGE;
1046 } 1721 }
1047 1722
1048 if (inta & CX2_INTA_BIT_BEACON_PERIOD_EXPIRED) { 1723 if (inta & IPW_INTA_BIT_BEACON_PERIOD_EXPIRED) {
1049 IPW_WARNING("TX_PERIOD_EXPIRED\n"); 1724 IPW_WARNING("TX_PERIOD_EXPIRED\n");
1050 handled |= CX2_INTA_BIT_BEACON_PERIOD_EXPIRED; 1725 handled |= IPW_INTA_BIT_BEACON_PERIOD_EXPIRED;
1051 } 1726 }
1052 1727
1053 if (inta & CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) { 1728 if (inta & IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
1054 IPW_WARNING("HOST_CMD_DONE\n"); 1729 IPW_WARNING("HOST_CMD_DONE\n");
1055 handled |= CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE; 1730 handled |= IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
1056 } 1731 }
1057 1732
1058 if (inta & CX2_INTA_BIT_FW_INITIALIZATION_DONE) { 1733 if (inta & IPW_INTA_BIT_FW_INITIALIZATION_DONE) {
1059 IPW_WARNING("FW_INITIALIZATION_DONE\n"); 1734 IPW_WARNING("FW_INITIALIZATION_DONE\n");
1060 handled |= CX2_INTA_BIT_FW_INITIALIZATION_DONE; 1735 handled |= IPW_INTA_BIT_FW_INITIALIZATION_DONE;
1061 } 1736 }
1062 1737
1063 if (inta & CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) { 1738 if (inta & IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
1064 IPW_WARNING("PHY_OFF_DONE\n"); 1739 IPW_WARNING("PHY_OFF_DONE\n");
1065 handled |= CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE; 1740 handled |= IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
1066 } 1741 }
1067 1742
1068 if (inta & CX2_INTA_BIT_RF_KILL_DONE) { 1743 if (inta & IPW_INTA_BIT_RF_KILL_DONE) {
1069 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n"); 1744 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
1070 priv->status |= STATUS_RF_KILL_HW; 1745 priv->status |= STATUS_RF_KILL_HW;
1071 wake_up_interruptible(&priv->wait_command_queue); 1746 wake_up_interruptible(&priv->wait_command_queue);
1072 netif_carrier_off(priv->net_dev); 1747 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1073 netif_stop_queue(priv->net_dev);
1074 cancel_delayed_work(&priv->request_scan); 1748 cancel_delayed_work(&priv->request_scan);
1749 schedule_work(&priv->link_down);
1075 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); 1750 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
1076 handled |= CX2_INTA_BIT_RF_KILL_DONE; 1751 handled |= IPW_INTA_BIT_RF_KILL_DONE;
1077 } 1752 }
1078 1753
1079 if (inta & CX2_INTA_BIT_FATAL_ERROR) { 1754 if (inta & IPW_INTA_BIT_FATAL_ERROR) {
1080 IPW_ERROR("Firmware error detected. Restarting.\n"); 1755 IPW_ERROR("Firmware error detected. Restarting.\n");
1756 if (priv->error) {
1757 IPW_ERROR("Sysfs 'error' log already exists.\n");
1081#ifdef CONFIG_IPW_DEBUG 1758#ifdef CONFIG_IPW_DEBUG
1082 if (ipw_debug_level & IPW_DL_FW_ERRORS) { 1759 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
1083 ipw_dump_nic_error_log(priv); 1760 struct ipw_fw_error *error =
1084 ipw_dump_nic_event_log(priv); 1761 ipw_alloc_error_log(priv);
1085 } 1762 ipw_dump_error_log(priv, error);
1763 if (error)
1764 ipw_free_error_log(error);
1765 }
1086#endif 1766#endif
1767 } else {
1768 priv->error = ipw_alloc_error_log(priv);
1769 if (priv->error)
1770 IPW_ERROR("Sysfs 'error' log captured.\n");
1771 else
1772 IPW_ERROR("Error allocating sysfs 'error' "
1773 "log.\n");
1774#ifdef CONFIG_IPW_DEBUG
1775 if (ipw_debug_level & IPW_DL_FW_ERRORS)
1776 ipw_dump_error_log(priv, priv->error);
1777#endif
1778 }
1779
1780 /* XXX: If hardware encryption is for WPA/WPA2,
1781 * we have to notify the supplicant. */
1782 if (priv->ieee->sec.encrypt) {
1783 priv->status &= ~STATUS_ASSOCIATED;
1784 notify_wx_assoc_event(priv);
1785 }
1786
1787 /* Keep the restart process from trying to send host
1788 * commands by clearing the INIT status bit */
1789 priv->status &= ~STATUS_INIT;
1790
1791 /* Cancel currently queued command. */
1792 priv->status &= ~STATUS_HCMD_ACTIVE;
1793 wake_up_interruptible(&priv->wait_command_queue);
1794
1087 queue_work(priv->workqueue, &priv->adapter_restart); 1795 queue_work(priv->workqueue, &priv->adapter_restart);
1088 handled |= CX2_INTA_BIT_FATAL_ERROR; 1796 handled |= IPW_INTA_BIT_FATAL_ERROR;
1089 } 1797 }
1090 1798
1091 if (inta & CX2_INTA_BIT_PARITY_ERROR) { 1799 if (inta & IPW_INTA_BIT_PARITY_ERROR) {
1092 IPW_ERROR("Parity error\n"); 1800 IPW_ERROR("Parity error\n");
1093 handled |= CX2_INTA_BIT_PARITY_ERROR; 1801 handled |= IPW_INTA_BIT_PARITY_ERROR;
1094 } 1802 }
1095 1803
1096 if (handled != inta) { 1804 if (handled != inta) {
@@ -1103,7 +1811,6 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1103 spin_unlock_irqrestore(&priv->lock, flags); 1811 spin_unlock_irqrestore(&priv->lock, flags);
1104} 1812}
1105 1813
1106#ifdef CONFIG_IPW_DEBUG
1107#define IPW_CMD(x) case IPW_CMD_ ## x : return #x 1814#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
1108static char *get_cmd_string(u8 cmd) 1815static char *get_cmd_string(u8 cmd)
1109{ 1816{
@@ -1162,44 +1869,78 @@ static char *get_cmd_string(u8 cmd)
1162 return "UNKNOWN"; 1869 return "UNKNOWN";
1163 } 1870 }
1164} 1871}
1165#endif /* CONFIG_IPW_DEBUG */
1166 1872
1167#define HOST_COMPLETE_TIMEOUT HZ 1873#define HOST_COMPLETE_TIMEOUT HZ
1168static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) 1874static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1169{ 1875{
1170 int rc = 0; 1876 int rc = 0;
1877 unsigned long flags;
1171 1878
1879 spin_lock_irqsave(&priv->lock, flags);
1172 if (priv->status & STATUS_HCMD_ACTIVE) { 1880 if (priv->status & STATUS_HCMD_ACTIVE) {
1173 IPW_ERROR("Already sending a command\n"); 1881 IPW_ERROR("Failed to send %s: Already sending a command.\n",
1174 return -1; 1882 get_cmd_string(cmd->cmd));
1883 spin_unlock_irqrestore(&priv->lock, flags);
1884 return -EAGAIN;
1175 } 1885 }
1176 1886
1177 priv->status |= STATUS_HCMD_ACTIVE; 1887 priv->status |= STATUS_HCMD_ACTIVE;
1178 1888
1179 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", 1889 if (priv->cmdlog) {
1180 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len); 1890 priv->cmdlog[priv->cmdlog_pos].jiffies = jiffies;
1891 priv->cmdlog[priv->cmdlog_pos].cmd.cmd = cmd->cmd;
1892 priv->cmdlog[priv->cmdlog_pos].cmd.len = cmd->len;
1893 memcpy(priv->cmdlog[priv->cmdlog_pos].cmd.param, cmd->param,
1894 cmd->len);
1895 priv->cmdlog[priv->cmdlog_pos].retcode = -1;
1896 }
1897
1898 IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
1899 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
1900 priv->status);
1181 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len); 1901 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
1182 1902
1183 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0); 1903 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
1184 if (rc) 1904 if (rc) {
1185 return rc; 1905 priv->status &= ~STATUS_HCMD_ACTIVE;
1906 IPW_ERROR("Failed to send %s: Reason %d\n",
1907 get_cmd_string(cmd->cmd), rc);
1908 spin_unlock_irqrestore(&priv->lock, flags);
1909 goto exit;
1910 }
1911 spin_unlock_irqrestore(&priv->lock, flags);
1186 1912
1187 rc = wait_event_interruptible_timeout(priv->wait_command_queue, 1913 rc = wait_event_interruptible_timeout(priv->wait_command_queue,
1188 !(priv-> 1914 !(priv->
1189 status & STATUS_HCMD_ACTIVE), 1915 status & STATUS_HCMD_ACTIVE),
1190 HOST_COMPLETE_TIMEOUT); 1916 HOST_COMPLETE_TIMEOUT);
1191 if (rc == 0) { 1917 if (rc == 0) {
1192 IPW_DEBUG_INFO("Command completion failed out after %dms.\n", 1918 spin_lock_irqsave(&priv->lock, flags);
1193 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 1919 if (priv->status & STATUS_HCMD_ACTIVE) {
1194 priv->status &= ~STATUS_HCMD_ACTIVE; 1920 IPW_ERROR("Failed to send %s: Command timed out.\n",
1195 return -EIO; 1921 get_cmd_string(cmd->cmd));
1196 } 1922 priv->status &= ~STATUS_HCMD_ACTIVE;
1197 if (priv->status & STATUS_RF_KILL_MASK) { 1923 spin_unlock_irqrestore(&priv->lock, flags);
1198 IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n"); 1924 rc = -EIO;
1199 return -EIO; 1925 goto exit;
1926 }
1927 spin_unlock_irqrestore(&priv->lock, flags);
1928 } else
1929 rc = 0;
1930
1931 if (priv->status & STATUS_RF_KILL_HW) {
1932 IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",
1933 get_cmd_string(cmd->cmd));
1934 rc = -EIO;
1935 goto exit;
1200 } 1936 }
1201 1937
1202 return 0; 1938 exit:
1939 if (priv->cmdlog) {
1940 priv->cmdlog[priv->cmdlog_pos++].retcode = rc;
1941 priv->cmdlog_pos %= priv->cmdlog_len;
1942 }
1943 return rc;
1203} 1944}
1204 1945
1205static int ipw_send_host_complete(struct ipw_priv *priv) 1946static int ipw_send_host_complete(struct ipw_priv *priv)
@@ -1214,12 +1955,7 @@ static int ipw_send_host_complete(struct ipw_priv *priv)
1214 return -1; 1955 return -1;
1215 } 1956 }
1216 1957
1217 if (ipw_send_cmd(priv, &cmd)) { 1958 return ipw_send_cmd(priv, &cmd);
1218 IPW_ERROR("failed to send HOST_COMPLETE command\n");
1219 return -1;
1220 }
1221
1222 return 0;
1223} 1959}
1224 1960
1225static int ipw_send_system_config(struct ipw_priv *priv, 1961static int ipw_send_system_config(struct ipw_priv *priv,
@@ -1235,13 +1971,8 @@ static int ipw_send_system_config(struct ipw_priv *priv,
1235 return -1; 1971 return -1;
1236 } 1972 }
1237 1973
1238 memcpy(&cmd.param, config, sizeof(*config)); 1974 memcpy(cmd.param, config, sizeof(*config));
1239 if (ipw_send_cmd(priv, &cmd)) { 1975 return ipw_send_cmd(priv, &cmd);
1240 IPW_ERROR("failed to send SYSTEM_CONFIG command\n");
1241 return -1;
1242 }
1243
1244 return 0;
1245} 1976}
1246 1977
1247static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len) 1978static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
@@ -1256,13 +1987,8 @@ static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
1256 return -1; 1987 return -1;
1257 } 1988 }
1258 1989
1259 memcpy(&cmd.param, ssid, cmd.len); 1990 memcpy(cmd.param, ssid, cmd.len);
1260 if (ipw_send_cmd(priv, &cmd)) { 1991 return ipw_send_cmd(priv, &cmd);
1261 IPW_ERROR("failed to send SSID command\n");
1262 return -1;
1263 }
1264
1265 return 0;
1266} 1992}
1267 1993
1268static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) 1994static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
@@ -1280,16 +2006,15 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
1280 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n", 2006 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
1281 priv->net_dev->name, MAC_ARG(mac)); 2007 priv->net_dev->name, MAC_ARG(mac));
1282 2008
1283 memcpy(&cmd.param, mac, ETH_ALEN); 2009 memcpy(cmd.param, mac, ETH_ALEN);
1284 2010 return ipw_send_cmd(priv, &cmd);
1285 if (ipw_send_cmd(priv, &cmd)) {
1286 IPW_ERROR("failed to send ADAPTER_ADDRESS command\n");
1287 return -1;
1288 }
1289
1290 return 0;
1291} 2011}
1292 2012
2013/*
2014 * NOTE: This must be executed from our workqueue as it results in udelay
2015 * being called which may corrupt the keyboard if executed on default
2016 * workqueue
2017 */
1293static void ipw_adapter_restart(void *adapter) 2018static void ipw_adapter_restart(void *adapter)
1294{ 2019{
1295 struct ipw_priv *priv = adapter; 2020 struct ipw_priv *priv = adapter;
@@ -1298,12 +2023,25 @@ static void ipw_adapter_restart(void *adapter)
1298 return; 2023 return;
1299 2024
1300 ipw_down(priv); 2025 ipw_down(priv);
2026
2027 if (priv->assoc_network &&
2028 (priv->assoc_network->capability & WLAN_CAPABILITY_IBSS))
2029 ipw_remove_current_network(priv);
2030
1301 if (ipw_up(priv)) { 2031 if (ipw_up(priv)) {
1302 IPW_ERROR("Failed to up device\n"); 2032 IPW_ERROR("Failed to up device\n");
1303 return; 2033 return;
1304 } 2034 }
1305} 2035}
1306 2036
2037static void ipw_bg_adapter_restart(void *data)
2038{
2039 struct ipw_priv *priv = data;
2040 down(&priv->sem);
2041 ipw_adapter_restart(data);
2042 up(&priv->sem);
2043}
2044
1307#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ) 2045#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
1308 2046
1309static void ipw_scan_check(void *data) 2047static void ipw_scan_check(void *data)
@@ -1313,10 +2051,18 @@ static void ipw_scan_check(void *data)
1313 IPW_DEBUG_SCAN("Scan completion watchdog resetting " 2051 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
1314 "adapter (%dms).\n", 2052 "adapter (%dms).\n",
1315 IPW_SCAN_CHECK_WATCHDOG / 100); 2053 IPW_SCAN_CHECK_WATCHDOG / 100);
1316 ipw_adapter_restart(priv); 2054 queue_work(priv->workqueue, &priv->adapter_restart);
1317 } 2055 }
1318} 2056}
1319 2057
2058static void ipw_bg_scan_check(void *data)
2059{
2060 struct ipw_priv *priv = data;
2061 down(&priv->sem);
2062 ipw_scan_check(data);
2063 up(&priv->sem);
2064}
2065
1320static int ipw_send_scan_request_ext(struct ipw_priv *priv, 2066static int ipw_send_scan_request_ext(struct ipw_priv *priv,
1321 struct ipw_scan_request_ext *request) 2067 struct ipw_scan_request_ext *request)
1322{ 2068{
@@ -1325,20 +2071,8 @@ static int ipw_send_scan_request_ext(struct ipw_priv *priv,
1325 .len = sizeof(*request) 2071 .len = sizeof(*request)
1326 }; 2072 };
1327 2073
1328 if (!priv || !request) { 2074 memcpy(cmd.param, request, sizeof(*request));
1329 IPW_ERROR("Invalid args\n"); 2075 return ipw_send_cmd(priv, &cmd);
1330 return -1;
1331 }
1332
1333 memcpy(&cmd.param, request, sizeof(*request));
1334 if (ipw_send_cmd(priv, &cmd)) {
1335 IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n");
1336 return -1;
1337 }
1338
1339 queue_delayed_work(priv->workqueue, &priv->scan_check,
1340 IPW_SCAN_CHECK_WATCHDOG);
1341 return 0;
1342} 2076}
1343 2077
1344static int ipw_send_scan_abort(struct ipw_priv *priv) 2078static int ipw_send_scan_abort(struct ipw_priv *priv)
@@ -1353,12 +2087,7 @@ static int ipw_send_scan_abort(struct ipw_priv *priv)
1353 return -1; 2087 return -1;
1354 } 2088 }
1355 2089
1356 if (ipw_send_cmd(priv, &cmd)) { 2090 return ipw_send_cmd(priv, &cmd);
1357 IPW_ERROR("failed to send SCAN_ABORT command\n");
1358 return -1;
1359 }
1360
1361 return 0;
1362} 2091}
1363 2092
1364static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) 2093static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
@@ -1370,12 +2099,7 @@ static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
1370 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *) 2099 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
1371 &cmd.param; 2100 &cmd.param;
1372 calib->beacon_rssi_raw = sens; 2101 calib->beacon_rssi_raw = sens;
1373 if (ipw_send_cmd(priv, &cmd)) { 2102 return ipw_send_cmd(priv, &cmd);
1374 IPW_ERROR("failed to send SENSITIVITY CALIB command\n");
1375 return -1;
1376 }
1377
1378 return 0;
1379} 2103}
1380 2104
1381static int ipw_send_associate(struct ipw_priv *priv, 2105static int ipw_send_associate(struct ipw_priv *priv,
@@ -1386,18 +2110,26 @@ static int ipw_send_associate(struct ipw_priv *priv,
1386 .len = sizeof(*associate) 2110 .len = sizeof(*associate)
1387 }; 2111 };
1388 2112
2113 struct ipw_associate tmp_associate;
2114 memcpy(&tmp_associate, associate, sizeof(*associate));
2115 tmp_associate.policy_support =
2116 cpu_to_le16(tmp_associate.policy_support);
2117 tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
2118 tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
2119 tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
2120 tmp_associate.listen_interval =
2121 cpu_to_le16(tmp_associate.listen_interval);
2122 tmp_associate.beacon_interval =
2123 cpu_to_le16(tmp_associate.beacon_interval);
2124 tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
2125
1389 if (!priv || !associate) { 2126 if (!priv || !associate) {
1390 IPW_ERROR("Invalid args\n"); 2127 IPW_ERROR("Invalid args\n");
1391 return -1; 2128 return -1;
1392 } 2129 }
1393 2130
1394 memcpy(&cmd.param, associate, sizeof(*associate)); 2131 memcpy(cmd.param, &tmp_associate, sizeof(*associate));
1395 if (ipw_send_cmd(priv, &cmd)) { 2132 return ipw_send_cmd(priv, &cmd);
1396 IPW_ERROR("failed to send ASSOCIATE command\n");
1397 return -1;
1398 }
1399
1400 return 0;
1401} 2133}
1402 2134
1403static int ipw_send_supported_rates(struct ipw_priv *priv, 2135static int ipw_send_supported_rates(struct ipw_priv *priv,
@@ -1413,13 +2145,8 @@ static int ipw_send_supported_rates(struct ipw_priv *priv,
1413 return -1; 2145 return -1;
1414 } 2146 }
1415 2147
1416 memcpy(&cmd.param, rates, sizeof(*rates)); 2148 memcpy(cmd.param, rates, sizeof(*rates));
1417 if (ipw_send_cmd(priv, &cmd)) { 2149 return ipw_send_cmd(priv, &cmd);
1418 IPW_ERROR("failed to send SUPPORTED_RATES command\n");
1419 return -1;
1420 }
1421
1422 return 0;
1423} 2150}
1424 2151
1425static int ipw_set_random_seed(struct ipw_priv *priv) 2152static int ipw_set_random_seed(struct ipw_priv *priv)
@@ -1436,15 +2163,9 @@ static int ipw_set_random_seed(struct ipw_priv *priv)
1436 2163
1437 get_random_bytes(&cmd.param, sizeof(u32)); 2164 get_random_bytes(&cmd.param, sizeof(u32));
1438 2165
1439 if (ipw_send_cmd(priv, &cmd)) { 2166 return ipw_send_cmd(priv, &cmd);
1440 IPW_ERROR("failed to send SEED_NUMBER command\n");
1441 return -1;
1442 }
1443
1444 return 0;
1445} 2167}
1446 2168
1447#if 0
1448static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off) 2169static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
1449{ 2170{
1450 struct host_cmd cmd = { 2171 struct host_cmd cmd = {
@@ -1459,14 +2180,8 @@ static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
1459 2180
1460 *((u32 *) & cmd.param) = phy_off; 2181 *((u32 *) & cmd.param) = phy_off;
1461 2182
1462 if (ipw_send_cmd(priv, &cmd)) { 2183 return ipw_send_cmd(priv, &cmd);
1463 IPW_ERROR("failed to send CARD_DISABLE command\n");
1464 return -1;
1465 }
1466
1467 return 0;
1468} 2184}
1469#endif
1470 2185
1471static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power) 2186static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
1472{ 2187{
@@ -1480,12 +2195,51 @@ static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
1480 return -1; 2195 return -1;
1481 } 2196 }
1482 2197
1483 memcpy(&cmd.param, power, sizeof(*power)); 2198 memcpy(cmd.param, power, sizeof(*power));
1484 if (ipw_send_cmd(priv, &cmd)) { 2199 return ipw_send_cmd(priv, &cmd);
1485 IPW_ERROR("failed to send TX_POWER command\n"); 2200}
1486 return -1; 2201
2202static int ipw_set_tx_power(struct ipw_priv *priv)
2203{
2204 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
2205 struct ipw_tx_power tx_power;
2206 s8 max_power;
2207 int i;
2208
2209 memset(&tx_power, 0, sizeof(tx_power));
2210
2211 /* configure device for 'G' band */
2212 tx_power.ieee_mode = IPW_G_MODE;
2213 tx_power.num_channels = geo->bg_channels;
2214 for (i = 0; i < geo->bg_channels; i++) {
2215 max_power = geo->bg[i].max_power;
2216 tx_power.channels_tx_power[i].channel_number =
2217 geo->bg[i].channel;
2218 tx_power.channels_tx_power[i].tx_power = max_power ?
2219 min(max_power, priv->tx_power) : priv->tx_power;
1487 } 2220 }
2221 if (ipw_send_tx_power(priv, &tx_power))
2222 return -EIO;
2223
2224 /* configure device to also handle 'B' band */
2225 tx_power.ieee_mode = IPW_B_MODE;
2226 if (ipw_send_tx_power(priv, &tx_power))
2227 return -EIO;
1488 2228
2229 /* configure device to also handle 'A' band */
2230 if (priv->ieee->abg_true) {
2231 tx_power.ieee_mode = IPW_A_MODE;
2232 tx_power.num_channels = geo->a_channels;
2233 for (i = 0; i < tx_power.num_channels; i++) {
2234 max_power = geo->a[i].max_power;
2235 tx_power.channels_tx_power[i].channel_number =
2236 geo->a[i].channel;
2237 tx_power.channels_tx_power[i].tx_power = max_power ?
2238 min(max_power, priv->tx_power) : priv->tx_power;
2239 }
2240 if (ipw_send_tx_power(priv, &tx_power))
2241 return -EIO;
2242 }
1489 return 0; 2243 return 0;
1490} 2244}
1491 2245
@@ -1504,13 +2258,8 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
1504 return -1; 2258 return -1;
1505 } 2259 }
1506 2260
1507 memcpy(&cmd.param, &rts_threshold, sizeof(rts_threshold)); 2261 memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold));
1508 if (ipw_send_cmd(priv, &cmd)) { 2262 return ipw_send_cmd(priv, &cmd);
1509 IPW_ERROR("failed to send RTS_THRESHOLD command\n");
1510 return -1;
1511 }
1512
1513 return 0;
1514} 2263}
1515 2264
1516static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) 2265static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
@@ -1528,13 +2277,8 @@ static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
1528 return -1; 2277 return -1;
1529 } 2278 }
1530 2279
1531 memcpy(&cmd.param, &frag_threshold, sizeof(frag_threshold)); 2280 memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold));
1532 if (ipw_send_cmd(priv, &cmd)) { 2281 return ipw_send_cmd(priv, &cmd);
1533 IPW_ERROR("failed to send FRAG_THRESHOLD command\n");
1534 return -1;
1535 }
1536
1537 return 0;
1538} 2282}
1539 2283
1540static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) 2284static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
@@ -1564,12 +2308,27 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
1564 break; 2308 break;
1565 } 2309 }
1566 2310
1567 if (ipw_send_cmd(priv, &cmd)) { 2311 return ipw_send_cmd(priv, &cmd);
1568 IPW_ERROR("failed to send POWER_MODE command\n"); 2312}
2313
2314static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
2315{
2316 struct ipw_retry_limit retry_limit = {
2317 .short_retry_limit = slimit,
2318 .long_retry_limit = llimit
2319 };
2320 struct host_cmd cmd = {
2321 .cmd = IPW_CMD_RETRY_LIMIT,
2322 .len = sizeof(retry_limit)
2323 };
2324
2325 if (!priv) {
2326 IPW_ERROR("Invalid args\n");
1569 return -1; 2327 return -1;
1570 } 2328 }
1571 2329
1572 return 0; 2330 memcpy(cmd.param, &retry_limit, sizeof(retry_limit));
2331 return ipw_send_cmd(priv, &cmd);
1573} 2332}
1574 2333
1575/* 2334/*
@@ -1671,8 +2430,7 @@ static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)
1671/* data's copy of the eeprom data */ 2430/* data's copy of the eeprom data */
1672static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac) 2431static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
1673{ 2432{
1674 u8 *ee = (u8 *) priv->eeprom; 2433 memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6);
1675 memcpy(mac, &ee[EEPROM_MAC_ADDRESS], 6);
1676} 2434}
1677 2435
1678/* 2436/*
@@ -1692,7 +2450,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
1692 2450
1693 /* read entire contents of eeprom into private buffer */ 2451 /* read entire contents of eeprom into private buffer */
1694 for (i = 0; i < 128; i++) 2452 for (i = 0; i < 128; i++)
1695 eeprom[i] = eeprom_read_u16(priv, (u8) i); 2453 eeprom[i] = le16_to_cpu(eeprom_read_u16(priv, (u8) i));
1696 2454
1697 /* 2455 /*
1698 If the data looks correct, then copy it to our private 2456 If the data looks correct, then copy it to our private
@@ -1703,7 +2461,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
1703 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n"); 2461 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
1704 2462
1705 /* write the eeprom data to sram */ 2463 /* write the eeprom data to sram */
1706 for (i = 0; i < CX2_EEPROM_IMAGE_SIZE; i++) 2464 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
1707 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]); 2465 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]);
1708 2466
1709 /* Do not load eeprom data on fatal error or suspend */ 2467 /* Do not load eeprom data on fatal error or suspend */
@@ -1723,14 +2481,14 @@ static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
1723 count >>= 2; 2481 count >>= 2;
1724 if (!count) 2482 if (!count)
1725 return; 2483 return;
1726 _ipw_write32(priv, CX2_AUTOINC_ADDR, start); 2484 _ipw_write32(priv, IPW_AUTOINC_ADDR, start);
1727 while (count--) 2485 while (count--)
1728 _ipw_write32(priv, CX2_AUTOINC_DATA, 0); 2486 _ipw_write32(priv, IPW_AUTOINC_DATA, 0);
1729} 2487}
1730 2488
1731static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv) 2489static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
1732{ 2490{
1733 ipw_zero_memory(priv, CX2_SHARED_SRAM_DMA_CONTROL, 2491 ipw_zero_memory(priv, IPW_SHARED_SRAM_DMA_CONTROL,
1734 CB_NUMBER_OF_ELEMENTS_SMALL * 2492 CB_NUMBER_OF_ELEMENTS_SMALL *
1735 sizeof(struct command_block)); 2493 sizeof(struct command_block));
1736} 2494}
@@ -1744,7 +2502,7 @@ static int ipw_fw_dma_enable(struct ipw_priv *priv)
1744 ipw_fw_dma_reset_command_blocks(priv); 2502 ipw_fw_dma_reset_command_blocks(priv);
1745 2503
1746 /* Write CB base address */ 2504 /* Write CB base address */
1747 ipw_write_reg32(priv, CX2_DMA_I_CB_BASE, CX2_SHARED_SRAM_DMA_CONTROL); 2505 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
1748 2506
1749 IPW_DEBUG_FW("<< : \n"); 2507 IPW_DEBUG_FW("<< : \n");
1750 return 0; 2508 return 0;
@@ -1758,7 +2516,7 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv)
1758 2516
1759 //set the Stop and Abort bit 2517 //set the Stop and Abort bit
1760 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT; 2518 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
1761 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); 2519 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
1762 priv->sram_desc.last_cb_index = 0; 2520 priv->sram_desc.last_cb_index = 0;
1763 2521
1764 IPW_DEBUG_FW("<< \n"); 2522 IPW_DEBUG_FW("<< \n");
@@ -1768,7 +2526,7 @@ static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
1768 struct command_block *cb) 2526 struct command_block *cb)
1769{ 2527{
1770 u32 address = 2528 u32 address =
1771 CX2_SHARED_SRAM_DMA_CONTROL + 2529 IPW_SHARED_SRAM_DMA_CONTROL +
1772 (sizeof(struct command_block) * index); 2530 (sizeof(struct command_block) * index);
1773 IPW_DEBUG_FW(">> :\n"); 2531 IPW_DEBUG_FW(">> :\n");
1774 2532
@@ -1792,13 +2550,13 @@ static int ipw_fw_dma_kick(struct ipw_priv *priv)
1792 &priv->sram_desc.cb_list[index]); 2550 &priv->sram_desc.cb_list[index]);
1793 2551
1794 /* Enable the DMA in the CSR register */ 2552 /* Enable the DMA in the CSR register */
1795 ipw_clear_bit(priv, CX2_RESET_REG, 2553 ipw_clear_bit(priv, IPW_RESET_REG,
1796 CX2_RESET_REG_MASTER_DISABLED | 2554 IPW_RESET_REG_MASTER_DISABLED |
1797 CX2_RESET_REG_STOP_MASTER); 2555 IPW_RESET_REG_STOP_MASTER);
1798 2556
1799 /* Set the Start bit. */ 2557 /* Set the Start bit. */
1800 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START; 2558 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;
1801 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); 2559 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
1802 2560
1803 IPW_DEBUG_FW("<< :\n"); 2561 IPW_DEBUG_FW("<< :\n");
1804 return 0; 2562 return 0;
@@ -1811,12 +2569,12 @@ static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
1811 u32 cb_fields_address = 0; 2569 u32 cb_fields_address = 0;
1812 2570
1813 IPW_DEBUG_FW(">> :\n"); 2571 IPW_DEBUG_FW(">> :\n");
1814 address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); 2572 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
1815 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address); 2573 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address);
1816 2574
1817 /* Read the DMA Controlor register */ 2575 /* Read the DMA Controlor register */
1818 register_value = ipw_read_reg32(priv, CX2_DMA_I_DMA_CONTROL); 2576 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
1819 IPW_DEBUG_FW_INFO("CX2_DMA_I_DMA_CONTROL is 0x%x \n", register_value); 2577 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x \n", register_value);
1820 2578
1821 /* Print the CB values */ 2579 /* Print the CB values */
1822 cb_fields_address = address; 2580 cb_fields_address = address;
@@ -1845,9 +2603,9 @@ static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
1845 u32 current_cb_index = 0; 2603 u32 current_cb_index = 0;
1846 2604
1847 IPW_DEBUG_FW("<< :\n"); 2605 IPW_DEBUG_FW("<< :\n");
1848 current_cb_address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); 2606 current_cb_address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
1849 2607
1850 current_cb_index = (current_cb_address - CX2_SHARED_SRAM_DMA_CONTROL) / 2608 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
1851 sizeof(struct command_block); 2609 sizeof(struct command_block);
1852 2610
1853 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n", 2611 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n",
@@ -1976,8 +2734,8 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
1976 ipw_fw_dma_abort(priv); 2734 ipw_fw_dma_abort(priv);
1977 2735
1978 /*Disable the DMA in the CSR register */ 2736 /*Disable the DMA in the CSR register */
1979 ipw_set_bit(priv, CX2_RESET_REG, 2737 ipw_set_bit(priv, IPW_RESET_REG,
1980 CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER); 2738 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
1981 2739
1982 IPW_DEBUG_FW("<< dmaWaitSync \n"); 2740 IPW_DEBUG_FW("<< dmaWaitSync \n");
1983 return 0; 2741 return 0;
@@ -1987,6 +2745,9 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
1987{ 2745{
1988 struct list_head *element, *safe; 2746 struct list_head *element, *safe;
1989 struct ieee80211_network *network = NULL; 2747 struct ieee80211_network *network = NULL;
2748 unsigned long flags;
2749
2750 spin_lock_irqsave(&priv->ieee->lock, flags);
1990 list_for_each_safe(element, safe, &priv->ieee->network_list) { 2751 list_for_each_safe(element, safe, &priv->ieee->network_list) {
1991 network = list_entry(element, struct ieee80211_network, list); 2752 network = list_entry(element, struct ieee80211_network, list);
1992 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 2753 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
@@ -1995,6 +2756,7 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
1995 &priv->ieee->network_free_list); 2756 &priv->ieee->network_free_list);
1996 } 2757 }
1997 } 2758 }
2759 spin_unlock_irqrestore(&priv->ieee->lock, flags);
1998} 2760}
1999 2761
2000/** 2762/**
@@ -2037,10 +2799,10 @@ static int ipw_stop_master(struct ipw_priv *priv)
2037 2799
2038 IPW_DEBUG_TRACE(">> \n"); 2800 IPW_DEBUG_TRACE(">> \n");
2039 /* stop master. typical delay - 0 */ 2801 /* stop master. typical delay - 0 */
2040 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); 2802 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
2041 2803
2042 rc = ipw_poll_bit(priv, CX2_RESET_REG, 2804 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2043 CX2_RESET_REG_MASTER_DISABLED, 100); 2805 IPW_RESET_REG_MASTER_DISABLED, 100);
2044 if (rc < 0) { 2806 if (rc < 0) {
2045 IPW_ERROR("stop master failed in 10ms\n"); 2807 IPW_ERROR("stop master failed in 10ms\n");
2046 return -1; 2808 return -1;
@@ -2056,7 +2818,7 @@ static void ipw_arc_release(struct ipw_priv *priv)
2056 IPW_DEBUG_TRACE(">> \n"); 2818 IPW_DEBUG_TRACE(">> \n");
2057 mdelay(5); 2819 mdelay(5);
2058 2820
2059 ipw_clear_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET); 2821 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
2060 2822
2061 /* no one knows timing, for safety add some delay */ 2823 /* no one knows timing, for safety add some delay */
2062 mdelay(5); 2824 mdelay(5);
@@ -2073,13 +2835,12 @@ struct fw_chunk {
2073}; 2835};
2074 2836
2075#define IPW_FW_MAJOR_VERSION 2 2837#define IPW_FW_MAJOR_VERSION 2
2076#define IPW_FW_MINOR_VERSION 2 2838#define IPW_FW_MINOR_VERSION 4
2077 2839
2078#define IPW_FW_MINOR(x) ((x & 0xff) >> 8) 2840#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
2079#define IPW_FW_MAJOR(x) (x & 0xff) 2841#define IPW_FW_MAJOR(x) (x & 0xff)
2080 2842
2081#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | \ 2843#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION)
2082 IPW_FW_MAJOR_VERSION)
2083 2844
2084#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \ 2845#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
2085"." __stringify(IPW_FW_MINOR_VERSION) "-" 2846"." __stringify(IPW_FW_MINOR_VERSION) "-"
@@ -2107,8 +2868,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2107 2868
2108// spin_lock_irqsave(&priv->lock, flags); 2869// spin_lock_irqsave(&priv->lock, flags);
2109 2870
2110 for (addr = CX2_SHARED_LOWER_BOUND; 2871 for (addr = IPW_SHARED_LOWER_BOUND;
2111 addr < CX2_REGISTER_DOMAIN1_END; addr += 4) { 2872 addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {
2112 ipw_write32(priv, addr, 0); 2873 ipw_write32(priv, addr, 0);
2113 } 2874 }
2114 2875
@@ -2117,16 +2878,16 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2117 /* destroy DMA queues */ 2878 /* destroy DMA queues */
2118 /* reset sequence */ 2879 /* reset sequence */
2119 2880
2120 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_ON); 2881 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_ON);
2121 ipw_arc_release(priv); 2882 ipw_arc_release(priv);
2122 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_OFF); 2883 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_OFF);
2123 mdelay(1); 2884 mdelay(1);
2124 2885
2125 /* reset PHY */ 2886 /* reset PHY */
2126 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, CX2_BASEBAND_POWER_DOWN); 2887 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, IPW_BASEBAND_POWER_DOWN);
2127 mdelay(1); 2888 mdelay(1);
2128 2889
2129 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, 0); 2890 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, 0);
2130 mdelay(1); 2891 mdelay(1);
2131 2892
2132 /* enable ucode store */ 2893 /* enable ucode store */
@@ -2144,18 +2905,19 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2144 */ 2905 */
2145 /* load new ipw uCode */ 2906 /* load new ipw uCode */
2146 for (i = 0; i < len / 2; i++) 2907 for (i = 0; i < len / 2; i++)
2147 ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE, image[i]); 2908 ipw_write_reg16(priv, IPW_BASEBAND_CONTROL_STORE,
2909 cpu_to_le16(image[i]));
2148 2910
2149 /* enable DINO */ 2911 /* enable DINO */
2150 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); 2912 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
2151 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM); 2913 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);
2152 2914
2153 /* this is where the igx / win driver deveates from the VAP driver. */ 2915 /* this is where the igx / win driver deveates from the VAP driver. */
2154 2916
2155 /* wait for alive response */ 2917 /* wait for alive response */
2156 for (i = 0; i < 100; i++) { 2918 for (i = 0; i < 100; i++) {
2157 /* poll for incoming data */ 2919 /* poll for incoming data */
2158 cr = ipw_read_reg8(priv, CX2_BASEBAND_CONTROL_STATUS); 2920 cr = ipw_read_reg8(priv, IPW_BASEBAND_CONTROL_STATUS);
2159 if (cr & DINO_RXFIFO_DATA) 2921 if (cr & DINO_RXFIFO_DATA)
2160 break; 2922 break;
2161 mdelay(1); 2923 mdelay(1);
@@ -2167,7 +2929,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2167 2929
2168 for (i = 0; i < ARRAY_SIZE(response_buffer); i++) 2930 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
2169 response_buffer[i] = 2931 response_buffer[i] =
2170 ipw_read_reg32(priv, CX2_BASEBAND_RX_FIFO_READ); 2932 le32_to_cpu(ipw_read_reg32(priv,
2933 IPW_BASEBAND_RX_FIFO_READ));
2171 memcpy(&priv->dino_alive, response_buffer, 2934 memcpy(&priv->dino_alive, response_buffer,
2172 sizeof(priv->dino_alive)); 2935 sizeof(priv->dino_alive));
2173 if (priv->dino_alive.alive_command == 1 2936 if (priv->dino_alive.alive_command == 1
@@ -2196,7 +2959,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2196 2959
2197 /* disable DINO, otherwise for some reason 2960 /* disable DINO, otherwise for some reason
2198 firmware have problem getting alive resp. */ 2961 firmware have problem getting alive resp. */
2199 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); 2962 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
2200 2963
2201// spin_unlock_irqrestore(&priv->lock, flags); 2964// spin_unlock_irqrestore(&priv->lock, flags);
2202 2965
@@ -2236,13 +2999,14 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
2236 * offeset*/ 2999 * offeset*/
2237 /* Dma loading */ 3000 /* Dma loading */
2238 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset, 3001 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
2239 chunk->address, chunk->length); 3002 le32_to_cpu(chunk->address),
3003 le32_to_cpu(chunk->length));
2240 if (rc) { 3004 if (rc) {
2241 IPW_DEBUG_INFO("dmaAddBuffer Failed\n"); 3005 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
2242 goto out; 3006 goto out;
2243 } 3007 }
2244 3008
2245 offset += chunk->length; 3009 offset += le32_to_cpu(chunk->length);
2246 } while (offset < len); 3010 } while (offset < len);
2247 3011
2248 /* Run the DMA and wait for the answer */ 3012 /* Run the DMA and wait for the answer */
@@ -2268,16 +3032,16 @@ static int ipw_stop_nic(struct ipw_priv *priv)
2268 int rc = 0; 3032 int rc = 0;
2269 3033
2270 /* stop */ 3034 /* stop */
2271 ipw_write32(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); 3035 ipw_write32(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
2272 3036
2273 rc = ipw_poll_bit(priv, CX2_RESET_REG, 3037 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2274 CX2_RESET_REG_MASTER_DISABLED, 500); 3038 IPW_RESET_REG_MASTER_DISABLED, 500);
2275 if (rc < 0) { 3039 if (rc < 0) {
2276 IPW_ERROR("wait for reg master disabled failed\n"); 3040 IPW_ERROR("wait for reg master disabled failed\n");
2277 return rc; 3041 return rc;
2278 } 3042 }
2279 3043
2280 ipw_set_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET); 3044 ipw_set_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
2281 3045
2282 return rc; 3046 return rc;
2283} 3047}
@@ -2287,14 +3051,14 @@ static void ipw_start_nic(struct ipw_priv *priv)
2287 IPW_DEBUG_TRACE(">>\n"); 3051 IPW_DEBUG_TRACE(">>\n");
2288 3052
2289 /* prvHwStartNic release ARC */ 3053 /* prvHwStartNic release ARC */
2290 ipw_clear_bit(priv, CX2_RESET_REG, 3054 ipw_clear_bit(priv, IPW_RESET_REG,
2291 CX2_RESET_REG_MASTER_DISABLED | 3055 IPW_RESET_REG_MASTER_DISABLED |
2292 CX2_RESET_REG_STOP_MASTER | 3056 IPW_RESET_REG_STOP_MASTER |
2293 CBD_RESET_REG_PRINCETON_RESET); 3057 CBD_RESET_REG_PRINCETON_RESET);
2294 3058
2295 /* enable power management */ 3059 /* enable power management */
2296 ipw_set_bit(priv, CX2_GP_CNTRL_RW, 3060 ipw_set_bit(priv, IPW_GP_CNTRL_RW,
2297 CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY); 3061 IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
2298 3062
2299 IPW_DEBUG_TRACE("<<\n"); 3063 IPW_DEBUG_TRACE("<<\n");
2300} 3064}
@@ -2307,25 +3071,25 @@ static int ipw_init_nic(struct ipw_priv *priv)
2307 /* reset */ 3071 /* reset */
2308 /*prvHwInitNic */ 3072 /*prvHwInitNic */
2309 /* set "initialization complete" bit to move adapter to D0 state */ 3073 /* set "initialization complete" bit to move adapter to D0 state */
2310 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE); 3074 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
2311 3075
2312 /* low-level PLL activation */ 3076 /* low-level PLL activation */
2313 ipw_write32(priv, CX2_READ_INT_REGISTER, 3077 ipw_write32(priv, IPW_READ_INT_REGISTER,
2314 CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER); 3078 IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
2315 3079
2316 /* wait for clock stabilization */ 3080 /* wait for clock stabilization */
2317 rc = ipw_poll_bit(priv, CX2_GP_CNTRL_RW, 3081 rc = ipw_poll_bit(priv, IPW_GP_CNTRL_RW,
2318 CX2_GP_CNTRL_BIT_CLOCK_READY, 250); 3082 IPW_GP_CNTRL_BIT_CLOCK_READY, 250);
2319 if (rc < 0) 3083 if (rc < 0)
2320 IPW_DEBUG_INFO("FAILED wait for clock stablization\n"); 3084 IPW_DEBUG_INFO("FAILED wait for clock stablization\n");
2321 3085
2322 /* assert SW reset */ 3086 /* assert SW reset */
2323 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_SW_RESET); 3087 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_SW_RESET);
2324 3088
2325 udelay(10); 3089 udelay(10);
2326 3090
2327 /* set "initialization complete" bit to move adapter to D0 state */ 3091 /* set "initialization complete" bit to move adapter to D0 state */
2328 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE); 3092 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
2329 3093
2330 IPW_DEBUG_TRACE(">>\n"); 3094 IPW_DEBUG_TRACE(">>\n");
2331 return 0; 3095 return 0;
@@ -2337,14 +3101,19 @@ static int ipw_init_nic(struct ipw_priv *priv)
2337static int ipw_reset_nic(struct ipw_priv *priv) 3101static int ipw_reset_nic(struct ipw_priv *priv)
2338{ 3102{
2339 int rc = 0; 3103 int rc = 0;
3104 unsigned long flags;
2340 3105
2341 IPW_DEBUG_TRACE(">>\n"); 3106 IPW_DEBUG_TRACE(">>\n");
2342 3107
2343 rc = ipw_init_nic(priv); 3108 rc = ipw_init_nic(priv);
2344 3109
3110 spin_lock_irqsave(&priv->lock, flags);
2345 /* Clear the 'host command active' bit... */ 3111 /* Clear the 'host command active' bit... */
2346 priv->status &= ~STATUS_HCMD_ACTIVE; 3112 priv->status &= ~STATUS_HCMD_ACTIVE;
2347 wake_up_interruptible(&priv->wait_command_queue); 3113 wake_up_interruptible(&priv->wait_command_queue);
3114 priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3115 wake_up_interruptible(&priv->wait_state);
3116 spin_unlock_irqrestore(&priv->lock, flags);
2348 3117
2349 IPW_DEBUG_TRACE("<<\n"); 3118 IPW_DEBUG_TRACE("<<\n");
2350 return rc; 3119 return rc;
@@ -2364,22 +3133,23 @@ static int ipw_get_fw(struct ipw_priv *priv,
2364 } 3133 }
2365 3134
2366 header = (struct fw_header *)(*fw)->data; 3135 header = (struct fw_header *)(*fw)->data;
2367 if (IPW_FW_MAJOR(header->version) != IPW_FW_MAJOR_VERSION) { 3136 if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) {
2368 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n", 3137 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
2369 name, 3138 name,
2370 IPW_FW_MAJOR(header->version), IPW_FW_MAJOR_VERSION); 3139 IPW_FW_MAJOR(le32_to_cpu(header->version)),
3140 IPW_FW_MAJOR_VERSION);
2371 return -EINVAL; 3141 return -EINVAL;
2372 } 3142 }
2373 3143
2374 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n", 3144 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
2375 name, 3145 name,
2376 IPW_FW_MAJOR(header->version), 3146 IPW_FW_MAJOR(le32_to_cpu(header->version)),
2377 IPW_FW_MINOR(header->version), 3147 IPW_FW_MINOR(le32_to_cpu(header->version)),
2378 (*fw)->size - sizeof(struct fw_header)); 3148 (*fw)->size - sizeof(struct fw_header));
2379 return 0; 3149 return 0;
2380} 3150}
2381 3151
2382#define CX2_RX_BUF_SIZE (3000) 3152#define IPW_RX_BUF_SIZE (3000)
2383 3153
2384static inline void ipw_rx_queue_reset(struct ipw_priv *priv, 3154static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2385 struct ipw_rx_queue *rxq) 3155 struct ipw_rx_queue *rxq)
@@ -2398,8 +3168,9 @@ static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2398 * to an SKB, so we need to unmap and free potential storage */ 3168 * to an SKB, so we need to unmap and free potential storage */
2399 if (rxq->pool[i].skb != NULL) { 3169 if (rxq->pool[i].skb != NULL) {
2400 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, 3170 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
2401 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 3171 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
2402 dev_kfree_skb(rxq->pool[i].skb); 3172 dev_kfree_skb(rxq->pool[i].skb);
3173 rxq->pool[i].skb = NULL;
2403 } 3174 }
2404 list_add_tail(&rxq->pool[i].list, &rxq->rx_used); 3175 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
2405 } 3176 }
@@ -2417,6 +3188,19 @@ static int fw_loaded = 0;
2417static const struct firmware *bootfw = NULL; 3188static const struct firmware *bootfw = NULL;
2418static const struct firmware *firmware = NULL; 3189static const struct firmware *firmware = NULL;
2419static const struct firmware *ucode = NULL; 3190static const struct firmware *ucode = NULL;
3191
3192static void free_firmware(void)
3193{
3194 if (fw_loaded) {
3195 release_firmware(bootfw);
3196 release_firmware(ucode);
3197 release_firmware(firmware);
3198 bootfw = ucode = firmware = NULL;
3199 fw_loaded = 0;
3200 }
3201}
3202#else
3203#define free_firmware() do {} while (0)
2420#endif 3204#endif
2421 3205
2422static int ipw_load(struct ipw_priv *priv) 3206static int ipw_load(struct ipw_priv *priv)
@@ -2445,10 +3229,10 @@ static int ipw_load(struct ipw_priv *priv)
2445 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss")); 3229 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
2446 break; 3230 break;
2447 3231
2448#ifdef CONFIG_IPW_PROMISC 3232#ifdef CONFIG_IPW2200_MONITOR
2449 case IW_MODE_MONITOR: 3233 case IW_MODE_MONITOR:
2450 rc = ipw_get_fw(priv, &ucode, 3234 rc = ipw_get_fw(priv, &ucode,
2451 IPW_FW_NAME("ibss_ucode")); 3235 IPW_FW_NAME("sniffer_ucode"));
2452 if (rc) 3236 if (rc)
2453 goto error; 3237 goto error;
2454 3238
@@ -2487,11 +3271,11 @@ static int ipw_load(struct ipw_priv *priv)
2487 3271
2488 retry: 3272 retry:
2489 /* Ensure interrupts are disabled */ 3273 /* Ensure interrupts are disabled */
2490 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 3274 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
2491 priv->status &= ~STATUS_INT_ENABLED; 3275 priv->status &= ~STATUS_INT_ENABLED;
2492 3276
2493 /* ack pending interrupts */ 3277 /* ack pending interrupts */
2494 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL); 3278 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2495 3279
2496 ipw_stop_nic(priv); 3280 ipw_stop_nic(priv);
2497 3281
@@ -2501,14 +3285,14 @@ static int ipw_load(struct ipw_priv *priv)
2501 goto error; 3285 goto error;
2502 } 3286 }
2503 3287
2504 ipw_zero_memory(priv, CX2_NIC_SRAM_LOWER_BOUND, 3288 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
2505 CX2_NIC_SRAM_UPPER_BOUND - CX2_NIC_SRAM_LOWER_BOUND); 3289 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
2506 3290
2507 /* DMA the initial boot firmware into the device */ 3291 /* DMA the initial boot firmware into the device */
2508 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), 3292 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
2509 bootfw->size - sizeof(struct fw_header)); 3293 bootfw->size - sizeof(struct fw_header));
2510 if (rc < 0) { 3294 if (rc < 0) {
2511 IPW_ERROR("Unable to load boot firmware\n"); 3295 IPW_ERROR("Unable to load boot firmware: %d\n", rc);
2512 goto error; 3296 goto error;
2513 } 3297 }
2514 3298
@@ -2516,8 +3300,8 @@ static int ipw_load(struct ipw_priv *priv)
2516 ipw_start_nic(priv); 3300 ipw_start_nic(priv);
2517 3301
2518 /* wait for the device to finish it's initial startup sequence */ 3302 /* wait for the device to finish it's initial startup sequence */
2519 rc = ipw_poll_bit(priv, CX2_INTA_RW, 3303 rc = ipw_poll_bit(priv, IPW_INTA_RW,
2520 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); 3304 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
2521 if (rc < 0) { 3305 if (rc < 0) {
2522 IPW_ERROR("device failed to boot initial fw image\n"); 3306 IPW_ERROR("device failed to boot initial fw image\n");
2523 goto error; 3307 goto error;
@@ -2525,13 +3309,13 @@ static int ipw_load(struct ipw_priv *priv)
2525 IPW_DEBUG_INFO("initial device response after %dms\n", rc); 3309 IPW_DEBUG_INFO("initial device response after %dms\n", rc);
2526 3310
2527 /* ack fw init done interrupt */ 3311 /* ack fw init done interrupt */
2528 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE); 3312 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
2529 3313
2530 /* DMA the ucode into the device */ 3314 /* DMA the ucode into the device */
2531 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), 3315 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
2532 ucode->size - sizeof(struct fw_header)); 3316 ucode->size - sizeof(struct fw_header));
2533 if (rc < 0) { 3317 if (rc < 0) {
2534 IPW_ERROR("Unable to load ucode\n"); 3318 IPW_ERROR("Unable to load ucode: %d\n", rc);
2535 goto error; 3319 goto error;
2536 } 3320 }
2537 3321
@@ -2543,7 +3327,7 @@ static int ipw_load(struct ipw_priv *priv)
2543 sizeof(struct fw_header), 3327 sizeof(struct fw_header),
2544 firmware->size - sizeof(struct fw_header)); 3328 firmware->size - sizeof(struct fw_header));
2545 if (rc < 0) { 3329 if (rc < 0) {
2546 IPW_ERROR("Unable to load firmware\n"); 3330 IPW_ERROR("Unable to load firmware: %d\n", rc);
2547 goto error; 3331 goto error;
2548 } 3332 }
2549 3333
@@ -2556,12 +3340,14 @@ static int ipw_load(struct ipw_priv *priv)
2556 } 3340 }
2557 3341
2558 /* Ensure interrupts are disabled */ 3342 /* Ensure interrupts are disabled */
2559 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 3343 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
3344 /* ack pending interrupts */
3345 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2560 3346
2561 /* kick start the device */ 3347 /* kick start the device */
2562 ipw_start_nic(priv); 3348 ipw_start_nic(priv);
2563 3349
2564 if (ipw_read32(priv, CX2_INTA_RW) & CX2_INTA_BIT_PARITY_ERROR) { 3350 if (ipw_read32(priv, IPW_INTA_RW) & IPW_INTA_BIT_PARITY_ERROR) {
2565 if (retries > 0) { 3351 if (retries > 0) {
2566 IPW_WARNING("Parity error. Retrying init.\n"); 3352 IPW_WARNING("Parity error. Retrying init.\n");
2567 retries--; 3353 retries--;
@@ -2574,8 +3360,8 @@ static int ipw_load(struct ipw_priv *priv)
2574 } 3360 }
2575 3361
2576 /* wait for the device */ 3362 /* wait for the device */
2577 rc = ipw_poll_bit(priv, CX2_INTA_RW, 3363 rc = ipw_poll_bit(priv, IPW_INTA_RW,
2578 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); 3364 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
2579 if (rc < 0) { 3365 if (rc < 0) {
2580 IPW_ERROR("device failed to start after 500ms\n"); 3366 IPW_ERROR("device failed to start after 500ms\n");
2581 goto error; 3367 goto error;
@@ -2583,7 +3369,7 @@ static int ipw_load(struct ipw_priv *priv)
2583 IPW_DEBUG_INFO("device response after %dms\n", rc); 3369 IPW_DEBUG_INFO("device response after %dms\n", rc);
2584 3370
2585 /* ack fw init done interrupt */ 3371 /* ack fw init done interrupt */
2586 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE); 3372 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
2587 3373
2588 /* read eeprom data and initialize the eeprom region of sram */ 3374 /* read eeprom data and initialize the eeprom region of sram */
2589 priv->eeprom_delay = 1; 3375 priv->eeprom_delay = 1;
@@ -2595,10 +3381,10 @@ static int ipw_load(struct ipw_priv *priv)
2595 /* Ensure our queue has valid packets */ 3381 /* Ensure our queue has valid packets */
2596 ipw_rx_queue_replenish(priv); 3382 ipw_rx_queue_replenish(priv);
2597 3383
2598 ipw_write32(priv, CX2_RX_READ_INDEX, priv->rxq->read); 3384 ipw_write32(priv, IPW_RX_READ_INDEX, priv->rxq->read);
2599 3385
2600 /* ack pending interrupts */ 3386 /* ack pending interrupts */
2601 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL); 3387 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2602 3388
2603#ifndef CONFIG_PM 3389#ifndef CONFIG_PM
2604 release_firmware(bootfw); 3390 release_firmware(bootfw);
@@ -2755,16 +3541,18 @@ static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
2755 return; 3541 return;
2756 3542
2757 /* sanity check */ 3543 /* sanity check */
2758 if (bd->u.data.num_chunks > NUM_TFD_CHUNKS) { 3544 if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
2759 IPW_ERROR("Too many chunks: %i\n", bd->u.data.num_chunks); 3545 IPW_ERROR("Too many chunks: %i\n",
3546 le32_to_cpu(bd->u.data.num_chunks));
2760 /** @todo issue fatal error, it is quite serious situation */ 3547 /** @todo issue fatal error, it is quite serious situation */
2761 return; 3548 return;
2762 } 3549 }
2763 3550
2764 /* unmap chunks if any */ 3551 /* unmap chunks if any */
2765 for (i = 0; i < bd->u.data.num_chunks; i++) { 3552 for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
2766 pci_unmap_single(dev, bd->u.data.chunk_ptr[i], 3553 pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
2767 bd->u.data.chunk_len[i], PCI_DMA_TODEVICE); 3554 le16_to_cpu(bd->u.data.chunk_len[i]),
3555 PCI_DMA_TODEVICE);
2768 if (txq->txb[txq->q.last_used]) { 3556 if (txq->txb[txq->q.last_used]) {
2769 ieee80211_txb_free(txq->txb[txq->q.last_used]); 3557 ieee80211_txb_free(txq->txb[txq->q.last_used]);
2770 txq->txb[txq->q.last_used] = NULL; 3558 txq->txb[txq->q.last_used] = NULL;
@@ -2821,21 +3609,6 @@ static void ipw_tx_queue_free(struct ipw_priv *priv)
2821 ipw_queue_tx_free(priv, &priv->txq[3]); 3609 ipw_queue_tx_free(priv, &priv->txq[3]);
2822} 3610}
2823 3611
2824static void inline __maybe_wake_tx(struct ipw_priv *priv)
2825{
2826 if (netif_running(priv->net_dev)) {
2827 switch (priv->port_type) {
2828 case DCR_TYPE_MU_BSS:
2829 case DCR_TYPE_MU_IBSS:
2830 if (!(priv->status & STATUS_ASSOCIATED)) {
2831 return;
2832 }
2833 }
2834 netif_wake_queue(priv->net_dev);
2835 }
2836
2837}
2838
2839static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid) 3612static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
2840{ 3613{
2841 /* First 3 bytes are manufacturer */ 3614 /* First 3 bytes are manufacturer */
@@ -2898,7 +3671,13 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2898{ 3671{
2899 int err; 3672 int err;
2900 3673
2901 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))) { 3674 if (priv->status & STATUS_ASSOCIATING) {
3675 IPW_DEBUG_ASSOC("Disassociating while associating.\n");
3676 queue_work(priv->workqueue, &priv->disassociate);
3677 return;
3678 }
3679
3680 if (!(priv->status & STATUS_ASSOCIATED)) {
2902 IPW_DEBUG_ASSOC("Disassociating while not associated.\n"); 3681 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
2903 return; 3682 return;
2904 } 3683 }
@@ -2915,6 +3694,7 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2915 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET; 3694 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
2916 else 3695 else
2917 priv->assoc_request.assoc_type = HC_DISASSOCIATE; 3696 priv->assoc_request.assoc_type = HC_DISASSOCIATE;
3697
2918 err = ipw_send_associate(priv, &priv->assoc_request); 3698 err = ipw_send_associate(priv, &priv->assoc_request);
2919 if (err) { 3699 if (err) {
2920 IPW_DEBUG_HC("Attempt to send [dis]associate command " 3700 IPW_DEBUG_HC("Attempt to send [dis]associate command "
@@ -2924,20 +3704,27 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2924 3704
2925} 3705}
2926 3706
2927static void ipw_disassociate(void *data) 3707static int ipw_disassociate(void *data)
2928{ 3708{
3709 struct ipw_priv *priv = data;
3710 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
3711 return 0;
2929 ipw_send_disassociate(data, 0); 3712 ipw_send_disassociate(data, 0);
3713 return 1;
2930} 3714}
2931 3715
2932static void notify_wx_assoc_event(struct ipw_priv *priv) 3716static void ipw_bg_disassociate(void *data)
2933{ 3717{
2934 union iwreq_data wrqu; 3718 struct ipw_priv *priv = data;
2935 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 3719 down(&priv->sem);
2936 if (priv->status & STATUS_ASSOCIATED) 3720 ipw_disassociate(data);
2937 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN); 3721 up(&priv->sem);
2938 else 3722}
2939 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 3723
2940 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); 3724static void ipw_system_config(void *data)
3725{
3726 struct ipw_priv *priv = data;
3727 ipw_send_system_config(priv, &priv->sys_config);
2941} 3728}
2942 3729
2943struct ipw_status_code { 3730struct ipw_status_code {
@@ -2997,7 +3784,7 @@ static const char *ipw_get_status_code(u16 status)
2997{ 3784{
2998 int i; 3785 int i;
2999 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++) 3786 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
3000 if (ipw_status_codes[i].status == status) 3787 if (ipw_status_codes[i].status == (status & 0xff))
3001 return ipw_status_codes[i].reason; 3788 return ipw_status_codes[i].reason;
3002 return "Unknown status value."; 3789 return "Unknown status value.";
3003} 3790}
@@ -3076,18 +3863,30 @@ static inline u32 ipw_get_max_rate(struct ipw_priv *priv)
3076 while (i && !(mask & i)) 3863 while (i && !(mask & i))
3077 i >>= 1; 3864 i >>= 1;
3078 switch (i) { 3865 switch (i) {
3079 case IEEE80211_CCK_RATE_1MB_MASK: return 1000000; 3866 case IEEE80211_CCK_RATE_1MB_MASK:
3080 case IEEE80211_CCK_RATE_2MB_MASK: return 2000000; 3867 return 1000000;
3081 case IEEE80211_CCK_RATE_5MB_MASK: return 5500000; 3868 case IEEE80211_CCK_RATE_2MB_MASK:
3082 case IEEE80211_OFDM_RATE_6MB_MASK: return 6000000; 3869 return 2000000;
3083 case IEEE80211_OFDM_RATE_9MB_MASK: return 9000000; 3870 case IEEE80211_CCK_RATE_5MB_MASK:
3084 case IEEE80211_CCK_RATE_11MB_MASK: return 11000000; 3871 return 5500000;
3085 case IEEE80211_OFDM_RATE_12MB_MASK: return 12000000; 3872 case IEEE80211_OFDM_RATE_6MB_MASK:
3086 case IEEE80211_OFDM_RATE_18MB_MASK: return 18000000; 3873 return 6000000;
3087 case IEEE80211_OFDM_RATE_24MB_MASK: return 24000000; 3874 case IEEE80211_OFDM_RATE_9MB_MASK:
3088 case IEEE80211_OFDM_RATE_36MB_MASK: return 36000000; 3875 return 9000000;
3089 case IEEE80211_OFDM_RATE_48MB_MASK: return 48000000; 3876 case IEEE80211_CCK_RATE_11MB_MASK:
3090 case IEEE80211_OFDM_RATE_54MB_MASK: return 54000000; 3877 return 11000000;
3878 case IEEE80211_OFDM_RATE_12MB_MASK:
3879 return 12000000;
3880 case IEEE80211_OFDM_RATE_18MB_MASK:
3881 return 18000000;
3882 case IEEE80211_OFDM_RATE_24MB_MASK:
3883 return 24000000;
3884 case IEEE80211_OFDM_RATE_36MB_MASK:
3885 return 36000000;
3886 case IEEE80211_OFDM_RATE_48MB_MASK:
3887 return 48000000;
3888 case IEEE80211_OFDM_RATE_54MB_MASK:
3889 return 54000000;
3091 } 3890 }
3092 3891
3093 if (priv->ieee->mode == IEEE_B) 3892 if (priv->ieee->mode == IEEE_B)
@@ -3115,25 +3914,35 @@ static u32 ipw_get_current_rate(struct ipw_priv *priv)
3115 return ipw_get_max_rate(priv); 3914 return ipw_get_max_rate(priv);
3116 3915
3117 switch (rate) { 3916 switch (rate) {
3118 case IPW_TX_RATE_1MB: return 1000000; 3917 case IPW_TX_RATE_1MB:
3119 case IPW_TX_RATE_2MB: return 2000000; 3918 return 1000000;
3120 case IPW_TX_RATE_5MB: return 5500000; 3919 case IPW_TX_RATE_2MB:
3121 case IPW_TX_RATE_6MB: return 6000000; 3920 return 2000000;
3122 case IPW_TX_RATE_9MB: return 9000000; 3921 case IPW_TX_RATE_5MB:
3123 case IPW_TX_RATE_11MB: return 11000000; 3922 return 5500000;
3124 case IPW_TX_RATE_12MB: return 12000000; 3923 case IPW_TX_RATE_6MB:
3125 case IPW_TX_RATE_18MB: return 18000000; 3924 return 6000000;
3126 case IPW_TX_RATE_24MB: return 24000000; 3925 case IPW_TX_RATE_9MB:
3127 case IPW_TX_RATE_36MB: return 36000000; 3926 return 9000000;
3128 case IPW_TX_RATE_48MB: return 48000000; 3927 case IPW_TX_RATE_11MB:
3129 case IPW_TX_RATE_54MB: return 54000000; 3928 return 11000000;
3929 case IPW_TX_RATE_12MB:
3930 return 12000000;
3931 case IPW_TX_RATE_18MB:
3932 return 18000000;
3933 case IPW_TX_RATE_24MB:
3934 return 24000000;
3935 case IPW_TX_RATE_36MB:
3936 return 36000000;
3937 case IPW_TX_RATE_48MB:
3938 return 48000000;
3939 case IPW_TX_RATE_54MB:
3940 return 54000000;
3130 } 3941 }
3131 3942
3132 return 0; 3943 return 0;
3133} 3944}
3134 3945
3135#define PERFECT_RSSI (-50)
3136#define WORST_RSSI (-85)
3137#define IPW_STATS_INTERVAL (2 * HZ) 3946#define IPW_STATS_INTERVAL (2 * HZ)
3138static void ipw_gather_stats(struct ipw_priv *priv) 3947static void ipw_gather_stats(struct ipw_priv *priv)
3139{ 3948{
@@ -3145,6 +3954,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3145 s16 rssi; 3954 s16 rssi;
3146 u32 beacon_quality, signal_quality, tx_quality, rx_quality, 3955 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
3147 rate_quality; 3956 rate_quality;
3957 u32 max_rate;
3148 3958
3149 if (!(priv->status & STATUS_ASSOCIATED)) { 3959 if (!(priv->status & STATUS_ASSOCIATED)) {
3150 priv->quality = 0; 3960 priv->quality = 0;
@@ -3201,7 +4011,8 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3201 beacon_quality, missed_beacons_percent); 4011 beacon_quality, missed_beacons_percent);
3202 4012
3203 priv->last_rate = ipw_get_current_rate(priv); 4013 priv->last_rate = ipw_get_current_rate(priv);
3204 rate_quality = priv->last_rate * 40 / priv->last_rate + 60; 4014 max_rate = ipw_get_max_rate(priv);
4015 rate_quality = priv->last_rate * 40 / max_rate + 60;
3205 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n", 4016 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
3206 rate_quality, priv->last_rate / 1000000); 4017 rate_quality, priv->last_rate / 1000000);
3207 4018
@@ -3222,13 +4033,20 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3222 tx_quality, tx_failures_delta, tx_packets_delta); 4033 tx_quality, tx_failures_delta, tx_packets_delta);
3223 4034
3224 rssi = average_value(&priv->average_rssi); 4035 rssi = average_value(&priv->average_rssi);
3225 if (rssi > PERFECT_RSSI) 4036 signal_quality =
4037 (100 *
4038 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4039 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
4040 (priv->ieee->perfect_rssi - rssi) *
4041 (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
4042 62 * (priv->ieee->perfect_rssi - rssi))) /
4043 ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4044 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
4045 if (signal_quality > 100)
3226 signal_quality = 100; 4046 signal_quality = 100;
3227 else if (rssi < WORST_RSSI) 4047 else if (signal_quality < 1)
3228 signal_quality = 0; 4048 signal_quality = 0;
3229 else 4049
3230 signal_quality = (rssi - WORST_RSSI) * 100 /
3231 (PERFECT_RSSI - WORST_RSSI);
3232 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n", 4050 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
3233 signal_quality, rssi); 4051 signal_quality, rssi);
3234 4052
@@ -3257,6 +4075,85 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3257 IPW_STATS_INTERVAL); 4075 IPW_STATS_INTERVAL);
3258} 4076}
3259 4077
4078static void ipw_bg_gather_stats(void *data)
4079{
4080 struct ipw_priv *priv = data;
4081 down(&priv->sem);
4082 ipw_gather_stats(data);
4083 up(&priv->sem);
4084}
4085
4086/* Missed beacon behavior:
4087 * 1st missed -> roaming_threshold, just wait, don't do any scan/roam.
4088 * roaming_threshold -> disassociate_threshold, scan and roam for better signal.
4089 * Above disassociate threshold, give up and stop scanning.
4090 * Roaming is disabled if disassociate_threshold <= roaming_threshold */
4091static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
4092 int missed_count)
4093{
4094 priv->notif_missed_beacons = missed_count;
4095
4096 if (missed_count > priv->disassociate_threshold &&
4097 priv->status & STATUS_ASSOCIATED) {
4098 /* If associated and we've hit the missed
4099 * beacon threshold, disassociate, turn
4100 * off roaming, and abort any active scans */
4101 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4102 IPW_DL_STATE | IPW_DL_ASSOC,
4103 "Missed beacon: %d - disassociate\n", missed_count);
4104 priv->status &= ~STATUS_ROAMING;
4105 if (priv->status & STATUS_SCANNING) {
4106 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4107 IPW_DL_STATE,
4108 "Aborting scan with missed beacon.\n");
4109 queue_work(priv->workqueue, &priv->abort_scan);
4110 }
4111
4112 queue_work(priv->workqueue, &priv->disassociate);
4113 return;
4114 }
4115
4116 if (priv->status & STATUS_ROAMING) {
4117 /* If we are currently roaming, then just
4118 * print a debug statement... */
4119 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4120 "Missed beacon: %d - roam in progress\n",
4121 missed_count);
4122 return;
4123 }
4124
4125 if (missed_count > priv->roaming_threshold &&
4126 missed_count <= priv->disassociate_threshold) {
4127 /* If we are not already roaming, set the ROAM
4128 * bit in the status and kick off a scan.
4129 * This can happen several times before we reach
4130 * disassociate_threshold. */
4131 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4132 "Missed beacon: %d - initiate "
4133 "roaming\n", missed_count);
4134 if (!(priv->status & STATUS_ROAMING)) {
4135 priv->status |= STATUS_ROAMING;
4136 if (!(priv->status & STATUS_SCANNING))
4137 queue_work(priv->workqueue,
4138 &priv->request_scan);
4139 }
4140 return;
4141 }
4142
4143 if (priv->status & STATUS_SCANNING) {
4144 /* Stop scan to keep fw from getting
4145 * stuck (only if we aren't roaming --
4146 * otherwise we'll never scan more than 2 or 3
4147 * channels..) */
4148 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
4149 "Aborting scan with missed beacon.\n");
4150 queue_work(priv->workqueue, &priv->abort_scan);
4151 }
4152
4153 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
4154
4155}
4156
3260/** 4157/**
3261 * Handle host notification packet. 4158 * Handle host notification packet.
3262 * Called from interrupt routine 4159 * Called from interrupt routine
@@ -3264,6 +4161,8 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3264static inline void ipw_rx_notification(struct ipw_priv *priv, 4161static inline void ipw_rx_notification(struct ipw_priv *priv,
3265 struct ipw_rx_notification *notif) 4162 struct ipw_rx_notification *notif)
3266{ 4163{
4164 notif->size = le16_to_cpu(notif->size);
4165
3267 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size); 4166 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size);
3268 4167
3269 switch (notif->subtype) { 4168 switch (notif->subtype) {
@@ -3307,30 +4206,44 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3307 4206
3308 priv->status &= ~STATUS_ASSOCIATING; 4207 priv->status &= ~STATUS_ASSOCIATING;
3309 priv->status |= STATUS_ASSOCIATED; 4208 priv->status |= STATUS_ASSOCIATED;
3310 4209 queue_work(priv->workqueue,
3311 netif_carrier_on(priv->net_dev); 4210 &priv->system_config);
3312 if (netif_queue_stopped(priv->net_dev)) { 4211
3313 IPW_DEBUG_NOTIF 4212#ifdef CONFIG_IPW_QOS
3314 ("waking queue\n"); 4213#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
3315 netif_wake_queue(priv->net_dev); 4214 le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_ctl))
3316 } else { 4215 if ((priv->status & STATUS_AUTH) &&
3317 IPW_DEBUG_NOTIF 4216 (IPW_GET_PACKET_STYPE(&notif->u.raw)
3318 ("starting queue\n"); 4217 == IEEE80211_STYPE_ASSOC_RESP)) {
3319 netif_start_queue(priv-> 4218 if ((sizeof
3320 net_dev); 4219 (struct
4220 ieee80211_assoc_response)
4221 <= notif->size)
4222 && (notif->size <= 2314)) {
4223 struct
4224 ieee80211_rx_stats
4225 stats = {
4226 .len =
4227 notif->
4228 size - 1,
4229 };
4230
4231 IPW_DEBUG_QOS
4232 ("QoS Associate "
4233 "size %d\n",
4234 notif->size);
4235 ieee80211_rx_mgt(priv->
4236 ieee,
4237 (struct
4238 ieee80211_hdr_4addr
4239 *)
4240 &notif->u.raw, &stats);
4241 }
3321 } 4242 }
4243#endif
3322 4244
3323 ipw_reset_stats(priv); 4245 schedule_work(&priv->link_up);
3324 /* Ensure the rate is updated immediately */
3325 priv->last_rate =
3326 ipw_get_current_rate(priv);
3327 schedule_work(&priv->gather_stats);
3328 notify_wx_assoc_event(priv);
3329 4246
3330/* queue_delayed_work(priv->workqueue,
3331 &priv->request_scan,
3332 SCAN_ASSOCIATED_INTERVAL);
3333*/
3334 break; 4247 break;
3335 } 4248 }
3336 4249
@@ -3363,12 +4276,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3363 STATUS_AUTH | 4276 STATUS_AUTH |
3364 STATUS_ASSOCIATED); 4277 STATUS_ASSOCIATED);
3365 4278
3366 netif_carrier_off(priv-> 4279 schedule_work(&priv->link_down);
3367 net_dev);
3368 netif_stop_queue(priv->net_dev);
3369 queue_work(priv->workqueue,
3370 &priv->request_scan);
3371 notify_wx_assoc_event(priv);
3372 break; 4280 break;
3373 } 4281 }
3374 4282
@@ -3383,6 +4291,24 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3383 } 4291 }
3384 4292
3385 case CMAS_INIT:{ 4293 case CMAS_INIT:{
4294 if (priv->status & STATUS_AUTH) {
4295 struct
4296 ieee80211_assoc_response
4297 *resp;
4298 resp =
4299 (struct
4300 ieee80211_assoc_response
4301 *)&notif->u.raw;
4302 IPW_DEBUG(IPW_DL_NOTIF |
4303 IPW_DL_STATE |
4304 IPW_DL_ASSOC,
4305 "association failed (0x%04X): %s\n",
4306 ntohs(resp->status),
4307 ipw_get_status_code
4308 (ntohs
4309 (resp->status)));
4310 }
4311
3386 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4312 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3387 IPW_DL_ASSOC, 4313 IPW_DL_ASSOC,
3388 "disassociated: '%s' " MAC_FMT 4314 "disassociated: '%s' " MAC_FMT
@@ -3395,35 +4321,21 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3395 ~(STATUS_DISASSOCIATING | 4321 ~(STATUS_DISASSOCIATING |
3396 STATUS_ASSOCIATING | 4322 STATUS_ASSOCIATING |
3397 STATUS_ASSOCIATED | STATUS_AUTH); 4323 STATUS_ASSOCIATED | STATUS_AUTH);
4324 if (priv->assoc_network
4325 && (priv->assoc_network->
4326 capability &
4327 WLAN_CAPABILITY_IBSS))
4328 ipw_remove_current_network
4329 (priv);
3398 4330
3399 netif_stop_queue(priv->net_dev); 4331 schedule_work(&priv->link_down);
3400 if (!(priv->status & STATUS_ROAMING)) {
3401 netif_carrier_off(priv->
3402 net_dev);
3403 notify_wx_assoc_event(priv);
3404
3405 /* Cancel any queued work ... */
3406 cancel_delayed_work(&priv->
3407 request_scan);
3408 cancel_delayed_work(&priv->
3409 adhoc_check);
3410
3411 /* Queue up another scan... */
3412 queue_work(priv->workqueue,
3413 &priv->request_scan);
3414
3415 cancel_delayed_work(&priv->
3416 gather_stats);
3417 } else {
3418 priv->status |= STATUS_ROAMING;
3419 queue_work(priv->workqueue,
3420 &priv->request_scan);
3421 }
3422 4332
3423 ipw_reset_stats(priv);
3424 break; 4333 break;
3425 } 4334 }
3426 4335
4336 case CMAS_RX_ASSOC_RESP:
4337 break;
4338
3427 default: 4339 default:
3428 IPW_ERROR("assoc: unknown (%d)\n", 4340 IPW_ERROR("assoc: unknown (%d)\n",
3429 assoc->state); 4341 assoc->state);
@@ -3466,11 +4378,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3466 STATUS_AUTH | 4378 STATUS_AUTH |
3467 STATUS_ASSOCIATED); 4379 STATUS_ASSOCIATED);
3468 4380
3469 netif_carrier_off(priv->net_dev); 4381 schedule_work(&priv->link_down);
3470 netif_stop_queue(priv->net_dev);
3471 queue_work(priv->workqueue,
3472 &priv->request_scan);
3473 notify_wx_assoc_event(priv);
3474 break; 4382 break;
3475 4383
3476 case CMAS_TX_AUTH_SEQ_1: 4384 case CMAS_TX_AUTH_SEQ_1:
@@ -3512,6 +4420,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3512 case CMAS_RX_ASSOC_RESP: 4420 case CMAS_RX_ASSOC_RESP:
3513 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4421 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3514 IPW_DL_ASSOC, "RX_ASSOC_RESP\n"); 4422 IPW_DL_ASSOC, "RX_ASSOC_RESP\n");
4423
3515 break; 4424 break;
3516 case CMAS_ASSOCIATED: 4425 case CMAS_ASSOCIATED:
3517 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4426 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
@@ -3556,43 +4465,67 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3556 priv->status &= 4465 priv->status &=
3557 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING); 4466 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3558 4467
4468 wake_up_interruptible(&priv->wait_state);
3559 cancel_delayed_work(&priv->scan_check); 4469 cancel_delayed_work(&priv->scan_check);
3560 4470
4471 if (priv->status & STATUS_EXIT_PENDING)
4472 break;
4473
4474 priv->ieee->scans++;
4475
4476#ifdef CONFIG_IPW2200_MONITOR
4477 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
4478 priv->status |= STATUS_SCAN_FORCED;
4479 queue_work(priv->workqueue,
4480 &priv->request_scan);
4481 break;
4482 }
4483 priv->status &= ~STATUS_SCAN_FORCED;
4484#endif /* CONFIG_IPW2200_MONITOR */
4485
3561 if (!(priv->status & (STATUS_ASSOCIATED | 4486 if (!(priv->status & (STATUS_ASSOCIATED |
3562 STATUS_ASSOCIATING | 4487 STATUS_ASSOCIATING |
3563 STATUS_ROAMING | 4488 STATUS_ROAMING |
3564 STATUS_DISASSOCIATING))) 4489 STATUS_DISASSOCIATING)))
3565 queue_work(priv->workqueue, &priv->associate); 4490 queue_work(priv->workqueue, &priv->associate);
3566 else if (priv->status & STATUS_ROAMING) { 4491 else if (priv->status & STATUS_ROAMING) {
3567 /* If a scan completed and we are in roam mode, then 4492 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
3568 * the scan that completed was the one requested as a 4493 /* If a scan completed and we are in roam mode, then
3569 * result of entering roam... so, schedule the 4494 * the scan that completed was the one requested as a
3570 * roam work */ 4495 * result of entering roam... so, schedule the
3571 queue_work(priv->workqueue, &priv->roam); 4496 * roam work */
4497 queue_work(priv->workqueue,
4498 &priv->roam);
4499 else
4500 /* Don't schedule if we aborted the scan */
4501 priv->status &= ~STATUS_ROAMING;
3572 } else if (priv->status & STATUS_SCAN_PENDING) 4502 } else if (priv->status & STATUS_SCAN_PENDING)
3573 queue_work(priv->workqueue, 4503 queue_work(priv->workqueue,
3574 &priv->request_scan); 4504 &priv->request_scan);
3575 4505 else if (priv->config & CFG_BACKGROUND_SCAN
3576 priv->ieee->scans++; 4506 && priv->status & STATUS_ASSOCIATED)
4507 queue_delayed_work(priv->workqueue,
4508 &priv->request_scan, HZ);
3577 break; 4509 break;
3578 } 4510 }
3579 4511
3580 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{ 4512 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
3581 struct notif_frag_length *x = &notif->u.frag_len; 4513 struct notif_frag_length *x = &notif->u.frag_len;
3582 4514
3583 if (notif->size == sizeof(*x)) { 4515 if (notif->size == sizeof(*x))
3584 IPW_ERROR("Frag length: %d\n", x->frag_length); 4516 IPW_ERROR("Frag length: %d\n",
3585 } else { 4517 le16_to_cpu(x->frag_length));
4518 else
3586 IPW_ERROR("Frag length of wrong size %d " 4519 IPW_ERROR("Frag length of wrong size %d "
3587 "(should be %zd)\n", 4520 "(should be %zd)\n",
3588 notif->size, sizeof(*x)); 4521 notif->size, sizeof(*x));
3589 }
3590 break; 4522 break;
3591 } 4523 }
3592 4524
3593 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{ 4525 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{
3594 struct notif_link_deterioration *x = 4526 struct notif_link_deterioration *x =
3595 &notif->u.link_deterioration; 4527 &notif->u.link_deterioration;
4528
3596 if (notif->size == sizeof(*x)) { 4529 if (notif->size == sizeof(*x)) {
3597 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, 4530 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3598 "link deterioration: '%s' " MAC_FMT 4531 "link deterioration: '%s' " MAC_FMT
@@ -3612,11 +4545,9 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3612 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{ 4545 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
3613 IPW_ERROR("Dino config\n"); 4546 IPW_ERROR("Dino config\n");
3614 if (priv->hcmd 4547 if (priv->hcmd
3615 && priv->hcmd->cmd == HOST_CMD_DINO_CONFIG) { 4548 && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
3616 /* TODO: Do anything special? */
3617 } else {
3618 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n"); 4549 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
3619 } 4550
3620 break; 4551 break;
3621 } 4552 }
3622 4553
@@ -3629,36 +4560,11 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3629 break; 4560 break;
3630 } 4561 }
3631 4562
3632 if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING) { 4563 if (le32_to_cpu(x->state) ==
3633 if (priv->status & STATUS_SCANNING) { 4564 HOST_NOTIFICATION_STATUS_BEACON_MISSING)
3634 /* Stop scan to keep fw from getting 4565 ipw_handle_missed_beacon(priv,
3635 * stuck... */ 4566 le32_to_cpu(x->
3636 queue_work(priv->workqueue, 4567 number));
3637 &priv->abort_scan);
3638 }
3639
3640 if (x->number > priv->missed_beacon_threshold &&
3641 priv->status & STATUS_ASSOCIATED) {
3642 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3643 IPW_DL_STATE,
3644 "Missed beacon: %d - disassociate\n",
3645 x->number);
3646 queue_work(priv->workqueue,
3647 &priv->disassociate);
3648 } else if (x->number > priv->roaming_threshold) {
3649 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3650 "Missed beacon: %d - initiate "
3651 "roaming\n", x->number);
3652 queue_work(priv->workqueue,
3653 &priv->roam);
3654 } else {
3655 IPW_DEBUG_NOTIF("Missed beacon: %d\n",
3656 x->number);
3657 }
3658
3659 priv->notif_missed_beacons = x->number;
3660
3661 }
3662 4568
3663 break; 4569 break;
3664 } 4570 }
@@ -3697,7 +4603,8 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3697 case HOST_NOTIFICATION_NOISE_STATS:{ 4603 case HOST_NOTIFICATION_NOISE_STATS:{
3698 if (notif->size == sizeof(u32)) { 4604 if (notif->size == sizeof(u32)) {
3699 priv->last_noise = 4605 priv->last_noise =
3700 (u8) (notif->u.noise.value & 0xff); 4606 (u8) (le32_to_cpu(notif->u.noise.value) &
4607 0xff);
3701 average_add(&priv->average_noise, 4608 average_add(&priv->average_noise,
3702 priv->last_noise); 4609 priv->last_noise);
3703 break; 4610 break;
@@ -3730,43 +4637,43 @@ static int ipw_queue_reset(struct ipw_priv *priv)
3730 ipw_tx_queue_free(priv); 4637 ipw_tx_queue_free(priv);
3731 /* Tx CMD queue */ 4638 /* Tx CMD queue */
3732 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd, 4639 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,
3733 CX2_TX_CMD_QUEUE_READ_INDEX, 4640 IPW_TX_CMD_QUEUE_READ_INDEX,
3734 CX2_TX_CMD_QUEUE_WRITE_INDEX, 4641 IPW_TX_CMD_QUEUE_WRITE_INDEX,
3735 CX2_TX_CMD_QUEUE_BD_BASE, 4642 IPW_TX_CMD_QUEUE_BD_BASE,
3736 CX2_TX_CMD_QUEUE_BD_SIZE); 4643 IPW_TX_CMD_QUEUE_BD_SIZE);
3737 if (rc) { 4644 if (rc) {
3738 IPW_ERROR("Tx Cmd queue init failed\n"); 4645 IPW_ERROR("Tx Cmd queue init failed\n");
3739 goto error; 4646 goto error;
3740 } 4647 }
3741 /* Tx queue(s) */ 4648 /* Tx queue(s) */
3742 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx, 4649 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,
3743 CX2_TX_QUEUE_0_READ_INDEX, 4650 IPW_TX_QUEUE_0_READ_INDEX,
3744 CX2_TX_QUEUE_0_WRITE_INDEX, 4651 IPW_TX_QUEUE_0_WRITE_INDEX,
3745 CX2_TX_QUEUE_0_BD_BASE, CX2_TX_QUEUE_0_BD_SIZE); 4652 IPW_TX_QUEUE_0_BD_BASE, IPW_TX_QUEUE_0_BD_SIZE);
3746 if (rc) { 4653 if (rc) {
3747 IPW_ERROR("Tx 0 queue init failed\n"); 4654 IPW_ERROR("Tx 0 queue init failed\n");
3748 goto error; 4655 goto error;
3749 } 4656 }
3750 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx, 4657 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,
3751 CX2_TX_QUEUE_1_READ_INDEX, 4658 IPW_TX_QUEUE_1_READ_INDEX,
3752 CX2_TX_QUEUE_1_WRITE_INDEX, 4659 IPW_TX_QUEUE_1_WRITE_INDEX,
3753 CX2_TX_QUEUE_1_BD_BASE, CX2_TX_QUEUE_1_BD_SIZE); 4660 IPW_TX_QUEUE_1_BD_BASE, IPW_TX_QUEUE_1_BD_SIZE);
3754 if (rc) { 4661 if (rc) {
3755 IPW_ERROR("Tx 1 queue init failed\n"); 4662 IPW_ERROR("Tx 1 queue init failed\n");
3756 goto error; 4663 goto error;
3757 } 4664 }
3758 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx, 4665 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,
3759 CX2_TX_QUEUE_2_READ_INDEX, 4666 IPW_TX_QUEUE_2_READ_INDEX,
3760 CX2_TX_QUEUE_2_WRITE_INDEX, 4667 IPW_TX_QUEUE_2_WRITE_INDEX,
3761 CX2_TX_QUEUE_2_BD_BASE, CX2_TX_QUEUE_2_BD_SIZE); 4668 IPW_TX_QUEUE_2_BD_BASE, IPW_TX_QUEUE_2_BD_SIZE);
3762 if (rc) { 4669 if (rc) {
3763 IPW_ERROR("Tx 2 queue init failed\n"); 4670 IPW_ERROR("Tx 2 queue init failed\n");
3764 goto error; 4671 goto error;
3765 } 4672 }
3766 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx, 4673 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,
3767 CX2_TX_QUEUE_3_READ_INDEX, 4674 IPW_TX_QUEUE_3_READ_INDEX,
3768 CX2_TX_QUEUE_3_WRITE_INDEX, 4675 IPW_TX_QUEUE_3_WRITE_INDEX,
3769 CX2_TX_QUEUE_3_BD_BASE, CX2_TX_QUEUE_3_BD_SIZE); 4676 IPW_TX_QUEUE_3_BD_BASE, IPW_TX_QUEUE_3_BD_SIZE);
3770 if (rc) { 4677 if (rc) {
3771 IPW_ERROR("Tx 3 queue init failed\n"); 4678 IPW_ERROR("Tx 3 queue init failed\n");
3772 goto error; 4679 goto error;
@@ -3814,9 +4721,10 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
3814 priv->tx_packets++; 4721 priv->tx_packets++;
3815 } 4722 }
3816 done: 4723 done:
3817 if (ipw_queue_space(q) > q->low_mark && qindex >= 0) { 4724 if ((ipw_queue_space(q) > q->low_mark) &&
3818 __maybe_wake_tx(priv); 4725 (qindex >= 0) &&
3819 } 4726 (priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev))
4727 netif_wake_queue(priv->net_dev);
3820 used = q->first_empty - q->last_used; 4728 used = q->first_empty - q->last_used;
3821 if (used < 0) 4729 if (used < 0)
3822 used += q->n_bd; 4730 used += q->n_bd;
@@ -3857,7 +4765,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
3857 * Rx theory of operation 4765 * Rx theory of operation
3858 * 4766 *
3859 * The host allocates 32 DMA target addresses and passes the host address 4767 * The host allocates 32 DMA target addresses and passes the host address
3860 * to the firmware at register CX2_RFDS_TABLE_LOWER + N * RFD_SIZE where N is 4768 * to the firmware at register IPW_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
3861 * 0 to 31 4769 * 0 to 31
3862 * 4770 *
3863 * Rx Queue Indexes 4771 * Rx Queue Indexes
@@ -3941,7 +4849,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
3941 rxb = list_entry(element, struct ipw_rx_mem_buffer, list); 4849 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
3942 list_del(element); 4850 list_del(element);
3943 4851
3944 ipw_write32(priv, CX2_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE, 4852 ipw_write32(priv, IPW_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
3945 rxb->dma_addr); 4853 rxb->dma_addr);
3946 rxq->queue[rxq->write] = rxb; 4854 rxq->queue[rxq->write] = rxb;
3947 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE; 4855 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;
@@ -3956,7 +4864,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
3956 4864
3957 /* If we've added more space for the firmware to place data, tell it */ 4865 /* If we've added more space for the firmware to place data, tell it */
3958 if (write != rxq->write) 4866 if (write != rxq->write)
3959 ipw_write32(priv, CX2_RX_WRITE_INDEX, rxq->write); 4867 ipw_write32(priv, IPW_RX_WRITE_INDEX, rxq->write);
3960} 4868}
3961 4869
3962/* 4870/*
@@ -3977,7 +4885,7 @@ static void ipw_rx_queue_replenish(void *data)
3977 while (!list_empty(&rxq->rx_used)) { 4885 while (!list_empty(&rxq->rx_used)) {
3978 element = rxq->rx_used.next; 4886 element = rxq->rx_used.next;
3979 rxb = list_entry(element, struct ipw_rx_mem_buffer, list); 4887 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
3980 rxb->skb = alloc_skb(CX2_RX_BUF_SIZE, GFP_ATOMIC); 4888 rxb->skb = alloc_skb(IPW_RX_BUF_SIZE, GFP_ATOMIC);
3981 if (!rxb->skb) { 4889 if (!rxb->skb) {
3982 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n", 4890 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",
3983 priv->net_dev->name); 4891 priv->net_dev->name);
@@ -3991,7 +4899,7 @@ static void ipw_rx_queue_replenish(void *data)
3991 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data; 4899 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data;
3992 rxb->dma_addr = 4900 rxb->dma_addr =
3993 pci_map_single(priv->pci_dev, rxb->skb->data, 4901 pci_map_single(priv->pci_dev, rxb->skb->data,
3994 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 4902 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
3995 4903
3996 list_add_tail(&rxb->list, &rxq->rx_free); 4904 list_add_tail(&rxb->list, &rxq->rx_free);
3997 rxq->free_count++; 4905 rxq->free_count++;
@@ -4001,6 +4909,14 @@ static void ipw_rx_queue_replenish(void *data)
4001 ipw_rx_queue_restock(priv); 4909 ipw_rx_queue_restock(priv);
4002} 4910}
4003 4911
4912static void ipw_bg_rx_queue_replenish(void *data)
4913{
4914 struct ipw_priv *priv = data;
4915 down(&priv->sem);
4916 ipw_rx_queue_replenish(data);
4917 up(&priv->sem);
4918}
4919
4004/* Assumes that the skb field of the buffers in 'pool' is kept accurate. 4920/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
4005 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL 4921 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
4006 * This free routine walks the list of POOL entries and if SKB is set to 4922 * This free routine walks the list of POOL entries and if SKB is set to
@@ -4016,7 +4932,7 @@ static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)
4016 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { 4932 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
4017 if (rxq->pool[i].skb != NULL) { 4933 if (rxq->pool[i].skb != NULL) {
4018 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, 4934 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
4019 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 4935 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
4020 dev_kfree_skb(rxq->pool[i].skb); 4936 dev_kfree_skb(rxq->pool[i].skb);
4021 } 4937 }
4022 } 4938 }
@@ -4135,8 +5051,18 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4135 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES); 5051 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
4136 rates->num_rates = 0; 5052 rates->num_rates = 0;
4137 for (i = 0; i < num_rates; i++) { 5053 for (i = 0; i < num_rates; i++) {
4138 if (!ipw_is_rate_in_mask 5054 if (!ipw_is_rate_in_mask(priv, network->mode,
4139 (priv, network->mode, network->rates[i])) { 5055 network->rates[i])) {
5056
5057 if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
5058 IPW_DEBUG_SCAN("Adding masked mandatory "
5059 "rate %02X\n",
5060 network->rates[i]);
5061 rates->supported_rates[rates->num_rates++] =
5062 network->rates[i];
5063 continue;
5064 }
5065
4140 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 5066 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4141 network->rates[i], priv->rates_mask); 5067 network->rates[i], priv->rates_mask);
4142 continue; 5068 continue;
@@ -4145,11 +5071,20 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4145 rates->supported_rates[rates->num_rates++] = network->rates[i]; 5071 rates->supported_rates[rates->num_rates++] = network->rates[i];
4146 } 5072 }
4147 5073
4148 num_rates = 5074 num_rates = min(network->rates_ex_len,
4149 min(network->rates_ex_len, (u8) (IPW_MAX_RATES - num_rates)); 5075 (u8) (IPW_MAX_RATES - num_rates));
4150 for (i = 0; i < num_rates; i++) { 5076 for (i = 0; i < num_rates; i++) {
4151 if (!ipw_is_rate_in_mask 5077 if (!ipw_is_rate_in_mask(priv, network->mode,
4152 (priv, network->mode, network->rates_ex[i])) { 5078 network->rates_ex[i])) {
5079 if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
5080 IPW_DEBUG_SCAN("Adding masked mandatory "
5081 "rate %02X\n",
5082 network->rates_ex[i]);
5083 rates->supported_rates[rates->num_rates++] =
5084 network->rates[i];
5085 continue;
5086 }
5087
4153 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 5088 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4154 network->rates_ex[i], priv->rates_mask); 5089 network->rates_ex[i], priv->rates_mask);
4155 continue; 5090 continue;
@@ -4159,7 +5094,7 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4159 network->rates_ex[i]; 5094 network->rates_ex[i];
4160 } 5095 }
4161 5096
4162 return rates->num_rates; 5097 return 1;
4163} 5098}
4164 5099
4165static inline void ipw_copy_rates(struct ipw_supported_rates *dest, 5100static inline void ipw_copy_rates(struct ipw_supported_rates *dest,
@@ -4241,6 +5176,216 @@ struct ipw_network_match {
4241 struct ipw_supported_rates rates; 5176 struct ipw_supported_rates rates;
4242}; 5177};
4243 5178
5179static int ipw_find_adhoc_network(struct ipw_priv *priv,
5180 struct ipw_network_match *match,
5181 struct ieee80211_network *network,
5182 int roaming)
5183{
5184 struct ipw_supported_rates rates;
5185
5186 /* Verify that this network's capability is compatible with the
5187 * current mode (AdHoc or Infrastructure) */
5188 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
5189 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5190 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded due to "
5191 "capability mismatch.\n",
5192 escape_essid(network->ssid, network->ssid_len),
5193 MAC_ARG(network->bssid));
5194 return 0;
5195 }
5196
5197 /* If we do not have an ESSID for this AP, we can not associate with
5198 * it */
5199 if (network->flags & NETWORK_EMPTY_ESSID) {
5200 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5201 "because of hidden ESSID.\n",
5202 escape_essid(network->ssid, network->ssid_len),
5203 MAC_ARG(network->bssid));
5204 return 0;
5205 }
5206
5207 if (unlikely(roaming)) {
5208 /* If we are roaming, then ensure check if this is a valid
5209 * network to try and roam to */
5210 if ((network->ssid_len != match->network->ssid_len) ||
5211 memcmp(network->ssid, match->network->ssid,
5212 network->ssid_len)) {
5213 IPW_DEBUG_MERGE("Netowrk '%s (" MAC_FMT ")' excluded "
5214 "because of non-network ESSID.\n",
5215 escape_essid(network->ssid,
5216 network->ssid_len),
5217 MAC_ARG(network->bssid));
5218 return 0;
5219 }
5220 } else {
5221 /* If an ESSID has been configured then compare the broadcast
5222 * ESSID to ours */
5223 if ((priv->config & CFG_STATIC_ESSID) &&
5224 ((network->ssid_len != priv->essid_len) ||
5225 memcmp(network->ssid, priv->essid,
5226 min(network->ssid_len, priv->essid_len)))) {
5227 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
5228
5229 strncpy(escaped,
5230 escape_essid(network->ssid, network->ssid_len),
5231 sizeof(escaped));
5232 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5233 "because of ESSID mismatch: '%s'.\n",
5234 escaped, MAC_ARG(network->bssid),
5235 escape_essid(priv->essid,
5236 priv->essid_len));
5237 return 0;
5238 }
5239 }
5240
5241 /* If the old network rate is better than this one, don't bother
5242 * testing everything else. */
5243
5244 if (network->time_stamp[0] < match->network->time_stamp[0]) {
5245 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5246 "current network.\n",
5247 escape_essid(match->network->ssid,
5248 match->network->ssid_len));
5249 return 0;
5250 } else if (network->time_stamp[1] < match->network->time_stamp[1]) {
5251 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5252 "current network.\n",
5253 escape_essid(match->network->ssid,
5254 match->network->ssid_len));
5255 return 0;
5256 }
5257
5258 /* Now go through and see if the requested network is valid... */
5259 if (priv->ieee->scan_age != 0 &&
5260 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
5261 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5262 "because of age: %lums.\n",
5263 escape_essid(network->ssid, network->ssid_len),
5264 MAC_ARG(network->bssid),
5265 1000 * (jiffies - network->last_scanned) / HZ);
5266 return 0;
5267 }
5268
5269 if ((priv->config & CFG_STATIC_CHANNEL) &&
5270 (network->channel != priv->channel)) {
5271 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5272 "because of channel mismatch: %d != %d.\n",
5273 escape_essid(network->ssid, network->ssid_len),
5274 MAC_ARG(network->bssid),
5275 network->channel, priv->channel);
5276 return 0;
5277 }
5278
5279 /* Verify privacy compatability */
5280 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
5281 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
5282 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5283 "because of privacy mismatch: %s != %s.\n",
5284 escape_essid(network->ssid, network->ssid_len),
5285 MAC_ARG(network->bssid),
5286 priv->
5287 capability & CAP_PRIVACY_ON ? "on" : "off",
5288 network->
5289 capability & WLAN_CAPABILITY_PRIVACY ? "on" :
5290 "off");
5291 return 0;
5292 }
5293
5294 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
5295 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5296 "because of the same BSSID match: " MAC_FMT
5297 ".\n", escape_essid(network->ssid,
5298 network->ssid_len),
5299 MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
5300 return 0;
5301 }
5302
5303 /* Filter out any incompatible freq / mode combinations */
5304 if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
5305 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5306 "because of invalid frequency/mode "
5307 "combination.\n",
5308 escape_essid(network->ssid, network->ssid_len),
5309 MAC_ARG(network->bssid));
5310 return 0;
5311 }
5312
5313 /* Ensure that the rates supported by the driver are compatible with
5314 * this AP, including verification of basic rates (mandatory) */
5315 if (!ipw_compatible_rates(priv, network, &rates)) {
5316 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5317 "because configured rate mask excludes "
5318 "AP mandatory rate.\n",
5319 escape_essid(network->ssid, network->ssid_len),
5320 MAC_ARG(network->bssid));
5321 return 0;
5322 }
5323
5324 if (rates.num_rates == 0) {
5325 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5326 "because of no compatible rates.\n",
5327 escape_essid(network->ssid, network->ssid_len),
5328 MAC_ARG(network->bssid));
5329 return 0;
5330 }
5331
5332 /* TODO: Perform any further minimal comparititive tests. We do not
5333 * want to put too much policy logic here; intelligent scan selection
5334 * should occur within a generic IEEE 802.11 user space tool. */
5335
5336 /* Set up 'new' AP to this network */
5337 ipw_copy_rates(&match->rates, &rates);
5338 match->network = network;
5339 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' is a viable match.\n",
5340 escape_essid(network->ssid, network->ssid_len),
5341 MAC_ARG(network->bssid));
5342
5343 return 1;
5344}
5345
5346static void ipw_merge_adhoc_network(void *data)
5347{
5348 struct ipw_priv *priv = data;
5349 struct ieee80211_network *network = NULL;
5350 struct ipw_network_match match = {
5351 .network = priv->assoc_network
5352 };
5353
5354 if ((priv->status & STATUS_ASSOCIATED) &&
5355 (priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5356 /* First pass through ROAM process -- look for a better
5357 * network */
5358 unsigned long flags;
5359
5360 spin_lock_irqsave(&priv->ieee->lock, flags);
5361 list_for_each_entry(network, &priv->ieee->network_list, list) {
5362 if (network != priv->assoc_network)
5363 ipw_find_adhoc_network(priv, &match, network,
5364 1);
5365 }
5366 spin_unlock_irqrestore(&priv->ieee->lock, flags);
5367
5368 if (match.network == priv->assoc_network) {
5369 IPW_DEBUG_MERGE("No better ADHOC in this network to "
5370 "merge to.\n");
5371 return;
5372 }
5373
5374 down(&priv->sem);
5375 if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5376 IPW_DEBUG_MERGE("remove network %s\n",
5377 escape_essid(priv->essid,
5378 priv->essid_len));
5379 ipw_remove_current_network(priv);
5380 }
5381
5382 ipw_disassociate(priv);
5383 priv->assoc_network = match.network;
5384 up(&priv->sem);
5385 return;
5386 }
5387}
5388
4244static int ipw_best_network(struct ipw_priv *priv, 5389static int ipw_best_network(struct ipw_priv *priv,
4245 struct ipw_network_match *match, 5390 struct ipw_network_match *match,
4246 struct ieee80211_network *network, int roaming) 5391 struct ieee80211_network *network, int roaming)
@@ -4322,9 +5467,9 @@ static int ipw_best_network(struct ipw_priv *priv,
4322 /* If this network has already had an association attempt within the 5467 /* If this network has already had an association attempt within the
4323 * last 3 seconds, do not try and associate again... */ 5468 * last 3 seconds, do not try and associate again... */
4324 if (network->last_associate && 5469 if (network->last_associate &&
4325 time_after(network->last_associate + (HZ * 5UL), jiffies)) { 5470 time_after(network->last_associate + (HZ * 3UL), jiffies)) {
4326 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5471 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4327 "because of storming (%lu since last " 5472 "because of storming (%lus since last "
4328 "assoc attempt).\n", 5473 "assoc attempt).\n",
4329 escape_essid(network->ssid, network->ssid_len), 5474 escape_essid(network->ssid, network->ssid_len),
4330 MAC_ARG(network->bssid), 5475 MAC_ARG(network->bssid),
@@ -4334,12 +5479,12 @@ static int ipw_best_network(struct ipw_priv *priv,
4334 5479
4335 /* Now go through and see if the requested network is valid... */ 5480 /* Now go through and see if the requested network is valid... */
4336 if (priv->ieee->scan_age != 0 && 5481 if (priv->ieee->scan_age != 0 &&
4337 jiffies - network->last_scanned > priv->ieee->scan_age) { 5482 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
4338 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5483 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4339 "because of age: %lums.\n", 5484 "because of age: %lums.\n",
4340 escape_essid(network->ssid, network->ssid_len), 5485 escape_essid(network->ssid, network->ssid_len),
4341 MAC_ARG(network->bssid), 5486 MAC_ARG(network->bssid),
4342 (jiffies - network->last_scanned) / (HZ / 100)); 5487 1000 * (jiffies - network->last_scanned) / HZ);
4343 return 0; 5488 return 0;
4344 } 5489 }
4345 5490
@@ -4367,6 +5512,15 @@ static int ipw_best_network(struct ipw_priv *priv,
4367 return 0; 5512 return 0;
4368 } 5513 }
4369 5514
5515 if (!priv->ieee->wpa_enabled && (network->wpa_ie_len > 0 ||
5516 network->rsn_ie_len > 0)) {
5517 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5518 "because of WPA capability mismatch.\n",
5519 escape_essid(network->ssid, network->ssid_len),
5520 MAC_ARG(network->bssid));
5521 return 0;
5522 }
5523
4370 if ((priv->config & CFG_STATIC_BSSID) && 5524 if ((priv->config & CFG_STATIC_BSSID) &&
4371 memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 5525 memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
4372 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5526 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
@@ -4386,7 +5540,26 @@ static int ipw_best_network(struct ipw_priv *priv,
4386 return 0; 5540 return 0;
4387 } 5541 }
4388 5542
4389 ipw_compatible_rates(priv, network, &rates); 5543 /* Filter out invalid channel in current GEO */
5544 if (!ipw_is_valid_channel(priv->ieee, network->channel)) {
5545 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5546 "because of invalid channel in current GEO\n",
5547 escape_essid(network->ssid, network->ssid_len),
5548 MAC_ARG(network->bssid));
5549 return 0;
5550 }
5551
5552 /* Ensure that the rates supported by the driver are compatible with
5553 * this AP, including verification of basic rates (mandatory) */
5554 if (!ipw_compatible_rates(priv, network, &rates)) {
5555 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5556 "because configured rate mask excludes "
5557 "AP mandatory rate.\n",
5558 escape_essid(network->ssid, network->ssid_len),
5559 MAC_ARG(network->bssid));
5560 return 0;
5561 }
5562
4390 if (rates.num_rates == 0) { 5563 if (rates.num_rates == 0) {
4391 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5564 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4392 "because of no compatible rates.\n", 5565 "because of no compatible rates.\n",
@@ -4413,6 +5586,9 @@ static int ipw_best_network(struct ipw_priv *priv,
4413static void ipw_adhoc_create(struct ipw_priv *priv, 5586static void ipw_adhoc_create(struct ipw_priv *priv,
4414 struct ieee80211_network *network) 5587 struct ieee80211_network *network)
4415{ 5588{
5589 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5590 int i;
5591
4416 /* 5592 /*
4417 * For the purposes of scanning, we can set our wireless mode 5593 * For the purposes of scanning, we can set our wireless mode
4418 * to trigger scans across combinations of bands, but when it 5594 * to trigger scans across combinations of bands, but when it
@@ -4423,22 +5599,47 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4423 * chossen band. Attempting to create a new ad-hoc network 5599 * chossen band. Attempting to create a new ad-hoc network
4424 * with an invalid channel for wireless mode will trigger a 5600 * with an invalid channel for wireless mode will trigger a
4425 * FW fatal error. 5601 * FW fatal error.
5602 *
4426 */ 5603 */
4427 network->mode = is_valid_channel(priv->ieee->mode, priv->channel); 5604 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
4428 if (network->mode) { 5605 case IEEE80211_52GHZ_BAND:
4429 network->channel = priv->channel; 5606 network->mode = IEEE_A;
4430 } else { 5607 i = ipw_channel_to_index(priv->ieee, priv->channel);
5608 if (i == -1)
5609 BUG();
5610 if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5611 IPW_WARNING("Overriding invalid channel\n");
5612 priv->channel = geo->a[0].channel;
5613 }
5614 break;
5615
5616 case IEEE80211_24GHZ_BAND:
5617 if (priv->ieee->mode & IEEE_G)
5618 network->mode = IEEE_G;
5619 else
5620 network->mode = IEEE_B;
5621 i = ipw_channel_to_index(priv->ieee, priv->channel);
5622 if (i == -1)
5623 BUG();
5624 if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5625 IPW_WARNING("Overriding invalid channel\n");
5626 priv->channel = geo->bg[0].channel;
5627 }
5628 break;
5629
5630 default:
4431 IPW_WARNING("Overriding invalid channel\n"); 5631 IPW_WARNING("Overriding invalid channel\n");
4432 if (priv->ieee->mode & IEEE_A) { 5632 if (priv->ieee->mode & IEEE_A) {
4433 network->mode = IEEE_A; 5633 network->mode = IEEE_A;
4434 priv->channel = band_a_active_channel[0]; 5634 priv->channel = geo->a[0].channel;
4435 } else if (priv->ieee->mode & IEEE_G) { 5635 } else if (priv->ieee->mode & IEEE_G) {
4436 network->mode = IEEE_G; 5636 network->mode = IEEE_G;
4437 priv->channel = band_b_active_channel[0]; 5637 priv->channel = geo->bg[0].channel;
4438 } else { 5638 } else {
4439 network->mode = IEEE_B; 5639 network->mode = IEEE_B;
4440 priv->channel = band_b_active_channel[0]; 5640 priv->channel = geo->bg[0].channel;
4441 } 5641 }
5642 break;
4442 } 5643 }
4443 5644
4444 network->channel = priv->channel; 5645 network->channel = priv->channel;
@@ -4448,6 +5649,8 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4448 memcpy(network->ssid, priv->essid, priv->essid_len); 5649 memcpy(network->ssid, priv->essid, priv->essid_len);
4449 memset(&network->stats, 0, sizeof(network->stats)); 5650 memset(&network->stats, 0, sizeof(network->stats));
4450 network->capability = WLAN_CAPABILITY_IBSS; 5651 network->capability = WLAN_CAPABILITY_IBSS;
5652 if (!(priv->config & CFG_PREAMBLE_LONG))
5653 network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
4451 if (priv->capability & CAP_PRIVACY_ON) 5654 if (priv->capability & CAP_PRIVACY_ON)
4452 network->capability |= WLAN_CAPABILITY_PRIVACY; 5655 network->capability |= WLAN_CAPABILITY_PRIVACY;
4453 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH); 5656 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
@@ -4464,13 +5667,35 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4464 network->beacon_interval = 100; /* Default */ 5667 network->beacon_interval = 100; /* Default */
4465 network->listen_interval = 10; /* Default */ 5668 network->listen_interval = 10; /* Default */
4466 network->atim_window = 0; /* Default */ 5669 network->atim_window = 0; /* Default */
4467#ifdef CONFIG_IEEE80211_WPA
4468 network->wpa_ie_len = 0; 5670 network->wpa_ie_len = 0;
4469 network->rsn_ie_len = 0; 5671 network->rsn_ie_len = 0;
4470#endif /* CONFIG_IEEE80211_WPA */
4471} 5672}
4472 5673
4473static void ipw_send_wep_keys(struct ipw_priv *priv) 5674static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
5675{
5676 struct ipw_tgi_tx_key *key;
5677 struct host_cmd cmd = {
5678 .cmd = IPW_CMD_TGI_TX_KEY,
5679 .len = sizeof(*key)
5680 };
5681
5682 if (!(priv->ieee->sec.flags & (1 << index)))
5683 return;
5684
5685 key = (struct ipw_tgi_tx_key *)&cmd.param;
5686 key->key_id = index;
5687 memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
5688 key->security_type = type;
5689 key->station_index = 0; /* always 0 for BSS */
5690 key->flags = 0;
5691 /* 0 for new key; previous value of counter (after fatal error) */
5692 key->tx_counter[0] = 0;
5693 key->tx_counter[1] = 0;
5694
5695 ipw_send_cmd(priv, &cmd);
5696}
5697
5698static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
4474{ 5699{
4475 struct ipw_wep_key *key; 5700 struct ipw_wep_key *key;
4476 int i; 5701 int i;
@@ -4483,19 +5708,97 @@ static void ipw_send_wep_keys(struct ipw_priv *priv)
4483 key->cmd_id = DINO_CMD_WEP_KEY; 5708 key->cmd_id = DINO_CMD_WEP_KEY;
4484 key->seq_num = 0; 5709 key->seq_num = 0;
4485 5710
5711 /* Note: AES keys cannot be set for multiple times.
5712 * Only set it at the first time. */
4486 for (i = 0; i < 4; i++) { 5713 for (i = 0; i < 4; i++) {
4487 key->key_index = i; 5714 key->key_index = i | type;
4488 if (!(priv->sec.flags & (1 << i))) { 5715 if (!(priv->ieee->sec.flags & (1 << i))) {
4489 key->key_size = 0; 5716 key->key_size = 0;
4490 } else { 5717 continue;
4491 key->key_size = priv->sec.key_sizes[i];
4492 memcpy(key->key, priv->sec.keys[i], key->key_size);
4493 } 5718 }
4494 5719
4495 if (ipw_send_cmd(priv, &cmd)) { 5720 key->key_size = priv->ieee->sec.key_sizes[i];
4496 IPW_ERROR("failed to send WEP_KEY command\n"); 5721 memcpy(key->key, priv->ieee->sec.keys[i], key->key_size);
4497 return; 5722
4498 } 5723 ipw_send_cmd(priv, &cmd);
5724 }
5725}
5726
5727static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level)
5728{
5729 if (priv->ieee->host_encrypt)
5730 return;
5731
5732 switch (level) {
5733 case SEC_LEVEL_3:
5734 priv->sys_config.disable_unicast_decryption = 0;
5735 priv->ieee->host_decrypt = 0;
5736 break;
5737 case SEC_LEVEL_2:
5738 priv->sys_config.disable_unicast_decryption = 1;
5739 priv->ieee->host_decrypt = 1;
5740 break;
5741 case SEC_LEVEL_1:
5742 priv->sys_config.disable_unicast_decryption = 0;
5743 priv->ieee->host_decrypt = 0;
5744 break;
5745 case SEC_LEVEL_0:
5746 priv->sys_config.disable_unicast_decryption = 1;
5747 break;
5748 default:
5749 break;
5750 }
5751}
5752
5753static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level)
5754{
5755 if (priv->ieee->host_encrypt)
5756 return;
5757
5758 switch (level) {
5759 case SEC_LEVEL_3:
5760 priv->sys_config.disable_multicast_decryption = 0;
5761 break;
5762 case SEC_LEVEL_2:
5763 priv->sys_config.disable_multicast_decryption = 1;
5764 break;
5765 case SEC_LEVEL_1:
5766 priv->sys_config.disable_multicast_decryption = 0;
5767 break;
5768 case SEC_LEVEL_0:
5769 priv->sys_config.disable_multicast_decryption = 1;
5770 break;
5771 default:
5772 break;
5773 }
5774}
5775
5776static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
5777{
5778 switch (priv->ieee->sec.level) {
5779 case SEC_LEVEL_3:
5780 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5781 ipw_send_tgi_tx_key(priv,
5782 DCT_FLAG_EXT_SECURITY_CCM,
5783 priv->ieee->sec.active_key);
5784
5785 if (!priv->ieee->host_mc_decrypt)
5786 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
5787 break;
5788 case SEC_LEVEL_2:
5789 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5790 ipw_send_tgi_tx_key(priv,
5791 DCT_FLAG_EXT_SECURITY_TKIP,
5792 priv->ieee->sec.active_key);
5793 break;
5794 case SEC_LEVEL_1:
5795 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
5796 ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
5797 ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
5798 break;
5799 case SEC_LEVEL_0:
5800 default:
5801 break;
4499 } 5802 }
4500} 5803}
4501 5804
@@ -4503,9 +5806,12 @@ static void ipw_adhoc_check(void *data)
4503{ 5806{
4504 struct ipw_priv *priv = data; 5807 struct ipw_priv *priv = data;
4505 5808
4506 if (priv->missed_adhoc_beacons++ > priv->missed_beacon_threshold && 5809 if (priv->missed_adhoc_beacons++ > priv->disassociate_threshold &&
4507 !(priv->config & CFG_ADHOC_PERSIST)) { 5810 !(priv->config & CFG_ADHOC_PERSIST)) {
4508 IPW_DEBUG_SCAN("Disassociating due to missed beacons\n"); 5811 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
5812 IPW_DL_STATE | IPW_DL_ASSOC,
5813 "Missed beacon: %d - disassociate\n",
5814 priv->missed_adhoc_beacons);
4509 ipw_remove_current_network(priv); 5815 ipw_remove_current_network(priv);
4510 ipw_disassociate(priv); 5816 ipw_disassociate(priv);
4511 return; 5817 return;
@@ -4515,6 +5821,14 @@ static void ipw_adhoc_check(void *data)
4515 priv->assoc_request.beacon_interval); 5821 priv->assoc_request.beacon_interval);
4516} 5822}
4517 5823
5824static void ipw_bg_adhoc_check(void *data)
5825{
5826 struct ipw_priv *priv = data;
5827 down(&priv->sem);
5828 ipw_adhoc_check(data);
5829 up(&priv->sem);
5830}
5831
4518#ifdef CONFIG_IPW_DEBUG 5832#ifdef CONFIG_IPW_DEBUG
4519static void ipw_debug_config(struct ipw_priv *priv) 5833static void ipw_debug_config(struct ipw_priv *priv)
4520{ 5834{
@@ -4530,7 +5844,8 @@ static void ipw_debug_config(struct ipw_priv *priv)
4530 else 5844 else
4531 IPW_DEBUG_INFO("ESSID unlocked.\n"); 5845 IPW_DEBUG_INFO("ESSID unlocked.\n");
4532 if (priv->config & CFG_STATIC_BSSID) 5846 if (priv->config & CFG_STATIC_BSSID)
4533 IPW_DEBUG_INFO("BSSID locked to %d\n", priv->channel); 5847 IPW_DEBUG_INFO("BSSID locked to " MAC_FMT "\n",
5848 MAC_ARG(priv->bssid));
4534 else 5849 else
4535 IPW_DEBUG_INFO("BSSID unlocked.\n"); 5850 IPW_DEBUG_INFO("BSSID unlocked.\n");
4536 if (priv->capability & CAP_PRIVACY_ON) 5851 if (priv->capability & CAP_PRIVACY_ON)
@@ -4543,8 +5858,7 @@ static void ipw_debug_config(struct ipw_priv *priv)
4543#define ipw_debug_config(x) do {} while (0) 5858#define ipw_debug_config(x) do {} while (0)
4544#endif 5859#endif
4545 5860
4546static inline void ipw_set_fixed_rate(struct ipw_priv *priv, 5861static inline void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
4547 struct ieee80211_network *network)
4548{ 5862{
4549 /* TODO: Verify that this works... */ 5863 /* TODO: Verify that this works... */
4550 struct ipw_fixed_rate fr = { 5864 struct ipw_fixed_rate fr = {
@@ -4561,6 +5875,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4561 /* IEEE_A */ 5875 /* IEEE_A */
4562 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) { 5876 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) {
4563 /* Invalid fixed rate mask */ 5877 /* Invalid fixed rate mask */
5878 IPW_DEBUG_WX
5879 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4564 fr.tx_rates = 0; 5880 fr.tx_rates = 0;
4565 break; 5881 break;
4566 } 5882 }
@@ -4570,9 +5886,11 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4570 5886
4571 default: /* 2.4Ghz or Mixed */ 5887 default: /* 2.4Ghz or Mixed */
4572 /* IEEE_B */ 5888 /* IEEE_B */
4573 if (network->mode == IEEE_B) { 5889 if (mode == IEEE_B) {
4574 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) { 5890 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
4575 /* Invalid fixed rate mask */ 5891 /* Invalid fixed rate mask */
5892 IPW_DEBUG_WX
5893 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4576 fr.tx_rates = 0; 5894 fr.tx_rates = 0;
4577 } 5895 }
4578 break; 5896 break;
@@ -4582,6 +5900,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4582 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK | 5900 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
4583 IEEE80211_OFDM_RATES_MASK)) { 5901 IEEE80211_OFDM_RATES_MASK)) {
4584 /* Invalid fixed rate mask */ 5902 /* Invalid fixed rate mask */
5903 IPW_DEBUG_WX
5904 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4585 fr.tx_rates = 0; 5905 fr.tx_rates = 0;
4586 break; 5906 break;
4587 } 5907 }
@@ -4609,6 +5929,1112 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4609 ipw_write_reg32(priv, reg, *(u32 *) & fr); 5929 ipw_write_reg32(priv, reg, *(u32 *) & fr);
4610} 5930}
4611 5931
5932static void ipw_abort_scan(struct ipw_priv *priv)
5933{
5934 int err;
5935
5936 if (priv->status & STATUS_SCAN_ABORTING) {
5937 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
5938 return;
5939 }
5940 priv->status |= STATUS_SCAN_ABORTING;
5941
5942 err = ipw_send_scan_abort(priv);
5943 if (err)
5944 IPW_DEBUG_HC("Request to abort scan failed.\n");
5945}
5946
5947static void ipw_add_scan_channels(struct ipw_priv *priv,
5948 struct ipw_scan_request_ext *scan,
5949 int scan_type)
5950{
5951 int channel_index = 0;
5952 const struct ieee80211_geo *geo;
5953 int i;
5954
5955 geo = ipw_get_geo(priv->ieee);
5956
5957 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
5958 int start = channel_index;
5959 for (i = 0; i < geo->a_channels; i++) {
5960 if ((priv->status & STATUS_ASSOCIATED) &&
5961 geo->a[i].channel == priv->channel)
5962 continue;
5963 channel_index++;
5964 scan->channels_list[channel_index] = geo->a[i].channel;
5965 ipw_set_scan_type(scan, channel_index,
5966 geo->a[i].
5967 flags & IEEE80211_CH_PASSIVE_ONLY ?
5968 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN :
5969 scan_type);
5970 }
5971
5972 if (start != channel_index) {
5973 scan->channels_list[start] = (u8) (IPW_A_MODE << 6) |
5974 (channel_index - start);
5975 channel_index++;
5976 }
5977 }
5978
5979 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
5980 int start = channel_index;
5981 if (priv->config & CFG_SPEED_SCAN) {
5982 int index;
5983 u8 channels[IEEE80211_24GHZ_CHANNELS] = {
5984 /* nop out the list */
5985 [0] = 0
5986 };
5987
5988 u8 channel;
5989 while (channel_index < IPW_SCAN_CHANNELS) {
5990 channel =
5991 priv->speed_scan[priv->speed_scan_pos];
5992 if (channel == 0) {
5993 priv->speed_scan_pos = 0;
5994 channel = priv->speed_scan[0];
5995 }
5996 if ((priv->status & STATUS_ASSOCIATED) &&
5997 channel == priv->channel) {
5998 priv->speed_scan_pos++;
5999 continue;
6000 }
6001
6002 /* If this channel has already been
6003 * added in scan, break from loop
6004 * and this will be the first channel
6005 * in the next scan.
6006 */
6007 if (channels[channel - 1] != 0)
6008 break;
6009
6010 channels[channel - 1] = 1;
6011 priv->speed_scan_pos++;
6012 channel_index++;
6013 scan->channels_list[channel_index] = channel;
6014 index =
6015 ipw_channel_to_index(priv->ieee, channel);
6016 ipw_set_scan_type(scan, channel_index,
6017 geo->bg[index].
6018 flags &
6019 IEEE80211_CH_PASSIVE_ONLY ?
6020 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6021 : scan_type);
6022 }
6023 } else {
6024 for (i = 0; i < geo->bg_channels; i++) {
6025 if ((priv->status & STATUS_ASSOCIATED) &&
6026 geo->bg[i].channel == priv->channel)
6027 continue;
6028 channel_index++;
6029 scan->channels_list[channel_index] =
6030 geo->bg[i].channel;
6031 ipw_set_scan_type(scan, channel_index,
6032 geo->bg[i].
6033 flags &
6034 IEEE80211_CH_PASSIVE_ONLY ?
6035 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6036 : scan_type);
6037 }
6038 }
6039
6040 if (start != channel_index) {
6041 scan->channels_list[start] = (u8) (IPW_B_MODE << 6) |
6042 (channel_index - start);
6043 }
6044 }
6045}
6046
6047static int ipw_request_scan(struct ipw_priv *priv)
6048{
6049 struct ipw_scan_request_ext scan;
6050 int err = 0, scan_type;
6051
6052 if (!(priv->status & STATUS_INIT) ||
6053 (priv->status & STATUS_EXIT_PENDING))
6054 return 0;
6055
6056 down(&priv->sem);
6057
6058 if (priv->status & STATUS_SCANNING) {
6059 IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n");
6060 priv->status |= STATUS_SCAN_PENDING;
6061 goto done;
6062 }
6063
6064 if (!(priv->status & STATUS_SCAN_FORCED) &&
6065 priv->status & STATUS_SCAN_ABORTING) {
6066 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
6067 priv->status |= STATUS_SCAN_PENDING;
6068 goto done;
6069 }
6070
6071 if (priv->status & STATUS_RF_KILL_MASK) {
6072 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
6073 priv->status |= STATUS_SCAN_PENDING;
6074 goto done;
6075 }
6076
6077 memset(&scan, 0, sizeof(scan));
6078
6079 if (priv->config & CFG_SPEED_SCAN)
6080 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6081 cpu_to_le16(30);
6082 else
6083 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6084 cpu_to_le16(20);
6085
6086 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
6087 cpu_to_le16(20);
6088 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
6089
6090 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
6091
6092#ifdef CONFIG_IPW2200_MONITOR
6093 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
6094 u8 channel;
6095 u8 band = 0;
6096
6097 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
6098 case IEEE80211_52GHZ_BAND:
6099 band = (u8) (IPW_A_MODE << 6) | 1;
6100 channel = priv->channel;
6101 break;
6102
6103 case IEEE80211_24GHZ_BAND:
6104 band = (u8) (IPW_B_MODE << 6) | 1;
6105 channel = priv->channel;
6106 break;
6107
6108 default:
6109 band = (u8) (IPW_B_MODE << 6) | 1;
6110 channel = 9;
6111 break;
6112 }
6113
6114 scan.channels_list[0] = band;
6115 scan.channels_list[1] = channel;
6116 ipw_set_scan_type(&scan, 1, IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
6117
6118 /* NOTE: The card will sit on this channel for this time
6119 * period. Scan aborts are timing sensitive and frequently
6120 * result in firmware restarts. As such, it is best to
6121 * set a small dwell_time here and just keep re-issuing
6122 * scans. Otherwise fast channel hopping will not actually
6123 * hop channels.
6124 *
6125 * TODO: Move SPEED SCAN support to all modes and bands */
6126 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
6127 cpu_to_le16(2000);
6128 } else {
6129#endif /* CONFIG_IPW2200_MONITOR */
6130 /* If we are roaming, then make this a directed scan for the
6131 * current network. Otherwise, ensure that every other scan
6132 * is a fast channel hop scan */
6133 if ((priv->status & STATUS_ROAMING)
6134 || (!(priv->status & STATUS_ASSOCIATED)
6135 && (priv->config & CFG_STATIC_ESSID)
6136 && (le32_to_cpu(scan.full_scan_index) % 2))) {
6137 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
6138 if (err) {
6139 IPW_DEBUG_HC("Attempt to send SSID command "
6140 "failed.\n");
6141 goto done;
6142 }
6143
6144 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
6145 } else
6146 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
6147
6148 ipw_add_scan_channels(priv, &scan, scan_type);
6149#ifdef CONFIG_IPW2200_MONITOR
6150 }
6151#endif
6152
6153 err = ipw_send_scan_request_ext(priv, &scan);
6154 if (err) {
6155 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
6156 goto done;
6157 }
6158
6159 priv->status |= STATUS_SCANNING;
6160 priv->status &= ~STATUS_SCAN_PENDING;
6161 queue_delayed_work(priv->workqueue, &priv->scan_check,
6162 IPW_SCAN_CHECK_WATCHDOG);
6163 done:
6164 up(&priv->sem);
6165 return err;
6166}
6167
6168static void ipw_bg_abort_scan(void *data)
6169{
6170 struct ipw_priv *priv = data;
6171 down(&priv->sem);
6172 ipw_abort_scan(data);
6173 up(&priv->sem);
6174}
6175
6176static int ipw_wpa_enable(struct ipw_priv *priv, int value)
6177{
6178 /* This is called when wpa_supplicant loads and closes the driver
6179 * interface. */
6180 priv->ieee->wpa_enabled = value;
6181 return 0;
6182}
6183
6184static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
6185{
6186 struct ieee80211_device *ieee = priv->ieee;
6187 struct ieee80211_security sec = {
6188 .flags = SEC_AUTH_MODE,
6189 };
6190 int ret = 0;
6191
6192 if (value & IW_AUTH_ALG_SHARED_KEY) {
6193 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
6194 ieee->open_wep = 0;
6195 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
6196 sec.auth_mode = WLAN_AUTH_OPEN;
6197 ieee->open_wep = 1;
6198 } else
6199 return -EINVAL;
6200
6201 if (ieee->set_security)
6202 ieee->set_security(ieee->dev, &sec);
6203 else
6204 ret = -EOPNOTSUPP;
6205
6206 return ret;
6207}
6208
6209void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
6210{
6211 /* make sure WPA is enabled */
6212 ipw_wpa_enable(priv, 1);
6213
6214 ipw_disassociate(priv);
6215}
6216
6217static int ipw_set_rsn_capa(struct ipw_priv *priv,
6218 char *capabilities, int length)
6219{
6220 struct host_cmd cmd = {
6221 .cmd = IPW_CMD_RSN_CAPABILITIES,
6222 .len = length,
6223 };
6224
6225 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
6226
6227 memcpy(cmd.param, capabilities, length);
6228 return ipw_send_cmd(priv, &cmd);
6229}
6230
6231/*
6232 * WE-18 support
6233 */
6234
6235/* SIOCSIWGENIE */
6236static int ipw_wx_set_genie(struct net_device *dev,
6237 struct iw_request_info *info,
6238 union iwreq_data *wrqu, char *extra)
6239{
6240 struct ipw_priv *priv = ieee80211_priv(dev);
6241 struct ieee80211_device *ieee = priv->ieee;
6242 u8 *buf;
6243 int err = 0;
6244
6245 if (wrqu->data.length > MAX_WPA_IE_LEN ||
6246 (wrqu->data.length && extra == NULL))
6247 return -EINVAL;
6248
6249 //down(&priv->sem);
6250
6251 //if (!ieee->wpa_enabled) {
6252 // err = -EOPNOTSUPP;
6253 // goto out;
6254 //}
6255
6256 if (wrqu->data.length) {
6257 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
6258 if (buf == NULL) {
6259 err = -ENOMEM;
6260 goto out;
6261 }
6262
6263 memcpy(buf, extra, wrqu->data.length);
6264 kfree(ieee->wpa_ie);
6265 ieee->wpa_ie = buf;
6266 ieee->wpa_ie_len = wrqu->data.length;
6267 } else {
6268 kfree(ieee->wpa_ie);
6269 ieee->wpa_ie = NULL;
6270 ieee->wpa_ie_len = 0;
6271 }
6272
6273 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
6274 out:
6275 //up(&priv->sem);
6276 return err;
6277}
6278
6279/* SIOCGIWGENIE */
6280static int ipw_wx_get_genie(struct net_device *dev,
6281 struct iw_request_info *info,
6282 union iwreq_data *wrqu, char *extra)
6283{
6284 struct ipw_priv *priv = ieee80211_priv(dev);
6285 struct ieee80211_device *ieee = priv->ieee;
6286 int err = 0;
6287
6288 //down(&priv->sem);
6289
6290 //if (!ieee->wpa_enabled) {
6291 // err = -EOPNOTSUPP;
6292 // goto out;
6293 //}
6294
6295 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
6296 wrqu->data.length = 0;
6297 goto out;
6298 }
6299
6300 if (wrqu->data.length < ieee->wpa_ie_len) {
6301 err = -E2BIG;
6302 goto out;
6303 }
6304
6305 wrqu->data.length = ieee->wpa_ie_len;
6306 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
6307
6308 out:
6309 //up(&priv->sem);
6310 return err;
6311}
6312
6313static int wext_cipher2level(int cipher)
6314{
6315 switch (cipher) {
6316 case IW_AUTH_CIPHER_NONE:
6317 return SEC_LEVEL_0;
6318 case IW_AUTH_CIPHER_WEP40:
6319 case IW_AUTH_CIPHER_WEP104:
6320 return SEC_LEVEL_1;
6321 case IW_AUTH_CIPHER_TKIP:
6322 return SEC_LEVEL_2;
6323 case IW_AUTH_CIPHER_CCMP:
6324 return SEC_LEVEL_3;
6325 default:
6326 return -1;
6327 }
6328}
6329
6330/* SIOCSIWAUTH */
6331static int ipw_wx_set_auth(struct net_device *dev,
6332 struct iw_request_info *info,
6333 union iwreq_data *wrqu, char *extra)
6334{
6335 struct ipw_priv *priv = ieee80211_priv(dev);
6336 struct ieee80211_device *ieee = priv->ieee;
6337 struct iw_param *param = &wrqu->param;
6338 struct ieee80211_crypt_data *crypt;
6339 unsigned long flags;
6340 int ret = 0;
6341
6342 switch (param->flags & IW_AUTH_INDEX) {
6343 case IW_AUTH_WPA_VERSION:
6344 break;
6345 case IW_AUTH_CIPHER_PAIRWISE:
6346 ipw_set_hw_decrypt_unicast(priv,
6347 wext_cipher2level(param->value));
6348 break;
6349 case IW_AUTH_CIPHER_GROUP:
6350 ipw_set_hw_decrypt_multicast(priv,
6351 wext_cipher2level(param->value));
6352 break;
6353 case IW_AUTH_KEY_MGMT:
6354 /*
6355 * ipw2200 does not use these parameters
6356 */
6357 break;
6358
6359 case IW_AUTH_TKIP_COUNTERMEASURES:
6360 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
6361 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
6362 break;
6363
6364 flags = crypt->ops->get_flags(crypt->priv);
6365
6366 if (param->value)
6367 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6368 else
6369 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6370
6371 crypt->ops->set_flags(flags, crypt->priv);
6372
6373 break;
6374
6375 case IW_AUTH_DROP_UNENCRYPTED:{
6376 /* HACK:
6377 *
6378 * wpa_supplicant calls set_wpa_enabled when the driver
6379 * is loaded and unloaded, regardless of if WPA is being
6380 * used. No other calls are made which can be used to
6381 * determine if encryption will be used or not prior to
6382 * association being expected. If encryption is not being
6383 * used, drop_unencrypted is set to false, else true -- we
6384 * can use this to determine if the CAP_PRIVACY_ON bit should
6385 * be set.
6386 */
6387 struct ieee80211_security sec = {
6388 .flags = SEC_ENABLED,
6389 .enabled = param->value,
6390 };
6391 priv->ieee->drop_unencrypted = param->value;
6392 /* We only change SEC_LEVEL for open mode. Others
6393 * are set by ipw_wpa_set_encryption.
6394 */
6395 if (!param->value) {
6396 sec.flags |= SEC_LEVEL;
6397 sec.level = SEC_LEVEL_0;
6398 } else {
6399 sec.flags |= SEC_LEVEL;
6400 sec.level = SEC_LEVEL_1;
6401 }
6402 if (priv->ieee->set_security)
6403 priv->ieee->set_security(priv->ieee->dev, &sec);
6404 break;
6405 }
6406
6407 case IW_AUTH_80211_AUTH_ALG:
6408 ret = ipw_wpa_set_auth_algs(priv, param->value);
6409 break;
6410
6411 case IW_AUTH_WPA_ENABLED:
6412 ret = ipw_wpa_enable(priv, param->value);
6413 break;
6414
6415 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6416 ieee->ieee802_1x = param->value;
6417 break;
6418
6419 //case IW_AUTH_ROAMING_CONTROL:
6420 case IW_AUTH_PRIVACY_INVOKED:
6421 ieee->privacy_invoked = param->value;
6422 break;
6423
6424 default:
6425 return -EOPNOTSUPP;
6426 }
6427 return ret;
6428}
6429
6430/* SIOCGIWAUTH */
6431static int ipw_wx_get_auth(struct net_device *dev,
6432 struct iw_request_info *info,
6433 union iwreq_data *wrqu, char *extra)
6434{
6435 struct ipw_priv *priv = ieee80211_priv(dev);
6436 struct ieee80211_device *ieee = priv->ieee;
6437 struct ieee80211_crypt_data *crypt;
6438 struct iw_param *param = &wrqu->param;
6439 int ret = 0;
6440
6441 switch (param->flags & IW_AUTH_INDEX) {
6442 case IW_AUTH_WPA_VERSION:
6443 case IW_AUTH_CIPHER_PAIRWISE:
6444 case IW_AUTH_CIPHER_GROUP:
6445 case IW_AUTH_KEY_MGMT:
6446 /*
6447 * wpa_supplicant will control these internally
6448 */
6449 ret = -EOPNOTSUPP;
6450 break;
6451
6452 case IW_AUTH_TKIP_COUNTERMEASURES:
6453 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
6454 if (!crypt || !crypt->ops->get_flags)
6455 break;
6456
6457 param->value = (crypt->ops->get_flags(crypt->priv) &
6458 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
6459
6460 break;
6461
6462 case IW_AUTH_DROP_UNENCRYPTED:
6463 param->value = ieee->drop_unencrypted;
6464 break;
6465
6466 case IW_AUTH_80211_AUTH_ALG:
6467 param->value = ieee->sec.auth_mode;
6468 break;
6469
6470 case IW_AUTH_WPA_ENABLED:
6471 param->value = ieee->wpa_enabled;
6472 break;
6473
6474 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6475 param->value = ieee->ieee802_1x;
6476 break;
6477
6478 case IW_AUTH_ROAMING_CONTROL:
6479 case IW_AUTH_PRIVACY_INVOKED:
6480 param->value = ieee->privacy_invoked;
6481 break;
6482
6483 default:
6484 return -EOPNOTSUPP;
6485 }
6486 return 0;
6487}
6488
6489/* SIOCSIWENCODEEXT */
6490static int ipw_wx_set_encodeext(struct net_device *dev,
6491 struct iw_request_info *info,
6492 union iwreq_data *wrqu, char *extra)
6493{
6494 struct ipw_priv *priv = ieee80211_priv(dev);
6495 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6496
6497 if (hwcrypto) {
6498 if (ext->alg == IW_ENCODE_ALG_TKIP) {
6499 /* IPW HW can't build TKIP MIC,
6500 host decryption still needed */
6501 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
6502 priv->ieee->host_mc_decrypt = 1;
6503 else {
6504 priv->ieee->host_encrypt = 0;
6505 priv->ieee->host_encrypt_msdu = 1;
6506 priv->ieee->host_decrypt = 1;
6507 }
6508 } else {
6509 priv->ieee->host_encrypt = 0;
6510 priv->ieee->host_encrypt_msdu = 0;
6511 priv->ieee->host_decrypt = 0;
6512 priv->ieee->host_mc_decrypt = 0;
6513 }
6514 }
6515
6516 return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
6517}
6518
6519/* SIOCGIWENCODEEXT */
6520static int ipw_wx_get_encodeext(struct net_device *dev,
6521 struct iw_request_info *info,
6522 union iwreq_data *wrqu, char *extra)
6523{
6524 struct ipw_priv *priv = ieee80211_priv(dev);
6525 return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
6526}
6527
6528/* SIOCSIWMLME */
6529static int ipw_wx_set_mlme(struct net_device *dev,
6530 struct iw_request_info *info,
6531 union iwreq_data *wrqu, char *extra)
6532{
6533 struct ipw_priv *priv = ieee80211_priv(dev);
6534 struct iw_mlme *mlme = (struct iw_mlme *)extra;
6535 u16 reason;
6536
6537 reason = cpu_to_le16(mlme->reason_code);
6538
6539 switch (mlme->cmd) {
6540 case IW_MLME_DEAUTH:
6541 // silently ignore
6542 break;
6543
6544 case IW_MLME_DISASSOC:
6545 ipw_disassociate(priv);
6546 break;
6547
6548 default:
6549 return -EOPNOTSUPP;
6550 }
6551 return 0;
6552}
6553
6554#ifdef CONFIG_IPW_QOS
6555
6556/* QoS */
6557/*
6558* get the modulation type of the current network or
6559* the card current mode
6560*/
6561u8 ipw_qos_current_mode(struct ipw_priv * priv)
6562{
6563 u8 mode = 0;
6564
6565 if (priv->status & STATUS_ASSOCIATED) {
6566 unsigned long flags;
6567
6568 spin_lock_irqsave(&priv->ieee->lock, flags);
6569 mode = priv->assoc_network->mode;
6570 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6571 } else {
6572 mode = priv->ieee->mode;
6573 }
6574 IPW_DEBUG_QOS("QoS network/card mode %d \n", mode);
6575 return mode;
6576}
6577
6578/*
6579* Handle management frame beacon and probe response
6580*/
6581static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
6582 int active_network,
6583 struct ieee80211_network *network)
6584{
6585 u32 size = sizeof(struct ieee80211_qos_parameters);
6586
6587 if (network->capability & WLAN_CAPABILITY_IBSS)
6588 network->qos_data.active = network->qos_data.supported;
6589
6590 if (network->flags & NETWORK_HAS_QOS_MASK) {
6591 if (active_network &&
6592 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
6593 network->qos_data.active = network->qos_data.supported;
6594
6595 if ((network->qos_data.active == 1) && (active_network == 1) &&
6596 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
6597 (network->qos_data.old_param_count !=
6598 network->qos_data.param_count)) {
6599 network->qos_data.old_param_count =
6600 network->qos_data.param_count;
6601 schedule_work(&priv->qos_activate);
6602 IPW_DEBUG_QOS("QoS parameters change call "
6603 "qos_activate\n");
6604 }
6605 } else {
6606 if ((priv->ieee->mode == IEEE_B) || (network->mode == IEEE_B))
6607 memcpy(&network->qos_data.parameters,
6608 &def_parameters_CCK, size);
6609 else
6610 memcpy(&network->qos_data.parameters,
6611 &def_parameters_OFDM, size);
6612
6613 if ((network->qos_data.active == 1) && (active_network == 1)) {
6614 IPW_DEBUG_QOS("QoS was disabled call qos_activate \n");
6615 schedule_work(&priv->qos_activate);
6616 }
6617
6618 network->qos_data.active = 0;
6619 network->qos_data.supported = 0;
6620 }
6621 if ((priv->status & STATUS_ASSOCIATED) &&
6622 (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {
6623 if (memcmp(network->bssid, priv->bssid, ETH_ALEN))
6624 if ((network->capability & WLAN_CAPABILITY_IBSS) &&
6625 !(network->flags & NETWORK_EMPTY_ESSID))
6626 if ((network->ssid_len ==
6627 priv->assoc_network->ssid_len) &&
6628 !memcmp(network->ssid,
6629 priv->assoc_network->ssid,
6630 network->ssid_len)) {
6631 queue_work(priv->workqueue,
6632 &priv->merge_networks);
6633 }
6634 }
6635
6636 return 0;
6637}
6638
6639/*
6640* This function set up the firmware to support QoS. It sends
6641* IPW_CMD_QOS_PARAMETERS and IPW_CMD_WME_INFO
6642*/
6643static int ipw_qos_activate(struct ipw_priv *priv,
6644 struct ieee80211_qos_data *qos_network_data)
6645{
6646 int err;
6647 struct ieee80211_qos_parameters qos_parameters[QOS_QOS_SETS];
6648 struct ieee80211_qos_parameters *active_one = NULL;
6649 u32 size = sizeof(struct ieee80211_qos_parameters);
6650 u32 burst_duration;
6651 int i;
6652 u8 type;
6653
6654 type = ipw_qos_current_mode(priv);
6655
6656 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_CCK]);
6657 memcpy(active_one, priv->qos_data.def_qos_parm_CCK, size);
6658 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_OFDM]);
6659 memcpy(active_one, priv->qos_data.def_qos_parm_OFDM, size);
6660
6661 if (qos_network_data == NULL) {
6662 if (type == IEEE_B) {
6663 IPW_DEBUG_QOS("QoS activate network mode %d\n", type);
6664 active_one = &def_parameters_CCK;
6665 } else
6666 active_one = &def_parameters_OFDM;
6667
6668 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6669 burst_duration = ipw_qos_get_burst_duration(priv);
6670 for (i = 0; i < QOS_QUEUE_NUM; i++)
6671 qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] =
6672 (u16) burst_duration;
6673 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6674 if (type == IEEE_B) {
6675 IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n",
6676 type);
6677 if (priv->qos_data.qos_enable == 0)
6678 active_one = &def_parameters_CCK;
6679 else
6680 active_one = priv->qos_data.def_qos_parm_CCK;
6681 } else {
6682 if (priv->qos_data.qos_enable == 0)
6683 active_one = &def_parameters_OFDM;
6684 else
6685 active_one = priv->qos_data.def_qos_parm_OFDM;
6686 }
6687 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6688 } else {
6689 unsigned long flags;
6690 int active;
6691
6692 spin_lock_irqsave(&priv->ieee->lock, flags);
6693 active_one = &(qos_network_data->parameters);
6694 qos_network_data->old_param_count =
6695 qos_network_data->param_count;
6696 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6697 active = qos_network_data->supported;
6698 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6699
6700 if (active == 0) {
6701 burst_duration = ipw_qos_get_burst_duration(priv);
6702 for (i = 0; i < QOS_QUEUE_NUM; i++)
6703 qos_parameters[QOS_PARAM_SET_ACTIVE].
6704 tx_op_limit[i] = (u16) burst_duration;
6705 }
6706 }
6707
6708 IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
6709 err = ipw_send_qos_params_command(priv,
6710 (struct ieee80211_qos_parameters *)
6711 &(qos_parameters[0]));
6712 if (err)
6713 IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");
6714
6715 return err;
6716}
6717
6718/*
6719* send IPW_CMD_WME_INFO to the firmware
6720*/
6721static int ipw_qos_set_info_element(struct ipw_priv *priv)
6722{
6723 int ret = 0;
6724 struct ieee80211_qos_information_element qos_info;
6725
6726 if (priv == NULL)
6727 return -1;
6728
6729 qos_info.elementID = QOS_ELEMENT_ID;
6730 qos_info.length = sizeof(struct ieee80211_qos_information_element) - 2;
6731
6732 qos_info.version = QOS_VERSION_1;
6733 qos_info.ac_info = 0;
6734
6735 memcpy(qos_info.qui, qos_oui, QOS_OUI_LEN);
6736 qos_info.qui_type = QOS_OUI_TYPE;
6737 qos_info.qui_subtype = QOS_OUI_INFO_SUB_TYPE;
6738
6739 ret = ipw_send_qos_info_command(priv, &qos_info);
6740 if (ret != 0) {
6741 IPW_DEBUG_QOS("QoS error calling ipw_send_qos_info_command\n");
6742 }
6743 return ret;
6744}
6745
6746/*
6747* Set the QoS parameter with the association request structure
6748*/
6749static int ipw_qos_association(struct ipw_priv *priv,
6750 struct ieee80211_network *network)
6751{
6752 int err = 0;
6753 struct ieee80211_qos_data *qos_data = NULL;
6754 struct ieee80211_qos_data ibss_data = {
6755 .supported = 1,
6756 .active = 1,
6757 };
6758
6759 switch (priv->ieee->iw_mode) {
6760 case IW_MODE_ADHOC:
6761 if (!(network->capability & WLAN_CAPABILITY_IBSS))
6762 BUG();
6763
6764 qos_data = &ibss_data;
6765 break;
6766
6767 case IW_MODE_INFRA:
6768 qos_data = &network->qos_data;
6769 break;
6770
6771 default:
6772 BUG();
6773 break;
6774 }
6775
6776 err = ipw_qos_activate(priv, qos_data);
6777 if (err) {
6778 priv->assoc_request.policy_support &= ~HC_QOS_SUPPORT_ASSOC;
6779 return err;
6780 }
6781
6782 if (priv->qos_data.qos_enable && qos_data->supported) {
6783 IPW_DEBUG_QOS("QoS will be enabled for this association\n");
6784 priv->assoc_request.policy_support |= HC_QOS_SUPPORT_ASSOC;
6785 return ipw_qos_set_info_element(priv);
6786 }
6787
6788 return 0;
6789}
6790
6791/*
6792* handling the beaconing responces. if we get different QoS setting
6793* of the network from the the associated setting adjust the QoS
6794* setting
6795*/
6796static int ipw_qos_association_resp(struct ipw_priv *priv,
6797 struct ieee80211_network *network)
6798{
6799 int ret = 0;
6800 unsigned long flags;
6801 u32 size = sizeof(struct ieee80211_qos_parameters);
6802 int set_qos_param = 0;
6803
6804 if ((priv == NULL) || (network == NULL) ||
6805 (priv->assoc_network == NULL))
6806 return ret;
6807
6808 if (!(priv->status & STATUS_ASSOCIATED))
6809 return ret;
6810
6811 if ((priv->ieee->iw_mode != IW_MODE_INFRA))
6812 return ret;
6813
6814 spin_lock_irqsave(&priv->ieee->lock, flags);
6815 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
6816 memcpy(&priv->assoc_network->qos_data, &network->qos_data,
6817 sizeof(struct ieee80211_qos_data));
6818 priv->assoc_network->qos_data.active = 1;
6819 if ((network->qos_data.old_param_count !=
6820 network->qos_data.param_count)) {
6821 set_qos_param = 1;
6822 network->qos_data.old_param_count =
6823 network->qos_data.param_count;
6824 }
6825
6826 } else {
6827 if ((network->mode == IEEE_B) || (priv->ieee->mode == IEEE_B))
6828 memcpy(&priv->assoc_network->qos_data.parameters,
6829 &def_parameters_CCK, size);
6830 else
6831 memcpy(&priv->assoc_network->qos_data.parameters,
6832 &def_parameters_OFDM, size);
6833 priv->assoc_network->qos_data.active = 0;
6834 priv->assoc_network->qos_data.supported = 0;
6835 set_qos_param = 1;
6836 }
6837
6838 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6839
6840 if (set_qos_param == 1)
6841 schedule_work(&priv->qos_activate);
6842
6843 return ret;
6844}
6845
6846static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)
6847{
6848 u32 ret = 0;
6849
6850 if ((priv == NULL))
6851 return 0;
6852
6853 if (!(priv->ieee->modulation & IEEE80211_OFDM_MODULATION))
6854 ret = priv->qos_data.burst_duration_CCK;
6855 else
6856 ret = priv->qos_data.burst_duration_OFDM;
6857
6858 return ret;
6859}
6860
6861/*
6862* Initialize the setting of QoS global
6863*/
6864static void ipw_qos_init(struct ipw_priv *priv, int enable,
6865 int burst_enable, u32 burst_duration_CCK,
6866 u32 burst_duration_OFDM)
6867{
6868 priv->qos_data.qos_enable = enable;
6869
6870 if (priv->qos_data.qos_enable) {
6871 priv->qos_data.def_qos_parm_CCK = &def_qos_parameters_CCK;
6872 priv->qos_data.def_qos_parm_OFDM = &def_qos_parameters_OFDM;
6873 IPW_DEBUG_QOS("QoS is enabled\n");
6874 } else {
6875 priv->qos_data.def_qos_parm_CCK = &def_parameters_CCK;
6876 priv->qos_data.def_qos_parm_OFDM = &def_parameters_OFDM;
6877 IPW_DEBUG_QOS("QoS is not enabled\n");
6878 }
6879
6880 priv->qos_data.burst_enable = burst_enable;
6881
6882 if (burst_enable) {
6883 priv->qos_data.burst_duration_CCK = burst_duration_CCK;
6884 priv->qos_data.burst_duration_OFDM = burst_duration_OFDM;
6885 } else {
6886 priv->qos_data.burst_duration_CCK = 0;
6887 priv->qos_data.burst_duration_OFDM = 0;
6888 }
6889}
6890
6891/*
6892* map the packet priority to the right TX Queue
6893*/
6894static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority)
6895{
6896 if (priority > 7 || !priv->qos_data.qos_enable)
6897 priority = 0;
6898
6899 return from_priority_to_tx_queue[priority] - 1;
6900}
6901
6902/*
6903* add QoS parameter to the TX command
6904*/
6905static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,
6906 u16 priority,
6907 struct tfd_data *tfd, u8 unicast)
6908{
6909 int ret = 0;
6910 int tx_queue_id = 0;
6911 struct ieee80211_qos_data *qos_data = NULL;
6912 int active, supported;
6913 unsigned long flags;
6914
6915 if (!(priv->status & STATUS_ASSOCIATED))
6916 return 0;
6917
6918 qos_data = &priv->assoc_network->qos_data;
6919
6920 spin_lock_irqsave(&priv->ieee->lock, flags);
6921
6922 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6923 if (unicast == 0)
6924 qos_data->active = 0;
6925 else
6926 qos_data->active = qos_data->supported;
6927 }
6928
6929 active = qos_data->active;
6930 supported = qos_data->supported;
6931
6932 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6933
6934 IPW_DEBUG_QOS("QoS %d network is QoS active %d supported %d "
6935 "unicast %d\n",
6936 priv->qos_data.qos_enable, active, supported, unicast);
6937 if (active && priv->qos_data.qos_enable) {
6938 ret = from_priority_to_tx_queue[priority];
6939 tx_queue_id = ret - 1;
6940 IPW_DEBUG_QOS("QoS packet priority is %d \n", priority);
6941 if (priority <= 7) {
6942 tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED;
6943 tfd->tfd.tfd_26.mchdr.qos_ctrl = priority;
6944 tfd->tfd.tfd_26.mchdr.frame_ctl |=
6945 IEEE80211_STYPE_QOS_DATA;
6946
6947 if (priv->qos_data.qos_no_ack_mask &
6948 (1UL << tx_queue_id)) {
6949 tfd->tx_flags &= ~DCT_FLAG_ACK_REQD;
6950 tfd->tfd.tfd_26.mchdr.qos_ctrl |=
6951 CTRL_QOS_NO_ACK;
6952 }
6953 }
6954 }
6955
6956 return ret;
6957}
6958
6959/*
6960* background support to run QoS activate functionality
6961*/
6962static void ipw_bg_qos_activate(void *data)
6963{
6964 struct ipw_priv *priv = data;
6965
6966 if (priv == NULL)
6967 return;
6968
6969 down(&priv->sem);
6970
6971 if (priv->status & STATUS_ASSOCIATED)
6972 ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
6973
6974 up(&priv->sem);
6975}
6976
6977static int ipw_handle_probe_response(struct net_device *dev,
6978 struct ieee80211_probe_response *resp,
6979 struct ieee80211_network *network)
6980{
6981 struct ipw_priv *priv = ieee80211_priv(dev);
6982 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
6983 (network == priv->assoc_network));
6984
6985 ipw_qos_handle_probe_response(priv, active_network, network);
6986
6987 return 0;
6988}
6989
6990static int ipw_handle_beacon(struct net_device *dev,
6991 struct ieee80211_beacon *resp,
6992 struct ieee80211_network *network)
6993{
6994 struct ipw_priv *priv = ieee80211_priv(dev);
6995 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
6996 (network == priv->assoc_network));
6997
6998 ipw_qos_handle_probe_response(priv, active_network, network);
6999
7000 return 0;
7001}
7002
7003static int ipw_handle_assoc_response(struct net_device *dev,
7004 struct ieee80211_assoc_response *resp,
7005 struct ieee80211_network *network)
7006{
7007 struct ipw_priv *priv = ieee80211_priv(dev);
7008 ipw_qos_association_resp(priv, network);
7009 return 0;
7010}
7011
7012static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
7013 *qos_param)
7014{
7015 struct host_cmd cmd = {
7016 .cmd = IPW_CMD_QOS_PARAMETERS,
7017 .len = (sizeof(struct ieee80211_qos_parameters) * 3)
7018 };
7019
7020 memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3);
7021 return ipw_send_cmd(priv, &cmd);
7022}
7023
7024static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
7025 *qos_param)
7026{
7027 struct host_cmd cmd = {
7028 .cmd = IPW_CMD_WME_INFO,
7029 .len = sizeof(*qos_param)
7030 };
7031
7032 memcpy(cmd.param, qos_param, sizeof(*qos_param));
7033 return ipw_send_cmd(priv, &cmd);
7034}
7035
7036#endif /* CONFIG_IPW_QOS */
7037
4612static int ipw_associate_network(struct ipw_priv *priv, 7038static int ipw_associate_network(struct ipw_priv *priv,
4613 struct ieee80211_network *network, 7039 struct ieee80211_network *network,
4614 struct ipw_supported_rates *rates, int roaming) 7040 struct ipw_supported_rates *rates, int roaming)
@@ -4616,7 +7042,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
4616 int err; 7042 int err;
4617 7043
4618 if (priv->config & CFG_FIXED_RATE) 7044 if (priv->config & CFG_FIXED_RATE)
4619 ipw_set_fixed_rate(priv, network); 7045 ipw_set_fixed_rate(priv, network->mode);
4620 7046
4621 if (!(priv->config & CFG_STATIC_ESSID)) { 7047 if (!(priv->config & CFG_STATIC_ESSID)) {
4622 priv->essid_len = min(network->ssid_len, 7048 priv->essid_len = min(network->ssid_len,
@@ -4631,14 +7057,22 @@ static int ipw_associate_network(struct ipw_priv *priv,
4631 if ((priv->capability & CAP_PRIVACY_ON) && 7057 if ((priv->capability & CAP_PRIVACY_ON) &&
4632 (priv->capability & CAP_SHARED_KEY)) { 7058 (priv->capability & CAP_SHARED_KEY)) {
4633 priv->assoc_request.auth_type = AUTH_SHARED_KEY; 7059 priv->assoc_request.auth_type = AUTH_SHARED_KEY;
4634 priv->assoc_request.auth_key = priv->sec.active_key; 7060 priv->assoc_request.auth_key = priv->ieee->sec.active_key;
7061
7062 if ((priv->capability & CAP_PRIVACY_ON) &&
7063 (priv->ieee->sec.level == SEC_LEVEL_1) &&
7064 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
7065 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
4635 } else { 7066 } else {
4636 priv->assoc_request.auth_type = AUTH_OPEN; 7067 priv->assoc_request.auth_type = AUTH_OPEN;
4637 priv->assoc_request.auth_key = 0; 7068 priv->assoc_request.auth_key = 0;
4638 } 7069 }
4639 7070
4640 if (priv->capability & CAP_PRIVACY_ON) 7071 if (priv->ieee->wpa_ie_len) {
4641 ipw_send_wep_keys(priv); 7072 priv->assoc_request.policy_support = 0x02; /* RSN active */
7073 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
7074 priv->ieee->wpa_ie_len);
7075 }
4642 7076
4643 /* 7077 /*
4644 * It is valid for our ieee device to support multiple modes, but 7078 * It is valid for our ieee device to support multiple modes, but
@@ -4652,20 +7086,41 @@ static int ipw_associate_network(struct ipw_priv *priv,
4652 else if (network->mode & priv->ieee->mode & IEEE_B) 7086 else if (network->mode & priv->ieee->mode & IEEE_B)
4653 priv->assoc_request.ieee_mode = IPW_B_MODE; 7087 priv->assoc_request.ieee_mode = IPW_B_MODE;
4654 7088
7089 priv->assoc_request.capability = network->capability;
7090 if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
7091 && !(priv->config & CFG_PREAMBLE_LONG)) {
7092 priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
7093 } else {
7094 priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;
7095
7096 /* Clear the short preamble if we won't be supporting it */
7097 priv->assoc_request.capability &=
7098 ~WLAN_CAPABILITY_SHORT_PREAMBLE;
7099 }
7100
7101 /* Clear capability bits that aren't used in Ad Hoc */
7102 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7103 priv->assoc_request.capability &=
7104 ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
7105
4655 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, " 7106 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
4656 "802.11%c [%d], enc=%s%s%s%c%c\n", 7107 "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
4657 roaming ? "Rea" : "A", 7108 roaming ? "Rea" : "A",
4658 escape_essid(priv->essid, priv->essid_len), 7109 escape_essid(priv->essid, priv->essid_len),
4659 network->channel, 7110 network->channel,
4660 ipw_modes[priv->assoc_request.ieee_mode], 7111 ipw_modes[priv->assoc_request.ieee_mode],
4661 rates->num_rates, 7112 rates->num_rates,
7113 (priv->assoc_request.preamble_length ==
7114 DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",
7115 network->capability &
7116 WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",
4662 priv->capability & CAP_PRIVACY_ON ? "on " : "off", 7117 priv->capability & CAP_PRIVACY_ON ? "on " : "off",
4663 priv->capability & CAP_PRIVACY_ON ? 7118 priv->capability & CAP_PRIVACY_ON ?
4664 (priv->capability & CAP_SHARED_KEY ? "(shared)" : 7119 (priv->capability & CAP_SHARED_KEY ? "(shared)" :
4665 "(open)") : "", 7120 "(open)") : "",
4666 priv->capability & CAP_PRIVACY_ON ? " key=" : "", 7121 priv->capability & CAP_PRIVACY_ON ? " key=" : "",
4667 priv->capability & CAP_PRIVACY_ON ? 7122 priv->capability & CAP_PRIVACY_ON ?
4668 '1' + priv->sec.active_key : '.', 7123 '1' + priv->ieee->sec.active_key : '.',
4669 priv->capability & CAP_PRIVACY_ON ? '.' : ' '); 7124 priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
4670 7125
4671 priv->assoc_request.beacon_interval = network->beacon_interval; 7126 priv->assoc_request.beacon_interval = network->beacon_interval;
@@ -4683,17 +7138,16 @@ static int ipw_associate_network(struct ipw_priv *priv,
4683 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0]; 7138 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0];
4684 } 7139 }
4685 7140
4686 memcpy(&priv->assoc_request.bssid, network->bssid, ETH_ALEN); 7141 memcpy(priv->assoc_request.bssid, network->bssid, ETH_ALEN);
4687 7142
4688 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 7143 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
4689 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN); 7144 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
4690 priv->assoc_request.atim_window = network->atim_window; 7145 priv->assoc_request.atim_window = network->atim_window;
4691 } else { 7146 } else {
4692 memcpy(&priv->assoc_request.dest, network->bssid, ETH_ALEN); 7147 memcpy(priv->assoc_request.dest, network->bssid, ETH_ALEN);
4693 priv->assoc_request.atim_window = 0; 7148 priv->assoc_request.atim_window = 0;
4694 } 7149 }
4695 7150
4696 priv->assoc_request.capability = network->capability;
4697 priv->assoc_request.listen_interval = network->listen_interval; 7151 priv->assoc_request.listen_interval = network->listen_interval;
4698 7152
4699 err = ipw_send_ssid(priv, priv->essid, priv->essid_len); 7153 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
@@ -4710,6 +7164,12 @@ static int ipw_associate_network(struct ipw_priv *priv,
4710 priv->sys_config.dot11g_auto_detection = 1; 7164 priv->sys_config.dot11g_auto_detection = 1;
4711 else 7165 else
4712 priv->sys_config.dot11g_auto_detection = 0; 7166 priv->sys_config.dot11g_auto_detection = 0;
7167
7168 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7169 priv->sys_config.answer_broadcast_ssid_probe = 1;
7170 else
7171 priv->sys_config.answer_broadcast_ssid_probe = 0;
7172
4713 err = ipw_send_system_config(priv, &priv->sys_config); 7173 err = ipw_send_system_config(priv, &priv->sys_config);
4714 if (err) { 7174 if (err) {
4715 IPW_DEBUG_HC("Attempt to send sys config command failed.\n"); 7175 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
@@ -4717,7 +7177,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
4717 } 7177 }
4718 7178
4719 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi); 7179 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
4720 err = ipw_set_sensitivity(priv, network->stats.rssi); 7180 err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);
4721 if (err) { 7181 if (err) {
4722 IPW_DEBUG_HC("Attempt to send associate command failed.\n"); 7182 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
4723 return err; 7183 return err;
@@ -4735,6 +7195,10 @@ static int ipw_associate_network(struct ipw_priv *priv,
4735 7195
4736 priv->assoc_network = network; 7196 priv->assoc_network = network;
4737 7197
7198#ifdef CONFIG_IPW_QOS
7199 ipw_qos_association(priv, network);
7200#endif
7201
4738 err = ipw_send_associate(priv, &priv->assoc_request); 7202 err = ipw_send_associate(priv, &priv->assoc_request);
4739 if (err) { 7203 if (err) {
4740 IPW_DEBUG_HC("Attempt to send associate command failed.\n"); 7204 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
@@ -4782,12 +7246,15 @@ static void ipw_roam(void *data)
4782 if (priv->status & STATUS_ASSOCIATED) { 7246 if (priv->status & STATUS_ASSOCIATED) {
4783 /* First pass through ROAM process -- look for a better 7247 /* First pass through ROAM process -- look for a better
4784 * network */ 7248 * network */
7249 unsigned long flags;
4785 u8 rssi = priv->assoc_network->stats.rssi; 7250 u8 rssi = priv->assoc_network->stats.rssi;
4786 priv->assoc_network->stats.rssi = -128; 7251 priv->assoc_network->stats.rssi = -128;
7252 spin_lock_irqsave(&priv->ieee->lock, flags);
4787 list_for_each_entry(network, &priv->ieee->network_list, list) { 7253 list_for_each_entry(network, &priv->ieee->network_list, list) {
4788 if (network != priv->assoc_network) 7254 if (network != priv->assoc_network)
4789 ipw_best_network(priv, &match, network, 1); 7255 ipw_best_network(priv, &match, network, 1);
4790 } 7256 }
7257 spin_unlock_irqrestore(&priv->ieee->lock, flags);
4791 priv->assoc_network->stats.rssi = rssi; 7258 priv->assoc_network->stats.rssi = rssi;
4792 7259
4793 if (match.network == priv->assoc_network) { 7260 if (match.network == priv->assoc_network) {
@@ -4810,7 +7277,15 @@ static void ipw_roam(void *data)
4810 priv->status &= ~STATUS_ROAMING; 7277 priv->status &= ~STATUS_ROAMING;
4811} 7278}
4812 7279
4813static void ipw_associate(void *data) 7280static void ipw_bg_roam(void *data)
7281{
7282 struct ipw_priv *priv = data;
7283 down(&priv->sem);
7284 ipw_roam(data);
7285 up(&priv->sem);
7286}
7287
7288static int ipw_associate(void *data)
4814{ 7289{
4815 struct ipw_priv *priv = data; 7290 struct ipw_priv *priv = data;
4816 7291
@@ -4820,14 +7295,41 @@ static void ipw_associate(void *data)
4820 }; 7295 };
4821 struct ipw_supported_rates *rates; 7296 struct ipw_supported_rates *rates;
4822 struct list_head *element; 7297 struct list_head *element;
7298 unsigned long flags;
7299
7300 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7301 IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");
7302 return 0;
7303 }
7304
7305 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
7306 IPW_DEBUG_ASSOC("Not attempting association (already in "
7307 "progress)\n");
7308 return 0;
7309 }
7310
7311 if (priv->status & STATUS_DISASSOCIATING) {
7312 IPW_DEBUG_ASSOC("Not attempting association (in "
7313 "disassociating)\n ");
7314 queue_work(priv->workqueue, &priv->associate);
7315 return 0;
7316 }
7317
7318 if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
7319 IPW_DEBUG_ASSOC("Not attempting association (scanning or not "
7320 "initialized)\n");
7321 return 0;
7322 }
4823 7323
4824 if (!(priv->config & CFG_ASSOCIATE) && 7324 if (!(priv->config & CFG_ASSOCIATE) &&
4825 !(priv->config & (CFG_STATIC_ESSID | 7325 !(priv->config & (CFG_STATIC_ESSID |
4826 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) { 7326 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
4827 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n"); 7327 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
4828 return; 7328 return 0;
4829 } 7329 }
4830 7330
7331 /* Protect our use of the network_list */
7332 spin_lock_irqsave(&priv->ieee->lock, flags);
4831 list_for_each_entry(network, &priv->ieee->network_list, list) 7333 list_for_each_entry(network, &priv->ieee->network_list, list)
4832 ipw_best_network(priv, &match, network, 0); 7334 ipw_best_network(priv, &match, network, 0);
4833 7335
@@ -4838,6 +7340,7 @@ static void ipw_associate(void *data)
4838 priv->ieee->iw_mode == IW_MODE_ADHOC && 7340 priv->ieee->iw_mode == IW_MODE_ADHOC &&
4839 priv->config & CFG_ADHOC_CREATE && 7341 priv->config & CFG_ADHOC_CREATE &&
4840 priv->config & CFG_STATIC_ESSID && 7342 priv->config & CFG_STATIC_ESSID &&
7343 priv->config & CFG_STATIC_CHANNEL &&
4841 !list_empty(&priv->ieee->network_free_list)) { 7344 !list_empty(&priv->ieee->network_free_list)) {
4842 element = priv->ieee->network_free_list.next; 7345 element = priv->ieee->network_free_list.next;
4843 network = list_entry(element, struct ieee80211_network, list); 7346 network = list_entry(element, struct ieee80211_network, list);
@@ -4846,25 +7349,83 @@ static void ipw_associate(void *data)
4846 list_del(element); 7349 list_del(element);
4847 list_add_tail(&network->list, &priv->ieee->network_list); 7350 list_add_tail(&network->list, &priv->ieee->network_list);
4848 } 7351 }
7352 spin_unlock_irqrestore(&priv->ieee->lock, flags);
4849 7353
4850 /* If we reached the end of the list, then we don't have any valid 7354 /* If we reached the end of the list, then we don't have any valid
4851 * matching APs */ 7355 * matching APs */
4852 if (!network) { 7356 if (!network) {
4853 ipw_debug_config(priv); 7357 ipw_debug_config(priv);
4854 7358
4855 queue_delayed_work(priv->workqueue, &priv->request_scan, 7359 if (!(priv->status & STATUS_SCANNING)) {
4856 SCAN_INTERVAL); 7360 if (!(priv->config & CFG_SPEED_SCAN))
7361 queue_delayed_work(priv->workqueue,
7362 &priv->request_scan,
7363 SCAN_INTERVAL);
7364 else
7365 queue_work(priv->workqueue,
7366 &priv->request_scan);
7367 }
4857 7368
4858 return; 7369 return 0;
4859 } 7370 }
4860 7371
4861 ipw_associate_network(priv, network, rates, 0); 7372 ipw_associate_network(priv, network, rates, 0);
7373
7374 return 1;
4862} 7375}
4863 7376
4864static inline void ipw_handle_data_packet(struct ipw_priv *priv, 7377static void ipw_bg_associate(void *data)
4865 struct ipw_rx_mem_buffer *rxb,
4866 struct ieee80211_rx_stats *stats)
4867{ 7378{
7379 struct ipw_priv *priv = data;
7380 down(&priv->sem);
7381 ipw_associate(data);
7382 up(&priv->sem);
7383}
7384
7385static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
7386 struct sk_buff *skb)
7387{
7388 struct ieee80211_hdr *hdr;
7389 u16 fc;
7390
7391 hdr = (struct ieee80211_hdr *)skb->data;
7392 fc = le16_to_cpu(hdr->frame_ctl);
7393 if (!(fc & IEEE80211_FCTL_PROTECTED))
7394 return;
7395
7396 fc &= ~IEEE80211_FCTL_PROTECTED;
7397 hdr->frame_ctl = cpu_to_le16(fc);
7398 switch (priv->ieee->sec.level) {
7399 case SEC_LEVEL_3:
7400 /* Remove CCMP HDR */
7401 memmove(skb->data + IEEE80211_3ADDR_LEN,
7402 skb->data + IEEE80211_3ADDR_LEN + 8,
7403 skb->len - IEEE80211_3ADDR_LEN - 8);
7404 skb_trim(skb, skb->len - 16); /* CCMP_HDR_LEN + CCMP_MIC_LEN */
7405 break;
7406 case SEC_LEVEL_2:
7407 break;
7408 case SEC_LEVEL_1:
7409 /* Remove IV */
7410 memmove(skb->data + IEEE80211_3ADDR_LEN,
7411 skb->data + IEEE80211_3ADDR_LEN + 4,
7412 skb->len - IEEE80211_3ADDR_LEN - 4);
7413 skb_trim(skb, skb->len - 8); /* IV + ICV */
7414 break;
7415 case SEC_LEVEL_0:
7416 break;
7417 default:
7418 printk(KERN_ERR "Unknow security level %d\n",
7419 priv->ieee->sec.level);
7420 break;
7421 }
7422}
7423
7424static void ipw_handle_data_packet(struct ipw_priv *priv,
7425 struct ipw_rx_mem_buffer *rxb,
7426 struct ieee80211_rx_stats *stats)
7427{
7428 struct ieee80211_hdr_4addr *hdr;
4868 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data; 7429 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
4869 7430
4870 /* We received data from the HW, so stop the watchdog */ 7431 /* We received data from the HW, so stop the watchdog */
@@ -4872,7 +7433,7 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
4872 7433
4873 /* We only process data packets if the 7434 /* We only process data packets if the
4874 * interface is open */ 7435 * interface is open */
4875 if (unlikely((pkt->u.frame.length + IPW_RX_FRAME_SIZE) > 7436 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
4876 skb_tailroom(rxb->skb))) { 7437 skb_tailroom(rxb->skb))) {
4877 priv->ieee->stats.rx_errors++; 7438 priv->ieee->stats.rx_errors++;
4878 priv->wstats.discard.misc++; 7439 priv->wstats.discard.misc++;
@@ -4889,14 +7450,351 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
4889 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data)); 7450 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
4890 7451
4891 /* Set the size of the skb to the size of the frame */ 7452 /* Set the size of the skb to the size of the frame */
4892 skb_put(rxb->skb, pkt->u.frame.length); 7453 skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
4893 7454
4894 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len); 7455 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
4895 7456
7457 /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
7458 hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
7459 if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
7460 ((is_multicast_ether_addr(hdr->addr1) ||
7461 is_broadcast_ether_addr(hdr->addr1)) ?
7462 !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
7463 ipw_rebuild_decrypted_skb(priv, rxb->skb);
7464
4896 if (!ieee80211_rx(priv->ieee, rxb->skb, stats)) 7465 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
4897 priv->ieee->stats.rx_errors++; 7466 priv->ieee->stats.rx_errors++;
4898 else /* ieee80211_rx succeeded, so it now owns the SKB */ 7467 else { /* ieee80211_rx succeeded, so it now owns the SKB */
4899 rxb->skb = NULL; 7468 rxb->skb = NULL;
7469 __ipw_led_activity_on(priv);
7470 }
7471}
7472
7473#ifdef CONFIG_IEEE80211_RADIOTAP
7474static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7475 struct ipw_rx_mem_buffer *rxb,
7476 struct ieee80211_rx_stats *stats)
7477{
7478 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7479 struct ipw_rx_frame *frame = &pkt->u.frame;
7480
7481 /* initial pull of some data */
7482 u16 received_channel = frame->received_channel;
7483 u8 antennaAndPhy = frame->antennaAndPhy;
7484 s8 antsignal = frame->rssi_dbm - IPW_RSSI_TO_DBM; /* call it signed anyhow */
7485 u16 pktrate = frame->rate;
7486
7487 /* Magic struct that slots into the radiotap header -- no reason
7488 * to build this manually element by element, we can write it much
7489 * more efficiently than we can parse it. ORDER MATTERS HERE */
7490 struct ipw_rt_hdr {
7491 struct ieee80211_radiotap_header rt_hdr;
7492 u8 rt_flags; /* radiotap packet flags */
7493 u8 rt_rate; /* rate in 500kb/s */
7494 u16 rt_channel; /* channel in mhz */
7495 u16 rt_chbitmask; /* channel bitfield */
7496 s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
7497 u8 rt_antenna; /* antenna number */
7498 } *ipw_rt;
7499
7500 short len = le16_to_cpu(pkt->u.frame.length);
7501
7502 /* We received data from the HW, so stop the watchdog */
7503 priv->net_dev->trans_start = jiffies;
7504
7505 /* We only process data packets if the
7506 * interface is open */
7507 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
7508 skb_tailroom(rxb->skb))) {
7509 priv->ieee->stats.rx_errors++;
7510 priv->wstats.discard.misc++;
7511 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7512 return;
7513 } else if (unlikely(!netif_running(priv->net_dev))) {
7514 priv->ieee->stats.rx_dropped++;
7515 priv->wstats.discard.misc++;
7516 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7517 return;
7518 }
7519
7520 /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
7521 * that now */
7522 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
7523 /* FIXME: Should alloc bigger skb instead */
7524 priv->ieee->stats.rx_dropped++;
7525 priv->wstats.discard.misc++;
7526 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
7527 return;
7528 }
7529
7530 /* copy the frame itself */
7531 memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr),
7532 rxb->skb->data + IPW_RX_FRAME_SIZE, len);
7533
7534 /* Zero the radiotap static buffer ... We only need to zero the bytes NOT
7535 * part of our real header, saves a little time.
7536 *
7537 * No longer necessary since we fill in all our data. Purge before merging
7538 * patch officially.
7539 * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
7540 * IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
7541 */
7542
7543 ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data;
7544
7545 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
7546 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
7547 ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total header+data */
7548
7549 /* Big bitfield of all the fields we provide in radiotap */
7550 ipw_rt->rt_hdr.it_present =
7551 ((1 << IEEE80211_RADIOTAP_FLAGS) |
7552 (1 << IEEE80211_RADIOTAP_RATE) |
7553 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7554 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
7555 (1 << IEEE80211_RADIOTAP_ANTENNA));
7556
7557 /* Zero the flags, we'll add to them as we go */
7558 ipw_rt->rt_flags = 0;
7559
7560 /* Convert signal to DBM */
7561 ipw_rt->rt_dbmsignal = antsignal;
7562
7563 /* Convert the channel data and set the flags */
7564 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
7565 if (received_channel > 14) { /* 802.11a */
7566 ipw_rt->rt_chbitmask =
7567 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
7568 } else if (antennaAndPhy & 32) { /* 802.11b */
7569 ipw_rt->rt_chbitmask =
7570 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
7571 } else { /* 802.11g */
7572 ipw_rt->rt_chbitmask =
7573 (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
7574 }
7575
7576 /* set the rate in multiples of 500k/s */
7577 switch (pktrate) {
7578 case IPW_TX_RATE_1MB:
7579 ipw_rt->rt_rate = 2;
7580 break;
7581 case IPW_TX_RATE_2MB:
7582 ipw_rt->rt_rate = 4;
7583 break;
7584 case IPW_TX_RATE_5MB:
7585 ipw_rt->rt_rate = 10;
7586 break;
7587 case IPW_TX_RATE_6MB:
7588 ipw_rt->rt_rate = 12;
7589 break;
7590 case IPW_TX_RATE_9MB:
7591 ipw_rt->rt_rate = 18;
7592 break;
7593 case IPW_TX_RATE_11MB:
7594 ipw_rt->rt_rate = 22;
7595 break;
7596 case IPW_TX_RATE_12MB:
7597 ipw_rt->rt_rate = 24;
7598 break;
7599 case IPW_TX_RATE_18MB:
7600 ipw_rt->rt_rate = 36;
7601 break;
7602 case IPW_TX_RATE_24MB:
7603 ipw_rt->rt_rate = 48;
7604 break;
7605 case IPW_TX_RATE_36MB:
7606 ipw_rt->rt_rate = 72;
7607 break;
7608 case IPW_TX_RATE_48MB:
7609 ipw_rt->rt_rate = 96;
7610 break;
7611 case IPW_TX_RATE_54MB:
7612 ipw_rt->rt_rate = 108;
7613 break;
7614 default:
7615 ipw_rt->rt_rate = 0;
7616 break;
7617 }
7618
7619 /* antenna number */
7620 ipw_rt->rt_antenna = (antennaAndPhy & 3); /* Is this right? */
7621
7622 /* set the preamble flag if we have it */
7623 if ((antennaAndPhy & 64))
7624 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7625
7626 /* Set the size of the skb to the size of the frame */
7627 skb_put(rxb->skb, len + sizeof(struct ipw_rt_hdr));
7628
7629 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7630
7631 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
7632 priv->ieee->stats.rx_errors++;
7633 else { /* ieee80211_rx succeeded, so it now owns the SKB */
7634 rxb->skb = NULL;
7635 /* no LED during capture */
7636 }
7637}
7638#endif
7639
7640static inline int is_network_packet(struct ipw_priv *priv,
7641 struct ieee80211_hdr_4addr *header)
7642{
7643 /* Filter incoming packets to determine if they are targetted toward
7644 * this network, discarding packets coming from ourselves */
7645 switch (priv->ieee->iw_mode) {
7646 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
7647 /* packets from our adapter are dropped (echo) */
7648 if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
7649 return 0;
7650
7651 /* {broad,multi}cast packets to our BSSID go through */
7652 if (is_multicast_ether_addr(header->addr1) ||
7653 is_broadcast_ether_addr(header->addr1))
7654 return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
7655
7656 /* packets to our adapter go through */
7657 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7658 ETH_ALEN);
7659
7660 case IW_MODE_INFRA: /* Header: Dest. | BSSID | Source */
7661 /* packets from our adapter are dropped (echo) */
7662 if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
7663 return 0;
7664
7665 /* {broad,multi}cast packets to our BSS go through */
7666 if (is_multicast_ether_addr(header->addr1) ||
7667 is_broadcast_ether_addr(header->addr1))
7668 return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
7669
7670 /* packets to our adapter go through */
7671 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7672 ETH_ALEN);
7673 }
7674
7675 return 1;
7676}
7677
7678#define IPW_PACKET_RETRY_TIME HZ
7679
7680static inline int is_duplicate_packet(struct ipw_priv *priv,
7681 struct ieee80211_hdr_4addr *header)
7682{
7683 u16 sc = le16_to_cpu(header->seq_ctl);
7684 u16 seq = WLAN_GET_SEQ_SEQ(sc);
7685 u16 frag = WLAN_GET_SEQ_FRAG(sc);
7686 u16 *last_seq, *last_frag;
7687 unsigned long *last_time;
7688
7689 switch (priv->ieee->iw_mode) {
7690 case IW_MODE_ADHOC:
7691 {
7692 struct list_head *p;
7693 struct ipw_ibss_seq *entry = NULL;
7694 u8 *mac = header->addr2;
7695 int index = mac[5] % IPW_IBSS_MAC_HASH_SIZE;
7696
7697 __list_for_each(p, &priv->ibss_mac_hash[index]) {
7698 entry =
7699 list_entry(p, struct ipw_ibss_seq, list);
7700 if (!memcmp(entry->mac, mac, ETH_ALEN))
7701 break;
7702 }
7703 if (p == &priv->ibss_mac_hash[index]) {
7704 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
7705 if (!entry) {
7706 IPW_ERROR
7707 ("Cannot malloc new mac entry\n");
7708 return 0;
7709 }
7710 memcpy(entry->mac, mac, ETH_ALEN);
7711 entry->seq_num = seq;
7712 entry->frag_num = frag;
7713 entry->packet_time = jiffies;
7714 list_add(&entry->list,
7715 &priv->ibss_mac_hash[index]);
7716 return 0;
7717 }
7718 last_seq = &entry->seq_num;
7719 last_frag = &entry->frag_num;
7720 last_time = &entry->packet_time;
7721 break;
7722 }
7723 case IW_MODE_INFRA:
7724 last_seq = &priv->last_seq_num;
7725 last_frag = &priv->last_frag_num;
7726 last_time = &priv->last_packet_time;
7727 break;
7728 default:
7729 return 0;
7730 }
7731 if ((*last_seq == seq) &&
7732 time_after(*last_time + IPW_PACKET_RETRY_TIME, jiffies)) {
7733 if (*last_frag == frag)
7734 goto drop;
7735 if (*last_frag + 1 != frag)
7736 /* out-of-order fragment */
7737 goto drop;
7738 } else
7739 *last_seq = seq;
7740
7741 *last_frag = frag;
7742 *last_time = jiffies;
7743 return 0;
7744
7745 drop:
7746 /* Comment this line now since we observed the card receives
7747 * duplicate packets but the FCTL_RETRY bit is not set in the
7748 * IBSS mode with fragmentation enabled.
7749 BUG_ON(!(le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_RETRY)); */
7750 return 1;
7751}
7752
7753static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
7754 struct ipw_rx_mem_buffer *rxb,
7755 struct ieee80211_rx_stats *stats)
7756{
7757 struct sk_buff *skb = rxb->skb;
7758 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)skb->data;
7759 struct ieee80211_hdr_4addr *header = (struct ieee80211_hdr_4addr *)
7760 (skb->data + IPW_RX_FRAME_SIZE);
7761
7762 ieee80211_rx_mgt(priv->ieee, header, stats);
7763
7764 if (priv->ieee->iw_mode == IW_MODE_ADHOC &&
7765 ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7766 IEEE80211_STYPE_PROBE_RESP) ||
7767 (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7768 IEEE80211_STYPE_BEACON))) {
7769 if (!memcmp(header->addr3, priv->bssid, ETH_ALEN))
7770 ipw_add_station(priv, header->addr2);
7771 }
7772
7773 if (priv->config & CFG_NET_STATS) {
7774 IPW_DEBUG_HC("sending stat packet\n");
7775
7776 /* Set the size of the skb to the size of the full
7777 * ipw header and 802.11 frame */
7778 skb_put(skb, le16_to_cpu(pkt->u.frame.length) +
7779 IPW_RX_FRAME_SIZE);
7780
7781 /* Advance past the ipw packet header to the 802.11 frame */
7782 skb_pull(skb, IPW_RX_FRAME_SIZE);
7783
7784 /* Push the ieee80211_rx_stats before the 802.11 frame */
7785 memcpy(skb_push(skb, sizeof(*stats)), stats, sizeof(*stats));
7786
7787 skb->dev = priv->ieee->dev;
7788
7789 /* Point raw at the ieee80211_stats */
7790 skb->mac.raw = skb->data;
7791
7792 skb->pkt_type = PACKET_OTHERHOST;
7793 skb->protocol = __constant_htons(ETH_P_80211_STATS);
7794 memset(skb->cb, 0, sizeof(rxb->skb->cb));
7795 netif_rx(skb);
7796 rxb->skb = NULL;
7797 }
4900} 7798}
4901 7799
4902/* 7800/*
@@ -4912,8 +7810,8 @@ static void ipw_rx(struct ipw_priv *priv)
4912 u32 r, w, i; 7810 u32 r, w, i;
4913 u8 network_packet; 7811 u8 network_packet;
4914 7812
4915 r = ipw_read32(priv, CX2_RX_READ_INDEX); 7813 r = ipw_read32(priv, IPW_RX_READ_INDEX);
4916 w = ipw_read32(priv, CX2_RX_WRITE_INDEX); 7814 w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
4917 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE; 7815 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
4918 7816
4919 while (i != r) { 7817 while (i != r) {
@@ -4927,7 +7825,7 @@ static void ipw_rx(struct ipw_priv *priv)
4927 priv->rxq->queue[i] = NULL; 7825 priv->rxq->queue[i] = NULL;
4928 7826
4929 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, 7827 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
4930 CX2_RX_BUF_SIZE, 7828 IPW_RX_BUF_SIZE,
4931 PCI_DMA_FROMDEVICE); 7829 PCI_DMA_FROMDEVICE);
4932 7830
4933 pkt = (struct ipw_rx_packet *)rxb->skb->data; 7831 pkt = (struct ipw_rx_packet *)rxb->skb->data;
@@ -4938,9 +7836,13 @@ static void ipw_rx(struct ipw_priv *priv)
4938 switch (pkt->header.message_type) { 7836 switch (pkt->header.message_type) {
4939 case RX_FRAME_TYPE: /* 802.11 frame */ { 7837 case RX_FRAME_TYPE: /* 802.11 frame */ {
4940 struct ieee80211_rx_stats stats = { 7838 struct ieee80211_rx_stats stats = {
4941 .rssi = pkt->u.frame.rssi_dbm - 7839 .rssi =
7840 le16_to_cpu(pkt->u.frame.rssi_dbm) -
4942 IPW_RSSI_TO_DBM, 7841 IPW_RSSI_TO_DBM,
4943 .signal = pkt->u.frame.signal, 7842 .signal =
7843 le16_to_cpu(pkt->u.frame.signal),
7844 .noise =
7845 le16_to_cpu(pkt->u.frame.noise),
4944 .rate = pkt->u.frame.rate, 7846 .rate = pkt->u.frame.rate,
4945 .mac_time = jiffies, 7847 .mac_time = jiffies,
4946 .received_channel = 7848 .received_channel =
@@ -4950,22 +7852,30 @@ static void ipw_rx(struct ipw_priv *priv)
4950 control & (1 << 0)) ? 7852 control & (1 << 0)) ?
4951 IEEE80211_24GHZ_BAND : 7853 IEEE80211_24GHZ_BAND :
4952 IEEE80211_52GHZ_BAND, 7854 IEEE80211_52GHZ_BAND,
4953 .len = pkt->u.frame.length, 7855 .len = le16_to_cpu(pkt->u.frame.length),
4954 }; 7856 };
4955 7857
4956 if (stats.rssi != 0) 7858 if (stats.rssi != 0)
4957 stats.mask |= IEEE80211_STATMASK_RSSI; 7859 stats.mask |= IEEE80211_STATMASK_RSSI;
4958 if (stats.signal != 0) 7860 if (stats.signal != 0)
4959 stats.mask |= IEEE80211_STATMASK_SIGNAL; 7861 stats.mask |= IEEE80211_STATMASK_SIGNAL;
7862 if (stats.noise != 0)
7863 stats.mask |= IEEE80211_STATMASK_NOISE;
4960 if (stats.rate != 0) 7864 if (stats.rate != 0)
4961 stats.mask |= IEEE80211_STATMASK_RATE; 7865 stats.mask |= IEEE80211_STATMASK_RATE;
4962 7866
4963 priv->rx_packets++; 7867 priv->rx_packets++;
4964 7868
4965#ifdef CONFIG_IPW_PROMISC 7869#ifdef CONFIG_IPW2200_MONITOR
4966 if (priv->ieee->iw_mode == IW_MODE_MONITOR) { 7870 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7871#ifdef CONFIG_IEEE80211_RADIOTAP
7872 ipw_handle_data_packet_monitor(priv,
7873 rxb,
7874 &stats);
7875#else
4967 ipw_handle_data_packet(priv, rxb, 7876 ipw_handle_data_packet(priv, rxb,
4968 &stats); 7877 &stats);
7878#endif
4969 break; 7879 break;
4970 } 7880 }
4971#endif 7881#endif
@@ -4979,35 +7889,9 @@ static void ipw_rx(struct ipw_priv *priv)
4979 * correctly -- we should probably use the 7889 * correctly -- we should probably use the
4980 * frame control of the packet and disregard 7890 * frame control of the packet and disregard
4981 * the current iw_mode */ 7891 * the current iw_mode */
4982 switch (priv->ieee->iw_mode) {
4983 case IW_MODE_ADHOC:
4984 network_packet =
4985 !memcmp(header->addr1,
4986 priv->net_dev->dev_addr,
4987 ETH_ALEN) ||
4988 !memcmp(header->addr3,
4989 priv->bssid, ETH_ALEN) ||
4990 is_broadcast_ether_addr(header->
4991 addr1)
4992 || is_multicast_ether_addr(header->
4993 addr1);
4994 break;
4995
4996 case IW_MODE_INFRA:
4997 default:
4998 network_packet =
4999 !memcmp(header->addr3,
5000 priv->bssid, ETH_ALEN) ||
5001 !memcmp(header->addr1,
5002 priv->net_dev->dev_addr,
5003 ETH_ALEN) ||
5004 is_broadcast_ether_addr(header->
5005 addr1)
5006 || is_multicast_ether_addr(header->
5007 addr1);
5008 break;
5009 }
5010 7892
7893 network_packet =
7894 is_network_packet(priv, header);
5011 if (network_packet && priv->assoc_network) { 7895 if (network_packet && priv->assoc_network) {
5012 priv->assoc_network->stats.rssi = 7896 priv->assoc_network->stats.rssi =
5013 stats.rssi; 7897 stats.rssi;
@@ -5017,9 +7901,10 @@ static void ipw_rx(struct ipw_priv *priv)
5017 } 7901 }
5018 7902
5019 IPW_DEBUG_RX("Frame: len=%u\n", 7903 IPW_DEBUG_RX("Frame: len=%u\n",
5020 pkt->u.frame.length); 7904 le16_to_cpu(pkt->u.frame.length));
5021 7905
5022 if (pkt->u.frame.length < frame_hdr_len(header)) { 7906 if (le16_to_cpu(pkt->u.frame.length) <
7907 frame_hdr_len(header)) {
5023 IPW_DEBUG_DROP 7908 IPW_DEBUG_DROP
5024 ("Received packet is too small. " 7909 ("Received packet is too small. "
5025 "Dropping.\n"); 7910 "Dropping.\n");
@@ -5028,34 +7913,22 @@ static void ipw_rx(struct ipw_priv *priv)
5028 break; 7913 break;
5029 } 7914 }
5030 7915
5031 switch (WLAN_FC_GET_TYPE(header->frame_ctl)) { 7916 switch (WLAN_FC_GET_TYPE
7917 (le16_to_cpu(header->frame_ctl))) {
7918
5032 case IEEE80211_FTYPE_MGMT: 7919 case IEEE80211_FTYPE_MGMT:
5033 ieee80211_rx_mgt(priv->ieee, header, 7920 ipw_handle_mgmt_packet(priv, rxb,
5034 &stats); 7921 &stats);
5035 if (priv->ieee->iw_mode == IW_MODE_ADHOC
5036 &&
5037 ((WLAN_FC_GET_STYPE
5038 (header->frame_ctl) ==
5039 IEEE80211_STYPE_PROBE_RESP)
5040 ||
5041 (WLAN_FC_GET_STYPE
5042 (header->frame_ctl) ==
5043 IEEE80211_STYPE_BEACON))
5044 && !memcmp(header->addr3,
5045 priv->bssid, ETH_ALEN))
5046 ipw_add_station(priv,
5047 header->addr2);
5048 break; 7922 break;
5049 7923
5050 case IEEE80211_FTYPE_CTL: 7924 case IEEE80211_FTYPE_CTL:
5051 break; 7925 break;
5052 7926
5053 case IEEE80211_FTYPE_DATA: 7927 case IEEE80211_FTYPE_DATA:
5054 if (network_packet) 7928 if (unlikely(!network_packet ||
5055 ipw_handle_data_packet(priv, 7929 is_duplicate_packet(priv,
5056 rxb, 7930 header)))
5057 &stats); 7931 {
5058 else
5059 IPW_DEBUG_DROP("Dropping: " 7932 IPW_DEBUG_DROP("Dropping: "
5060 MAC_FMT ", " 7933 MAC_FMT ", "
5061 MAC_FMT ", " 7934 MAC_FMT ", "
@@ -5066,6 +7939,12 @@ static void ipw_rx(struct ipw_priv *priv)
5066 addr2), 7939 addr2),
5067 MAC_ARG(header-> 7940 MAC_ARG(header->
5068 addr3)); 7941 addr3));
7942 break;
7943 }
7944
7945 ipw_handle_data_packet(priv, rxb,
7946 &stats);
7947
5069 break; 7948 break;
5070 } 7949 }
5071 break; 7950 break;
@@ -5096,7 +7975,7 @@ static void ipw_rx(struct ipw_priv *priv)
5096 } 7975 }
5097 7976
5098 pci_unmap_single(priv->pci_dev, rxb->dma_addr, 7977 pci_unmap_single(priv->pci_dev, rxb->dma_addr,
5099 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 7978 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
5100 list_add_tail(&rxb->list, &priv->rxq->rx_used); 7979 list_add_tail(&rxb->list, &priv->rxq->rx_used);
5101 7980
5102 i = (i + 1) % RX_QUEUE_SIZE; 7981 i = (i + 1) % RX_QUEUE_SIZE;
@@ -5108,128 +7987,129 @@ static void ipw_rx(struct ipw_priv *priv)
5108 ipw_rx_queue_restock(priv); 7987 ipw_rx_queue_restock(priv);
5109} 7988}
5110 7989
5111static void ipw_abort_scan(struct ipw_priv *priv) 7990#define DEFAULT_RTS_THRESHOLD 2304U
7991#define MIN_RTS_THRESHOLD 1U
7992#define MAX_RTS_THRESHOLD 2304U
7993#define DEFAULT_BEACON_INTERVAL 100U
7994#define DEFAULT_SHORT_RETRY_LIMIT 7U
7995#define DEFAULT_LONG_RETRY_LIMIT 4U
7996
7997static int ipw_sw_reset(struct ipw_priv *priv, int init)
5112{ 7998{
5113 int err; 7999 int band, modulation;
8000 int old_mode = priv->ieee->iw_mode;
5114 8001
5115 if (priv->status & STATUS_SCAN_ABORTING) { 8002 /* Initialize module parameter values here */
5116 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n"); 8003 priv->config = 0;
5117 return;
5118 }
5119 priv->status |= STATUS_SCAN_ABORTING;
5120 8004
5121 err = ipw_send_scan_abort(priv); 8005 /* We default to disabling the LED code as right now it causes
5122 if (err) 8006 * too many systems to lock up... */
5123 IPW_DEBUG_HC("Request to abort scan failed.\n"); 8007 if (!led)
5124} 8008 priv->config |= CFG_NO_LED;
5125 8009
5126static int ipw_request_scan(struct ipw_priv *priv) 8010 if (associate)
5127{ 8011 priv->config |= CFG_ASSOCIATE;
5128 struct ipw_scan_request_ext scan; 8012 else
5129 int channel_index = 0; 8013 IPW_DEBUG_INFO("Auto associate disabled.\n");
5130 int i, err, scan_type;
5131 8014
5132 if (priv->status & STATUS_EXIT_PENDING) { 8015 if (auto_create)
5133 IPW_DEBUG_SCAN("Aborting scan due to device shutdown\n"); 8016 priv->config |= CFG_ADHOC_CREATE;
5134 priv->status |= STATUS_SCAN_PENDING; 8017 else
5135 return 0; 8018 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
5136 }
5137 8019
5138 if (priv->status & STATUS_SCANNING) { 8020 if (disable) {
5139 IPW_DEBUG_HC("Concurrent scan requested. Aborting first.\n"); 8021 priv->status |= STATUS_RF_KILL_SW;
5140 priv->status |= STATUS_SCAN_PENDING; 8022 IPW_DEBUG_INFO("Radio disabled.\n");
5141 ipw_abort_scan(priv);
5142 return 0;
5143 } 8023 }
5144 8024
5145 if (priv->status & STATUS_SCAN_ABORTING) { 8025 if (channel != 0) {
5146 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n"); 8026 priv->config |= CFG_STATIC_CHANNEL;
5147 priv->status |= STATUS_SCAN_PENDING; 8027 priv->channel = channel;
5148 return 0; 8028 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
8029 /* TODO: Validate that provided channel is in range */
5149 } 8030 }
8031#ifdef CONFIG_IPW_QOS
8032 ipw_qos_init(priv, qos_enable, qos_burst_enable,
8033 burst_duration_CCK, burst_duration_OFDM);
8034#endif /* CONFIG_IPW_QOS */
5150 8035
5151 if (priv->status & STATUS_RF_KILL_MASK) { 8036 switch (mode) {
5152 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n"); 8037 case 1:
5153 priv->status |= STATUS_SCAN_PENDING; 8038 priv->ieee->iw_mode = IW_MODE_ADHOC;
5154 return 0; 8039 priv->net_dev->type = ARPHRD_ETHER;
8040
8041 break;
8042#ifdef CONFIG_IPW2200_MONITOR
8043 case 2:
8044 priv->ieee->iw_mode = IW_MODE_MONITOR;
8045#ifdef CONFIG_IEEE80211_RADIOTAP
8046 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8047#else
8048 priv->net_dev->type = ARPHRD_IEEE80211;
8049#endif
8050 break;
8051#endif
8052 default:
8053 case 0:
8054 priv->net_dev->type = ARPHRD_ETHER;
8055 priv->ieee->iw_mode = IW_MODE_INFRA;
8056 break;
5155 } 8057 }
5156 8058
5157 memset(&scan, 0, sizeof(scan)); 8059 if (hwcrypto) {
8060 priv->ieee->host_encrypt = 0;
8061 priv->ieee->host_encrypt_msdu = 0;
8062 priv->ieee->host_decrypt = 0;
8063 priv->ieee->host_mc_decrypt = 0;
8064 }
8065 IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
5158 8066
5159 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 20; 8067 /* IPW2200/2915 is abled to do hardware fragmentation. */
5160 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = 20; 8068 priv->ieee->host_open_frag = 0;
5161 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 20;
5162
5163 scan.full_scan_index = ieee80211_get_scans(priv->ieee);
5164 /* If we are roaming, then make this a directed scan for the current
5165 * network. Otherwise, ensure that every other scan is a fast
5166 * channel hop scan */
5167 if ((priv->status & STATUS_ROAMING)
5168 || (!(priv->status & STATUS_ASSOCIATED)
5169 && (priv->config & CFG_STATIC_ESSID)
5170 && (scan.full_scan_index % 2))) {
5171 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
5172 if (err) {
5173 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
5174 return err;
5175 }
5176 8069
5177 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN; 8070 if ((priv->pci_dev->device == 0x4223) ||
8071 (priv->pci_dev->device == 0x4224)) {
8072 if (init)
8073 printk(KERN_INFO DRV_NAME
8074 ": Detected Intel PRO/Wireless 2915ABG Network "
8075 "Connection\n");
8076 priv->ieee->abg_true = 1;
8077 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
8078 modulation = IEEE80211_OFDM_MODULATION |
8079 IEEE80211_CCK_MODULATION;
8080 priv->adapter = IPW_2915ABG;
8081 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
5178 } else { 8082 } else {
5179 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN; 8083 if (init)
5180 } 8084 printk(KERN_INFO DRV_NAME
5181 8085 ": Detected Intel PRO/Wireless 2200BG Network "
5182 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { 8086 "Connection\n");
5183 int start = channel_index;
5184 for (i = 0; i < MAX_A_CHANNELS; i++) {
5185 if (band_a_active_channel[i] == 0)
5186 break;
5187 if ((priv->status & STATUS_ASSOCIATED) &&
5188 band_a_active_channel[i] == priv->channel)
5189 continue;
5190 channel_index++;
5191 scan.channels_list[channel_index] =
5192 band_a_active_channel[i];
5193 ipw_set_scan_type(&scan, channel_index, scan_type);
5194 }
5195 8087
5196 if (start != channel_index) { 8088 priv->ieee->abg_true = 0;
5197 scan.channels_list[start] = (u8) (IPW_A_MODE << 6) | 8089 band = IEEE80211_24GHZ_BAND;
5198 (channel_index - start); 8090 modulation = IEEE80211_OFDM_MODULATION |
5199 channel_index++; 8091 IEEE80211_CCK_MODULATION;
5200 } 8092 priv->adapter = IPW_2200BG;
8093 priv->ieee->mode = IEEE_G | IEEE_B;
5201 } 8094 }
5202 8095
5203 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) { 8096 priv->ieee->freq_band = band;
5204 int start = channel_index; 8097 priv->ieee->modulation = modulation;
5205 for (i = 0; i < MAX_B_CHANNELS; i++) {
5206 if (band_b_active_channel[i] == 0)
5207 break;
5208 if ((priv->status & STATUS_ASSOCIATED) &&
5209 band_b_active_channel[i] == priv->channel)
5210 continue;
5211 channel_index++;
5212 scan.channels_list[channel_index] =
5213 band_b_active_channel[i];
5214 ipw_set_scan_type(&scan, channel_index, scan_type);
5215 }
5216 8098
5217 if (start != channel_index) { 8099 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
5218 scan.channels_list[start] = (u8) (IPW_B_MODE << 6) |
5219 (channel_index - start);
5220 }
5221 }
5222 8100
5223 err = ipw_send_scan_request_ext(priv, &scan); 8101 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
5224 if (err) { 8102 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
5225 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
5226 return -EIO;
5227 }
5228 8103
5229 priv->status |= STATUS_SCANNING; 8104 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
5230 priv->status &= ~STATUS_SCAN_PENDING; 8105 priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;
8106 priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;
5231 8107
5232 return 0; 8108 /* If power management is turned on, default to AC mode */
8109 priv->power_mode = IPW_POWER_AC;
8110 priv->tx_power = IPW_TX_POWER_DEFAULT;
8111
8112 return old_mode == priv->ieee->iw_mode;
5233} 8113}
5234 8114
5235/* 8115/*
@@ -5247,12 +8127,16 @@ static int ipw_wx_get_name(struct net_device *dev,
5247 union iwreq_data *wrqu, char *extra) 8127 union iwreq_data *wrqu, char *extra)
5248{ 8128{
5249 struct ipw_priv *priv = ieee80211_priv(dev); 8129 struct ipw_priv *priv = ieee80211_priv(dev);
5250 if (!(priv->status & STATUS_ASSOCIATED)) 8130 down(&priv->sem);
8131 if (priv->status & STATUS_RF_KILL_MASK)
8132 strcpy(wrqu->name, "radio off");
8133 else if (!(priv->status & STATUS_ASSOCIATED))
5251 strcpy(wrqu->name, "unassociated"); 8134 strcpy(wrqu->name, "unassociated");
5252 else 8135 else
5253 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", 8136 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
5254 ipw_modes[priv->assoc_request.ieee_mode]); 8137 ipw_modes[priv->assoc_request.ieee_mode]);
5255 IPW_DEBUG_WX("Name: %s\n", wrqu->name); 8138 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
8139 up(&priv->sem);
5256 return 0; 8140 return 0;
5257} 8141}
5258 8142
@@ -5261,13 +8145,9 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
5261 if (channel == 0) { 8145 if (channel == 0) {
5262 IPW_DEBUG_INFO("Setting channel to ANY (0)\n"); 8146 IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
5263 priv->config &= ~CFG_STATIC_CHANNEL; 8147 priv->config &= ~CFG_STATIC_CHANNEL;
5264 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8148 IPW_DEBUG_ASSOC("Attempting to associate with new "
5265 STATUS_ASSOCIATING))) { 8149 "parameters.\n");
5266 IPW_DEBUG_ASSOC("Attempting to associate with new " 8150 ipw_associate(priv);
5267 "parameters.\n");
5268 ipw_associate(priv);
5269 }
5270
5271 return 0; 8151 return 0;
5272 } 8152 }
5273 8153
@@ -5282,14 +8162,32 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
5282 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel); 8162 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
5283 priv->channel = channel; 8163 priv->channel = channel;
5284 8164
5285 /* If we are currently associated, or trying to associate 8165#ifdef CONFIG_IPW2200_MONITOR
5286 * then see if this is a new channel (causing us to disassociate) */ 8166 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
5287 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8167 int i;
5288 IPW_DEBUG_ASSOC("Disassociating due to channel change.\n"); 8168 if (priv->status & STATUS_SCANNING) {
5289 ipw_disassociate(priv); 8169 IPW_DEBUG_SCAN("Scan abort triggered due to "
5290 } else { 8170 "channel change.\n");
5291 ipw_associate(priv); 8171 ipw_abort_scan(priv);
8172 }
8173
8174 for (i = 1000; i && (priv->status & STATUS_SCANNING); i--)
8175 udelay(10);
8176
8177 if (priv->status & STATUS_SCANNING)
8178 IPW_DEBUG_SCAN("Still scanning...\n");
8179 else
8180 IPW_DEBUG_SCAN("Took %dms to abort current scan\n",
8181 1000 - i);
8182
8183 return 0;
5292 } 8184 }
8185#endif /* CONFIG_IPW2200_MONITOR */
8186
8187 /* Network configuration changed -- force [re]association */
8188 IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");
8189 if (!ipw_disassociate(priv))
8190 ipw_associate(priv);
5293 8191
5294 return 0; 8192 return 0;
5295} 8193}
@@ -5299,29 +8197,48 @@ static int ipw_wx_set_freq(struct net_device *dev,
5299 union iwreq_data *wrqu, char *extra) 8197 union iwreq_data *wrqu, char *extra)
5300{ 8198{
5301 struct ipw_priv *priv = ieee80211_priv(dev); 8199 struct ipw_priv *priv = ieee80211_priv(dev);
8200 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5302 struct iw_freq *fwrq = &wrqu->freq; 8201 struct iw_freq *fwrq = &wrqu->freq;
5303 8202 int ret = 0, i;
8203 u8 channel, flags;
8204 int band;
8205
8206 if (fwrq->m == 0) {
8207 IPW_DEBUG_WX("SET Freq/Channel -> any\n");
8208 down(&priv->sem);
8209 ret = ipw_set_channel(priv, 0);
8210 up(&priv->sem);
8211 return ret;
8212 }
5304 /* if setting by freq convert to channel */ 8213 /* if setting by freq convert to channel */
5305 if (fwrq->e == 1) { 8214 if (fwrq->e == 1) {
5306 if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) { 8215 channel = ipw_freq_to_channel(priv->ieee, fwrq->m);
5307 int f = fwrq->m / 100000; 8216 if (channel == 0)
5308 int c = 0; 8217 return -EINVAL;
8218 } else
8219 channel = fwrq->m;
8220
8221 if (!(band = ipw_is_valid_channel(priv->ieee, channel)))
8222 return -EINVAL;
5309 8223
5310 while ((c < REG_MAX_CHANNEL) && 8224 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5311 (f != ipw_frequencies[c])) 8225 i = ipw_channel_to_index(priv->ieee, channel);
5312 c++; 8226 if (i == -1)
8227 return -EINVAL;
5313 8228
5314 /* hack to fall through */ 8229 flags = (band == IEEE80211_24GHZ_BAND) ?
5315 fwrq->e = 0; 8230 geo->bg[i].flags : geo->a[i].flags;
5316 fwrq->m = c + 1; 8231 if (flags & IEEE80211_CH_PASSIVE_ONLY) {
8232 IPW_DEBUG_WX("Invalid Ad-Hoc channel for 802.11a\n");
8233 return -EINVAL;
5317 } 8234 }
5318 } 8235 }
5319 8236
5320 if (fwrq->e > 0 || fwrq->m > 1000)
5321 return -EOPNOTSUPP;
5322
5323 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 8237 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
5324 return ipw_set_channel(priv, (u8) fwrq->m); 8238 down(&priv->sem);
8239 ret = ipw_set_channel(priv, channel);
8240 up(&priv->sem);
8241 return ret;
5325} 8242}
5326 8243
5327static int ipw_wx_get_freq(struct net_device *dev, 8244static int ipw_wx_get_freq(struct net_device *dev,
@@ -5334,12 +8251,14 @@ static int ipw_wx_get_freq(struct net_device *dev,
5334 8251
5335 /* If we are associated, trying to associate, or have a statically 8252 /* If we are associated, trying to associate, or have a statically
5336 * configured CHANNEL then return that; otherwise return ANY */ 8253 * configured CHANNEL then return that; otherwise return ANY */
8254 down(&priv->sem);
5337 if (priv->config & CFG_STATIC_CHANNEL || 8255 if (priv->config & CFG_STATIC_CHANNEL ||
5338 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) 8256 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
5339 wrqu->freq.m = priv->channel; 8257 wrqu->freq.m = priv->channel;
5340 else 8258 else
5341 wrqu->freq.m = 0; 8259 wrqu->freq.m = 0;
5342 8260
8261 up(&priv->sem);
5343 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); 8262 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
5344 return 0; 8263 return 0;
5345} 8264}
@@ -5353,11 +8272,8 @@ static int ipw_wx_set_mode(struct net_device *dev,
5353 8272
5354 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode); 8273 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
5355 8274
5356 if (wrqu->mode == priv->ieee->iw_mode)
5357 return 0;
5358
5359 switch (wrqu->mode) { 8275 switch (wrqu->mode) {
5360#ifdef CONFIG_IPW_PROMISC 8276#ifdef CONFIG_IPW2200_MONITOR
5361 case IW_MODE_MONITOR: 8277 case IW_MODE_MONITOR:
5362#endif 8278#endif
5363 case IW_MODE_ADHOC: 8279 case IW_MODE_ADHOC:
@@ -5369,31 +8285,33 @@ static int ipw_wx_set_mode(struct net_device *dev,
5369 default: 8285 default:
5370 return -EINVAL; 8286 return -EINVAL;
5371 } 8287 }
8288 if (wrqu->mode == priv->ieee->iw_mode)
8289 return 0;
8290
8291 down(&priv->sem);
8292
8293 ipw_sw_reset(priv, 0);
5372 8294
5373#ifdef CONFIG_IPW_PROMISC 8295#ifdef CONFIG_IPW2200_MONITOR
5374 if (priv->ieee->iw_mode == IW_MODE_MONITOR) 8296 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
5375 priv->net_dev->type = ARPHRD_ETHER; 8297 priv->net_dev->type = ARPHRD_ETHER;
5376 8298
5377 if (wrqu->mode == IW_MODE_MONITOR) 8299 if (wrqu->mode == IW_MODE_MONITOR)
8300#ifdef CONFIG_IEEE80211_RADIOTAP
8301 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8302#else
5378 priv->net_dev->type = ARPHRD_IEEE80211; 8303 priv->net_dev->type = ARPHRD_IEEE80211;
5379#endif /* CONFIG_IPW_PROMISC */ 8304#endif
8305#endif /* CONFIG_IPW2200_MONITOR */
5380 8306
5381#ifdef CONFIG_PM
5382 /* Free the existing firmware and reset the fw_loaded 8307 /* Free the existing firmware and reset the fw_loaded
5383 * flag so ipw_load() will bring in the new firmawre */ 8308 * flag so ipw_load() will bring in the new firmawre */
5384 if (fw_loaded) { 8309 free_firmware();
5385 fw_loaded = 0;
5386 }
5387
5388 release_firmware(bootfw);
5389 release_firmware(ucode);
5390 release_firmware(firmware);
5391 bootfw = ucode = firmware = NULL;
5392#endif
5393 8310
5394 priv->ieee->iw_mode = wrqu->mode; 8311 priv->ieee->iw_mode = wrqu->mode;
5395 ipw_adapter_restart(priv);
5396 8312
8313 queue_work(priv->workqueue, &priv->adapter_restart);
8314 up(&priv->sem);
5397 return err; 8315 return err;
5398} 8316}
5399 8317
@@ -5402,20 +8320,13 @@ static int ipw_wx_get_mode(struct net_device *dev,
5402 union iwreq_data *wrqu, char *extra) 8320 union iwreq_data *wrqu, char *extra)
5403{ 8321{
5404 struct ipw_priv *priv = ieee80211_priv(dev); 8322 struct ipw_priv *priv = ieee80211_priv(dev);
5405 8323 down(&priv->sem);
5406 wrqu->mode = priv->ieee->iw_mode; 8324 wrqu->mode = priv->ieee->iw_mode;
5407 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode); 8325 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
5408 8326 up(&priv->sem);
5409 return 0; 8327 return 0;
5410} 8328}
5411 8329
5412#define DEFAULT_RTS_THRESHOLD 2304U
5413#define MIN_RTS_THRESHOLD 1U
5414#define MAX_RTS_THRESHOLD 2304U
5415#define DEFAULT_BEACON_INTERVAL 100U
5416#define DEFAULT_SHORT_RETRY_LIMIT 7U
5417#define DEFAULT_LONG_RETRY_LIMIT 4U
5418
5419/* Values are in microsecond */ 8330/* Values are in microsecond */
5420static const s32 timeout_duration[] = { 8331static const s32 timeout_duration[] = {
5421 350000, 8332 350000,
@@ -5439,8 +8350,8 @@ static int ipw_wx_get_range(struct net_device *dev,
5439{ 8350{
5440 struct ipw_priv *priv = ieee80211_priv(dev); 8351 struct ipw_priv *priv = ieee80211_priv(dev);
5441 struct iw_range *range = (struct iw_range *)extra; 8352 struct iw_range *range = (struct iw_range *)extra;
5442 u16 val; 8353 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5443 int i; 8354 int i = 0, j;
5444 8355
5445 wrqu->data.length = sizeof(*range); 8356 wrqu->data.length = sizeof(*range);
5446 memset(range, 0, sizeof(*range)); 8357 memset(range, 0, sizeof(*range));
@@ -5451,7 +8362,7 @@ static int ipw_wx_get_range(struct net_device *dev,
5451 range->max_qual.qual = 100; 8362 range->max_qual.qual = 100;
5452 /* TODO: Find real max RSSI and stick here */ 8363 /* TODO: Find real max RSSI and stick here */
5453 range->max_qual.level = 0; 8364 range->max_qual.level = 0;
5454 range->max_qual.noise = 0; 8365 range->max_qual.noise = priv->ieee->worst_rssi + 0x100;
5455 range->max_qual.updated = 7; /* Updated all three */ 8366 range->max_qual.updated = 7; /* Updated all three */
5456 8367
5457 range->avg_qual.qual = 70; 8368 range->avg_qual.qual = 70;
@@ -5459,7 +8370,7 @@ static int ipw_wx_get_range(struct net_device *dev,
5459 range->avg_qual.level = 0; /* FIXME to real average level */ 8370 range->avg_qual.level = 0; /* FIXME to real average level */
5460 range->avg_qual.noise = 0; 8371 range->avg_qual.noise = 0;
5461 range->avg_qual.updated = 7; /* Updated all three */ 8372 range->avg_qual.updated = 7; /* Updated all three */
5462 8373 down(&priv->sem);
5463 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES); 8374 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
5464 8375
5465 for (i = 0; i < range->num_bitrates; i++) 8376 for (i = 0; i < range->num_bitrates; i++)
@@ -5479,19 +8390,35 @@ static int ipw_wx_get_range(struct net_device *dev,
5479 range->we_version_compiled = WIRELESS_EXT; 8390 range->we_version_compiled = WIRELESS_EXT;
5480 range->we_version_source = 16; 8391 range->we_version_source = 16;
5481 8392
5482 range->num_channels = FREQ_COUNT; 8393 i = 0;
5483 8394 if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
5484 val = 0; 8395 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES;
5485 for (i = 0; i < FREQ_COUNT; i++) { 8396 i++, j++) {
5486 range->freq[val].i = i + 1; 8397 range->freq[i].i = geo->bg[j].channel;
5487 range->freq[val].m = ipw_frequencies[i] * 100000; 8398 range->freq[i].m = geo->bg[j].freq * 100000;
5488 range->freq[val].e = 1; 8399 range->freq[i].e = 1;
5489 val++; 8400 }
8401 }
5490 8402
5491 if (val == IW_MAX_FREQUENCIES) 8403 if (priv->ieee->mode & IEEE_A) {
5492 break; 8404 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES;
8405 i++, j++) {
8406 range->freq[i].i = geo->a[j].channel;
8407 range->freq[i].m = geo->a[j].freq * 100000;
8408 range->freq[i].e = 1;
8409 }
5493 } 8410 }
5494 range->num_frequency = val; 8411
8412 range->num_channels = i;
8413 range->num_frequency = i;
8414
8415 up(&priv->sem);
8416
8417 /* Event capability (kernel + driver) */
8418 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
8419 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
8420 IW_EVENT_CAPA_MASK(SIOCGIWAP));
8421 range->event_capa[1] = IW_EVENT_CAPA_K_1;
5495 8422
5496 IPW_DEBUG_WX("GET Range\n"); 8423 IPW_DEBUG_WX("GET Range\n");
5497 return 0; 8424 return 0;
@@ -5512,25 +8439,23 @@ static int ipw_wx_set_wap(struct net_device *dev,
5512 8439
5513 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) 8440 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
5514 return -EINVAL; 8441 return -EINVAL;
5515 8442 down(&priv->sem);
5516 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) || 8443 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
5517 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) { 8444 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
5518 /* we disable mandatory BSSID association */ 8445 /* we disable mandatory BSSID association */
5519 IPW_DEBUG_WX("Setting AP BSSID to ANY\n"); 8446 IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
5520 priv->config &= ~CFG_STATIC_BSSID; 8447 priv->config &= ~CFG_STATIC_BSSID;
5521 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8448 IPW_DEBUG_ASSOC("Attempting to associate with new "
5522 STATUS_ASSOCIATING))) { 8449 "parameters.\n");
5523 IPW_DEBUG_ASSOC("Attempting to associate with new " 8450 ipw_associate(priv);
5524 "parameters.\n"); 8451 up(&priv->sem);
5525 ipw_associate(priv);
5526 }
5527
5528 return 0; 8452 return 0;
5529 } 8453 }
5530 8454
5531 priv->config |= CFG_STATIC_BSSID; 8455 priv->config |= CFG_STATIC_BSSID;
5532 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) { 8456 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
5533 IPW_DEBUG_WX("BSSID set to current BSSID.\n"); 8457 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
8458 up(&priv->sem);
5534 return 0; 8459 return 0;
5535 } 8460 }
5536 8461
@@ -5539,15 +8464,12 @@ static int ipw_wx_set_wap(struct net_device *dev,
5539 8464
5540 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN); 8465 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
5541 8466
5542 /* If we are currently associated, or trying to associate 8467 /* Network configuration changed -- force [re]association */
5543 * then see if this is a new BSSID (causing us to disassociate) */ 8468 IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");
5544 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8469 if (!ipw_disassociate(priv))
5545 IPW_DEBUG_ASSOC("Disassociating due to BSSID change.\n");
5546 ipw_disassociate(priv);
5547 } else {
5548 ipw_associate(priv); 8470 ipw_associate(priv);
5549 }
5550 8471
8472 up(&priv->sem);
5551 return 0; 8473 return 0;
5552} 8474}
5553 8475
@@ -5558,15 +8480,17 @@ static int ipw_wx_get_wap(struct net_device *dev,
5558 struct ipw_priv *priv = ieee80211_priv(dev); 8480 struct ipw_priv *priv = ieee80211_priv(dev);
5559 /* If we are associated, trying to associate, or have a statically 8481 /* If we are associated, trying to associate, or have a statically
5560 * configured BSSID then return that; otherwise return ANY */ 8482 * configured BSSID then return that; otherwise return ANY */
8483 down(&priv->sem);
5561 if (priv->config & CFG_STATIC_BSSID || 8484 if (priv->config & CFG_STATIC_BSSID ||
5562 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8485 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5563 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 8486 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
5564 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN); 8487 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
5565 } else 8488 } else
5566 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 8489 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
5567 8490
5568 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n", 8491 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
5569 MAC_ARG(wrqu->ap_addr.sa_data)); 8492 MAC_ARG(wrqu->ap_addr.sa_data));
8493 up(&priv->sem);
5570 return 0; 8494 return 0;
5571} 8495}
5572 8496
@@ -5577,21 +8501,22 @@ static int ipw_wx_set_essid(struct net_device *dev,
5577 struct ipw_priv *priv = ieee80211_priv(dev); 8501 struct ipw_priv *priv = ieee80211_priv(dev);
5578 char *essid = ""; /* ANY */ 8502 char *essid = ""; /* ANY */
5579 int length = 0; 8503 int length = 0;
5580 8504 down(&priv->sem);
5581 if (wrqu->essid.flags && wrqu->essid.length) { 8505 if (wrqu->essid.flags && wrqu->essid.length) {
5582 length = wrqu->essid.length - 1; 8506 length = wrqu->essid.length - 1;
5583 essid = extra; 8507 essid = extra;
5584 } 8508 }
5585 if (length == 0) { 8509 if (length == 0) {
5586 IPW_DEBUG_WX("Setting ESSID to ANY\n"); 8510 IPW_DEBUG_WX("Setting ESSID to ANY\n");
5587 priv->config &= ~CFG_STATIC_ESSID; 8511 if ((priv->config & CFG_STATIC_ESSID) &&
5588 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8512 !(priv->status & (STATUS_ASSOCIATED |
5589 STATUS_ASSOCIATING))) { 8513 STATUS_ASSOCIATING))) {
5590 IPW_DEBUG_ASSOC("Attempting to associate with new " 8514 IPW_DEBUG_ASSOC("Attempting to associate with new "
5591 "parameters.\n"); 8515 "parameters.\n");
8516 priv->config &= ~CFG_STATIC_ESSID;
5592 ipw_associate(priv); 8517 ipw_associate(priv);
5593 } 8518 }
5594 8519 up(&priv->sem);
5595 return 0; 8520 return 0;
5596 } 8521 }
5597 8522
@@ -5601,6 +8526,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
5601 8526
5602 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) { 8527 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
5603 IPW_DEBUG_WX("ESSID set to current ESSID.\n"); 8528 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
8529 up(&priv->sem);
5604 return 0; 8530 return 0;
5605 } 8531 }
5606 8532
@@ -5610,15 +8536,12 @@ static int ipw_wx_set_essid(struct net_device *dev,
5610 priv->essid_len = length; 8536 priv->essid_len = length;
5611 memcpy(priv->essid, essid, priv->essid_len); 8537 memcpy(priv->essid, essid, priv->essid_len);
5612 8538
5613 /* If we are currently associated, or trying to associate 8539 /* Network configuration changed -- force [re]association */
5614 * then see if this is a new ESSID (causing us to disassociate) */ 8540 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
5615 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8541 if (!ipw_disassociate(priv))
5616 IPW_DEBUG_ASSOC("Disassociating due to ESSID change.\n");
5617 ipw_disassociate(priv);
5618 } else {
5619 ipw_associate(priv); 8542 ipw_associate(priv);
5620 }
5621 8543
8544 up(&priv->sem);
5622 return 0; 8545 return 0;
5623} 8546}
5624 8547
@@ -5630,6 +8553,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
5630 8553
5631 /* If we are associated, trying to associate, or have a statically 8554 /* If we are associated, trying to associate, or have a statically
5632 * configured ESSID then return that; otherwise return ANY */ 8555 * configured ESSID then return that; otherwise return ANY */
8556 down(&priv->sem);
5633 if (priv->config & CFG_STATIC_ESSID || 8557 if (priv->config & CFG_STATIC_ESSID ||
5634 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8558 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5635 IPW_DEBUG_WX("Getting essid: '%s'\n", 8559 IPW_DEBUG_WX("Getting essid: '%s'\n",
@@ -5642,7 +8566,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
5642 wrqu->essid.length = 0; 8566 wrqu->essid.length = 0;
5643 wrqu->essid.flags = 0; /* active */ 8567 wrqu->essid.flags = 0; /* active */
5644 } 8568 }
5645 8569 up(&priv->sem);
5646 return 0; 8570 return 0;
5647} 8571}
5648 8572
@@ -5655,11 +8579,12 @@ static int ipw_wx_set_nick(struct net_device *dev,
5655 IPW_DEBUG_WX("Setting nick to '%s'\n", extra); 8579 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
5656 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 8580 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
5657 return -E2BIG; 8581 return -E2BIG;
5658 8582 down(&priv->sem);
5659 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); 8583 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
5660 memset(priv->nick, 0, sizeof(priv->nick)); 8584 memset(priv->nick, 0, sizeof(priv->nick));
5661 memcpy(priv->nick, extra, wrqu->data.length); 8585 memcpy(priv->nick, extra, wrqu->data.length);
5662 IPW_DEBUG_TRACE("<<\n"); 8586 IPW_DEBUG_TRACE("<<\n");
8587 up(&priv->sem);
5663 return 0; 8588 return 0;
5664 8589
5665} 8590}
@@ -5670,9 +8595,11 @@ static int ipw_wx_get_nick(struct net_device *dev,
5670{ 8595{
5671 struct ipw_priv *priv = ieee80211_priv(dev); 8596 struct ipw_priv *priv = ieee80211_priv(dev);
5672 IPW_DEBUG_WX("Getting nick\n"); 8597 IPW_DEBUG_WX("Getting nick\n");
8598 down(&priv->sem);
5673 wrqu->data.length = strlen(priv->nick) + 1; 8599 wrqu->data.length = strlen(priv->nick) + 1;
5674 memcpy(extra, priv->nick, wrqu->data.length); 8600 memcpy(extra, priv->nick, wrqu->data.length);
5675 wrqu->data.flags = 1; /* active */ 8601 wrqu->data.flags = 1; /* active */
8602 up(&priv->sem);
5676 return 0; 8603 return 0;
5677} 8604}
5678 8605
@@ -5680,8 +8607,113 @@ static int ipw_wx_set_rate(struct net_device *dev,
5680 struct iw_request_info *info, 8607 struct iw_request_info *info,
5681 union iwreq_data *wrqu, char *extra) 8608 union iwreq_data *wrqu, char *extra)
5682{ 8609{
5683 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8610 /* TODO: We should use semaphores or locks for access to priv */
5684 return -EOPNOTSUPP; 8611 struct ipw_priv *priv = ieee80211_priv(dev);
8612 u32 target_rate = wrqu->bitrate.value;
8613 u32 fixed, mask;
8614
8615 /* value = -1, fixed = 0 means auto only, so we should use all rates offered by AP */
8616 /* value = X, fixed = 1 means only rate X */
8617 /* value = X, fixed = 0 means all rates lower equal X */
8618
8619 if (target_rate == -1) {
8620 fixed = 0;
8621 mask = IEEE80211_DEFAULT_RATES_MASK;
8622 /* Now we should reassociate */
8623 goto apply;
8624 }
8625
8626 mask = 0;
8627 fixed = wrqu->bitrate.fixed;
8628
8629 if (target_rate == 1000000 || !fixed)
8630 mask |= IEEE80211_CCK_RATE_1MB_MASK;
8631 if (target_rate == 1000000)
8632 goto apply;
8633
8634 if (target_rate == 2000000 || !fixed)
8635 mask |= IEEE80211_CCK_RATE_2MB_MASK;
8636 if (target_rate == 2000000)
8637 goto apply;
8638
8639 if (target_rate == 5500000 || !fixed)
8640 mask |= IEEE80211_CCK_RATE_5MB_MASK;
8641 if (target_rate == 5500000)
8642 goto apply;
8643
8644 if (target_rate == 6000000 || !fixed)
8645 mask |= IEEE80211_OFDM_RATE_6MB_MASK;
8646 if (target_rate == 6000000)
8647 goto apply;
8648
8649 if (target_rate == 9000000 || !fixed)
8650 mask |= IEEE80211_OFDM_RATE_9MB_MASK;
8651 if (target_rate == 9000000)
8652 goto apply;
8653
8654 if (target_rate == 11000000 || !fixed)
8655 mask |= IEEE80211_CCK_RATE_11MB_MASK;
8656 if (target_rate == 11000000)
8657 goto apply;
8658
8659 if (target_rate == 12000000 || !fixed)
8660 mask |= IEEE80211_OFDM_RATE_12MB_MASK;
8661 if (target_rate == 12000000)
8662 goto apply;
8663
8664 if (target_rate == 18000000 || !fixed)
8665 mask |= IEEE80211_OFDM_RATE_18MB_MASK;
8666 if (target_rate == 18000000)
8667 goto apply;
8668
8669 if (target_rate == 24000000 || !fixed)
8670 mask |= IEEE80211_OFDM_RATE_24MB_MASK;
8671 if (target_rate == 24000000)
8672 goto apply;
8673
8674 if (target_rate == 36000000 || !fixed)
8675 mask |= IEEE80211_OFDM_RATE_36MB_MASK;
8676 if (target_rate == 36000000)
8677 goto apply;
8678
8679 if (target_rate == 48000000 || !fixed)
8680 mask |= IEEE80211_OFDM_RATE_48MB_MASK;
8681 if (target_rate == 48000000)
8682 goto apply;
8683
8684 if (target_rate == 54000000 || !fixed)
8685 mask |= IEEE80211_OFDM_RATE_54MB_MASK;
8686 if (target_rate == 54000000)
8687 goto apply;
8688
8689 IPW_DEBUG_WX("invalid rate specified, returning error\n");
8690 return -EINVAL;
8691
8692 apply:
8693 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
8694 mask, fixed ? "fixed" : "sub-rates");
8695 down(&priv->sem);
8696 if (mask == IEEE80211_DEFAULT_RATES_MASK) {
8697 priv->config &= ~CFG_FIXED_RATE;
8698 ipw_set_fixed_rate(priv, priv->ieee->mode);
8699 } else
8700 priv->config |= CFG_FIXED_RATE;
8701
8702 if (priv->rates_mask == mask) {
8703 IPW_DEBUG_WX("Mask set to current mask.\n");
8704 up(&priv->sem);
8705 return 0;
8706 }
8707
8708 priv->rates_mask = mask;
8709
8710 /* Network configuration changed -- force [re]association */
8711 IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");
8712 if (!ipw_disassociate(priv))
8713 ipw_associate(priv);
8714
8715 up(&priv->sem);
8716 return 0;
5685} 8717}
5686 8718
5687static int ipw_wx_get_rate(struct net_device *dev, 8719static int ipw_wx_get_rate(struct net_device *dev,
@@ -5689,8 +8721,9 @@ static int ipw_wx_get_rate(struct net_device *dev,
5689 union iwreq_data *wrqu, char *extra) 8721 union iwreq_data *wrqu, char *extra)
5690{ 8722{
5691 struct ipw_priv *priv = ieee80211_priv(dev); 8723 struct ipw_priv *priv = ieee80211_priv(dev);
8724 down(&priv->sem);
5692 wrqu->bitrate.value = priv->last_rate; 8725 wrqu->bitrate.value = priv->last_rate;
5693 8726 up(&priv->sem);
5694 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 8727 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
5695 return 0; 8728 return 0;
5696} 8729}
@@ -5700,18 +8733,20 @@ static int ipw_wx_set_rts(struct net_device *dev,
5700 union iwreq_data *wrqu, char *extra) 8733 union iwreq_data *wrqu, char *extra)
5701{ 8734{
5702 struct ipw_priv *priv = ieee80211_priv(dev); 8735 struct ipw_priv *priv = ieee80211_priv(dev);
5703 8736 down(&priv->sem);
5704 if (wrqu->rts.disabled) 8737 if (wrqu->rts.disabled)
5705 priv->rts_threshold = DEFAULT_RTS_THRESHOLD; 8738 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
5706 else { 8739 else {
5707 if (wrqu->rts.value < MIN_RTS_THRESHOLD || 8740 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
5708 wrqu->rts.value > MAX_RTS_THRESHOLD) 8741 wrqu->rts.value > MAX_RTS_THRESHOLD) {
8742 up(&priv->sem);
5709 return -EINVAL; 8743 return -EINVAL;
5710 8744 }
5711 priv->rts_threshold = wrqu->rts.value; 8745 priv->rts_threshold = wrqu->rts.value;
5712 } 8746 }
5713 8747
5714 ipw_send_rts_threshold(priv, priv->rts_threshold); 8748 ipw_send_rts_threshold(priv, priv->rts_threshold);
8749 up(&priv->sem);
5715 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold); 8750 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
5716 return 0; 8751 return 0;
5717} 8752}
@@ -5721,10 +8756,11 @@ static int ipw_wx_get_rts(struct net_device *dev,
5721 union iwreq_data *wrqu, char *extra) 8756 union iwreq_data *wrqu, char *extra)
5722{ 8757{
5723 struct ipw_priv *priv = ieee80211_priv(dev); 8758 struct ipw_priv *priv = ieee80211_priv(dev);
8759 down(&priv->sem);
5724 wrqu->rts.value = priv->rts_threshold; 8760 wrqu->rts.value = priv->rts_threshold;
5725 wrqu->rts.fixed = 0; /* no auto select */ 8761 wrqu->rts.fixed = 0; /* no auto select */
5726 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); 8762 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
5727 8763 up(&priv->sem);
5728 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); 8764 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
5729 return 0; 8765 return 0;
5730} 8766}
@@ -5734,41 +8770,33 @@ static int ipw_wx_set_txpow(struct net_device *dev,
5734 union iwreq_data *wrqu, char *extra) 8770 union iwreq_data *wrqu, char *extra)
5735{ 8771{
5736 struct ipw_priv *priv = ieee80211_priv(dev); 8772 struct ipw_priv *priv = ieee80211_priv(dev);
5737 struct ipw_tx_power tx_power; 8773 int err = 0;
5738 int i;
5739
5740 if (ipw_radio_kill_sw(priv, wrqu->power.disabled))
5741 return -EINPROGRESS;
5742
5743 if (wrqu->power.flags != IW_TXPOW_DBM)
5744 return -EINVAL;
5745 8774
5746 if ((wrqu->power.value > 20) || (wrqu->power.value < -12)) 8775 down(&priv->sem);
5747 return -EINVAL; 8776 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
8777 err = -EINPROGRESS;
8778 goto out;
8779 }
5748 8780
5749 priv->tx_power = wrqu->power.value; 8781 if (!wrqu->power.fixed)
8782 wrqu->power.value = IPW_TX_POWER_DEFAULT;
5750 8783
5751 memset(&tx_power, 0, sizeof(tx_power)); 8784 if (wrqu->power.flags != IW_TXPOW_DBM) {
5752 8785 err = -EINVAL;
5753 /* configure device for 'G' band */ 8786 goto out;
5754 tx_power.ieee_mode = IPW_G_MODE;
5755 tx_power.num_channels = 11;
5756 for (i = 0; i < 11; i++) {
5757 tx_power.channels_tx_power[i].channel_number = i + 1;
5758 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
5759 } 8787 }
5760 if (ipw_send_tx_power(priv, &tx_power))
5761 goto error;
5762 8788
5763 /* configure device to also handle 'B' band */ 8789 if ((wrqu->power.value > IPW_TX_POWER_MAX) ||
5764 tx_power.ieee_mode = IPW_B_MODE; 8790 (wrqu->power.value < IPW_TX_POWER_MIN)) {
5765 if (ipw_send_tx_power(priv, &tx_power)) 8791 err = -EINVAL;
5766 goto error; 8792 goto out;
5767 8793 }
5768 return 0;
5769 8794
5770 error: 8795 priv->tx_power = wrqu->power.value;
5771 return -EIO; 8796 err = ipw_set_tx_power(priv);
8797 out:
8798 up(&priv->sem);
8799 return err;
5772} 8800}
5773 8801
5774static int ipw_wx_get_txpow(struct net_device *dev, 8802static int ipw_wx_get_txpow(struct net_device *dev,
@@ -5776,14 +8804,15 @@ static int ipw_wx_get_txpow(struct net_device *dev,
5776 union iwreq_data *wrqu, char *extra) 8804 union iwreq_data *wrqu, char *extra)
5777{ 8805{
5778 struct ipw_priv *priv = ieee80211_priv(dev); 8806 struct ipw_priv *priv = ieee80211_priv(dev);
5779 8807 down(&priv->sem);
5780 wrqu->power.value = priv->tx_power; 8808 wrqu->power.value = priv->tx_power;
5781 wrqu->power.fixed = 1; 8809 wrqu->power.fixed = 1;
5782 wrqu->power.flags = IW_TXPOW_DBM; 8810 wrqu->power.flags = IW_TXPOW_DBM;
5783 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; 8811 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
8812 up(&priv->sem);
5784 8813
5785 IPW_DEBUG_WX("GET TX Power -> %s %d \n", 8814 IPW_DEBUG_WX("GET TX Power -> %s %d \n",
5786 wrqu->power.disabled ? "ON" : "OFF", wrqu->power.value); 8815 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
5787 8816
5788 return 0; 8817 return 0;
5789} 8818}
@@ -5793,18 +8822,21 @@ static int ipw_wx_set_frag(struct net_device *dev,
5793 union iwreq_data *wrqu, char *extra) 8822 union iwreq_data *wrqu, char *extra)
5794{ 8823{
5795 struct ipw_priv *priv = ieee80211_priv(dev); 8824 struct ipw_priv *priv = ieee80211_priv(dev);
5796 8825 down(&priv->sem);
5797 if (wrqu->frag.disabled) 8826 if (wrqu->frag.disabled)
5798 priv->ieee->fts = DEFAULT_FTS; 8827 priv->ieee->fts = DEFAULT_FTS;
5799 else { 8828 else {
5800 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 8829 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
5801 wrqu->frag.value > MAX_FRAG_THRESHOLD) 8830 wrqu->frag.value > MAX_FRAG_THRESHOLD) {
8831 up(&priv->sem);
5802 return -EINVAL; 8832 return -EINVAL;
8833 }
5803 8834
5804 priv->ieee->fts = wrqu->frag.value & ~0x1; 8835 priv->ieee->fts = wrqu->frag.value & ~0x1;
5805 } 8836 }
5806 8837
5807 ipw_send_frag_threshold(priv, wrqu->frag.value); 8838 ipw_send_frag_threshold(priv, wrqu->frag.value);
8839 up(&priv->sem);
5808 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value); 8840 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
5809 return 0; 8841 return 0;
5810} 8842}
@@ -5814,10 +8846,11 @@ static int ipw_wx_get_frag(struct net_device *dev,
5814 union iwreq_data *wrqu, char *extra) 8846 union iwreq_data *wrqu, char *extra)
5815{ 8847{
5816 struct ipw_priv *priv = ieee80211_priv(dev); 8848 struct ipw_priv *priv = ieee80211_priv(dev);
8849 down(&priv->sem);
5817 wrqu->frag.value = priv->ieee->fts; 8850 wrqu->frag.value = priv->ieee->fts;
5818 wrqu->frag.fixed = 0; /* no auto select */ 8851 wrqu->frag.fixed = 0; /* no auto select */
5819 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS); 8852 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
5820 8853 up(&priv->sem);
5821 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); 8854 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
5822 8855
5823 return 0; 8856 return 0;
@@ -5827,16 +8860,128 @@ static int ipw_wx_set_retry(struct net_device *dev,
5827 struct iw_request_info *info, 8860 struct iw_request_info *info,
5828 union iwreq_data *wrqu, char *extra) 8861 union iwreq_data *wrqu, char *extra)
5829{ 8862{
5830 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8863 struct ipw_priv *priv = ieee80211_priv(dev);
5831 return -EOPNOTSUPP; 8864
8865 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
8866 return -EINVAL;
8867
8868 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
8869 return 0;
8870
8871 if (wrqu->retry.value < 0 || wrqu->retry.value > 255)
8872 return -EINVAL;
8873
8874 down(&priv->sem);
8875 if (wrqu->retry.flags & IW_RETRY_MIN)
8876 priv->short_retry_limit = (u8) wrqu->retry.value;
8877 else if (wrqu->retry.flags & IW_RETRY_MAX)
8878 priv->long_retry_limit = (u8) wrqu->retry.value;
8879 else {
8880 priv->short_retry_limit = (u8) wrqu->retry.value;
8881 priv->long_retry_limit = (u8) wrqu->retry.value;
8882 }
8883
8884 ipw_send_retry_limit(priv, priv->short_retry_limit,
8885 priv->long_retry_limit);
8886 up(&priv->sem);
8887 IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
8888 priv->short_retry_limit, priv->long_retry_limit);
8889 return 0;
5832} 8890}
5833 8891
5834static int ipw_wx_get_retry(struct net_device *dev, 8892static int ipw_wx_get_retry(struct net_device *dev,
5835 struct iw_request_info *info, 8893 struct iw_request_info *info,
5836 union iwreq_data *wrqu, char *extra) 8894 union iwreq_data *wrqu, char *extra)
5837{ 8895{
5838 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8896 struct ipw_priv *priv = ieee80211_priv(dev);
5839 return -EOPNOTSUPP; 8897
8898 down(&priv->sem);
8899 wrqu->retry.disabled = 0;
8900
8901 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
8902 up(&priv->sem);
8903 return -EINVAL;
8904 }
8905
8906 if (wrqu->retry.flags & IW_RETRY_MAX) {
8907 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
8908 wrqu->retry.value = priv->long_retry_limit;
8909 } else if (wrqu->retry.flags & IW_RETRY_MIN) {
8910 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
8911 wrqu->retry.value = priv->short_retry_limit;
8912 } else {
8913 wrqu->retry.flags = IW_RETRY_LIMIT;
8914 wrqu->retry.value = priv->short_retry_limit;
8915 }
8916 up(&priv->sem);
8917
8918 IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value);
8919
8920 return 0;
8921}
8922
8923static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
8924 int essid_len)
8925{
8926 struct ipw_scan_request_ext scan;
8927 int err = 0, scan_type;
8928
8929 down(&priv->sem);
8930
8931 if (priv->status & STATUS_RF_KILL_MASK) {
8932 IPW_DEBUG_HC("Aborting scan due to RF kill activation\n");
8933 priv->status |= STATUS_SCAN_PENDING;
8934 goto done;
8935 }
8936
8937 IPW_DEBUG_HC("starting request direct scan!\n");
8938
8939 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
8940 err = wait_event_interruptible(priv->wait_state,
8941 !(priv->
8942 status & (STATUS_SCANNING |
8943 STATUS_SCAN_ABORTING)));
8944 if (err) {
8945 IPW_DEBUG_HC("aborting direct scan");
8946 goto done;
8947 }
8948 }
8949 memset(&scan, 0, sizeof(scan));
8950
8951 if (priv->config & CFG_SPEED_SCAN)
8952 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
8953 cpu_to_le16(30);
8954 else
8955 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
8956 cpu_to_le16(20);
8957
8958 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
8959 cpu_to_le16(20);
8960 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
8961 scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
8962
8963 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
8964
8965 err = ipw_send_ssid(priv, essid, essid_len);
8966 if (err) {
8967 IPW_DEBUG_HC("Attempt to send SSID command failed\n");
8968 goto done;
8969 }
8970 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
8971
8972 ipw_add_scan_channels(priv, &scan, scan_type);
8973
8974 err = ipw_send_scan_request_ext(priv, &scan);
8975 if (err) {
8976 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
8977 goto done;
8978 }
8979
8980 priv->status |= STATUS_SCANNING;
8981
8982 done:
8983 up(&priv->sem);
8984 return err;
5840} 8985}
5841 8986
5842static int ipw_wx_set_scan(struct net_device *dev, 8987static int ipw_wx_set_scan(struct net_device *dev,
@@ -5844,9 +8989,21 @@ static int ipw_wx_set_scan(struct net_device *dev,
5844 union iwreq_data *wrqu, char *extra) 8989 union iwreq_data *wrqu, char *extra)
5845{ 8990{
5846 struct ipw_priv *priv = ieee80211_priv(dev); 8991 struct ipw_priv *priv = ieee80211_priv(dev);
8992 struct iw_scan_req *req = NULL;
8993 if (wrqu->data.length
8994 && wrqu->data.length == sizeof(struct iw_scan_req)) {
8995 req = (struct iw_scan_req *)extra;
8996 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
8997 ipw_request_direct_scan(priv, req->essid,
8998 req->essid_len);
8999 return 0;
9000 }
9001 }
9002
5847 IPW_DEBUG_WX("Start scan\n"); 9003 IPW_DEBUG_WX("Start scan\n");
5848 if (ipw_request_scan(priv)) 9004
5849 return -EIO; 9005 queue_work(priv->workqueue, &priv->request_scan);
9006
5850 return 0; 9007 return 0;
5851} 9008}
5852 9009
@@ -5863,7 +9020,21 @@ static int ipw_wx_set_encode(struct net_device *dev,
5863 union iwreq_data *wrqu, char *key) 9020 union iwreq_data *wrqu, char *key)
5864{ 9021{
5865 struct ipw_priv *priv = ieee80211_priv(dev); 9022 struct ipw_priv *priv = ieee80211_priv(dev);
5866 return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key); 9023 int ret;
9024 u32 cap = priv->capability;
9025
9026 down(&priv->sem);
9027 ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
9028
9029 /* In IBSS mode, we need to notify the firmware to update
9030 * the beacon info after we changed the capability. */
9031 if (cap != priv->capability &&
9032 priv->ieee->iw_mode == IW_MODE_ADHOC &&
9033 priv->status & STATUS_ASSOCIATED)
9034 ipw_disassociate(priv);
9035
9036 up(&priv->sem);
9037 return ret;
5867} 9038}
5868 9039
5869static int ipw_wx_get_encode(struct net_device *dev, 9040static int ipw_wx_get_encode(struct net_device *dev,
@@ -5880,17 +9051,17 @@ static int ipw_wx_set_power(struct net_device *dev,
5880{ 9051{
5881 struct ipw_priv *priv = ieee80211_priv(dev); 9052 struct ipw_priv *priv = ieee80211_priv(dev);
5882 int err; 9053 int err;
5883 9054 down(&priv->sem);
5884 if (wrqu->power.disabled) { 9055 if (wrqu->power.disabled) {
5885 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode); 9056 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
5886 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM); 9057 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
5887 if (err) { 9058 if (err) {
5888 IPW_DEBUG_WX("failed setting power mode.\n"); 9059 IPW_DEBUG_WX("failed setting power mode.\n");
9060 up(&priv->sem);
5889 return err; 9061 return err;
5890 } 9062 }
5891
5892 IPW_DEBUG_WX("SET Power Management Mode -> off\n"); 9063 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
5893 9064 up(&priv->sem);
5894 return 0; 9065 return 0;
5895 } 9066 }
5896 9067
@@ -5902,6 +9073,7 @@ static int ipw_wx_set_power(struct net_device *dev,
5902 default: /* Otherwise we don't support it */ 9073 default: /* Otherwise we don't support it */
5903 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", 9074 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
5904 wrqu->power.flags); 9075 wrqu->power.flags);
9076 up(&priv->sem);
5905 return -EOPNOTSUPP; 9077 return -EOPNOTSUPP;
5906 } 9078 }
5907 9079
@@ -5914,11 +9086,12 @@ static int ipw_wx_set_power(struct net_device *dev,
5914 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); 9086 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
5915 if (err) { 9087 if (err) {
5916 IPW_DEBUG_WX("failed setting power mode.\n"); 9088 IPW_DEBUG_WX("failed setting power mode.\n");
9089 up(&priv->sem);
5917 return err; 9090 return err;
5918 } 9091 }
5919 9092
5920 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); 9093 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
5921 9094 up(&priv->sem);
5922 return 0; 9095 return 0;
5923} 9096}
5924 9097
@@ -5927,13 +9100,13 @@ static int ipw_wx_get_power(struct net_device *dev,
5927 union iwreq_data *wrqu, char *extra) 9100 union iwreq_data *wrqu, char *extra)
5928{ 9101{
5929 struct ipw_priv *priv = ieee80211_priv(dev); 9102 struct ipw_priv *priv = ieee80211_priv(dev);
5930 9103 down(&priv->sem);
5931 if (!(priv->power_mode & IPW_POWER_ENABLED)) { 9104 if (!(priv->power_mode & IPW_POWER_ENABLED))
5932 wrqu->power.disabled = 1; 9105 wrqu->power.disabled = 1;
5933 } else { 9106 else
5934 wrqu->power.disabled = 0; 9107 wrqu->power.disabled = 0;
5935 }
5936 9108
9109 up(&priv->sem);
5937 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode); 9110 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
5938 9111
5939 return 0; 9112 return 0;
@@ -5946,7 +9119,7 @@ static int ipw_wx_set_powermode(struct net_device *dev,
5946 struct ipw_priv *priv = ieee80211_priv(dev); 9119 struct ipw_priv *priv = ieee80211_priv(dev);
5947 int mode = *(int *)extra; 9120 int mode = *(int *)extra;
5948 int err; 9121 int err;
5949 9122 down(&priv->sem);
5950 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) { 9123 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
5951 mode = IPW_POWER_AC; 9124 mode = IPW_POWER_AC;
5952 priv->power_mode = mode; 9125 priv->power_mode = mode;
@@ -5959,10 +9132,11 @@ static int ipw_wx_set_powermode(struct net_device *dev,
5959 9132
5960 if (err) { 9133 if (err) {
5961 IPW_DEBUG_WX("failed setting power mode.\n"); 9134 IPW_DEBUG_WX("failed setting power mode.\n");
9135 up(&priv->sem);
5962 return err; 9136 return err;
5963 } 9137 }
5964 } 9138 }
5965 9139 up(&priv->sem);
5966 return 0; 9140 return 0;
5967} 9141}
5968 9142
@@ -6011,7 +9185,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6011 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode); 9185 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
6012 return -EINVAL; 9186 return -EINVAL;
6013 } 9187 }
6014 9188 down(&priv->sem);
6015 if (priv->adapter == IPW_2915ABG) { 9189 if (priv->adapter == IPW_2915ABG) {
6016 priv->ieee->abg_true = 1; 9190 priv->ieee->abg_true = 1;
6017 if (mode & IEEE_A) { 9191 if (mode & IEEE_A) {
@@ -6023,6 +9197,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6023 if (mode & IEEE_A) { 9197 if (mode & IEEE_A) {
6024 IPW_WARNING("Attempt to set 2200BG into " 9198 IPW_WARNING("Attempt to set 2200BG into "
6025 "802.11a mode\n"); 9199 "802.11a mode\n");
9200 up(&priv->sem);
6026 return -EINVAL; 9201 return -EINVAL;
6027 } 9202 }
6028 9203
@@ -6046,20 +9221,20 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6046 priv->ieee->modulation = modulation; 9221 priv->ieee->modulation = modulation;
6047 init_supported_rates(priv, &priv->rates); 9222 init_supported_rates(priv, &priv->rates);
6048 9223
6049 /* If we are currently associated, or trying to associate 9224 /* Network configuration changed -- force [re]association */
6050 * then see if this is a new configuration (causing us to 9225 IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
6051 * disassociate) */ 9226 if (!ipw_disassociate(priv)) {
6052 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
6053 /* The resulting association will trigger
6054 * the new rates to be sent to the device */
6055 IPW_DEBUG_ASSOC("Disassociating due to mode change.\n");
6056 ipw_disassociate(priv);
6057 } else
6058 ipw_send_supported_rates(priv, &priv->rates); 9227 ipw_send_supported_rates(priv, &priv->rates);
9228 ipw_associate(priv);
9229 }
9230
9231 /* Update the band LEDs */
9232 ipw_led_band_on(priv);
6059 9233
6060 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", 9234 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
6061 mode & IEEE_A ? 'a' : '.', 9235 mode & IEEE_A ? 'a' : '.',
6062 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.'); 9236 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
9237 up(&priv->sem);
6063 return 0; 9238 return 0;
6064} 9239}
6065 9240
@@ -6068,124 +9243,234 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
6068 union iwreq_data *wrqu, char *extra) 9243 union iwreq_data *wrqu, char *extra)
6069{ 9244{
6070 struct ipw_priv *priv = ieee80211_priv(dev); 9245 struct ipw_priv *priv = ieee80211_priv(dev);
6071 9246 down(&priv->sem);
6072 switch (priv->ieee->freq_band) { 9247 switch (priv->ieee->mode) {
6073 case IEEE80211_24GHZ_BAND: 9248 case IEEE_A:
6074 switch (priv->ieee->modulation) {
6075 case IEEE80211_CCK_MODULATION:
6076 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
6077 break;
6078 case IEEE80211_OFDM_MODULATION:
6079 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
6080 break;
6081 default:
6082 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
6083 break;
6084 }
6085 break;
6086
6087 case IEEE80211_52GHZ_BAND:
6088 strncpy(extra, "802.11a (1)", MAX_WX_STRING); 9249 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
6089 break; 9250 break;
6090 9251 case IEEE_B:
6091 default: /* Mixed Band */ 9252 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
6092 switch (priv->ieee->modulation) { 9253 break;
6093 case IEEE80211_CCK_MODULATION: 9254 case IEEE_A | IEEE_B:
6094 strncpy(extra, "802.11ab (3)", MAX_WX_STRING); 9255 strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
6095 break; 9256 break;
6096 case IEEE80211_OFDM_MODULATION: 9257 case IEEE_G:
6097 strncpy(extra, "802.11ag (5)", MAX_WX_STRING); 9258 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
6098 break; 9259 break;
6099 default: 9260 case IEEE_A | IEEE_G:
6100 strncpy(extra, "802.11abg (7)", MAX_WX_STRING); 9261 strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
6101 break; 9262 break;
6102 } 9263 case IEEE_B | IEEE_G:
9264 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
9265 break;
9266 case IEEE_A | IEEE_B | IEEE_G:
9267 strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
9268 break;
9269 default:
9270 strncpy(extra, "unknown", MAX_WX_STRING);
6103 break; 9271 break;
6104 } 9272 }
6105 9273
6106 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra); 9274 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
6107 9275
6108 wrqu->data.length = strlen(extra) + 1; 9276 wrqu->data.length = strlen(extra) + 1;
9277 up(&priv->sem);
6109 9278
6110 return 0; 9279 return 0;
6111} 9280}
6112 9281
6113#ifdef CONFIG_IPW_PROMISC 9282static int ipw_wx_set_preamble(struct net_device *dev,
6114static int ipw_wx_set_promisc(struct net_device *dev, 9283 struct iw_request_info *info,
9284 union iwreq_data *wrqu, char *extra)
9285{
9286 struct ipw_priv *priv = ieee80211_priv(dev);
9287 int mode = *(int *)extra;
9288 down(&priv->sem);
9289 /* Switching from SHORT -> LONG requires a disassociation */
9290 if (mode == 1) {
9291 if (!(priv->config & CFG_PREAMBLE_LONG)) {
9292 priv->config |= CFG_PREAMBLE_LONG;
9293
9294 /* Network configuration changed -- force [re]association */
9295 IPW_DEBUG_ASSOC
9296 ("[re]association triggered due to preamble change.\n");
9297 if (!ipw_disassociate(priv))
9298 ipw_associate(priv);
9299 }
9300 goto done;
9301 }
9302
9303 if (mode == 0) {
9304 priv->config &= ~CFG_PREAMBLE_LONG;
9305 goto done;
9306 }
9307 up(&priv->sem);
9308 return -EINVAL;
9309
9310 done:
9311 up(&priv->sem);
9312 return 0;
9313}
9314
9315static int ipw_wx_get_preamble(struct net_device *dev,
9316 struct iw_request_info *info,
9317 union iwreq_data *wrqu, char *extra)
9318{
9319 struct ipw_priv *priv = ieee80211_priv(dev);
9320 down(&priv->sem);
9321 if (priv->config & CFG_PREAMBLE_LONG)
9322 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
9323 else
9324 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
9325 up(&priv->sem);
9326 return 0;
9327}
9328
9329#ifdef CONFIG_IPW2200_MONITOR
9330static int ipw_wx_set_monitor(struct net_device *dev,
6115 struct iw_request_info *info, 9331 struct iw_request_info *info,
6116 union iwreq_data *wrqu, char *extra) 9332 union iwreq_data *wrqu, char *extra)
6117{ 9333{
6118 struct ipw_priv *priv = ieee80211_priv(dev); 9334 struct ipw_priv *priv = ieee80211_priv(dev);
6119 int *parms = (int *)extra; 9335 int *parms = (int *)extra;
6120 int enable = (parms[0] > 0); 9336 int enable = (parms[0] > 0);
6121 9337 down(&priv->sem);
6122 IPW_DEBUG_WX("SET PROMISC: %d %d\n", enable, parms[1]); 9338 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
6123 if (enable) { 9339 if (enable) {
6124 if (priv->ieee->iw_mode != IW_MODE_MONITOR) { 9340 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9341#ifdef CONFIG_IEEE80211_RADIOTAP
9342 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
9343#else
6125 priv->net_dev->type = ARPHRD_IEEE80211; 9344 priv->net_dev->type = ARPHRD_IEEE80211;
6126 ipw_adapter_restart(priv); 9345#endif
9346 queue_work(priv->workqueue, &priv->adapter_restart);
6127 } 9347 }
6128 9348
6129 ipw_set_channel(priv, parms[1]); 9349 ipw_set_channel(priv, parms[1]);
6130 } else { 9350 } else {
6131 if (priv->ieee->iw_mode != IW_MODE_MONITOR) 9351 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9352 up(&priv->sem);
6132 return 0; 9353 return 0;
9354 }
6133 priv->net_dev->type = ARPHRD_ETHER; 9355 priv->net_dev->type = ARPHRD_ETHER;
6134 ipw_adapter_restart(priv); 9356 queue_work(priv->workqueue, &priv->adapter_restart);
6135 } 9357 }
9358 up(&priv->sem);
6136 return 0; 9359 return 0;
6137} 9360}
6138 9361
9362#endif // CONFIG_IPW2200_MONITOR
9363
6139static int ipw_wx_reset(struct net_device *dev, 9364static int ipw_wx_reset(struct net_device *dev,
6140 struct iw_request_info *info, 9365 struct iw_request_info *info,
6141 union iwreq_data *wrqu, char *extra) 9366 union iwreq_data *wrqu, char *extra)
6142{ 9367{
6143 struct ipw_priv *priv = ieee80211_priv(dev); 9368 struct ipw_priv *priv = ieee80211_priv(dev);
6144 IPW_DEBUG_WX("RESET\n"); 9369 IPW_DEBUG_WX("RESET\n");
6145 ipw_adapter_restart(priv); 9370 queue_work(priv->workqueue, &priv->adapter_restart);
9371 return 0;
9372}
9373
9374static int ipw_wx_sw_reset(struct net_device *dev,
9375 struct iw_request_info *info,
9376 union iwreq_data *wrqu, char *extra)
9377{
9378 struct ipw_priv *priv = ieee80211_priv(dev);
9379 union iwreq_data wrqu_sec = {
9380 .encoding = {
9381 .flags = IW_ENCODE_DISABLED,
9382 },
9383 };
9384 int ret;
9385
9386 IPW_DEBUG_WX("SW_RESET\n");
9387
9388 down(&priv->sem);
9389
9390 ret = ipw_sw_reset(priv, 0);
9391 if (!ret) {
9392 free_firmware();
9393 ipw_adapter_restart(priv);
9394 }
9395
9396 /* The SW reset bit might have been toggled on by the 'disable'
9397 * module parameter, so take appropriate action */
9398 ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
9399
9400 up(&priv->sem);
9401 ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
9402 down(&priv->sem);
9403
9404 if (!(priv->status & STATUS_RF_KILL_MASK)) {
9405 /* Configuration likely changed -- force [re]association */
9406 IPW_DEBUG_ASSOC("[re]association triggered due to sw "
9407 "reset.\n");
9408 if (!ipw_disassociate(priv))
9409 ipw_associate(priv);
9410 }
9411
9412 up(&priv->sem);
9413
6146 return 0; 9414 return 0;
6147} 9415}
6148#endif // CONFIG_IPW_PROMISC
6149 9416
6150/* Rebase the WE IOCTLs to zero for the handler array */ 9417/* Rebase the WE IOCTLs to zero for the handler array */
6151#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] 9418#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
6152static iw_handler ipw_wx_handlers[] = { 9419static iw_handler ipw_wx_handlers[] = {
6153 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, 9420 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
6154 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, 9421 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
6155 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 9422 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
6156 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 9423 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
6157 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, 9424 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
6158 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, 9425 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
6159 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, 9426 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
6160 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, 9427 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
6161 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan, 9428 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
6162 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan, 9429 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
6163 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid, 9430 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
6164 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid, 9431 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
6165 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick, 9432 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
6166 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick, 9433 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
6167 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate, 9434 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
6168 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate, 9435 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
6169 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts, 9436 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
6170 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts, 9437 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
6171 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag, 9438 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
6172 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag, 9439 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
6173 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow, 9440 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
6174 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow, 9441 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
6175 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry, 9442 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
6176 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry, 9443 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
6177 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode, 9444 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
6178 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode, 9445 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
6179 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power, 9446 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
6180 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power, 9447 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
9448 IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
9449 IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
9450 IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
9451 IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
9452 IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie,
9453 IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie,
9454 IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme,
9455 IW_IOCTL(SIOCSIWAUTH) = ipw_wx_set_auth,
9456 IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth,
9457 IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext,
9458 IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext,
6181}; 9459};
6182 9460
6183#define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV 9461enum {
6184#define IPW_PRIV_GET_POWER SIOCIWFIRSTPRIV+1 9462 IPW_PRIV_SET_POWER = SIOCIWFIRSTPRIV,
6185#define IPW_PRIV_SET_MODE SIOCIWFIRSTPRIV+2 9463 IPW_PRIV_GET_POWER,
6186#define IPW_PRIV_GET_MODE SIOCIWFIRSTPRIV+3 9464 IPW_PRIV_SET_MODE,
6187#define IPW_PRIV_SET_PROMISC SIOCIWFIRSTPRIV+4 9465 IPW_PRIV_GET_MODE,
6188#define IPW_PRIV_RESET SIOCIWFIRSTPRIV+5 9466 IPW_PRIV_SET_PREAMBLE,
9467 IPW_PRIV_GET_PREAMBLE,
9468 IPW_PRIV_RESET,
9469 IPW_PRIV_SW_RESET,
9470#ifdef CONFIG_IPW2200_MONITOR
9471 IPW_PRIV_SET_MONITOR,
9472#endif
9473};
6189 9474
6190static struct iw_priv_args ipw_priv_args[] = { 9475static struct iw_priv_args ipw_priv_args[] = {
6191 { 9476 {
@@ -6204,14 +9489,25 @@ static struct iw_priv_args ipw_priv_args[] = {
6204 .cmd = IPW_PRIV_GET_MODE, 9489 .cmd = IPW_PRIV_GET_MODE,
6205 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, 9490 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
6206 .name = "get_mode"}, 9491 .name = "get_mode"},
6207#ifdef CONFIG_IPW_PROMISC
6208 { 9492 {
6209 IPW_PRIV_SET_PROMISC, 9493 .cmd = IPW_PRIV_SET_PREAMBLE,
6210 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"}, 9494 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9495 .name = "set_preamble"},
9496 {
9497 .cmd = IPW_PRIV_GET_PREAMBLE,
9498 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,
9499 .name = "get_preamble"},
6211 { 9500 {
6212 IPW_PRIV_RESET, 9501 IPW_PRIV_RESET,
6213 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"}, 9502 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
6214#endif /* CONFIG_IPW_PROMISC */ 9503 {
9504 IPW_PRIV_SW_RESET,
9505 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "sw_reset"},
9506#ifdef CONFIG_IPW2200_MONITOR
9507 {
9508 IPW_PRIV_SET_MONITOR,
9509 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
9510#endif /* CONFIG_IPW2200_MONITOR */
6215}; 9511};
6216 9512
6217static iw_handler ipw_priv_handler[] = { 9513static iw_handler ipw_priv_handler[] = {
@@ -6219,19 +9515,23 @@ static iw_handler ipw_priv_handler[] = {
6219 ipw_wx_get_powermode, 9515 ipw_wx_get_powermode,
6220 ipw_wx_set_wireless_mode, 9516 ipw_wx_set_wireless_mode,
6221 ipw_wx_get_wireless_mode, 9517 ipw_wx_get_wireless_mode,
6222#ifdef CONFIG_IPW_PROMISC 9518 ipw_wx_set_preamble,
6223 ipw_wx_set_promisc, 9519 ipw_wx_get_preamble,
6224 ipw_wx_reset, 9520 ipw_wx_reset,
9521 ipw_wx_sw_reset,
9522#ifdef CONFIG_IPW2200_MONITOR
9523 ipw_wx_set_monitor,
6225#endif 9524#endif
6226}; 9525};
6227 9526
6228static struct iw_handler_def ipw_wx_handler_def = { 9527static struct iw_handler_def ipw_wx_handler_def = {
6229 .standard = ipw_wx_handlers, 9528 .standard = ipw_wx_handlers,
6230 .num_standard = ARRAY_SIZE(ipw_wx_handlers), 9529 .num_standard = ARRAY_SIZE(ipw_wx_handlers),
6231 .num_private = ARRAY_SIZE(ipw_priv_handler), 9530 .num_private = ARRAY_SIZE(ipw_priv_handler),
6232 .num_private_args = ARRAY_SIZE(ipw_priv_args), 9531 .num_private_args = ARRAY_SIZE(ipw_priv_args),
6233 .private = ipw_priv_handler, 9532 .private = ipw_priv_handler,
6234 .private_args = ipw_priv_args, 9533 .private_args = ipw_priv_args,
9534 .get_wireless_stats = ipw_get_wireless_stats,
6235}; 9535};
6236 9536
6237/* 9537/*
@@ -6246,8 +9546,8 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
6246 9546
6247 wstats = &priv->wstats; 9547 wstats = &priv->wstats;
6248 9548
6249 /* if hw is disabled, then ipw2100_get_ordinal() can't be called. 9549 /* if hw is disabled, then ipw_get_ordinal() can't be called.
6250 * ipw2100_wx_wireless_stats seems to be called before fw is 9550 * netdev->get_wireless_stats seems to be called before fw is
6251 * initialized. STATUS_ASSOCIATED will only be set if the hw is up 9551 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
6252 * and associated; if not associcated, the values are all meaningless 9552 * and associated; if not associcated, the values are all meaningless
6253 * anyway, so set them all to NULL and INVALID */ 9553 * anyway, so set them all to NULL and INVALID */
@@ -6298,7 +9598,7 @@ static inline void init_sys_config(struct ipw_sys_config *sys_config)
6298 sys_config->dot11g_auto_detection = 0; 9598 sys_config->dot11g_auto_detection = 0;
6299 sys_config->enable_cts_to_self = 0; 9599 sys_config->enable_cts_to_self = 0;
6300 sys_config->bt_coexist_collision_thr = 0; 9600 sys_config->bt_coexist_collision_thr = 0;
6301 sys_config->pass_noise_stats_to_host = 1; 9601 sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256
6302} 9602}
6303 9603
6304static int ipw_net_open(struct net_device *dev) 9604static int ipw_net_open(struct net_device *dev)
@@ -6306,9 +9606,11 @@ static int ipw_net_open(struct net_device *dev)
6306 struct ipw_priv *priv = ieee80211_priv(dev); 9606 struct ipw_priv *priv = ieee80211_priv(dev);
6307 IPW_DEBUG_INFO("dev->open\n"); 9607 IPW_DEBUG_INFO("dev->open\n");
6308 /* we should be verifying the device is ready to be opened */ 9608 /* we should be verifying the device is ready to be opened */
9609 down(&priv->sem);
6309 if (!(priv->status & STATUS_RF_KILL_MASK) && 9610 if (!(priv->status & STATUS_RF_KILL_MASK) &&
6310 (priv->status & STATUS_ASSOCIATED)) 9611 (priv->status & STATUS_ASSOCIATED))
6311 netif_start_queue(dev); 9612 netif_start_queue(dev);
9613 up(&priv->sem);
6312 return 0; 9614 return 0;
6313} 9615}
6314 9616
@@ -6326,22 +9628,34 @@ modify to send one tfd per fragment instead of using chunking. otherwise
6326we need to heavily modify the ieee80211_skb_to_txb. 9628we need to heavily modify the ieee80211_skb_to_txb.
6327*/ 9629*/
6328 9630
6329static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) 9631static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
9632 int pri)
6330{ 9633{
6331 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) 9634 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
6332 txb->fragments[0]->data; 9635 txb->fragments[0]->data;
6333 int i = 0; 9636 int i = 0;
6334 struct tfd_frame *tfd; 9637 struct tfd_frame *tfd;
9638#ifdef CONFIG_IPW_QOS
9639 int tx_id = ipw_get_tx_queue_number(priv, pri);
9640 struct clx2_tx_queue *txq = &priv->txq[tx_id];
9641#else
6335 struct clx2_tx_queue *txq = &priv->txq[0]; 9642 struct clx2_tx_queue *txq = &priv->txq[0];
9643#endif
6336 struct clx2_queue *q = &txq->q; 9644 struct clx2_queue *q = &txq->q;
6337 u8 id, hdr_len, unicast; 9645 u8 id, hdr_len, unicast;
6338 u16 remaining_bytes; 9646 u16 remaining_bytes;
9647 int fc;
9648
9649 /* If there isn't room in the queue, we return busy and let the
9650 * network stack requeue the packet for us */
9651 if (ipw_queue_space(q) < q->high_mark)
9652 return NETDEV_TX_BUSY;
6339 9653
6340 switch (priv->ieee->iw_mode) { 9654 switch (priv->ieee->iw_mode) {
6341 case IW_MODE_ADHOC: 9655 case IW_MODE_ADHOC:
6342 hdr_len = IEEE80211_3ADDR_LEN; 9656 hdr_len = IEEE80211_3ADDR_LEN;
6343 unicast = !is_broadcast_ether_addr(hdr->addr1) && 9657 unicast = !(is_multicast_ether_addr(hdr->addr1) ||
6344 !is_multicast_ether_addr(hdr->addr1); 9658 is_broadcast_ether_addr(hdr->addr1));
6345 id = ipw_find_station(priv, hdr->addr1); 9659 id = ipw_find_station(priv, hdr->addr1);
6346 if (id == IPW_INVALID_STATION) { 9660 if (id == IPW_INVALID_STATION) {
6347 id = ipw_add_station(priv, hdr->addr1); 9661 id = ipw_add_station(priv, hdr->addr1);
@@ -6356,8 +9670,8 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6356 9670
6357 case IW_MODE_INFRA: 9671 case IW_MODE_INFRA:
6358 default: 9672 default:
6359 unicast = !is_broadcast_ether_addr(hdr->addr3) && 9673 unicast = !(is_multicast_ether_addr(hdr->addr3) ||
6360 !is_multicast_ether_addr(hdr->addr3); 9674 is_broadcast_ether_addr(hdr->addr3));
6361 hdr_len = IEEE80211_3ADDR_LEN; 9675 hdr_len = IEEE80211_3ADDR_LEN;
6362 id = 0; 9676 id = 0;
6363 break; 9677 break;
@@ -6372,26 +9686,83 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6372 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK; 9686 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
6373 9687
6374 tfd->u.data.cmd_id = DINO_CMD_TX; 9688 tfd->u.data.cmd_id = DINO_CMD_TX;
6375 tfd->u.data.len = txb->payload_size; 9689 tfd->u.data.len = cpu_to_le16(txb->payload_size);
6376 remaining_bytes = txb->payload_size; 9690 remaining_bytes = txb->payload_size;
6377 if (unlikely(!unicast))
6378 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP;
6379 else
6380 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP | DCT_FLAG_ACK_REQD;
6381 9691
6382 if (priv->assoc_request.ieee_mode == IPW_B_MODE) 9692 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
6383 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_CCK; 9693 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
6384 else 9694 else
6385 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_OFDM; 9695 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_OFDM;
6386 9696
6387 if (priv->config & CFG_PREAMBLE) 9697 if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
6388 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREMBL; 9698 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
9699
9700 fc = le16_to_cpu(hdr->frame_ctl);
9701 hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);
6389 9702
6390 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len); 9703 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
6391 9704
9705 if (likely(unicast))
9706 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9707
9708 if (txb->encrypted && !priv->ieee->host_encrypt) {
9709 switch (priv->ieee->sec.level) {
9710 case SEC_LEVEL_3:
9711 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9712 IEEE80211_FCTL_PROTECTED;
9713 /* XXX: ACK flag must be set for CCMP even if it
9714 * is a multicast/broadcast packet, because CCMP
9715 * group communication encrypted by GTK is
9716 * actually done by the AP. */
9717 if (!unicast)
9718 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9719
9720 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9721 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_CCM;
9722 tfd->u.data.key_index = 0;
9723 tfd->u.data.key_index |= DCT_WEP_INDEX_USE_IMMEDIATE;
9724 break;
9725 case SEC_LEVEL_2:
9726 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9727 IEEE80211_FCTL_PROTECTED;
9728 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9729 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP;
9730 tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE;
9731 break;
9732 case SEC_LEVEL_1:
9733 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9734 IEEE80211_FCTL_PROTECTED;
9735 tfd->u.data.key_index = priv->ieee->tx_keyidx;
9736 if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <=
9737 40)
9738 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
9739 else
9740 tfd->u.data.key_index |= DCT_WEP_KEY_128Bit;
9741 break;
9742 case SEC_LEVEL_0:
9743 break;
9744 default:
9745 printk(KERN_ERR "Unknow security level %d\n",
9746 priv->ieee->sec.level);
9747 break;
9748 }
9749 } else
9750 /* No hardware encryption */
9751 tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP;
9752
9753#ifdef CONFIG_IPW_QOS
9754 ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data), unicast);
9755#endif /* CONFIG_IPW_QOS */
9756
6392 /* payload */ 9757 /* payload */
6393 tfd->u.data.num_chunks = min((u8) (NUM_TFD_CHUNKS - 2), txb->nr_frags); 9758 tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
6394 for (i = 0; i < tfd->u.data.num_chunks; i++) { 9759 txb->nr_frags));
9760 IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
9761 txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
9762 for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
9763 IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
9764 i, le32_to_cpu(tfd->u.data.num_chunks),
9765 txb->fragments[i]->len - hdr_len);
6395 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n", 9766 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
6396 i, tfd->u.data.num_chunks, 9767 i, tfd->u.data.num_chunks,
6397 txb->fragments[i]->len - hdr_len); 9768 txb->fragments[i]->len - hdr_len);
@@ -6399,11 +9770,13 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6399 txb->fragments[i]->len - hdr_len); 9770 txb->fragments[i]->len - hdr_len);
6400 9771
6401 tfd->u.data.chunk_ptr[i] = 9772 tfd->u.data.chunk_ptr[i] =
6402 pci_map_single(priv->pci_dev, 9773 cpu_to_le32(pci_map_single
6403 txb->fragments[i]->data + hdr_len, 9774 (priv->pci_dev,
6404 txb->fragments[i]->len - hdr_len, 9775 txb->fragments[i]->data + hdr_len,
6405 PCI_DMA_TODEVICE); 9776 txb->fragments[i]->len - hdr_len,
6406 tfd->u.data.chunk_len[i] = txb->fragments[i]->len - hdr_len; 9777 PCI_DMA_TODEVICE));
9778 tfd->u.data.chunk_len[i] =
9779 cpu_to_le16(txb->fragments[i]->len - hdr_len);
6407 } 9780 }
6408 9781
6409 if (i != txb->nr_frags) { 9782 if (i != txb->nr_frags) {
@@ -6418,9 +9791,10 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6418 remaining_bytes); 9791 remaining_bytes);
6419 skb = alloc_skb(remaining_bytes, GFP_ATOMIC); 9792 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
6420 if (skb != NULL) { 9793 if (skb != NULL) {
6421 tfd->u.data.chunk_len[i] = remaining_bytes; 9794 tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
6422 for (j = i; j < txb->nr_frags; j++) { 9795 for (j = i; j < txb->nr_frags; j++) {
6423 int size = txb->fragments[j]->len - hdr_len; 9796 int size = txb->fragments[j]->len - hdr_len;
9797
6424 printk(KERN_INFO "Adding frag %d %d...\n", 9798 printk(KERN_INFO "Adding frag %d %d...\n",
6425 j, size); 9799 j, size);
6426 memcpy(skb_put(skb, size), 9800 memcpy(skb_put(skb, size),
@@ -6429,10 +9803,14 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6429 dev_kfree_skb_any(txb->fragments[i]); 9803 dev_kfree_skb_any(txb->fragments[i]);
6430 txb->fragments[i] = skb; 9804 txb->fragments[i] = skb;
6431 tfd->u.data.chunk_ptr[i] = 9805 tfd->u.data.chunk_ptr[i] =
6432 pci_map_single(priv->pci_dev, skb->data, 9806 cpu_to_le32(pci_map_single
6433 tfd->u.data.chunk_len[i], 9807 (priv->pci_dev, skb->data,
6434 PCI_DMA_TODEVICE); 9808 tfd->u.data.chunk_len[i],
6435 tfd->u.data.num_chunks++; 9809 PCI_DMA_TODEVICE));
9810
9811 tfd->u.data.num_chunks =
9812 cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) +
9813 1);
6436 } 9814 }
6437 } 9815 }
6438 9816
@@ -6440,14 +9818,28 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6440 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); 9818 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
6441 ipw_write32(priv, q->reg_w, q->first_empty); 9819 ipw_write32(priv, q->reg_w, q->first_empty);
6442 9820
6443 if (ipw_queue_space(q) < q->high_mark) 9821 return NETDEV_TX_OK;
6444 netif_stop_queue(priv->net_dev);
6445
6446 return;
6447 9822
6448 drop: 9823 drop:
6449 IPW_DEBUG_DROP("Silently dropping Tx packet.\n"); 9824 IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
6450 ieee80211_txb_free(txb); 9825 ieee80211_txb_free(txb);
9826 return NETDEV_TX_OK;
9827}
9828
9829static int ipw_net_is_queue_full(struct net_device *dev, int pri)
9830{
9831 struct ipw_priv *priv = ieee80211_priv(dev);
9832#ifdef CONFIG_IPW_QOS
9833 int tx_id = ipw_get_tx_queue_number(priv, pri);
9834 struct clx2_tx_queue *txq = &priv->txq[tx_id];
9835#else
9836 struct clx2_tx_queue *txq = &priv->txq[0];
9837#endif /* CONFIG_IPW_QOS */
9838
9839 if (ipw_queue_space(&txq->q) < txq->q.high_mark)
9840 return 1;
9841
9842 return 0;
6451} 9843}
6452 9844
6453static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, 9845static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
@@ -6455,9 +9847,9 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
6455{ 9847{
6456 struct ipw_priv *priv = ieee80211_priv(dev); 9848 struct ipw_priv *priv = ieee80211_priv(dev);
6457 unsigned long flags; 9849 unsigned long flags;
9850 int ret;
6458 9851
6459 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size); 9852 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
6460
6461 spin_lock_irqsave(&priv->lock, flags); 9853 spin_lock_irqsave(&priv->lock, flags);
6462 9854
6463 if (!(priv->status & STATUS_ASSOCIATED)) { 9855 if (!(priv->status & STATUS_ASSOCIATED)) {
@@ -6467,10 +9859,12 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
6467 goto fail_unlock; 9859 goto fail_unlock;
6468 } 9860 }
6469 9861
6470 ipw_tx_skb(priv, txb); 9862 ret = ipw_tx_skb(priv, txb, pri);
6471 9863 if (ret == NETDEV_TX_OK)
9864 __ipw_led_activity_on(priv);
6472 spin_unlock_irqrestore(&priv->lock, flags); 9865 spin_unlock_irqrestore(&priv->lock, flags);
6473 return 0; 9866
9867 return ret;
6474 9868
6475 fail_unlock: 9869 fail_unlock:
6476 spin_unlock_irqrestore(&priv->lock, flags); 9870 spin_unlock_irqrestore(&priv->lock, flags);
@@ -6497,11 +9891,13 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
6497 struct sockaddr *addr = p; 9891 struct sockaddr *addr = p;
6498 if (!is_valid_ether_addr(addr->sa_data)) 9892 if (!is_valid_ether_addr(addr->sa_data))
6499 return -EADDRNOTAVAIL; 9893 return -EADDRNOTAVAIL;
9894 down(&priv->sem);
6500 priv->config |= CFG_CUSTOM_MAC; 9895 priv->config |= CFG_CUSTOM_MAC;
6501 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); 9896 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
6502 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n", 9897 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
6503 priv->net_dev->name, MAC_ARG(priv->mac_addr)); 9898 priv->net_dev->name, MAC_ARG(priv->mac_addr));
6504 ipw_adapter_restart(priv); 9899 queue_work(priv->workqueue, &priv->adapter_restart);
9900 up(&priv->sem);
6505 return 0; 9901 return 0;
6506} 9902}
6507 9903
@@ -6524,7 +9920,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6524 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)", 9920 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
6525 vers, date); 9921 vers, date);
6526 strcpy(info->bus_info, pci_name(p->pci_dev)); 9922 strcpy(info->bus_info, pci_name(p->pci_dev));
6527 info->eedump_len = CX2_EEPROM_IMAGE_SIZE; 9923 info->eedump_len = IPW_EEPROM_IMAGE_SIZE;
6528} 9924}
6529 9925
6530static u32 ipw_ethtool_get_link(struct net_device *dev) 9926static u32 ipw_ethtool_get_link(struct net_device *dev)
@@ -6535,7 +9931,7 @@ static u32 ipw_ethtool_get_link(struct net_device *dev)
6535 9931
6536static int ipw_ethtool_get_eeprom_len(struct net_device *dev) 9932static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
6537{ 9933{
6538 return CX2_EEPROM_IMAGE_SIZE; 9934 return IPW_EEPROM_IMAGE_SIZE;
6539} 9935}
6540 9936
6541static int ipw_ethtool_get_eeprom(struct net_device *dev, 9937static int ipw_ethtool_get_eeprom(struct net_device *dev,
@@ -6543,10 +9939,11 @@ static int ipw_ethtool_get_eeprom(struct net_device *dev,
6543{ 9939{
6544 struct ipw_priv *p = ieee80211_priv(dev); 9940 struct ipw_priv *p = ieee80211_priv(dev);
6545 9941
6546 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) 9942 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
6547 return -EINVAL; 9943 return -EINVAL;
6548 9944 down(&p->sem);
6549 memcpy(bytes, &((u8 *) p->eeprom)[eeprom->offset], eeprom->len); 9945 memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
9946 up(&p->sem);
6550 return 0; 9947 return 0;
6551} 9948}
6552 9949
@@ -6556,23 +9953,23 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
6556 struct ipw_priv *p = ieee80211_priv(dev); 9953 struct ipw_priv *p = ieee80211_priv(dev);
6557 int i; 9954 int i;
6558 9955
6559 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) 9956 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
6560 return -EINVAL; 9957 return -EINVAL;
6561 9958 down(&p->sem);
6562 memcpy(&((u8 *) p->eeprom)[eeprom->offset], bytes, eeprom->len); 9959 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
6563 for (i = IPW_EEPROM_DATA; 9960 for (i = IPW_EEPROM_DATA;
6564 i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; i++) 9961 i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
6565 ipw_write8(p, i, p->eeprom[i]); 9962 ipw_write8(p, i, p->eeprom[i]);
6566 9963 up(&p->sem);
6567 return 0; 9964 return 0;
6568} 9965}
6569 9966
6570static struct ethtool_ops ipw_ethtool_ops = { 9967static struct ethtool_ops ipw_ethtool_ops = {
6571 .get_link = ipw_ethtool_get_link, 9968 .get_link = ipw_ethtool_get_link,
6572 .get_drvinfo = ipw_ethtool_get_drvinfo, 9969 .get_drvinfo = ipw_ethtool_get_drvinfo,
6573 .get_eeprom_len = ipw_ethtool_get_eeprom_len, 9970 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
6574 .get_eeprom = ipw_ethtool_get_eeprom, 9971 .get_eeprom = ipw_ethtool_get_eeprom,
6575 .set_eeprom = ipw_ethtool_set_eeprom, 9972 .set_eeprom = ipw_ethtool_set_eeprom,
6576}; 9973};
6577 9974
6578static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) 9975static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
@@ -6590,8 +9987,8 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6590 goto none; 9987 goto none;
6591 } 9988 }
6592 9989
6593 inta = ipw_read32(priv, CX2_INTA_RW); 9990 inta = ipw_read32(priv, IPW_INTA_RW);
6594 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R); 9991 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
6595 9992
6596 if (inta == 0xFFFFFFFF) { 9993 if (inta == 0xFFFFFFFF) {
6597 /* Hardware disappeared */ 9994 /* Hardware disappeared */
@@ -6599,7 +9996,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6599 goto none; 9996 goto none;
6600 } 9997 }
6601 9998
6602 if (!(inta & (CX2_INTA_MASK_ALL & inta_mask))) { 9999 if (!(inta & (IPW_INTA_MASK_ALL & inta_mask))) {
6603 /* Shared interrupt */ 10000 /* Shared interrupt */
6604 goto none; 10001 goto none;
6605 } 10002 }
@@ -6608,8 +10005,8 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6608 ipw_disable_interrupts(priv); 10005 ipw_disable_interrupts(priv);
6609 10006
6610 /* ack current interrupts */ 10007 /* ack current interrupts */
6611 inta &= (CX2_INTA_MASK_ALL & inta_mask); 10008 inta &= (IPW_INTA_MASK_ALL & inta_mask);
6612 ipw_write32(priv, CX2_INTA_RW, inta); 10009 ipw_write32(priv, IPW_INTA_RW, inta);
6613 10010
6614 /* Cache INTA value for our tasklet */ 10011 /* Cache INTA value for our tasklet */
6615 priv->isr_inta = inta; 10012 priv->isr_inta = inta;
@@ -6655,28 +10052,116 @@ static void ipw_rf_kill(void *adapter)
6655 spin_unlock_irqrestore(&priv->lock, flags); 10052 spin_unlock_irqrestore(&priv->lock, flags);
6656} 10053}
6657 10054
10055static void ipw_bg_rf_kill(void *data)
10056{
10057 struct ipw_priv *priv = data;
10058 down(&priv->sem);
10059 ipw_rf_kill(data);
10060 up(&priv->sem);
10061}
10062
10063void ipw_link_up(struct ipw_priv *priv)
10064{
10065 priv->last_seq_num = -1;
10066 priv->last_frag_num = -1;
10067 priv->last_packet_time = 0;
10068
10069 netif_carrier_on(priv->net_dev);
10070 if (netif_queue_stopped(priv->net_dev)) {
10071 IPW_DEBUG_NOTIF("waking queue\n");
10072 netif_wake_queue(priv->net_dev);
10073 } else {
10074 IPW_DEBUG_NOTIF("starting queue\n");
10075 netif_start_queue(priv->net_dev);
10076 }
10077
10078 cancel_delayed_work(&priv->request_scan);
10079 ipw_reset_stats(priv);
10080 /* Ensure the rate is updated immediately */
10081 priv->last_rate = ipw_get_current_rate(priv);
10082 ipw_gather_stats(priv);
10083 ipw_led_link_up(priv);
10084 notify_wx_assoc_event(priv);
10085
10086 if (priv->config & CFG_BACKGROUND_SCAN)
10087 queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
10088}
10089
10090static void ipw_bg_link_up(void *data)
10091{
10092 struct ipw_priv *priv = data;
10093 down(&priv->sem);
10094 ipw_link_up(data);
10095 up(&priv->sem);
10096}
10097
10098void ipw_link_down(struct ipw_priv *priv)
10099{
10100 ipw_led_link_down(priv);
10101 netif_carrier_off(priv->net_dev);
10102 netif_stop_queue(priv->net_dev);
10103 notify_wx_assoc_event(priv);
10104
10105 /* Cancel any queued work ... */
10106 cancel_delayed_work(&priv->request_scan);
10107 cancel_delayed_work(&priv->adhoc_check);
10108 cancel_delayed_work(&priv->gather_stats);
10109
10110 ipw_reset_stats(priv);
10111
10112 if (!(priv->status & STATUS_EXIT_PENDING)) {
10113 /* Queue up another scan... */
10114 queue_work(priv->workqueue, &priv->request_scan);
10115 }
10116}
10117
10118static void ipw_bg_link_down(void *data)
10119{
10120 struct ipw_priv *priv = data;
10121 down(&priv->sem);
10122 ipw_link_down(data);
10123 up(&priv->sem);
10124}
10125
6658static int ipw_setup_deferred_work(struct ipw_priv *priv) 10126static int ipw_setup_deferred_work(struct ipw_priv *priv)
6659{ 10127{
6660 int ret = 0; 10128 int ret = 0;
6661 10129
6662 priv->workqueue = create_workqueue(DRV_NAME); 10130 priv->workqueue = create_workqueue(DRV_NAME);
6663 init_waitqueue_head(&priv->wait_command_queue); 10131 init_waitqueue_head(&priv->wait_command_queue);
6664 10132 init_waitqueue_head(&priv->wait_state);
6665 INIT_WORK(&priv->adhoc_check, ipw_adhoc_check, priv); 10133
6666 INIT_WORK(&priv->associate, ipw_associate, priv); 10134 INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
6667 INIT_WORK(&priv->disassociate, ipw_disassociate, priv); 10135 INIT_WORK(&priv->associate, ipw_bg_associate, priv);
6668 INIT_WORK(&priv->rx_replenish, ipw_rx_queue_replenish, priv); 10136 INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
6669 INIT_WORK(&priv->adapter_restart, ipw_adapter_restart, priv); 10137 INIT_WORK(&priv->system_config, ipw_system_config, priv);
6670 INIT_WORK(&priv->rf_kill, ipw_rf_kill, priv); 10138 INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
6671 INIT_WORK(&priv->up, (void (*)(void *))ipw_up, priv); 10139 INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
6672 INIT_WORK(&priv->down, (void (*)(void *))ipw_down, priv); 10140 INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
10141 INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv);
10142 INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
6673 INIT_WORK(&priv->request_scan, 10143 INIT_WORK(&priv->request_scan,
6674 (void (*)(void *))ipw_request_scan, priv); 10144 (void (*)(void *))ipw_request_scan, priv);
6675 INIT_WORK(&priv->gather_stats, 10145 INIT_WORK(&priv->gather_stats,
6676 (void (*)(void *))ipw_gather_stats, priv); 10146 (void (*)(void *))ipw_bg_gather_stats, priv);
6677 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_abort_scan, priv); 10147 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
6678 INIT_WORK(&priv->roam, ipw_roam, priv); 10148 INIT_WORK(&priv->roam, ipw_bg_roam, priv);
6679 INIT_WORK(&priv->scan_check, ipw_scan_check, priv); 10149 INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv);
10150 INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv);
10151 INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv);
10152 INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on,
10153 priv);
10154 INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off,
10155 priv);
10156 INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off,
10157 priv);
10158 INIT_WORK(&priv->merge_networks,
10159 (void (*)(void *))ipw_merge_adhoc_network, priv);
10160
10161#ifdef CONFIG_IPW_QOS
10162 INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate,
10163 priv);
10164#endif /* CONFIG_IPW_QOS */
6680 10165
6681 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 10166 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
6682 ipw_irq_tasklet, (unsigned long)priv); 10167 ipw_irq_tasklet, (unsigned long)priv);
@@ -6689,34 +10174,36 @@ static void shim__set_security(struct net_device *dev,
6689{ 10174{
6690 struct ipw_priv *priv = ieee80211_priv(dev); 10175 struct ipw_priv *priv = ieee80211_priv(dev);
6691 int i; 10176 int i;
6692
6693 for (i = 0; i < 4; i++) { 10177 for (i = 0; i < 4; i++) {
6694 if (sec->flags & (1 << i)) { 10178 if (sec->flags & (1 << i)) {
6695 priv->sec.key_sizes[i] = sec->key_sizes[i]; 10179 priv->ieee->sec.encode_alg[i] = sec->encode_alg[i];
10180 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
6696 if (sec->key_sizes[i] == 0) 10181 if (sec->key_sizes[i] == 0)
6697 priv->sec.flags &= ~(1 << i); 10182 priv->ieee->sec.flags &= ~(1 << i);
6698 else 10183 else {
6699 memcpy(priv->sec.keys[i], sec->keys[i], 10184 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
6700 sec->key_sizes[i]); 10185 sec->key_sizes[i]);
6701 priv->sec.flags |= (1 << i); 10186 priv->ieee->sec.flags |= (1 << i);
10187 }
6702 priv->status |= STATUS_SECURITY_UPDATED; 10188 priv->status |= STATUS_SECURITY_UPDATED;
6703 } 10189 } else if (sec->level != SEC_LEVEL_1)
10190 priv->ieee->sec.flags &= ~(1 << i);
6704 } 10191 }
6705 10192
6706 if ((sec->flags & SEC_ACTIVE_KEY) && 10193 if (sec->flags & SEC_ACTIVE_KEY) {
6707 priv->sec.active_key != sec->active_key) {
6708 if (sec->active_key <= 3) { 10194 if (sec->active_key <= 3) {
6709 priv->sec.active_key = sec->active_key; 10195 priv->ieee->sec.active_key = sec->active_key;
6710 priv->sec.flags |= SEC_ACTIVE_KEY; 10196 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
6711 } else 10197 } else
6712 priv->sec.flags &= ~SEC_ACTIVE_KEY; 10198 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
6713 priv->status |= STATUS_SECURITY_UPDATED; 10199 priv->status |= STATUS_SECURITY_UPDATED;
6714 } 10200 } else
10201 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
6715 10202
6716 if ((sec->flags & SEC_AUTH_MODE) && 10203 if ((sec->flags & SEC_AUTH_MODE) &&
6717 (priv->sec.auth_mode != sec->auth_mode)) { 10204 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
6718 priv->sec.auth_mode = sec->auth_mode; 10205 priv->ieee->sec.auth_mode = sec->auth_mode;
6719 priv->sec.flags |= SEC_AUTH_MODE; 10206 priv->ieee->sec.flags |= SEC_AUTH_MODE;
6720 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY) 10207 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)
6721 priv->capability |= CAP_SHARED_KEY; 10208 priv->capability |= CAP_SHARED_KEY;
6722 else 10209 else
@@ -6724,9 +10211,9 @@ static void shim__set_security(struct net_device *dev,
6724 priv->status |= STATUS_SECURITY_UPDATED; 10211 priv->status |= STATUS_SECURITY_UPDATED;
6725 } 10212 }
6726 10213
6727 if (sec->flags & SEC_ENABLED && priv->sec.enabled != sec->enabled) { 10214 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
6728 priv->sec.flags |= SEC_ENABLED; 10215 priv->ieee->sec.flags |= SEC_ENABLED;
6729 priv->sec.enabled = sec->enabled; 10216 priv->ieee->sec.enabled = sec->enabled;
6730 priv->status |= STATUS_SECURITY_UPDATED; 10217 priv->status |= STATUS_SECURITY_UPDATED;
6731 if (sec->enabled) 10218 if (sec->enabled)
6732 priv->capability |= CAP_PRIVACY_ON; 10219 priv->capability |= CAP_PRIVACY_ON;
@@ -6734,12 +10221,18 @@ static void shim__set_security(struct net_device *dev,
6734 priv->capability &= ~CAP_PRIVACY_ON; 10221 priv->capability &= ~CAP_PRIVACY_ON;
6735 } 10222 }
6736 10223
6737 if (sec->flags & SEC_LEVEL && priv->sec.level != sec->level) { 10224 if (sec->flags & SEC_ENCRYPT)
6738 priv->sec.level = sec->level; 10225 priv->ieee->sec.encrypt = sec->encrypt;
6739 priv->sec.flags |= SEC_LEVEL; 10226
10227 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
10228 priv->ieee->sec.level = sec->level;
10229 priv->ieee->sec.flags |= SEC_LEVEL;
6740 priv->status |= STATUS_SECURITY_UPDATED; 10230 priv->status |= STATUS_SECURITY_UPDATED;
6741 } 10231 }
6742 10232
10233 if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))
10234 ipw_set_hwcrypto_keys(priv);
10235
6743 /* To match current functionality of ipw2100 (which works well w/ 10236 /* To match current functionality of ipw2100 (which works well w/
6744 * various supplicants, we don't force a disassociate if the 10237 * various supplicants, we don't force a disassociate if the
6745 * privacy capability changes ... */ 10238 * privacy capability changes ... */
@@ -6788,29 +10281,10 @@ static int init_supported_rates(struct ipw_priv *priv,
6788 10281
6789static int ipw_config(struct ipw_priv *priv) 10282static int ipw_config(struct ipw_priv *priv)
6790{ 10283{
6791 int i;
6792 struct ipw_tx_power tx_power;
6793
6794 memset(&priv->sys_config, 0, sizeof(priv->sys_config));
6795 memset(&tx_power, 0, sizeof(tx_power));
6796
6797 /* This is only called from ipw_up, which resets/reloads the firmware 10284 /* This is only called from ipw_up, which resets/reloads the firmware
6798 so, we don't need to first disable the card before we configure 10285 so, we don't need to first disable the card before we configure
6799 it */ 10286 it */
6800 10287 if (ipw_set_tx_power(priv))
6801 /* configure device for 'G' band */
6802 tx_power.ieee_mode = IPW_G_MODE;
6803 tx_power.num_channels = 11;
6804 for (i = 0; i < 11; i++) {
6805 tx_power.channels_tx_power[i].channel_number = i + 1;
6806 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
6807 }
6808 if (ipw_send_tx_power(priv, &tx_power))
6809 goto error;
6810
6811 /* configure device to also handle 'B' band */
6812 tx_power.ieee_mode = IPW_B_MODE;
6813 if (ipw_send_tx_power(priv, &tx_power))
6814 goto error; 10288 goto error;
6815 10289
6816 /* initialize adapter address */ 10290 /* initialize adapter address */
@@ -6819,6 +10293,11 @@ static int ipw_config(struct ipw_priv *priv)
6819 10293
6820 /* set basic system config settings */ 10294 /* set basic system config settings */
6821 init_sys_config(&priv->sys_config); 10295 init_sys_config(&priv->sys_config);
10296 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
10297 priv->sys_config.answer_broadcast_ssid_probe = 1;
10298 else
10299 priv->sys_config.answer_broadcast_ssid_probe = 0;
10300
6822 if (ipw_send_system_config(priv, &priv->sys_config)) 10301 if (ipw_send_system_config(priv, &priv->sys_config))
6823 goto error; 10302 goto error;
6824 10303
@@ -6831,6 +10310,10 @@ static int ipw_config(struct ipw_priv *priv)
6831 if (ipw_send_rts_threshold(priv, priv->rts_threshold)) 10310 if (ipw_send_rts_threshold(priv, priv->rts_threshold))
6832 goto error; 10311 goto error;
6833 } 10312 }
10313#ifdef CONFIG_IPW_QOS
10314 IPW_DEBUG_QOS("QoS: call ipw_qos_activate\n");
10315 ipw_qos_activate(priv, NULL);
10316#endif /* CONFIG_IPW_QOS */
6834 10317
6835 if (ipw_set_random_seed(priv)) 10318 if (ipw_set_random_seed(priv))
6836 goto error; 10319 goto error;
@@ -6839,9 +10322,17 @@ static int ipw_config(struct ipw_priv *priv)
6839 if (ipw_send_host_complete(priv)) 10322 if (ipw_send_host_complete(priv))
6840 goto error; 10323 goto error;
6841 10324
6842 /* If configured to try and auto-associate, kick off a scan */ 10325 priv->status |= STATUS_INIT;
6843 if ((priv->config & CFG_ASSOCIATE) && ipw_request_scan(priv)) 10326
6844 goto error; 10327 ipw_led_init(priv);
10328 ipw_led_radio_on(priv);
10329 priv->notif_missed_beacons = 0;
10330
10331 /* Set hardware WEP key if it is configured. */
10332 if ((priv->capability & CAP_PRIVACY_ON) &&
10333 (priv->ieee->sec.level == SEC_LEVEL_1) &&
10334 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
10335 ipw_set_hwcrypto_keys(priv);
6845 10336
6846 return 0; 10337 return 0;
6847 10338
@@ -6849,20 +10340,379 @@ static int ipw_config(struct ipw_priv *priv)
6849 return -EIO; 10340 return -EIO;
6850} 10341}
6851 10342
10343/*
10344 * NOTE:
10345 *
10346 * These tables have been tested in conjunction with the
10347 * Intel PRO/Wireless 2200BG and 2915ABG Network Connection Adapters.
10348 *
10349 * Altering this values, using it on other hardware, or in geographies
10350 * not intended for resale of the above mentioned Intel adapters has
10351 * not been tested.
10352 *
10353 */
10354static const struct ieee80211_geo ipw_geos[] = {
10355 { /* Restricted */
10356 "---",
10357 .bg_channels = 11,
10358 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10359 {2427, 4}, {2432, 5}, {2437, 6},
10360 {2442, 7}, {2447, 8}, {2452, 9},
10361 {2457, 10}, {2462, 11}},
10362 },
10363
10364 { /* Custom US/Canada */
10365 "ZZF",
10366 .bg_channels = 11,
10367 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10368 {2427, 4}, {2432, 5}, {2437, 6},
10369 {2442, 7}, {2447, 8}, {2452, 9},
10370 {2457, 10}, {2462, 11}},
10371 .a_channels = 8,
10372 .a = {{5180, 36},
10373 {5200, 40},
10374 {5220, 44},
10375 {5240, 48},
10376 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10377 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10378 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10379 {5320, 64, IEEE80211_CH_PASSIVE_ONLY}},
10380 },
10381
10382 { /* Rest of World */
10383 "ZZD",
10384 .bg_channels = 13,
10385 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10386 {2427, 4}, {2432, 5}, {2437, 6},
10387 {2442, 7}, {2447, 8}, {2452, 9},
10388 {2457, 10}, {2462, 11}, {2467, 12},
10389 {2472, 13}},
10390 },
10391
10392 { /* Custom USA & Europe & High */
10393 "ZZA",
10394 .bg_channels = 11,
10395 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10396 {2427, 4}, {2432, 5}, {2437, 6},
10397 {2442, 7}, {2447, 8}, {2452, 9},
10398 {2457, 10}, {2462, 11}},
10399 .a_channels = 13,
10400 .a = {{5180, 36},
10401 {5200, 40},
10402 {5220, 44},
10403 {5240, 48},
10404 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10405 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10406 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10407 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10408 {5745, 149},
10409 {5765, 153},
10410 {5785, 157},
10411 {5805, 161},
10412 {5825, 165}},
10413 },
10414
10415 { /* Custom NA & Europe */
10416 "ZZB",
10417 .bg_channels = 11,
10418 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10419 {2427, 4}, {2432, 5}, {2437, 6},
10420 {2442, 7}, {2447, 8}, {2452, 9},
10421 {2457, 10}, {2462, 11}},
10422 .a_channels = 13,
10423 .a = {{5180, 36},
10424 {5200, 40},
10425 {5220, 44},
10426 {5240, 48},
10427 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10428 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10429 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10430 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10431 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10432 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10433 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10434 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10435 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10436 },
10437
10438 { /* Custom Japan */
10439 "ZZC",
10440 .bg_channels = 11,
10441 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10442 {2427, 4}, {2432, 5}, {2437, 6},
10443 {2442, 7}, {2447, 8}, {2452, 9},
10444 {2457, 10}, {2462, 11}},
10445 .a_channels = 4,
10446 .a = {{5170, 34}, {5190, 38},
10447 {5210, 42}, {5230, 46}},
10448 },
10449
10450 { /* Custom */
10451 "ZZM",
10452 .bg_channels = 11,
10453 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10454 {2427, 4}, {2432, 5}, {2437, 6},
10455 {2442, 7}, {2447, 8}, {2452, 9},
10456 {2457, 10}, {2462, 11}},
10457 },
10458
10459 { /* Europe */
10460 "ZZE",
10461 .bg_channels = 13,
10462 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10463 {2427, 4}, {2432, 5}, {2437, 6},
10464 {2442, 7}, {2447, 8}, {2452, 9},
10465 {2457, 10}, {2462, 11}, {2467, 12},
10466 {2472, 13}},
10467 .a_channels = 19,
10468 .a = {{5180, 36},
10469 {5200, 40},
10470 {5220, 44},
10471 {5240, 48},
10472 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10473 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10474 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10475 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10476 {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
10477 {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
10478 {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
10479 {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
10480 {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
10481 {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
10482 {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
10483 {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
10484 {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
10485 {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
10486 {5700, 140, IEEE80211_CH_PASSIVE_ONLY}},
10487 },
10488
10489 { /* Custom Japan */
10490 "ZZJ",
10491 .bg_channels = 14,
10492 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10493 {2427, 4}, {2432, 5}, {2437, 6},
10494 {2442, 7}, {2447, 8}, {2452, 9},
10495 {2457, 10}, {2462, 11}, {2467, 12},
10496 {2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY}},
10497 .a_channels = 4,
10498 .a = {{5170, 34}, {5190, 38},
10499 {5210, 42}, {5230, 46}},
10500 },
10501
10502 { /* Rest of World */
10503 "ZZR",
10504 .bg_channels = 14,
10505 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10506 {2427, 4}, {2432, 5}, {2437, 6},
10507 {2442, 7}, {2447, 8}, {2452, 9},
10508 {2457, 10}, {2462, 11}, {2467, 12},
10509 {2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY |
10510 IEEE80211_CH_PASSIVE_ONLY}},
10511 },
10512
10513 { /* High Band */
10514 "ZZH",
10515 .bg_channels = 13,
10516 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10517 {2427, 4}, {2432, 5}, {2437, 6},
10518 {2442, 7}, {2447, 8}, {2452, 9},
10519 {2457, 10}, {2462, 11},
10520 {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
10521 {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
10522 .a_channels = 4,
10523 .a = {{5745, 149}, {5765, 153},
10524 {5785, 157}, {5805, 161}},
10525 },
10526
10527 { /* Custom Europe */
10528 "ZZG",
10529 .bg_channels = 13,
10530 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10531 {2427, 4}, {2432, 5}, {2437, 6},
10532 {2442, 7}, {2447, 8}, {2452, 9},
10533 {2457, 10}, {2462, 11},
10534 {2467, 12}, {2472, 13}},
10535 .a_channels = 4,
10536 .a = {{5180, 36}, {5200, 40},
10537 {5220, 44}, {5240, 48}},
10538 },
10539
10540 { /* Europe */
10541 "ZZK",
10542 .bg_channels = 13,
10543 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10544 {2427, 4}, {2432, 5}, {2437, 6},
10545 {2442, 7}, {2447, 8}, {2452, 9},
10546 {2457, 10}, {2462, 11},
10547 {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
10548 {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
10549 .a_channels = 24,
10550 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
10551 {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
10552 {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
10553 {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
10554 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10555 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10556 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10557 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10558 {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
10559 {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
10560 {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
10561 {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
10562 {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
10563 {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
10564 {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
10565 {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
10566 {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
10567 {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
10568 {5700, 140, IEEE80211_CH_PASSIVE_ONLY},
10569 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10570 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10571 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10572 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10573 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10574 },
10575
10576 { /* Europe */
10577 "ZZL",
10578 .bg_channels = 11,
10579 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10580 {2427, 4}, {2432, 5}, {2437, 6},
10581 {2442, 7}, {2447, 8}, {2452, 9},
10582 {2457, 10}, {2462, 11}},
10583 .a_channels = 13,
10584 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
10585 {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
10586 {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
10587 {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
10588 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10589 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10590 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10591 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10592 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10593 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10594 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10595 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10596 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10597 }
10598};
10599
10600/* GEO code borrowed from ieee80211_geo.c */
10601static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
10602{
10603 int i;
10604
10605 /* Driver needs to initialize the geography map before using
10606 * these helper functions */
10607 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10608
10609 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10610 for (i = 0; i < ieee->geo.bg_channels; i++)
10611 /* NOTE: If G mode is currently supported but
10612 * this is a B only channel, we don't see it
10613 * as valid. */
10614 if ((ieee->geo.bg[i].channel == channel) &&
10615 (!(ieee->mode & IEEE_G) ||
10616 !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
10617 return IEEE80211_24GHZ_BAND;
10618
10619 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10620 for (i = 0; i < ieee->geo.a_channels; i++)
10621 if (ieee->geo.a[i].channel == channel)
10622 return IEEE80211_52GHZ_BAND;
10623
10624 return 0;
10625}
10626
10627static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel)
10628{
10629 int i;
10630
10631 /* Driver needs to initialize the geography map before using
10632 * these helper functions */
10633 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10634
10635 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10636 for (i = 0; i < ieee->geo.bg_channels; i++)
10637 if (ieee->geo.bg[i].channel == channel)
10638 return i;
10639
10640 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10641 for (i = 0; i < ieee->geo.a_channels; i++)
10642 if (ieee->geo.a[i].channel == channel)
10643 return i;
10644
10645 return -1;
10646}
10647
10648static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq)
10649{
10650 int i;
10651
10652 /* Driver needs to initialize the geography map before using
10653 * these helper functions */
10654 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10655
10656 freq /= 100000;
10657
10658 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10659 for (i = 0; i < ieee->geo.bg_channels; i++)
10660 if (ieee->geo.bg[i].freq == freq)
10661 return ieee->geo.bg[i].channel;
10662
10663 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10664 for (i = 0; i < ieee->geo.a_channels; i++)
10665 if (ieee->geo.a[i].freq == freq)
10666 return ieee->geo.a[i].channel;
10667
10668 return 0;
10669}
10670
10671static int ipw_set_geo(struct ieee80211_device *ieee,
10672 const struct ieee80211_geo *geo)
10673{
10674 memcpy(ieee->geo.name, geo->name, 3);
10675 ieee->geo.name[3] = '\0';
10676 ieee->geo.bg_channels = geo->bg_channels;
10677 ieee->geo.a_channels = geo->a_channels;
10678 memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
10679 sizeof(struct ieee80211_channel));
10680 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
10681 sizeof(struct ieee80211_channel));
10682 return 0;
10683}
10684
10685static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee)
10686{
10687 return &ieee->geo;
10688}
10689
6852#define MAX_HW_RESTARTS 5 10690#define MAX_HW_RESTARTS 5
6853static int ipw_up(struct ipw_priv *priv) 10691static int ipw_up(struct ipw_priv *priv)
6854{ 10692{
6855 int rc, i; 10693 int rc, i, j;
6856 10694
6857 if (priv->status & STATUS_EXIT_PENDING) 10695 if (priv->status & STATUS_EXIT_PENDING)
6858 return -EIO; 10696 return -EIO;
6859 10697
10698 if (cmdlog && !priv->cmdlog) {
10699 priv->cmdlog = kmalloc(sizeof(*priv->cmdlog) * cmdlog,
10700 GFP_KERNEL);
10701 if (priv->cmdlog == NULL) {
10702 IPW_ERROR("Error allocating %d command log entries.\n",
10703 cmdlog);
10704 } else {
10705 memset(priv->cmdlog, 0, sizeof(*priv->cmdlog) * cmdlog);
10706 priv->cmdlog_len = cmdlog;
10707 }
10708 }
10709
6860 for (i = 0; i < MAX_HW_RESTARTS; i++) { 10710 for (i = 0; i < MAX_HW_RESTARTS; i++) {
6861 /* Load the microcode, firmware, and eeprom. 10711 /* Load the microcode, firmware, and eeprom.
6862 * Also start the clocks. */ 10712 * Also start the clocks. */
6863 rc = ipw_load(priv); 10713 rc = ipw_load(priv);
6864 if (rc) { 10714 if (rc) {
6865 IPW_ERROR("Unable to load firmware: 0x%08X\n", rc); 10715 IPW_ERROR("Unable to load firmware: %d\n", rc);
6866 return rc; 10716 return rc;
6867 } 10717 }
6868 10718
@@ -6871,20 +10721,50 @@ static int ipw_up(struct ipw_priv *priv)
6871 eeprom_parse_mac(priv, priv->mac_addr); 10721 eeprom_parse_mac(priv, priv->mac_addr);
6872 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); 10722 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
6873 10723
6874 if (priv->status & STATUS_RF_KILL_MASK) 10724 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
10725 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
10726 ipw_geos[j].name, 3))
10727 break;
10728 }
10729 if (j == ARRAY_SIZE(ipw_geos)) {
10730 IPW_WARNING("SKU [%c%c%c] not recognized.\n",
10731 priv->eeprom[EEPROM_COUNTRY_CODE + 0],
10732 priv->eeprom[EEPROM_COUNTRY_CODE + 1],
10733 priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
10734 j = 0;
10735 }
10736 if (ipw_set_geo(priv->ieee, &ipw_geos[j])) {
10737 IPW_WARNING("Could not set geography.");
10738 return 0;
10739 }
10740
10741 IPW_DEBUG_INFO("Geography %03d [%s] detected.\n",
10742 j, priv->ieee->geo.name);
10743
10744 if (priv->status & STATUS_RF_KILL_SW) {
10745 IPW_WARNING("Radio disabled by module parameter.\n");
10746 return 0;
10747 } else if (rf_kill_active(priv)) {
10748 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
10749 "Kill switch must be turned off for "
10750 "wireless networking to work.\n");
10751 queue_delayed_work(priv->workqueue, &priv->rf_kill,
10752 2 * HZ);
6875 return 0; 10753 return 0;
10754 }
6876 10755
6877 rc = ipw_config(priv); 10756 rc = ipw_config(priv);
6878 if (!rc) { 10757 if (!rc) {
6879 IPW_DEBUG_INFO("Configured device on count %i\n", i); 10758 IPW_DEBUG_INFO("Configured device on count %i\n", i);
6880 priv->notif_missed_beacons = 0; 10759
6881 netif_start_queue(priv->net_dev); 10760 /* If configure to try and auto-associate, kick
10761 * off a scan. */
10762 queue_work(priv->workqueue, &priv->request_scan);
10763
6882 return 0; 10764 return 0;
6883 } else {
6884 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n",
6885 rc);
6886 } 10765 }
6887 10766
10767 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);
6888 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n", 10768 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
6889 i, MAX_HW_RESTARTS); 10769 i, MAX_HW_RESTARTS);
6890 10770
@@ -6896,47 +10776,101 @@ static int ipw_up(struct ipw_priv *priv)
6896 /* tried to restart and config the device for as long as our 10776 /* tried to restart and config the device for as long as our
6897 * patience could withstand */ 10777 * patience could withstand */
6898 IPW_ERROR("Unable to initialize device after %d attempts.\n", i); 10778 IPW_ERROR("Unable to initialize device after %d attempts.\n", i);
10779
6899 return -EIO; 10780 return -EIO;
6900} 10781}
6901 10782
6902static void ipw_down(struct ipw_priv *priv) 10783static void ipw_bg_up(void *data)
10784{
10785 struct ipw_priv *priv = data;
10786 down(&priv->sem);
10787 ipw_up(data);
10788 up(&priv->sem);
10789}
10790
10791static void ipw_deinit(struct ipw_priv *priv)
6903{ 10792{
10793 int i;
10794
10795 if (priv->status & STATUS_SCANNING) {
10796 IPW_DEBUG_INFO("Aborting scan during shutdown.\n");
10797 ipw_abort_scan(priv);
10798 }
10799
10800 if (priv->status & STATUS_ASSOCIATED) {
10801 IPW_DEBUG_INFO("Disassociating during shutdown.\n");
10802 ipw_disassociate(priv);
10803 }
10804
10805 ipw_led_shutdown(priv);
10806
10807 /* Wait up to 1s for status to change to not scanning and not
10808 * associated (disassociation can take a while for a ful 802.11
10809 * exchange */
10810 for (i = 1000; i && (priv->status &
10811 (STATUS_DISASSOCIATING |
10812 STATUS_ASSOCIATED | STATUS_SCANNING)); i--)
10813 udelay(10);
10814
10815 if (priv->status & (STATUS_DISASSOCIATING |
10816 STATUS_ASSOCIATED | STATUS_SCANNING))
10817 IPW_DEBUG_INFO("Still associated or scanning...\n");
10818 else
10819 IPW_DEBUG_INFO("Took %dms to de-init\n", 1000 - i);
10820
6904 /* Attempt to disable the card */ 10821 /* Attempt to disable the card */
6905#if 0
6906 ipw_send_card_disable(priv, 0); 10822 ipw_send_card_disable(priv, 0);
6907#endif 10823
10824 priv->status &= ~STATUS_INIT;
10825}
10826
10827static void ipw_down(struct ipw_priv *priv)
10828{
10829 int exit_pending = priv->status & STATUS_EXIT_PENDING;
10830
10831 priv->status |= STATUS_EXIT_PENDING;
10832
10833 if (ipw_is_init(priv))
10834 ipw_deinit(priv);
10835
10836 /* Wipe out the EXIT_PENDING status bit if we are not actually
10837 * exiting the module */
10838 if (!exit_pending)
10839 priv->status &= ~STATUS_EXIT_PENDING;
6908 10840
6909 /* tell the device to stop sending interrupts */ 10841 /* tell the device to stop sending interrupts */
6910 ipw_disable_interrupts(priv); 10842 ipw_disable_interrupts(priv);
6911 10843
6912 /* Clear all bits but the RF Kill */ 10844 /* Clear all bits but the RF Kill */
6913 priv->status &= STATUS_RF_KILL_MASK; 10845 priv->status &= STATUS_RF_KILL_MASK | STATUS_EXIT_PENDING;
6914
6915 netif_carrier_off(priv->net_dev); 10846 netif_carrier_off(priv->net_dev);
6916 netif_stop_queue(priv->net_dev); 10847 netif_stop_queue(priv->net_dev);
6917 10848
6918 ipw_stop_nic(priv); 10849 ipw_stop_nic(priv);
10850
10851 ipw_led_radio_off(priv);
10852}
10853
10854static void ipw_bg_down(void *data)
10855{
10856 struct ipw_priv *priv = data;
10857 down(&priv->sem);
10858 ipw_down(data);
10859 up(&priv->sem);
6919} 10860}
6920 10861
6921/* Called by register_netdev() */ 10862/* Called by register_netdev() */
6922static int ipw_net_init(struct net_device *dev) 10863static int ipw_net_init(struct net_device *dev)
6923{ 10864{
6924 struct ipw_priv *priv = ieee80211_priv(dev); 10865 struct ipw_priv *priv = ieee80211_priv(dev);
10866 down(&priv->sem);
6925 10867
6926 if (priv->status & STATUS_RF_KILL_SW) { 10868 if (ipw_up(priv)) {
6927 IPW_WARNING("Radio disabled by module parameter.\n"); 10869 up(&priv->sem);
6928 return 0;
6929 } else if (rf_kill_active(priv)) {
6930 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
6931 "Kill switch must be turned off for "
6932 "wireless networking to work.\n");
6933 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
6934 return 0;
6935 }
6936
6937 if (ipw_up(priv))
6938 return -EIO; 10870 return -EIO;
10871 }
6939 10872
10873 up(&priv->sem);
6940 return 0; 10874 return 0;
6941} 10875}
6942 10876
@@ -6961,7 +10895,7 @@ static struct pci_device_id card_ids[] = {
6961 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0}, 10895 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
6962 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 10896 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
6963 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */ 10897 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
6964 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 2225BG */ 10898 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
6965 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ 10899 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
6966 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ 10900 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
6967 10901
@@ -6981,11 +10915,16 @@ static struct attribute *ipw_sysfs_entries[] = {
6981 &dev_attr_nic_type.attr, 10915 &dev_attr_nic_type.attr,
6982 &dev_attr_status.attr, 10916 &dev_attr_status.attr,
6983 &dev_attr_cfg.attr, 10917 &dev_attr_cfg.attr,
6984 &dev_attr_dump_errors.attr, 10918 &dev_attr_error.attr,
6985 &dev_attr_dump_events.attr, 10919 &dev_attr_event_log.attr,
10920 &dev_attr_cmd_log.attr,
6986 &dev_attr_eeprom_delay.attr, 10921 &dev_attr_eeprom_delay.attr,
6987 &dev_attr_ucode_version.attr, 10922 &dev_attr_ucode_version.attr,
6988 &dev_attr_rtc.attr, 10923 &dev_attr_rtc.attr,
10924 &dev_attr_scan_age.attr,
10925 &dev_attr_led.attr,
10926 &dev_attr_speed_scan.attr,
10927 &dev_attr_net_stats.attr,
6989 NULL 10928 NULL
6990}; 10929};
6991 10930
@@ -7001,7 +10940,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7001 void __iomem *base; 10940 void __iomem *base;
7002 u32 length, val; 10941 u32 length, val;
7003 struct ipw_priv *priv; 10942 struct ipw_priv *priv;
7004 int band, modulation; 10943 int i;
7005 10944
7006 net_dev = alloc_ieee80211(sizeof(struct ipw_priv)); 10945 net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
7007 if (net_dev == NULL) { 10946 if (net_dev == NULL) {
@@ -7011,13 +10950,17 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7011 10950
7012 priv = ieee80211_priv(net_dev); 10951 priv = ieee80211_priv(net_dev);
7013 priv->ieee = netdev_priv(net_dev); 10952 priv->ieee = netdev_priv(net_dev);
10953
7014 priv->net_dev = net_dev; 10954 priv->net_dev = net_dev;
7015 priv->pci_dev = pdev; 10955 priv->pci_dev = pdev;
7016#ifdef CONFIG_IPW_DEBUG 10956#ifdef CONFIG_IPW_DEBUG
7017 ipw_debug_level = debug; 10957 ipw_debug_level = debug;
7018#endif 10958#endif
7019 spin_lock_init(&priv->lock); 10959 spin_lock_init(&priv->lock);
10960 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
10961 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
7020 10962
10963 init_MUTEX(&priv->sem);
7021 if (pci_enable_device(pdev)) { 10964 if (pci_enable_device(pdev)) {
7022 err = -ENODEV; 10965 err = -ENODEV;
7023 goto out_free_ieee80211; 10966 goto out_free_ieee80211;
@@ -7064,90 +11007,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7064 goto out_iounmap; 11007 goto out_iounmap;
7065 } 11008 }
7066 11009
7067 /* Initialize module parameter values here */ 11010 ipw_sw_reset(priv, 1);
7068 if (ifname)
7069 strncpy(net_dev->name, ifname, IFNAMSIZ);
7070
7071 if (associate)
7072 priv->config |= CFG_ASSOCIATE;
7073 else
7074 IPW_DEBUG_INFO("Auto associate disabled.\n");
7075
7076 if (auto_create)
7077 priv->config |= CFG_ADHOC_CREATE;
7078 else
7079 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
7080
7081 if (disable) {
7082 priv->status |= STATUS_RF_KILL_SW;
7083 IPW_DEBUG_INFO("Radio disabled.\n");
7084 }
7085
7086 if (channel != 0) {
7087 priv->config |= CFG_STATIC_CHANNEL;
7088 priv->channel = channel;
7089 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
7090 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
7091 /* TODO: Validate that provided channel is in range */
7092 }
7093
7094 switch (mode) {
7095 case 1:
7096 priv->ieee->iw_mode = IW_MODE_ADHOC;
7097 break;
7098#ifdef CONFIG_IPW_PROMISC
7099 case 2:
7100 priv->ieee->iw_mode = IW_MODE_MONITOR;
7101 break;
7102#endif
7103 default:
7104 case 0:
7105 priv->ieee->iw_mode = IW_MODE_INFRA;
7106 break;
7107 }
7108
7109 if ((priv->pci_dev->device == 0x4223) ||
7110 (priv->pci_dev->device == 0x4224)) {
7111 printk(KERN_INFO DRV_NAME
7112 ": Detected Intel PRO/Wireless 2915ABG Network "
7113 "Connection\n");
7114 priv->ieee->abg_true = 1;
7115 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
7116 modulation = IEEE80211_OFDM_MODULATION |
7117 IEEE80211_CCK_MODULATION;
7118 priv->adapter = IPW_2915ABG;
7119 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
7120 } else {
7121 if (priv->pci_dev->device == 0x4221)
7122 printk(KERN_INFO DRV_NAME
7123 ": Detected Intel PRO/Wireless 2225BG Network "
7124 "Connection\n");
7125 else
7126 printk(KERN_INFO DRV_NAME
7127 ": Detected Intel PRO/Wireless 2200BG Network "
7128 "Connection\n");
7129
7130 priv->ieee->abg_true = 0;
7131 band = IEEE80211_24GHZ_BAND;
7132 modulation = IEEE80211_OFDM_MODULATION |
7133 IEEE80211_CCK_MODULATION;
7134 priv->adapter = IPW_2200BG;
7135 priv->ieee->mode = IEEE_G | IEEE_B;
7136 }
7137
7138 priv->ieee->freq_band = band;
7139 priv->ieee->modulation = modulation;
7140
7141 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
7142
7143 priv->missed_beacon_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
7144 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
7145
7146 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
7147
7148 /* If power management is turned on, default to AC mode */
7149 priv->power_mode = IPW_POWER_AC;
7150 priv->tx_power = IPW_DEFAULT_TX_POWER;
7151 11011
7152 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv); 11012 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv);
7153 if (err) { 11013 if (err) {
@@ -7158,8 +11018,20 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7158 SET_MODULE_OWNER(net_dev); 11018 SET_MODULE_OWNER(net_dev);
7159 SET_NETDEV_DEV(net_dev, &pdev->dev); 11019 SET_NETDEV_DEV(net_dev, &pdev->dev);
7160 11020
11021 down(&priv->sem);
11022
7161 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit; 11023 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
7162 priv->ieee->set_security = shim__set_security; 11024 priv->ieee->set_security = shim__set_security;
11025 priv->ieee->is_queue_full = ipw_net_is_queue_full;
11026
11027#ifdef CONFIG_IPW_QOS
11028 priv->ieee->handle_probe_response = ipw_handle_beacon;
11029 priv->ieee->handle_beacon = ipw_handle_probe_response;
11030 priv->ieee->handle_assoc_response = ipw_handle_assoc_response;
11031#endif /* CONFIG_IPW_QOS */
11032
11033 priv->ieee->perfect_rssi = -20;
11034 priv->ieee->worst_rssi = -85;
7163 11035
7164 net_dev->open = ipw_net_open; 11036 net_dev->open = ipw_net_open;
7165 net_dev->stop = ipw_net_stop; 11037 net_dev->stop = ipw_net_stop;
@@ -7167,7 +11039,9 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7167 net_dev->get_stats = ipw_net_get_stats; 11039 net_dev->get_stats = ipw_net_get_stats;
7168 net_dev->set_multicast_list = ipw_net_set_multicast_list; 11040 net_dev->set_multicast_list = ipw_net_set_multicast_list;
7169 net_dev->set_mac_address = ipw_net_set_mac_address; 11041 net_dev->set_mac_address = ipw_net_set_mac_address;
7170 net_dev->get_wireless_stats = ipw_get_wireless_stats; 11042 priv->wireless_data.spy_data = &priv->ieee->spy_data;
11043 priv->wireless_data.ieee80211 = priv->ieee;
11044 net_dev->wireless_data = &priv->wireless_data;
7171 net_dev->wireless_handlers = &ipw_wx_handler_def; 11045 net_dev->wireless_handlers = &ipw_wx_handler_def;
7172 net_dev->ethtool_ops = &ipw_ethtool_ops; 11046 net_dev->ethtool_ops = &ipw_ethtool_ops;
7173 net_dev->irq = pdev->irq; 11047 net_dev->irq = pdev->irq;
@@ -7178,18 +11052,19 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7178 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group); 11052 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
7179 if (err) { 11053 if (err) {
7180 IPW_ERROR("failed to create sysfs device attributes\n"); 11054 IPW_ERROR("failed to create sysfs device attributes\n");
11055 up(&priv->sem);
7181 goto out_release_irq; 11056 goto out_release_irq;
7182 } 11057 }
7183 11058
11059 up(&priv->sem);
7184 err = register_netdev(net_dev); 11060 err = register_netdev(net_dev);
7185 if (err) { 11061 if (err) {
7186 IPW_ERROR("failed to register network device\n"); 11062 IPW_ERROR("failed to register network device\n");
7187 goto out_remove_group; 11063 goto out_remove_sysfs;
7188 } 11064 }
7189
7190 return 0; 11065 return 0;
7191 11066
7192 out_remove_group: 11067 out_remove_sysfs:
7193 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); 11068 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
7194 out_release_irq: 11069 out_release_irq:
7195 free_irq(pdev->irq, priv); 11070 free_irq(pdev->irq, priv);
@@ -7212,14 +11087,19 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7212static void ipw_pci_remove(struct pci_dev *pdev) 11087static void ipw_pci_remove(struct pci_dev *pdev)
7213{ 11088{
7214 struct ipw_priv *priv = pci_get_drvdata(pdev); 11089 struct ipw_priv *priv = pci_get_drvdata(pdev);
11090 struct list_head *p, *q;
11091 int i;
11092
7215 if (!priv) 11093 if (!priv)
7216 return; 11094 return;
7217 11095
7218 priv->status |= STATUS_EXIT_PENDING; 11096 down(&priv->sem);
7219 11097
11098 priv->status |= STATUS_EXIT_PENDING;
11099 ipw_down(priv);
7220 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); 11100 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
7221 11101
7222 ipw_down(priv); 11102 up(&priv->sem);
7223 11103
7224 unregister_netdev(priv->net_dev); 11104 unregister_netdev(priv->net_dev);
7225 11105
@@ -7229,16 +11109,31 @@ static void ipw_pci_remove(struct pci_dev *pdev)
7229 } 11109 }
7230 ipw_tx_queue_free(priv); 11110 ipw_tx_queue_free(priv);
7231 11111
11112 if (priv->cmdlog) {
11113 kfree(priv->cmdlog);
11114 priv->cmdlog = NULL;
11115 }
7232 /* ipw_down will ensure that there is no more pending work 11116 /* ipw_down will ensure that there is no more pending work
7233 * in the workqueue's, so we can safely remove them now. */ 11117 * in the workqueue's, so we can safely remove them now. */
7234 if (priv->workqueue) { 11118 cancel_delayed_work(&priv->adhoc_check);
7235 cancel_delayed_work(&priv->adhoc_check); 11119 cancel_delayed_work(&priv->gather_stats);
7236 cancel_delayed_work(&priv->gather_stats); 11120 cancel_delayed_work(&priv->request_scan);
7237 cancel_delayed_work(&priv->request_scan); 11121 cancel_delayed_work(&priv->rf_kill);
7238 cancel_delayed_work(&priv->rf_kill); 11122 cancel_delayed_work(&priv->scan_check);
7239 cancel_delayed_work(&priv->scan_check); 11123 destroy_workqueue(priv->workqueue);
7240 destroy_workqueue(priv->workqueue); 11124 priv->workqueue = NULL;
7241 priv->workqueue = NULL; 11125
11126 /* Free MAC hash list for ADHOC */
11127 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
11128 list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
11129 kfree(list_entry(p, struct ipw_ibss_seq, list));
11130 list_del(p);
11131 }
11132 }
11133
11134 if (priv->error) {
11135 ipw_free_error_log(priv->error);
11136 priv->error = NULL;
7242 } 11137 }
7243 11138
7244 free_irq(pdev->irq, priv); 11139 free_irq(pdev->irq, priv);
@@ -7247,15 +11142,7 @@ static void ipw_pci_remove(struct pci_dev *pdev)
7247 pci_disable_device(pdev); 11142 pci_disable_device(pdev);
7248 pci_set_drvdata(pdev, NULL); 11143 pci_set_drvdata(pdev, NULL);
7249 free_ieee80211(priv->net_dev); 11144 free_ieee80211(priv->net_dev);
7250 11145 free_firmware();
7251#ifdef CONFIG_PM
7252 if (fw_loaded) {
7253 release_firmware(bootfw);
7254 release_firmware(ucode);
7255 release_firmware(firmware);
7256 fw_loaded = 0;
7257 }
7258#endif
7259} 11146}
7260 11147
7261#ifdef CONFIG_PM 11148#ifdef CONFIG_PM
@@ -7287,13 +11174,10 @@ static int ipw_pci_resume(struct pci_dev *pdev)
7287 11174
7288 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name); 11175 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
7289 11176
7290 pci_set_power_state(pdev, 0); 11177 pci_set_power_state(pdev, PCI_D0);
7291 pci_enable_device(pdev); 11178 pci_enable_device(pdev);
7292#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
7293 pci_restore_state(pdev, priv->pm_state);
7294#else
7295 pci_restore_state(pdev); 11179 pci_restore_state(pdev);
7296#endif 11180
7297 /* 11181 /*
7298 * Suspend/Resume resets the PCI configuration space, so we have to 11182 * Suspend/Resume resets the PCI configuration space, so we have to
7299 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries 11183 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@@ -7365,16 +11249,33 @@ MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
7365module_param(auto_create, int, 0444); 11249module_param(auto_create, int, 0444);
7366MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); 11250MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
7367 11251
11252module_param(led, int, 0444);
11253MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
11254
7368module_param(debug, int, 0444); 11255module_param(debug, int, 0444);
7369MODULE_PARM_DESC(debug, "debug output mask"); 11256MODULE_PARM_DESC(debug, "debug output mask");
7370 11257
7371module_param(channel, int, 0444); 11258module_param(channel, int, 0444);
7372MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); 11259MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
7373 11260
7374module_param(ifname, charp, 0444); 11261#ifdef CONFIG_IPW_QOS
7375MODULE_PARM_DESC(ifname, "network device name (default eth%d)"); 11262module_param(qos_enable, int, 0444);
11263MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");
11264
11265module_param(qos_burst_enable, int, 0444);
11266MODULE_PARM_DESC(qos_burst_enable, "enable QoS burst mode");
11267
11268module_param(qos_no_ack_mask, int, 0444);
11269MODULE_PARM_DESC(qos_no_ack_mask, "mask Tx_Queue to no ack");
7376 11270
7377#ifdef CONFIG_IPW_PROMISC 11271module_param(burst_duration_CCK, int, 0444);
11272MODULE_PARM_DESC(burst_duration_CCK, "set CCK burst value");
11273
11274module_param(burst_duration_OFDM, int, 0444);
11275MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
11276#endif /* CONFIG_IPW_QOS */
11277
11278#ifdef CONFIG_IPW2200_MONITOR
7378module_param(mode, int, 0444); 11279module_param(mode, int, 0444);
7379MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)"); 11280MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
7380#else 11281#else
@@ -7382,5 +11283,12 @@ module_param(mode, int, 0444);
7382MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)"); 11283MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
7383#endif 11284#endif
7384 11285
11286module_param(hwcrypto, int, 0444);
11287MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)");
11288
11289module_param(cmdlog, int, 0444);
11290MODULE_PARM_DESC(cmdlog,
11291 "allocate a ring buffer for logging firmware commands");
11292
7385module_exit(ipw_exit); 11293module_exit(ipw_exit);
7386module_init(ipw_init); 11294module_init(ipw_init);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index e9cf32bf3e31..1c98db0652c9 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -34,7 +34,6 @@
34#include <linux/config.h> 34#include <linux/config.h>
35#include <linux/init.h> 35#include <linux/init.h>
36 36
37#include <linux/version.h>
38#include <linux/pci.h> 37#include <linux/pci.h>
39#include <linux/netdevice.h> 38#include <linux/netdevice.h>
40#include <linux/ethtool.h> 39#include <linux/ethtool.h>
@@ -50,6 +49,7 @@
50#include <asm/io.h> 49#include <asm/io.h>
51 50
52#include <net/ieee80211.h> 51#include <net/ieee80211.h>
52#include <net/ieee80211_radiotap.h>
53 53
54#define DRV_NAME "ipw2200" 54#define DRV_NAME "ipw2200"
55 55
@@ -161,6 +161,16 @@ enum connection_manager_assoc_states {
161 * TX Queue Flag Definitions 161 * TX Queue Flag Definitions
162 */ 162 */
163 163
164/* tx wep key definition */
165#define DCT_WEP_KEY_NOT_IMMIDIATE 0x00
166#define DCT_WEP_KEY_64Bit 0x40
167#define DCT_WEP_KEY_128Bit 0x80
168#define DCT_WEP_KEY_128bitIV 0xC0
169#define DCT_WEP_KEY_SIZE_MASK 0xC0
170
171#define DCT_WEP_KEY_INDEX_MASK 0x0F
172#define DCT_WEP_INDEX_USE_IMMEDIATE 0x20
173
164/* abort attempt if mgmt frame is rx'd */ 174/* abort attempt if mgmt frame is rx'd */
165#define DCT_FLAG_ABORT_MGMT 0x01 175#define DCT_FLAG_ABORT_MGMT 0x01
166 176
@@ -168,7 +178,8 @@ enum connection_manager_assoc_states {
168#define DCT_FLAG_CTS_REQUIRED 0x02 178#define DCT_FLAG_CTS_REQUIRED 0x02
169 179
170/* use short preamble */ 180/* use short preamble */
171#define DCT_FLAG_SHORT_PREMBL 0x04 181#define DCT_FLAG_LONG_PREAMBLE 0x00
182#define DCT_FLAG_SHORT_PREAMBLE 0x04
172 183
173/* RTS/CTS first */ 184/* RTS/CTS first */
174#define DCT_FLAG_RTS_REQD 0x08 185#define DCT_FLAG_RTS_REQD 0x08
@@ -185,9 +196,23 @@ enum connection_manager_assoc_states {
185/* ACK rx is expected to follow */ 196/* ACK rx is expected to follow */
186#define DCT_FLAG_ACK_REQD 0x80 197#define DCT_FLAG_ACK_REQD 0x80
187 198
199/* TX flags extension */
188#define DCT_FLAG_EXT_MODE_CCK 0x01 200#define DCT_FLAG_EXT_MODE_CCK 0x01
189#define DCT_FLAG_EXT_MODE_OFDM 0x00 201#define DCT_FLAG_EXT_MODE_OFDM 0x00
190 202
203#define DCT_FLAG_EXT_SECURITY_WEP 0x00
204#define DCT_FLAG_EXT_SECURITY_NO DCT_FLAG_EXT_SECURITY_WEP
205#define DCT_FLAG_EXT_SECURITY_CKIP 0x04
206#define DCT_FLAG_EXT_SECURITY_CCM 0x08
207#define DCT_FLAG_EXT_SECURITY_TKIP 0x0C
208#define DCT_FLAG_EXT_SECURITY_MASK 0x0C
209
210#define DCT_FLAG_EXT_QOS_ENABLED 0x10
211
212#define DCT_FLAG_EXT_HC_NO_SIFS_PIFS 0x00
213#define DCT_FLAG_EXT_HC_SIFS 0x20
214#define DCT_FLAG_EXT_HC_PIFS 0x40
215
191#define TX_RX_TYPE_MASK 0xFF 216#define TX_RX_TYPE_MASK 0xFF
192#define TX_FRAME_TYPE 0x00 217#define TX_FRAME_TYPE 0x00
193#define TX_HOST_COMMAND_TYPE 0x01 218#define TX_HOST_COMMAND_TYPE 0x01
@@ -233,6 +258,117 @@ enum connection_manager_assoc_states {
233#define DCR_TYPE_SNIFFER 0x06 258#define DCR_TYPE_SNIFFER 0x06
234#define DCR_TYPE_MU_BSS DCR_TYPE_MU_ESS 259#define DCR_TYPE_MU_BSS DCR_TYPE_MU_ESS
235 260
261/* QoS definitions */
262
263#define CW_MIN_OFDM 15
264#define CW_MAX_OFDM 1023
265#define CW_MIN_CCK 31
266#define CW_MAX_CCK 1023
267
268#define QOS_TX0_CW_MIN_OFDM CW_MIN_OFDM
269#define QOS_TX1_CW_MIN_OFDM CW_MIN_OFDM
270#define QOS_TX2_CW_MIN_OFDM ( (CW_MIN_OFDM + 1) / 2 - 1 )
271#define QOS_TX3_CW_MIN_OFDM ( (CW_MIN_OFDM + 1) / 4 - 1 )
272
273#define QOS_TX0_CW_MIN_CCK CW_MIN_CCK
274#define QOS_TX1_CW_MIN_CCK CW_MIN_CCK
275#define QOS_TX2_CW_MIN_CCK ( (CW_MIN_CCK + 1) / 2 - 1 )
276#define QOS_TX3_CW_MIN_CCK ( (CW_MIN_CCK + 1) / 4 - 1 )
277
278#define QOS_TX0_CW_MAX_OFDM CW_MAX_OFDM
279#define QOS_TX1_CW_MAX_OFDM CW_MAX_OFDM
280#define QOS_TX2_CW_MAX_OFDM CW_MIN_OFDM
281#define QOS_TX3_CW_MAX_OFDM ( (CW_MIN_OFDM + 1) / 2 - 1 )
282
283#define QOS_TX0_CW_MAX_CCK CW_MAX_CCK
284#define QOS_TX1_CW_MAX_CCK CW_MAX_CCK
285#define QOS_TX2_CW_MAX_CCK CW_MIN_CCK
286#define QOS_TX3_CW_MAX_CCK ( (CW_MIN_CCK + 1) / 2 - 1 )
287
288#define QOS_TX0_AIFS (3 - QOS_AIFSN_MIN_VALUE)
289#define QOS_TX1_AIFS (7 - QOS_AIFSN_MIN_VALUE)
290#define QOS_TX2_AIFS (2 - QOS_AIFSN_MIN_VALUE)
291#define QOS_TX3_AIFS (2 - QOS_AIFSN_MIN_VALUE)
292
293#define QOS_TX0_ACM 0
294#define QOS_TX1_ACM 0
295#define QOS_TX2_ACM 0
296#define QOS_TX3_ACM 0
297
298#define QOS_TX0_TXOP_LIMIT_CCK 0
299#define QOS_TX1_TXOP_LIMIT_CCK 0
300#define QOS_TX2_TXOP_LIMIT_CCK 6016
301#define QOS_TX3_TXOP_LIMIT_CCK 3264
302
303#define QOS_TX0_TXOP_LIMIT_OFDM 0
304#define QOS_TX1_TXOP_LIMIT_OFDM 0
305#define QOS_TX2_TXOP_LIMIT_OFDM 3008
306#define QOS_TX3_TXOP_LIMIT_OFDM 1504
307
308#define DEF_TX0_CW_MIN_OFDM CW_MIN_OFDM
309#define DEF_TX1_CW_MIN_OFDM CW_MIN_OFDM
310#define DEF_TX2_CW_MIN_OFDM CW_MIN_OFDM
311#define DEF_TX3_CW_MIN_OFDM CW_MIN_OFDM
312
313#define DEF_TX0_CW_MIN_CCK CW_MIN_CCK
314#define DEF_TX1_CW_MIN_CCK CW_MIN_CCK
315#define DEF_TX2_CW_MIN_CCK CW_MIN_CCK
316#define DEF_TX3_CW_MIN_CCK CW_MIN_CCK
317
318#define DEF_TX0_CW_MAX_OFDM CW_MAX_OFDM
319#define DEF_TX1_CW_MAX_OFDM CW_MAX_OFDM
320#define DEF_TX2_CW_MAX_OFDM CW_MAX_OFDM
321#define DEF_TX3_CW_MAX_OFDM CW_MAX_OFDM
322
323#define DEF_TX0_CW_MAX_CCK CW_MAX_CCK
324#define DEF_TX1_CW_MAX_CCK CW_MAX_CCK
325#define DEF_TX2_CW_MAX_CCK CW_MAX_CCK
326#define DEF_TX3_CW_MAX_CCK CW_MAX_CCK
327
328#define DEF_TX0_AIFS 0
329#define DEF_TX1_AIFS 0
330#define DEF_TX2_AIFS 0
331#define DEF_TX3_AIFS 0
332
333#define DEF_TX0_ACM 0
334#define DEF_TX1_ACM 0
335#define DEF_TX2_ACM 0
336#define DEF_TX3_ACM 0
337
338#define DEF_TX0_TXOP_LIMIT_CCK 0
339#define DEF_TX1_TXOP_LIMIT_CCK 0
340#define DEF_TX2_TXOP_LIMIT_CCK 0
341#define DEF_TX3_TXOP_LIMIT_CCK 0
342
343#define DEF_TX0_TXOP_LIMIT_OFDM 0
344#define DEF_TX1_TXOP_LIMIT_OFDM 0
345#define DEF_TX2_TXOP_LIMIT_OFDM 0
346#define DEF_TX3_TXOP_LIMIT_OFDM 0
347
348#define QOS_QOS_SETS 3
349#define QOS_PARAM_SET_ACTIVE 0
350#define QOS_PARAM_SET_DEF_CCK 1
351#define QOS_PARAM_SET_DEF_OFDM 2
352
353#define CTRL_QOS_NO_ACK (0x0020)
354
355#define IPW_TX_QUEUE_1 1
356#define IPW_TX_QUEUE_2 2
357#define IPW_TX_QUEUE_3 3
358#define IPW_TX_QUEUE_4 4
359
360/* QoS sturctures */
361struct ipw_qos_info {
362 int qos_enable;
363 struct ieee80211_qos_parameters *def_qos_parm_OFDM;
364 struct ieee80211_qos_parameters *def_qos_parm_CCK;
365 u32 burst_duration_CCK;
366 u32 burst_duration_OFDM;
367 u16 qos_no_ack_mask;
368 int burst_enable;
369};
370
371/**************************************************************/
236/** 372/**
237 * Generic queue structure 373 * Generic queue structure
238 * 374 *
@@ -402,9 +538,9 @@ struct clx2_tx_queue {
402#define RX_FREE_BUFFERS 32 538#define RX_FREE_BUFFERS 32
403#define RX_LOW_WATERMARK 8 539#define RX_LOW_WATERMARK 8
404 540
405#define SUP_RATE_11A_MAX_NUM_CHANNELS (8) 541#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
406#define SUP_RATE_11B_MAX_NUM_CHANNELS (4) 542#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
407#define SUP_RATE_11G_MAX_NUM_CHANNELS (12) 543#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
408 544
409// Used for passing to driver number of successes and failures per rate 545// Used for passing to driver number of successes and failures per rate
410struct rate_histogram { 546struct rate_histogram {
@@ -453,6 +589,9 @@ struct notif_channel_result {
453 u8 uReserved; 589 u8 uReserved;
454} __attribute__ ((packed)); 590} __attribute__ ((packed));
455 591
592#define SCAN_COMPLETED_STATUS_COMPLETE 1
593#define SCAN_COMPLETED_STATUS_ABORTED 2
594
456struct notif_scan_complete { 595struct notif_scan_complete {
457 u8 scan_type; 596 u8 scan_type;
458 u8 num_channels; 597 u8 num_channels;
@@ -563,8 +702,8 @@ struct ipw_rx_packet {
563} __attribute__ ((packed)); 702} __attribute__ ((packed));
564 703
565#define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12 704#define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12
566#define IPW_RX_FRAME_SIZE sizeof(struct ipw_rx_header) + \ 705#define IPW_RX_FRAME_SIZE (unsigned int)(sizeof(struct ipw_rx_header) + \
567 sizeof(struct ipw_rx_frame) 706 sizeof(struct ipw_rx_frame))
568 707
569struct ipw_rx_mem_buffer { 708struct ipw_rx_mem_buffer {
570 dma_addr_t dma_addr; 709 dma_addr_t dma_addr;
@@ -657,6 +796,19 @@ struct ipw_multicast_addr {
657 u8 mac4[6]; 796 u8 mac4[6];
658} __attribute__ ((packed)); 797} __attribute__ ((packed));
659 798
799#define DCW_WEP_KEY_INDEX_MASK 0x03 /* bits [0:1] */
800#define DCW_WEP_KEY_SEC_TYPE_MASK 0x30 /* bits [4:5] */
801
802#define DCW_WEP_KEY_SEC_TYPE_WEP 0x00
803#define DCW_WEP_KEY_SEC_TYPE_CCM 0x20
804#define DCW_WEP_KEY_SEC_TYPE_TKIP 0x30
805
806#define DCW_WEP_KEY_INVALID_SIZE 0x00 /* 0 = Invalid key */
807#define DCW_WEP_KEY64Bit_SIZE 0x05 /* 64-bit encryption */
808#define DCW_WEP_KEY128Bit_SIZE 0x0D /* 128-bit encryption */
809#define DCW_CCM_KEY128Bit_SIZE 0x10 /* 128-bit key */
810//#define DCW_WEP_KEY128BitIV_SIZE 0x10 /* 128-bit key and 128-bit IV */
811
660struct ipw_wep_key { 812struct ipw_wep_key {
661 u8 cmd_id; 813 u8 cmd_id;
662 u8 seq_num; 814 u8 seq_num;
@@ -818,14 +970,6 @@ struct ipw_tx_power {
818 struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS]; 970 struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS];
819} __attribute__ ((packed)); 971} __attribute__ ((packed));
820 972
821struct ipw_qos_parameters {
822 u16 cw_min[4];
823 u16 cw_max[4];
824 u8 aifs[4];
825 u8 flag[4];
826 u16 tx_op_limit[4];
827} __attribute__ ((packed));
828
829struct ipw_rsn_capabilities { 973struct ipw_rsn_capabilities {
830 u8 id; 974 u8 id;
831 u8 length; 975 u8 length;
@@ -888,6 +1032,10 @@ struct ipw_cmd {
888#define STATUS_SCAN_PENDING (1<<20) 1032#define STATUS_SCAN_PENDING (1<<20)
889#define STATUS_SCANNING (1<<21) 1033#define STATUS_SCANNING (1<<21)
890#define STATUS_SCAN_ABORTING (1<<22) 1034#define STATUS_SCAN_ABORTING (1<<22)
1035#define STATUS_SCAN_FORCED (1<<23)
1036
1037#define STATUS_LED_LINK_ON (1<<24)
1038#define STATUS_LED_ACT_ON (1<<25)
891 1039
892#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */ 1040#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */
893#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */ 1041#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */
@@ -899,11 +1047,15 @@ struct ipw_cmd {
899#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */ 1047#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
900#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */ 1048#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
901#define CFG_CUSTOM_MAC (1<<3) 1049#define CFG_CUSTOM_MAC (1<<3)
902#define CFG_PREAMBLE (1<<4) 1050#define CFG_PREAMBLE_LONG (1<<4)
903#define CFG_ADHOC_PERSIST (1<<5) 1051#define CFG_ADHOC_PERSIST (1<<5)
904#define CFG_ASSOCIATE (1<<6) 1052#define CFG_ASSOCIATE (1<<6)
905#define CFG_FIXED_RATE (1<<7) 1053#define CFG_FIXED_RATE (1<<7)
906#define CFG_ADHOC_CREATE (1<<8) 1054#define CFG_ADHOC_CREATE (1<<8)
1055#define CFG_NO_LED (1<<9)
1056#define CFG_BACKGROUND_SCAN (1<<10)
1057#define CFG_SPEED_SCAN (1<<11)
1058#define CFG_NET_STATS (1<<12)
907 1059
908#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ 1060#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
909#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ 1061#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
@@ -925,13 +1077,50 @@ struct average {
925 s32 sum; 1077 s32 sum;
926}; 1078};
927 1079
1080#define MAX_SPEED_SCAN 100
1081#define IPW_IBSS_MAC_HASH_SIZE 31
1082
1083struct ipw_ibss_seq {
1084 u8 mac[ETH_ALEN];
1085 u16 seq_num;
1086 u16 frag_num;
1087 unsigned long packet_time;
1088 struct list_head list;
1089};
1090
1091struct ipw_error_elem {
1092 u32 desc;
1093 u32 time;
1094 u32 blink1;
1095 u32 blink2;
1096 u32 link1;
1097 u32 link2;
1098 u32 data;
1099};
1100
1101struct ipw_event {
1102 u32 event;
1103 u32 time;
1104 u32 data;
1105} __attribute__ ((packed));
1106
1107struct ipw_fw_error {
1108 unsigned long jiffies;
1109 u32 status;
1110 u32 config;
1111 u32 elem_len;
1112 u32 log_len;
1113 struct ipw_error_elem *elem;
1114 struct ipw_event *log;
1115 u8 payload[0];
1116} __attribute__ ((packed));
1117
928struct ipw_priv { 1118struct ipw_priv {
929 /* ieee device used by generic ieee processing code */ 1119 /* ieee device used by generic ieee processing code */
930 struct ieee80211_device *ieee; 1120 struct ieee80211_device *ieee;
931 struct ieee80211_security sec;
932 1121
933 /* spinlock */
934 spinlock_t lock; 1122 spinlock_t lock;
1123 struct semaphore sem;
935 1124
936 /* basic pci-network driver stuff */ 1125 /* basic pci-network driver stuff */
937 struct pci_dev *pci_dev; 1126 struct pci_dev *pci_dev;
@@ -966,7 +1155,7 @@ struct ipw_priv {
966 int rx_bufs_min; /**< minimum number of bufs in Rx queue */ 1155 int rx_bufs_min; /**< minimum number of bufs in Rx queue */
967 int rx_pend_max; /**< maximum pending buffers for one IRQ */ 1156 int rx_pend_max; /**< maximum pending buffers for one IRQ */
968 u32 hcmd_seq; /**< sequence number for hcmd */ 1157 u32 hcmd_seq; /**< sequence number for hcmd */
969 u32 missed_beacon_threshold; 1158 u32 disassociate_threshold;
970 u32 roaming_threshold; 1159 u32 roaming_threshold;
971 1160
972 struct ipw_associate assoc_request; 1161 struct ipw_associate assoc_request;
@@ -1007,6 +1196,8 @@ struct ipw_priv {
1007 u8 mac_addr[ETH_ALEN]; 1196 u8 mac_addr[ETH_ALEN];
1008 u8 num_stations; 1197 u8 num_stations;
1009 u8 stations[MAX_STATIONS][ETH_ALEN]; 1198 u8 stations[MAX_STATIONS][ETH_ALEN];
1199 u8 short_retry_limit;
1200 u8 long_retry_limit;
1010 1201
1011 u32 notif_missed_beacons; 1202 u32 notif_missed_beacons;
1012 1203
@@ -1024,17 +1215,29 @@ struct ipw_priv {
1024 u32 tx_packets; 1215 u32 tx_packets;
1025 u32 quality; 1216 u32 quality;
1026 1217
1218 u8 speed_scan[MAX_SPEED_SCAN];
1219 u8 speed_scan_pos;
1220
1221 u16 last_seq_num;
1222 u16 last_frag_num;
1223 unsigned long last_packet_time;
1224 struct list_head ibss_mac_hash[IPW_IBSS_MAC_HASH_SIZE];
1225
1027 /* eeprom */ 1226 /* eeprom */
1028 u8 eeprom[0x100]; /* 256 bytes of eeprom */ 1227 u8 eeprom[0x100]; /* 256 bytes of eeprom */
1228 u8 country[4];
1029 int eeprom_delay; 1229 int eeprom_delay;
1030 1230
1031 struct iw_statistics wstats; 1231 struct iw_statistics wstats;
1032 1232
1233 struct iw_public_data wireless_data;
1234
1033 struct workqueue_struct *workqueue; 1235 struct workqueue_struct *workqueue;
1034 1236
1035 struct work_struct adhoc_check; 1237 struct work_struct adhoc_check;
1036 struct work_struct associate; 1238 struct work_struct associate;
1037 struct work_struct disassociate; 1239 struct work_struct disassociate;
1240 struct work_struct system_config;
1038 struct work_struct rx_replenish; 1241 struct work_struct rx_replenish;
1039 struct work_struct request_scan; 1242 struct work_struct request_scan;
1040 struct work_struct adapter_restart; 1243 struct work_struct adapter_restart;
@@ -1045,25 +1248,51 @@ struct ipw_priv {
1045 struct work_struct abort_scan; 1248 struct work_struct abort_scan;
1046 struct work_struct roam; 1249 struct work_struct roam;
1047 struct work_struct scan_check; 1250 struct work_struct scan_check;
1251 struct work_struct link_up;
1252 struct work_struct link_down;
1048 1253
1049 struct tasklet_struct irq_tasklet; 1254 struct tasklet_struct irq_tasklet;
1050 1255
1256 /* LED related variables and work_struct */
1257 u8 nic_type;
1258 u32 led_activity_on;
1259 u32 led_activity_off;
1260 u32 led_association_on;
1261 u32 led_association_off;
1262 u32 led_ofdm_on;
1263 u32 led_ofdm_off;
1264
1265 struct work_struct led_link_on;
1266 struct work_struct led_link_off;
1267 struct work_struct led_act_off;
1268 struct work_struct merge_networks;
1269
1270 struct ipw_cmd_log *cmdlog;
1271 int cmdlog_len;
1272 int cmdlog_pos;
1273
1051#define IPW_2200BG 1 1274#define IPW_2200BG 1
1052#define IPW_2915ABG 2 1275#define IPW_2915ABG 2
1053 u8 adapter; 1276 u8 adapter;
1054 1277
1055#define IPW_DEFAULT_TX_POWER 0x14 1278 s8 tx_power;
1056 u8 tx_power;
1057 1279
1058#ifdef CONFIG_PM 1280#ifdef CONFIG_PM
1059 u32 pm_state[16]; 1281 u32 pm_state[16];
1060#endif 1282#endif
1061 1283
1284 struct ipw_fw_error *error;
1285
1062 /* network state */ 1286 /* network state */
1063 1287
1064 /* Used to pass the current INTA value from ISR to Tasklet */ 1288 /* Used to pass the current INTA value from ISR to Tasklet */
1065 u32 isr_inta; 1289 u32 isr_inta;
1066 1290
1291 /* QoS */
1292 struct ipw_qos_info qos_data;
1293 struct work_struct qos_activate;
1294 /*********************************/
1295
1067 /* debugging info */ 1296 /* debugging info */
1068 u32 indirect_dword; 1297 u32 indirect_dword;
1069 u32 direct_dword; 1298 u32 direct_dword;
@@ -1125,6 +1354,8 @@ do { if (ipw_debug_level & (level)) \
1125#define IPW_DL_RF_KILL (1<<17) 1354#define IPW_DL_RF_KILL (1<<17)
1126#define IPW_DL_FW_ERRORS (1<<18) 1355#define IPW_DL_FW_ERRORS (1<<18)
1127 1356
1357#define IPW_DL_LED (1<<19)
1358
1128#define IPW_DL_ORD (1<<20) 1359#define IPW_DL_ORD (1<<20)
1129 1360
1130#define IPW_DL_FRAG (1<<21) 1361#define IPW_DL_FRAG (1<<21)
@@ -1137,6 +1368,8 @@ do { if (ipw_debug_level & (level)) \
1137#define IPW_DL_TRACE (1<<28) 1368#define IPW_DL_TRACE (1<<28)
1138 1369
1139#define IPW_DL_STATS (1<<29) 1370#define IPW_DL_STATS (1<<29)
1371#define IPW_DL_MERGE (1<<30)
1372#define IPW_DL_QOS (1<<31)
1140 1373
1141#define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a) 1374#define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
1142#define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a) 1375#define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
@@ -1150,6 +1383,7 @@ do { if (ipw_debug_level & (level)) \
1150#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a) 1383#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a)
1151#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a) 1384#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a)
1152#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a) 1385#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a)
1386#define IPW_DEBUG_LED(f, a...) IPW_DEBUG(IPW_DL_LED, f, ## a)
1153#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a) 1387#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a)
1154#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a) 1388#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a)
1155#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a) 1389#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a)
@@ -1163,6 +1397,8 @@ do { if (ipw_debug_level & (level)) \
1163#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) 1397#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1164#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) 1398#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1165#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a) 1399#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a)
1400#define IPW_DEBUG_MERGE(f, a...) IPW_DEBUG(IPW_DL_MERGE, f, ## a)
1401#define IPW_DEBUG_QOS(f, a...) IPW_DEBUG(IPW_DL_QOS, f, ## a)
1166 1402
1167#include <linux/ctype.h> 1403#include <linux/ctype.h>
1168 1404
@@ -1177,59 +1413,65 @@ do { if (ipw_debug_level & (level)) \
1177#define DINO_RXFIFO_DATA 0x01 1413#define DINO_RXFIFO_DATA 0x01
1178#define DINO_CONTROL_REG 0x00200000 1414#define DINO_CONTROL_REG 0x00200000
1179 1415
1180#define CX2_INTA_RW 0x00000008 1416#define IPW_INTA_RW 0x00000008
1181#define CX2_INTA_MASK_R 0x0000000C 1417#define IPW_INTA_MASK_R 0x0000000C
1182#define CX2_INDIRECT_ADDR 0x00000010 1418#define IPW_INDIRECT_ADDR 0x00000010
1183#define CX2_INDIRECT_DATA 0x00000014 1419#define IPW_INDIRECT_DATA 0x00000014
1184#define CX2_AUTOINC_ADDR 0x00000018 1420#define IPW_AUTOINC_ADDR 0x00000018
1185#define CX2_AUTOINC_DATA 0x0000001C 1421#define IPW_AUTOINC_DATA 0x0000001C
1186#define CX2_RESET_REG 0x00000020 1422#define IPW_RESET_REG 0x00000020
1187#define CX2_GP_CNTRL_RW 0x00000024 1423#define IPW_GP_CNTRL_RW 0x00000024
1188 1424
1189#define CX2_READ_INT_REGISTER 0xFF4 1425#define IPW_READ_INT_REGISTER 0xFF4
1190 1426
1191#define CX2_GP_CNTRL_BIT_INIT_DONE 0x00000004 1427#define IPW_GP_CNTRL_BIT_INIT_DONE 0x00000004
1192 1428
1193#define CX2_REGISTER_DOMAIN1_END 0x00001000 1429#define IPW_REGISTER_DOMAIN1_END 0x00001000
1194#define CX2_SRAM_READ_INT_REGISTER 0x00000ff4 1430#define IPW_SRAM_READ_INT_REGISTER 0x00000ff4
1195 1431
1196#define CX2_SHARED_LOWER_BOUND 0x00000200 1432#define IPW_SHARED_LOWER_BOUND 0x00000200
1197#define CX2_INTERRUPT_AREA_LOWER_BOUND 0x00000f80 1433#define IPW_INTERRUPT_AREA_LOWER_BOUND 0x00000f80
1198 1434
1199#define CX2_NIC_SRAM_LOWER_BOUND 0x00000000 1435#define IPW_NIC_SRAM_LOWER_BOUND 0x00000000
1200#define CX2_NIC_SRAM_UPPER_BOUND 0x00030000 1436#define IPW_NIC_SRAM_UPPER_BOUND 0x00030000
1201 1437
1202#define CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER (1 << 29) 1438#define IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER (1 << 29)
1203#define CX2_GP_CNTRL_BIT_CLOCK_READY 0x00000001 1439#define IPW_GP_CNTRL_BIT_CLOCK_READY 0x00000001
1204#define CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY 0x00000002 1440#define IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY 0x00000002
1205 1441
1206/* 1442/*
1207 * RESET Register Bit Indexes 1443 * RESET Register Bit Indexes
1208 */ 1444 */
1209#define CBD_RESET_REG_PRINCETON_RESET 0x00000001 /* Bit 0 (LSB) */ 1445#define CBD_RESET_REG_PRINCETON_RESET (1<<0)
1210#define CX2_RESET_REG_SW_RESET 0x00000080 /* Bit 7 */ 1446#define IPW_START_STANDBY (1<<2)
1211#define CX2_RESET_REG_MASTER_DISABLED 0x00000100 /* Bit 8 */ 1447#define IPW_ACTIVITY_LED (1<<4)
1212#define CX2_RESET_REG_STOP_MASTER 0x00000200 /* Bit 9 */ 1448#define IPW_ASSOCIATED_LED (1<<5)
1213#define CX2_ARC_KESHET_CONFIG 0x08000000 /* Bit 27 */ 1449#define IPW_OFDM_LED (1<<6)
1214#define CX2_START_STANDBY 0x00000004 /* Bit 2 */ 1450#define IPW_RESET_REG_SW_RESET (1<<7)
1215 1451#define IPW_RESET_REG_MASTER_DISABLED (1<<8)
1216#define CX2_CSR_CIS_UPPER_BOUND 0x00000200 1452#define IPW_RESET_REG_STOP_MASTER (1<<9)
1217#define CX2_DOMAIN_0_END 0x1000 1453#define IPW_GATE_ODMA (1<<25)
1454#define IPW_GATE_IDMA (1<<26)
1455#define IPW_ARC_KESHET_CONFIG (1<<27)
1456#define IPW_GATE_ADMA (1<<29)
1457
1458#define IPW_CSR_CIS_UPPER_BOUND 0x00000200
1459#define IPW_DOMAIN_0_END 0x1000
1218#define CLX_MEM_BAR_SIZE 0x1000 1460#define CLX_MEM_BAR_SIZE 0x1000
1219 1461
1220#define CX2_BASEBAND_CONTROL_STATUS 0X00200000 1462#define IPW_BASEBAND_CONTROL_STATUS 0X00200000
1221#define CX2_BASEBAND_TX_FIFO_WRITE 0X00200004 1463#define IPW_BASEBAND_TX_FIFO_WRITE 0X00200004
1222#define CX2_BASEBAND_RX_FIFO_READ 0X00200004 1464#define IPW_BASEBAND_RX_FIFO_READ 0X00200004
1223#define CX2_BASEBAND_CONTROL_STORE 0X00200010 1465#define IPW_BASEBAND_CONTROL_STORE 0X00200010
1224 1466
1225#define CX2_INTERNAL_CMD_EVENT 0X00300004 1467#define IPW_INTERNAL_CMD_EVENT 0X00300004
1226#define CX2_BASEBAND_POWER_DOWN 0x00000001 1468#define IPW_BASEBAND_POWER_DOWN 0x00000001
1227 1469
1228#define CX2_MEM_HALT_AND_RESET 0x003000e0 1470#define IPW_MEM_HALT_AND_RESET 0x003000e0
1229 1471
1230/* defgroup bits_halt_reset MEM_HALT_AND_RESET register bits */ 1472/* defgroup bits_halt_reset MEM_HALT_AND_RESET register bits */
1231#define CX2_BIT_HALT_RESET_ON 0x80000000 1473#define IPW_BIT_HALT_RESET_ON 0x80000000
1232#define CX2_BIT_HALT_RESET_OFF 0x00000000 1474#define IPW_BIT_HALT_RESET_OFF 0x00000000
1233 1475
1234#define CB_LAST_VALID 0x20000000 1476#define CB_LAST_VALID 0x20000000
1235#define CB_INT_ENABLED 0x40000000 1477#define CB_INT_ENABLED 0x40000000
@@ -1248,63 +1490,63 @@ do { if (ipw_debug_level & (level)) \
1248#define DMA_CB_STOP_AND_ABORT 0x00000C00 1490#define DMA_CB_STOP_AND_ABORT 0x00000C00
1249#define DMA_CB_START 0x00000100 1491#define DMA_CB_START 0x00000100
1250 1492
1251#define CX2_SHARED_SRAM_SIZE 0x00030000 1493#define IPW_SHARED_SRAM_SIZE 0x00030000
1252#define CX2_SHARED_SRAM_DMA_CONTROL 0x00027000 1494#define IPW_SHARED_SRAM_DMA_CONTROL 0x00027000
1253#define CB_MAX_LENGTH 0x1FFF 1495#define CB_MAX_LENGTH 0x1FFF
1254 1496
1255#define CX2_HOST_EEPROM_DATA_SRAM_SIZE 0xA18 1497#define IPW_HOST_EEPROM_DATA_SRAM_SIZE 0xA18
1256#define CX2_EEPROM_IMAGE_SIZE 0x100 1498#define IPW_EEPROM_IMAGE_SIZE 0x100
1257 1499
1258/* DMA defs */ 1500/* DMA defs */
1259#define CX2_DMA_I_CURRENT_CB 0x003000D0 1501#define IPW_DMA_I_CURRENT_CB 0x003000D0
1260#define CX2_DMA_O_CURRENT_CB 0x003000D4 1502#define IPW_DMA_O_CURRENT_CB 0x003000D4
1261#define CX2_DMA_I_DMA_CONTROL 0x003000A4 1503#define IPW_DMA_I_DMA_CONTROL 0x003000A4
1262#define CX2_DMA_I_CB_BASE 0x003000A0 1504#define IPW_DMA_I_CB_BASE 0x003000A0
1263 1505
1264#define CX2_TX_CMD_QUEUE_BD_BASE (0x00000200) 1506#define IPW_TX_CMD_QUEUE_BD_BASE 0x00000200
1265#define CX2_TX_CMD_QUEUE_BD_SIZE (0x00000204) 1507#define IPW_TX_CMD_QUEUE_BD_SIZE 0x00000204
1266#define CX2_TX_QUEUE_0_BD_BASE (0x00000208) 1508#define IPW_TX_QUEUE_0_BD_BASE 0x00000208
1267#define CX2_TX_QUEUE_0_BD_SIZE (0x0000020C) 1509#define IPW_TX_QUEUE_0_BD_SIZE (0x0000020C)
1268#define CX2_TX_QUEUE_1_BD_BASE (0x00000210) 1510#define IPW_TX_QUEUE_1_BD_BASE 0x00000210
1269#define CX2_TX_QUEUE_1_BD_SIZE (0x00000214) 1511#define IPW_TX_QUEUE_1_BD_SIZE 0x00000214
1270#define CX2_TX_QUEUE_2_BD_BASE (0x00000218) 1512#define IPW_TX_QUEUE_2_BD_BASE 0x00000218
1271#define CX2_TX_QUEUE_2_BD_SIZE (0x0000021C) 1513#define IPW_TX_QUEUE_2_BD_SIZE (0x0000021C)
1272#define CX2_TX_QUEUE_3_BD_BASE (0x00000220) 1514#define IPW_TX_QUEUE_3_BD_BASE 0x00000220
1273#define CX2_TX_QUEUE_3_BD_SIZE (0x00000224) 1515#define IPW_TX_QUEUE_3_BD_SIZE 0x00000224
1274#define CX2_RX_BD_BASE (0x00000240) 1516#define IPW_RX_BD_BASE 0x00000240
1275#define CX2_RX_BD_SIZE (0x00000244) 1517#define IPW_RX_BD_SIZE 0x00000244
1276#define CX2_RFDS_TABLE_LOWER (0x00000500) 1518#define IPW_RFDS_TABLE_LOWER 0x00000500
1277 1519
1278#define CX2_TX_CMD_QUEUE_READ_INDEX (0x00000280) 1520#define IPW_TX_CMD_QUEUE_READ_INDEX 0x00000280
1279#define CX2_TX_QUEUE_0_READ_INDEX (0x00000284) 1521#define IPW_TX_QUEUE_0_READ_INDEX 0x00000284
1280#define CX2_TX_QUEUE_1_READ_INDEX (0x00000288) 1522#define IPW_TX_QUEUE_1_READ_INDEX 0x00000288
1281#define CX2_TX_QUEUE_2_READ_INDEX (0x0000028C) 1523#define IPW_TX_QUEUE_2_READ_INDEX (0x0000028C)
1282#define CX2_TX_QUEUE_3_READ_INDEX (0x00000290) 1524#define IPW_TX_QUEUE_3_READ_INDEX 0x00000290
1283#define CX2_RX_READ_INDEX (0x000002A0) 1525#define IPW_RX_READ_INDEX (0x000002A0)
1284 1526
1285#define CX2_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80) 1527#define IPW_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80)
1286#define CX2_TX_QUEUE_0_WRITE_INDEX (0x00000F84) 1528#define IPW_TX_QUEUE_0_WRITE_INDEX (0x00000F84)
1287#define CX2_TX_QUEUE_1_WRITE_INDEX (0x00000F88) 1529#define IPW_TX_QUEUE_1_WRITE_INDEX (0x00000F88)
1288#define CX2_TX_QUEUE_2_WRITE_INDEX (0x00000F8C) 1530#define IPW_TX_QUEUE_2_WRITE_INDEX (0x00000F8C)
1289#define CX2_TX_QUEUE_3_WRITE_INDEX (0x00000F90) 1531#define IPW_TX_QUEUE_3_WRITE_INDEX (0x00000F90)
1290#define CX2_RX_WRITE_INDEX (0x00000FA0) 1532#define IPW_RX_WRITE_INDEX (0x00000FA0)
1291 1533
1292/* 1534/*
1293 * EEPROM Related Definitions 1535 * EEPROM Related Definitions
1294 */ 1536 */
1295 1537
1296#define IPW_EEPROM_DATA_SRAM_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x814) 1538#define IPW_EEPROM_DATA_SRAM_ADDRESS (IPW_SHARED_LOWER_BOUND + 0x814)
1297#define IPW_EEPROM_DATA_SRAM_SIZE (CX2_SHARED_LOWER_BOUND + 0x818) 1539#define IPW_EEPROM_DATA_SRAM_SIZE (IPW_SHARED_LOWER_BOUND + 0x818)
1298#define IPW_EEPROM_LOAD_DISABLE (CX2_SHARED_LOWER_BOUND + 0x81C) 1540#define IPW_EEPROM_LOAD_DISABLE (IPW_SHARED_LOWER_BOUND + 0x81C)
1299#define IPW_EEPROM_DATA (CX2_SHARED_LOWER_BOUND + 0x820) 1541#define IPW_EEPROM_DATA (IPW_SHARED_LOWER_BOUND + 0x820)
1300#define IPW_EEPROM_UPPER_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x9E0) 1542#define IPW_EEPROM_UPPER_ADDRESS (IPW_SHARED_LOWER_BOUND + 0x9E0)
1301 1543
1302#define IPW_STATION_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0xA0C) 1544#define IPW_STATION_TABLE_LOWER (IPW_SHARED_LOWER_BOUND + 0xA0C)
1303#define IPW_STATION_TABLE_UPPER (CX2_SHARED_LOWER_BOUND + 0xB0C) 1545#define IPW_STATION_TABLE_UPPER (IPW_SHARED_LOWER_BOUND + 0xB0C)
1304#define IPW_REQUEST_ATIM (CX2_SHARED_LOWER_BOUND + 0xB0C) 1546#define IPW_REQUEST_ATIM (IPW_SHARED_LOWER_BOUND + 0xB0C)
1305#define IPW_ATIM_SENT (CX2_SHARED_LOWER_BOUND + 0xB10) 1547#define IPW_ATIM_SENT (IPW_SHARED_LOWER_BOUND + 0xB10)
1306#define IPW_WHO_IS_AWAKE (CX2_SHARED_LOWER_BOUND + 0xB14) 1548#define IPW_WHO_IS_AWAKE (IPW_SHARED_LOWER_BOUND + 0xB14)
1307#define IPW_DURING_ATIM_WINDOW (CX2_SHARED_LOWER_BOUND + 0xB18) 1549#define IPW_DURING_ATIM_WINDOW (IPW_SHARED_LOWER_BOUND + 0xB18)
1308 1550
1309#define MSB 1 1551#define MSB 1
1310#define LSB 0 1552#define LSB 0
@@ -1326,15 +1568,15 @@ do { if (ipw_debug_level & (level)) \
1326#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */ 1568#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */
1327 1569
1328/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/ 1570/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/
1329#define EEPROM_NIC_TYPE_STANDARD 0 1571#define EEPROM_NIC_TYPE_0 0
1330#define EEPROM_NIC_TYPE_DELL 1 1572#define EEPROM_NIC_TYPE_1 1
1331#define EEPROM_NIC_TYPE_FUJITSU 2 1573#define EEPROM_NIC_TYPE_2 2
1332#define EEPROM_NIC_TYPE_IBM 3 1574#define EEPROM_NIC_TYPE_3 3
1333#define EEPROM_NIC_TYPE_HP 4 1575#define EEPROM_NIC_TYPE_4 4
1334 1576
1335#define FW_MEM_REG_LOWER_BOUND 0x00300000 1577#define FW_MEM_REG_LOWER_BOUND 0x00300000
1336#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40) 1578#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40)
1337 1579#define IPW_EVENT_REG (FW_MEM_REG_LOWER_BOUND + 0x04)
1338#define EEPROM_BIT_SK (1<<0) 1580#define EEPROM_BIT_SK (1<<0)
1339#define EEPROM_BIT_CS (1<<1) 1581#define EEPROM_BIT_CS (1<<1)
1340#define EEPROM_BIT_DI (1<<2) 1582#define EEPROM_BIT_DI (1<<2)
@@ -1343,50 +1585,47 @@ do { if (ipw_debug_level & (level)) \
1343#define EEPROM_CMD_READ 0x2 1585#define EEPROM_CMD_READ 0x2
1344 1586
1345/* Interrupts masks */ 1587/* Interrupts masks */
1346#define CX2_INTA_NONE 0x00000000 1588#define IPW_INTA_NONE 0x00000000
1347 1589
1348#define CX2_INTA_BIT_RX_TRANSFER 0x00000002 1590#define IPW_INTA_BIT_RX_TRANSFER 0x00000002
1349#define CX2_INTA_BIT_STATUS_CHANGE 0x00000010 1591#define IPW_INTA_BIT_STATUS_CHANGE 0x00000010
1350#define CX2_INTA_BIT_BEACON_PERIOD_EXPIRED 0x00000020 1592#define IPW_INTA_BIT_BEACON_PERIOD_EXPIRED 0x00000020
1351 1593
1352//Inta Bits for CF 1594//Inta Bits for CF
1353#define CX2_INTA_BIT_TX_CMD_QUEUE 0x00000800 1595#define IPW_INTA_BIT_TX_CMD_QUEUE 0x00000800
1354#define CX2_INTA_BIT_TX_QUEUE_1 0x00001000 1596#define IPW_INTA_BIT_TX_QUEUE_1 0x00001000
1355#define CX2_INTA_BIT_TX_QUEUE_2 0x00002000 1597#define IPW_INTA_BIT_TX_QUEUE_2 0x00002000
1356#define CX2_INTA_BIT_TX_QUEUE_3 0x00004000 1598#define IPW_INTA_BIT_TX_QUEUE_3 0x00004000
1357#define CX2_INTA_BIT_TX_QUEUE_4 0x00008000 1599#define IPW_INTA_BIT_TX_QUEUE_4 0x00008000
1358 1600
1359#define CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE 0x00010000 1601#define IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE 0x00010000
1360 1602
1361#define CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN 0x00100000 1603#define IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN 0x00100000
1362#define CX2_INTA_BIT_POWER_DOWN 0x00200000 1604#define IPW_INTA_BIT_POWER_DOWN 0x00200000
1363 1605
1364#define CX2_INTA_BIT_FW_INITIALIZATION_DONE 0x01000000 1606#define IPW_INTA_BIT_FW_INITIALIZATION_DONE 0x01000000
1365#define CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE 0x02000000 1607#define IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE 0x02000000
1366#define CX2_INTA_BIT_RF_KILL_DONE 0x04000000 1608#define IPW_INTA_BIT_RF_KILL_DONE 0x04000000
1367#define CX2_INTA_BIT_FATAL_ERROR 0x40000000 1609#define IPW_INTA_BIT_FATAL_ERROR 0x40000000
1368#define CX2_INTA_BIT_PARITY_ERROR 0x80000000 1610#define IPW_INTA_BIT_PARITY_ERROR 0x80000000
1369 1611
1370/* Interrupts enabled at init time. */ 1612/* Interrupts enabled at init time. */
1371#define CX2_INTA_MASK_ALL \ 1613#define IPW_INTA_MASK_ALL \
1372 (CX2_INTA_BIT_TX_QUEUE_1 | \ 1614 (IPW_INTA_BIT_TX_QUEUE_1 | \
1373 CX2_INTA_BIT_TX_QUEUE_2 | \ 1615 IPW_INTA_BIT_TX_QUEUE_2 | \
1374 CX2_INTA_BIT_TX_QUEUE_3 | \ 1616 IPW_INTA_BIT_TX_QUEUE_3 | \
1375 CX2_INTA_BIT_TX_QUEUE_4 | \ 1617 IPW_INTA_BIT_TX_QUEUE_4 | \
1376 CX2_INTA_BIT_TX_CMD_QUEUE | \ 1618 IPW_INTA_BIT_TX_CMD_QUEUE | \
1377 CX2_INTA_BIT_RX_TRANSFER | \ 1619 IPW_INTA_BIT_RX_TRANSFER | \
1378 CX2_INTA_BIT_FATAL_ERROR | \ 1620 IPW_INTA_BIT_FATAL_ERROR | \
1379 CX2_INTA_BIT_PARITY_ERROR | \ 1621 IPW_INTA_BIT_PARITY_ERROR | \
1380 CX2_INTA_BIT_STATUS_CHANGE | \ 1622 IPW_INTA_BIT_STATUS_CHANGE | \
1381 CX2_INTA_BIT_FW_INITIALIZATION_DONE | \ 1623 IPW_INTA_BIT_FW_INITIALIZATION_DONE | \
1382 CX2_INTA_BIT_BEACON_PERIOD_EXPIRED | \ 1624 IPW_INTA_BIT_BEACON_PERIOD_EXPIRED | \
1383 CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \ 1625 IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \
1384 CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN | \ 1626 IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN | \
1385 CX2_INTA_BIT_POWER_DOWN | \ 1627 IPW_INTA_BIT_POWER_DOWN | \
1386 CX2_INTA_BIT_RF_KILL_DONE ) 1628 IPW_INTA_BIT_RF_KILL_DONE )
1387
1388#define IPWSTATUS_ERROR_LOG (CX2_SHARED_LOWER_BOUND + 0x410)
1389#define IPW_EVENT_LOG (CX2_SHARED_LOWER_BOUND + 0x414)
1390 1629
1391/* FW event log definitions */ 1630/* FW event log definitions */
1392#define EVENT_ELEM_SIZE (3 * sizeof(u32)) 1631#define EVENT_ELEM_SIZE (3 * sizeof(u32))
@@ -1396,6 +1635,11 @@ do { if (ipw_debug_level & (level)) \
1396#define ERROR_ELEM_SIZE (7 * sizeof(u32)) 1635#define ERROR_ELEM_SIZE (7 * sizeof(u32))
1397#define ERROR_START_OFFSET (1 * sizeof(u32)) 1636#define ERROR_START_OFFSET (1 * sizeof(u32))
1398 1637
1638/* TX power level (dbm) */
1639#define IPW_TX_POWER_MIN -12
1640#define IPW_TX_POWER_MAX 20
1641#define IPW_TX_POWER_DEFAULT IPW_TX_POWER_MAX
1642
1399enum { 1643enum {
1400 IPW_FW_ERROR_OK = 0, 1644 IPW_FW_ERROR_OK = 0,
1401 IPW_FW_ERROR_FAIL, 1645 IPW_FW_ERROR_FAIL,
@@ -1408,8 +1652,8 @@ enum {
1408 IPW_FW_ERROR_ALLOC_FAIL, 1652 IPW_FW_ERROR_ALLOC_FAIL,
1409 IPW_FW_ERROR_DMA_UNDERRUN, 1653 IPW_FW_ERROR_DMA_UNDERRUN,
1410 IPW_FW_ERROR_DMA_STATUS, 1654 IPW_FW_ERROR_DMA_STATUS,
1411 IPW_FW_ERROR_DINOSTATUS_ERROR, 1655 IPW_FW_ERROR_DINO_ERROR,
1412 IPW_FW_ERROR_EEPROMSTATUS_ERROR, 1656 IPW_FW_ERROR_EEPROM_ERROR,
1413 IPW_FW_ERROR_SYSASSERT, 1657 IPW_FW_ERROR_SYSASSERT,
1414 IPW_FW_ERROR_FATAL_ERROR 1658 IPW_FW_ERROR_FATAL_ERROR
1415}; 1659};
@@ -1425,6 +1669,8 @@ enum {
1425#define HC_IBSS_RECONF 4 1669#define HC_IBSS_RECONF 4
1426#define HC_DISASSOC_QUIET 5 1670#define HC_DISASSOC_QUIET 5
1427 1671
1672#define HC_QOS_SUPPORT_ASSOC 0x01
1673
1428#define IPW_RATE_CAPABILITIES 1 1674#define IPW_RATE_CAPABILITIES 1
1429#define IPW_RATE_CONNECT 0 1675#define IPW_RATE_CONNECT 0
1430 1676
@@ -1595,18 +1841,20 @@ enum {
1595 IPW_ORD_TABLE_7_LAST 1841 IPW_ORD_TABLE_7_LAST
1596}; 1842};
1597 1843
1598#define IPW_ORDINALS_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0x500) 1844#define IPW_ERROR_LOG (IPW_SHARED_LOWER_BOUND + 0x410)
1599#define IPW_ORDINALS_TABLE_0 (CX2_SHARED_LOWER_BOUND + 0x180) 1845#define IPW_EVENT_LOG (IPW_SHARED_LOWER_BOUND + 0x414)
1600#define IPW_ORDINALS_TABLE_1 (CX2_SHARED_LOWER_BOUND + 0x184) 1846#define IPW_ORDINALS_TABLE_LOWER (IPW_SHARED_LOWER_BOUND + 0x500)
1601#define IPW_ORDINALS_TABLE_2 (CX2_SHARED_LOWER_BOUND + 0x188) 1847#define IPW_ORDINALS_TABLE_0 (IPW_SHARED_LOWER_BOUND + 0x180)
1602#define IPW_MEM_FIXED_OVERRIDE (CX2_SHARED_LOWER_BOUND + 0x41C) 1848#define IPW_ORDINALS_TABLE_1 (IPW_SHARED_LOWER_BOUND + 0x184)
1849#define IPW_ORDINALS_TABLE_2 (IPW_SHARED_LOWER_BOUND + 0x188)
1850#define IPW_MEM_FIXED_OVERRIDE (IPW_SHARED_LOWER_BOUND + 0x41C)
1603 1851
1604struct ipw_fixed_rate { 1852struct ipw_fixed_rate {
1605 u16 tx_rates; 1853 u16 tx_rates;
1606 u16 reserved; 1854 u16 reserved;
1607} __attribute__ ((packed)); 1855} __attribute__ ((packed));
1608 1856
1609#define CX2_INDIRECT_ADDR_MASK (~0x3ul) 1857#define IPW_INDIRECT_ADDR_MASK (~0x3ul)
1610 1858
1611struct host_cmd { 1859struct host_cmd {
1612 u8 cmd; 1860 u8 cmd;
@@ -1615,6 +1863,12 @@ struct host_cmd {
1615 u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH]; 1863 u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH];
1616} __attribute__ ((packed)); 1864} __attribute__ ((packed));
1617 1865
1866struct ipw_cmd_log {
1867 unsigned long jiffies;
1868 int retcode;
1869 struct host_cmd cmd;
1870};
1871
1618#define CFG_BT_COEXISTENCE_MIN 0x00 1872#define CFG_BT_COEXISTENCE_MIN 0x00
1619#define CFG_BT_COEXISTENCE_DEFER 0x02 1873#define CFG_BT_COEXISTENCE_DEFER 0x02
1620#define CFG_BT_COEXISTENCE_KILL 0x04 1874#define CFG_BT_COEXISTENCE_KILL 0x04
@@ -1643,15 +1897,6 @@ struct host_cmd {
1643#define REG_CHANNEL_MASK 0x00003FFF 1897#define REG_CHANNEL_MASK 0x00003FFF
1644#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff 1898#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff
1645 1899
1646static const long ipw_frequencies[] = {
1647 2412, 2417, 2422, 2427,
1648 2432, 2437, 2442, 2447,
1649 2452, 2457, 2462, 2467,
1650 2472, 2484
1651};
1652
1653#define FREQ_COUNT ARRAY_SIZE(ipw_frequencies)
1654
1655#define IPW_MAX_CONFIG_RETRIES 10 1900#define IPW_MAX_CONFIG_RETRIES 10
1656 1901
1657static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr) 1902static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 7a17bb31fc89..f5d856db92a1 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -12,7 +12,6 @@
12#include <linux/netdevice.h> 12#include <linux/netdevice.h>
13#include <linux/wireless.h> 13#include <linux/wireless.h>
14#include <net/iw_handler.h> 14#include <net/iw_handler.h>
15#include <linux/version.h>
16 15
17#include "hermes.h" 16#include "hermes.h"
18 17
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index adc7499136dc..109a96d90007 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -18,7 +18,6 @@
18 * 18 *
19 */ 19 */
20 20
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/types.h> 22#include <linux/types.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
@@ -112,9 +111,10 @@ isl38xx_handle_wakeup(isl38xx_control_block *control_block,
112void 111void
113isl38xx_trigger_device(int asleep, void __iomem *device_base) 112isl38xx_trigger_device(int asleep, void __iomem *device_base)
114{ 113{
115 u32 reg, counter = 0; 114 u32 reg;
116 115
117#if VERBOSE > SHOW_ERROR_MESSAGES 116#if VERBOSE > SHOW_ERROR_MESSAGES
117 u32 counter = 0;
118 struct timeval current_time; 118 struct timeval current_time;
119 DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n"); 119 DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
120#endif 120#endif
@@ -131,7 +131,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
131 current_time.tv_sec, (long)current_time.tv_usec, 131 current_time.tv_sec, (long)current_time.tv_usec,
132 readl(device_base + ISL38XX_CTRL_STAT_REG)); 132 readl(device_base + ISL38XX_CTRL_STAT_REG));
133#endif 133#endif
134 udelay(ISL38XX_WRITEIO_DELAY);
135 134
136 reg = readl(device_base + ISL38XX_INT_IDENT_REG); 135 reg = readl(device_base + ISL38XX_INT_IDENT_REG);
137 if (reg == 0xabadface) { 136 if (reg == 0xabadface) {
@@ -145,7 +144,9 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
145 while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG), 144 while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG),
146 (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) { 145 (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) {
147 udelay(ISL38XX_WRITEIO_DELAY); 146 udelay(ISL38XX_WRITEIO_DELAY);
147#if VERBOSE > SHOW_ERROR_MESSAGES
148 counter++; 148 counter++;
149#endif
149 } 150 }
150 151
151#if VERBOSE > SHOW_ERROR_MESSAGES 152#if VERBOSE > SHOW_ERROR_MESSAGES
@@ -153,10 +154,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
153 "%08li.%08li Device register read %08x\n", 154 "%08li.%08li Device register read %08x\n",
154 current_time.tv_sec, (long)current_time.tv_usec, 155 current_time.tv_sec, (long)current_time.tv_usec,
155 readl(device_base + ISL38XX_CTRL_STAT_REG)); 156 readl(device_base + ISL38XX_CTRL_STAT_REG));
156#endif
157 udelay(ISL38XX_WRITEIO_DELAY);
158
159#if VERBOSE > SHOW_ERROR_MESSAGES
160 do_gettimeofday(&current_time); 157 do_gettimeofday(&current_time);
161 DEBUG(SHOW_TRACING, 158 DEBUG(SHOW_TRACING,
162 "%08li.%08li Device asleep counter %i\n", 159 "%08li.%08li Device asleep counter %i\n",
@@ -171,7 +168,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
171 168
172 /* perform another read on the Device Status Register */ 169 /* perform another read on the Device Status Register */
173 reg = readl(device_base + ISL38XX_CTRL_STAT_REG); 170 reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
174 udelay(ISL38XX_WRITEIO_DELAY);
175 171
176#if VERBOSE > SHOW_ERROR_MESSAGES 172#if VERBOSE > SHOW_ERROR_MESSAGES
177 do_gettimeofday(&current_time); 173 do_gettimeofday(&current_time);
@@ -187,7 +183,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
187 183
188 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE, 184 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
189 ISL38XX_DEV_INT_REG); 185 ISL38XX_DEV_INT_REG);
190 udelay(ISL38XX_WRITEIO_DELAY);
191 } 186 }
192} 187}
193 188
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
index e83e4912ab66..8af20980af8d 100644
--- a/drivers/net/wireless/prism54/isl_38xx.h
+++ b/drivers/net/wireless/prism54/isl_38xx.h
@@ -20,7 +20,6 @@
20#ifndef _ISL_38XX_H 20#ifndef _ISL_38XX_H
21#define _ISL_38XX_H 21#define _ISL_38XX_H
22 22
23#include <linux/version.h>
24#include <asm/io.h> 23#include <asm/io.h>
25#include <asm/byteorder.h> 24#include <asm/byteorder.h>
26 25
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 5c1a1adf1ff8..135a156db25d 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#include <linux/version.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/kernel.h> 24#include <linux/kernel.h>
26#include <linux/if_arp.h> 25#include <linux/if_arp.h>
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 78bdb359835e..5ddf29599032 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <linux/version.h>
23#include <linux/module.h> 22#include <linux/module.h>
24 23
25#include <linux/netdevice.h> 24#include <linux/netdevice.h>
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index efbed4397951..07053165e4c5 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -23,7 +23,6 @@
23#ifndef _ISLPCI_DEV_H 23#ifndef _ISLPCI_DEV_H
24#define _ISLPCI_DEV_H 24#define _ISLPCI_DEV_H
25 25
26#include <linux/version.h>
27#include <linux/netdevice.h> 26#include <linux/netdevice.h>
28#include <linux/wireless.h> 27#include <linux/wireless.h>
29#include <net/iw_handler.h> 28#include <net/iw_handler.h>
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index fc1eb3564832..33d64d2ee53f 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -17,7 +17,6 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/version.h>
21#include <linux/module.h> 20#include <linux/module.h>
22 21
23#include <linux/pci.h> 22#include <linux/pci.h>
@@ -227,17 +226,17 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
227 priv->data_low_tx_full = 1; 226 priv->data_low_tx_full = 1;
228 } 227 }
229 228
229 /* set the transmission time */
230 ndev->trans_start = jiffies;
231 priv->statistics.tx_packets++;
232 priv->statistics.tx_bytes += skb->len;
233
230 /* trigger the device */ 234 /* trigger the device */
231 islpci_trigger(priv); 235 islpci_trigger(priv);
232 236
233 /* unlock the driver code */ 237 /* unlock the driver code */
234 spin_unlock_irqrestore(&priv->slock, flags); 238 spin_unlock_irqrestore(&priv->slock, flags);
235 239
236 /* set the transmission time */
237 ndev->trans_start = jiffies;
238 priv->statistics.tx_packets++;
239 priv->statistics.tx_bytes += skb->len;
240
241 return 0; 240 return 0;
242 241
243 drop_free: 242 drop_free:
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index dc040caab7d7..b41d666fea3c 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -18,7 +18,6 @@
18 * 18 *
19 */ 19 */
20 20
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/pci.h> 22#include <linux/pci.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 4b3c98f5c564..c822cad3333f 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4608,9 +4608,8 @@ wavelan_attach(void)
4608#endif 4608#endif
4609 4609
4610 /* Initialize the dev_link_t structure */ 4610 /* Initialize the dev_link_t structure */
4611 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 4611 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
4612 if (!link) return NULL; 4612 if (!link) return NULL;
4613 memset(link, 0, sizeof(struct dev_link_t));
4614 4613
4615 /* The io structure describes IO port mapping */ 4614 /* The io structure describes IO port mapping */
4616 link->io.NumPorts1 = 8; 4615 link->io.NumPorts1 = 8;
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 3f8c27f0871b..978fdc606781 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1965,10 +1965,9 @@ static dev_link_t *wl3501_attach(void)
1965 int ret; 1965 int ret;
1966 1966
1967 /* Initialize the dev_link_t structure */ 1967 /* Initialize the dev_link_t structure */
1968 link = kmalloc(sizeof(*link), GFP_KERNEL); 1968 link = kzalloc(sizeof(*link), GFP_KERNEL);
1969 if (!link) 1969 if (!link)
1970 goto out; 1970 goto out;
1971 memset(link, 0, sizeof(struct dev_link_t));
1972 1971
1973 /* The io structure describes IO port mapping */ 1972 /* The io structure describes IO port mapping */
1974 link->io.NumPorts1 = 16; 1973 link->io.NumPorts1 = 16;
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index d414a3bb50b9..86c0808d6a05 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -30,7 +30,6 @@
30#include <linux/timer.h> 30#include <linux/timer.h>
31#include <linux/mm.h> 31#include <linux/mm.h>
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/version.h>
34#include <linux/types.h> 33#include <linux/types.h>
35 34
36#include <pcmcia/cs_types.h> 35#include <pcmcia/cs_types.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index f113b69d699b..01a895bc9a47 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -35,7 +35,6 @@
35#include <linux/timer.h> 35#include <linux/timer.h>
36#include <linux/mm.h> 36#include <linux/mm.h>
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38#include <linux/version.h>
39#include <linux/types.h> 38#include <linux/types.h>
40 39
41#include <pcmcia/cs_types.h> 40#include <pcmcia/cs_types.h>
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index fe5ea36e7de3..56c58831e80e 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -22,16 +22,20 @@
22#include <asm/hardware.h> 22#include <asm/hardware.h>
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <asm/hardware/scoop.h> 24#include <asm/hardware/scoop.h>
25#ifdef CONFIG_SA1100_COLLIE
26#include <asm/arch-sa1100/collie.h>
27#else
28#include <asm/arch-pxa/pxa-regs.h>
29#endif
30 25
31#include "soc_common.h" 26#include "soc_common.h"
32 27
33#define NO_KEEP_VS 0x0001 28#define NO_KEEP_VS 0x0001
34 29
30/* PCMCIA to Scoop linkage
31
32 There is no easy way to link multiple scoop devices into one
33 single entity for the pxa2xx_pcmcia device so this structure
34 is used which is setup by the platform code
35*/
36struct scoop_pcmcia_config *platform_scoop_config;
37#define SCOOP_DEV platform_scoop_config->devs
38
35static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev) 39static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev)
36{ 40{
37 reset_scoop(scoopdev->dev); 41 reset_scoop(scoopdev->dev);
@@ -43,38 +47,16 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
43{ 47{
44 int ret; 48 int ret;
45 49
46#ifndef CONFIG_SA1100_COLLIE 50 if (platform_scoop_config->pcmcia_init)
47 /* 51 platform_scoop_config->pcmcia_init();
48 * Setup default state of GPIO outputs
49 * before we enable them as outputs.
50 */
51 GPSR(GPIO48_nPOE) =
52 GPIO_bit(GPIO48_nPOE) |
53 GPIO_bit(GPIO49_nPWE) |
54 GPIO_bit(GPIO50_nPIOR) |
55 GPIO_bit(GPIO51_nPIOW) |
56 GPIO_bit(GPIO52_nPCE_1) |
57 GPIO_bit(GPIO53_nPCE_2);
58
59 pxa_gpio_mode(GPIO48_nPOE_MD);
60 pxa_gpio_mode(GPIO49_nPWE_MD);
61 pxa_gpio_mode(GPIO50_nPIOR_MD);
62 pxa_gpio_mode(GPIO51_nPIOW_MD);
63 pxa_gpio_mode(GPIO52_nPCE_1_MD);
64 pxa_gpio_mode(GPIO53_nPCE_2_MD);
65 pxa_gpio_mode(GPIO54_pSKTSEL_MD);
66 pxa_gpio_mode(GPIO55_nPREG_MD);
67 pxa_gpio_mode(GPIO56_nPWAIT_MD);
68 pxa_gpio_mode(GPIO57_nIOIS16_MD);
69#endif
70 52
71 /* Register interrupts */ 53 /* Register interrupts */
72 if (scoop_devs[skt->nr].cd_irq >= 0) { 54 if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
73 struct pcmcia_irqs cd_irq; 55 struct pcmcia_irqs cd_irq;
74 56
75 cd_irq.sock = skt->nr; 57 cd_irq.sock = skt->nr;
76 cd_irq.irq = scoop_devs[skt->nr].cd_irq; 58 cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
77 cd_irq.str = scoop_devs[skt->nr].cd_irq_str; 59 cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
78 ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); 60 ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
79 61
80 if (ret) { 62 if (ret) {
@@ -83,19 +65,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
83 } 65 }
84 } 66 }
85 67
86 skt->irq = scoop_devs[skt->nr].irq; 68 skt->irq = SCOOP_DEV[skt->nr].irq;
87 69
88 return 0; 70 return 0;
89} 71}
90 72
91static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 73static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
92{ 74{
93 if (scoop_devs[skt->nr].cd_irq >= 0) { 75 if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
94 struct pcmcia_irqs cd_irq; 76 struct pcmcia_irqs cd_irq;
95 77
96 cd_irq.sock = skt->nr; 78 cd_irq.sock = skt->nr;
97 cd_irq.irq = scoop_devs[skt->nr].cd_irq; 79 cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
98 cd_irq.str = scoop_devs[skt->nr].cd_irq_str; 80 cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
99 soc_pcmcia_free_irqs(skt, &cd_irq, 1); 81 soc_pcmcia_free_irqs(skt, &cd_irq, 1);
100 } 82 }
101} 83}
@@ -105,9 +87,9 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
105 struct pcmcia_state *state) 87 struct pcmcia_state *state)
106{ 88{
107 unsigned short cpr, csr; 89 unsigned short cpr, csr;
108 struct device *scoop = scoop_devs[skt->nr].dev; 90 struct device *scoop = SCOOP_DEV[skt->nr].dev;
109 91
110 cpr = read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR); 92 cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR);
111 93
112 write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); 94 write_scoop_reg(scoop, SCOOP_IRM, 0x00FF);
113 write_scoop_reg(scoop, SCOOP_ISR, 0x0000); 95 write_scoop_reg(scoop, SCOOP_ISR, 0x0000);
@@ -116,21 +98,25 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
116 if (csr & 0x0004) { 98 if (csr & 0x0004) {
117 /* card eject */ 99 /* card eject */
118 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 100 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
119 scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; 101 SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
120 } 102 }
121 else if (!(scoop_devs[skt->nr].keep_vs & NO_KEEP_VS)) { 103 else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) {
122 /* keep vs1,vs2 */ 104 /* keep vs1,vs2 */
123 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 105 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
124 csr |= scoop_devs[skt->nr].keep_vs; 106 csr |= SCOOP_DEV[skt->nr].keep_vs;
125 } 107 }
126 else if (cpr & 0x0003) { 108 else if (cpr & 0x0003) {
127 /* power on */ 109 /* power on */
128 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 110 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
129 scoop_devs[skt->nr].keep_vs = (csr & 0x00C0); 111 SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0);
130 } 112 }
131 else { 113 else {
132 /* card detect */ 114 /* card detect */
133 write_scoop_reg(scoop, SCOOP_CDR, 0x0002); 115 if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) {
116 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
117 } else {
118 write_scoop_reg(scoop, SCOOP_CDR, 0x0002);
119 }
134 } 120 }
135 121
136 state->detect = (csr & 0x0004) ? 0 : 1; 122 state->detect = (csr & 0x0004) ? 0 : 1;
@@ -144,7 +130,6 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
144 if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { 130 if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) {
145 printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); 131 printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr);
146 } 132 }
147
148} 133}
149 134
150 135
@@ -152,7 +137,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
152 const socket_state_t *state) 137 const socket_state_t *state)
153{ 138{
154 unsigned long flags; 139 unsigned long flags;
155 struct device *scoop = scoop_devs[skt->nr].dev; 140 struct device *scoop = SCOOP_DEV[skt->nr].dev;
156 141
157 unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; 142 unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr;
158 143
@@ -177,8 +162,13 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
177 nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; 162 nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080;
178 nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; 163 nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E;
179 164
180 ncpr |= (state->Vcc == 33) ? 0x0001 : 165 if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) {
181 (state->Vcc == 50) ? 0x0002 : 0; 166 ncpr |= (state->Vcc == 33) ? 0x0002 :
167 (state->Vcc == 50) ? 0x0002 : 0;
168 } else {
169 ncpr |= (state->Vcc == 33) ? 0x0001 :
170 (state->Vcc == 50) ? 0x0002 : 0;
171 }
182 nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; 172 nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0;
183 ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; 173 ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0;
184 nccr |= (state->flags&SS_RESET)? 0x0080: 0; 174 nccr |= (state->flags&SS_RESET)? 0x0080: 0;
@@ -190,18 +180,22 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
190 ((skt->status&SS_WRPROT) ? 0x0008 : 0); 180 ((skt->status&SS_WRPROT) ? 0x0008 : 0);
191 181
192 if (!(ncpr & 0x0003)) { 182 if (!(ncpr & 0x0003)) {
193 scoop_devs[skt->nr].keep_rd = 0; 183 SCOOP_DEV[skt->nr].keep_rd = 0;
194 } else if (!scoop_devs[skt->nr].keep_rd) { 184 } else if (!SCOOP_DEV[skt->nr].keep_rd) {
195 if (nccr & 0x0080) 185 if (nccr & 0x0080)
196 scoop_devs[skt->nr].keep_rd = 1; 186 SCOOP_DEV[skt->nr].keep_rd = 1;
197 else 187 else
198 nccr |= 0x0080; 188 nccr |= 0x0080;
199 } 189 }
200 190
201 if (mcr != nmcr) 191 if (mcr != nmcr)
202 write_scoop_reg(scoop, SCOOP_MCR, nmcr); 192 write_scoop_reg(scoop, SCOOP_MCR, nmcr);
203 if (cpr != ncpr) 193 if (cpr != ncpr) {
204 write_scoop_reg(scoop, SCOOP_CPR, ncpr); 194 if (platform_scoop_config->power_ctrl)
195 platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr);
196 else
197 write_scoop_reg(scoop, SCOOP_CPR, ncpr);
198 }
205 if (ccr != nccr) 199 if (ccr != nccr)
206 write_scoop_reg(scoop, SCOOP_CCR, nccr); 200 write_scoop_reg(scoop, SCOOP_CCR, nccr);
207 if (imr != nimr) 201 if (imr != nimr)
@@ -214,43 +208,43 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
214 208
215static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) 209static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
216{ 210{
217 sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); 211 sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
218 212
219 /* Enable interrupt */ 213 /* Enable interrupt */
220 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0); 214 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0);
221 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101); 215 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101);
222 scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; 216 SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
223 217
224 if (machine_is_collie()) 218 if (machine_is_collie())
225 /* We need to disable SS_OUTPUT_ENA here. */ 219 /* We need to disable SS_OUTPUT_ENA here. */
226 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); 220 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
227} 221}
228 222
229static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) 223static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
230{ 224{
231 /* CF_BUS_OFF */ 225 /* CF_BUS_OFF */
232 sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); 226 sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
233 227
234 if (machine_is_collie()) 228 if (machine_is_collie())
235 /* We need to disable SS_OUTPUT_ENA here. */ 229 /* We need to disable SS_OUTPUT_ENA here. */
236 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); 230 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
237} 231}
238 232
239static struct pcmcia_low_level sharpsl_pcmcia_ops = { 233static struct pcmcia_low_level sharpsl_pcmcia_ops = {
240 .owner = THIS_MODULE, 234 .owner = THIS_MODULE,
241 .hw_init = sharpsl_pcmcia_hw_init, 235 .hw_init = sharpsl_pcmcia_hw_init,
242 .hw_shutdown = sharpsl_pcmcia_hw_shutdown, 236 .hw_shutdown = sharpsl_pcmcia_hw_shutdown,
243 .socket_state = sharpsl_pcmcia_socket_state, 237 .socket_state = sharpsl_pcmcia_socket_state,
244 .configure_socket = sharpsl_pcmcia_configure_socket, 238 .configure_socket = sharpsl_pcmcia_configure_socket,
245 .socket_init = sharpsl_pcmcia_socket_init, 239 .socket_init = sharpsl_pcmcia_socket_init,
246 .socket_suspend = sharpsl_pcmcia_socket_suspend, 240 .socket_suspend = sharpsl_pcmcia_socket_suspend,
247 .first = 0, 241 .first = 0,
248 .nr = 0, 242 .nr = 0,
249}; 243};
250 244
251static struct platform_device *sharpsl_pcmcia_device;
252
253#ifdef CONFIG_SA1100_COLLIE 245#ifdef CONFIG_SA1100_COLLIE
246#include "sa11xx_base.h"
247
254int __init pcmcia_collie_init(struct device *dev) 248int __init pcmcia_collie_init(struct device *dev)
255{ 249{
256 int ret = -ENODEV; 250 int ret = -ENODEV;
@@ -263,11 +257,13 @@ int __init pcmcia_collie_init(struct device *dev)
263 257
264#else 258#else
265 259
260static struct platform_device *sharpsl_pcmcia_device;
261
266static int __init sharpsl_pcmcia_init(void) 262static int __init sharpsl_pcmcia_init(void)
267{ 263{
268 int ret; 264 int ret;
269 265
270 sharpsl_pcmcia_ops.nr=scoop_num; 266 sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
271 sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); 267 sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
272 if (!sharpsl_pcmcia_device) 268 if (!sharpsl_pcmcia_device)
273 return -ENOMEM; 269 return -ENOMEM;
@@ -275,7 +271,7 @@ static int __init sharpsl_pcmcia_init(void)
275 memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device)); 271 memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
276 sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; 272 sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
277 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; 273 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
278 sharpsl_pcmcia_device->dev.parent=scoop_devs[0].dev; 274 sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
279 275
280 ret = platform_device_register(sharpsl_pcmcia_device); 276 ret = platform_device_register(sharpsl_pcmcia_device);
281 if (ret) 277 if (ret)
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h
index 3b4da5a9cf79..f7bf45c6bf0d 100644
--- a/drivers/s390/char/keyboard.h
+++ b/drivers/s390/char/keyboard.h
@@ -41,14 +41,14 @@ int kbd_ioctl(struct kbd_data *, struct file *, unsigned int, unsigned long);
41/* 41/*
42 * Helper Functions. 42 * Helper Functions.
43 */ 43 */
44extern inline void 44static inline void
45kbd_put_queue(struct tty_struct *tty, int ch) 45kbd_put_queue(struct tty_struct *tty, int ch)
46{ 46{
47 tty_insert_flip_char(tty, ch, 0); 47 tty_insert_flip_char(tty, ch, 0);
48 tty_schedule_flip(tty); 48 tty_schedule_flip(tty);
49} 49}
50 50
51extern inline void 51static inline void
52kbd_puts_queue(struct tty_struct *tty, char *cp) 52kbd_puts_queue(struct tty_struct *tty, char *cp)
53{ 53{
54 while (*cp) 54 while (*cp)
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 6b8aa6a852be..328e31cc6854 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -265,7 +265,7 @@ QDIO_PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
265/* 265/*
266 * Some instructions as assembly 266 * Some instructions as assembly
267 */ 267 */
268extern __inline__ int 268static inline int
269do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2) 269do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
270{ 270{
271 int cc; 271 int cc;
@@ -300,7 +300,7 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
300 return cc; 300 return cc;
301} 301}
302 302
303extern __inline__ int 303static inline int
304do_siga_input(unsigned int irq, unsigned int mask) 304do_siga_input(unsigned int irq, unsigned int mask)
305{ 305{
306 int cc; 306 int cc;
@@ -334,7 +334,7 @@ do_siga_input(unsigned int irq, unsigned int mask)
334 return cc; 334 return cc;
335} 335}
336 336
337extern __inline__ int 337static inline int
338do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb) 338do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
339{ 339{
340 int cc; 340 int cc;
@@ -401,7 +401,7 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
401 return cc; 401 return cc;
402} 402}
403 403
404extern __inline__ unsigned long 404static inline unsigned long
405do_clear_global_summary(void) 405do_clear_global_summary(void)
406{ 406{
407 407
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
index 04c2ef778ec6..4010f2bb85af 100644
--- a/drivers/s390/crypto/z90main.c
+++ b/drivers/s390/crypto/z90main.c
@@ -37,7 +37,6 @@
37#include <linux/kobject_uevent.h> 37#include <linux/kobject_uevent.h>
38#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
39#include <linux/syscalls.h> 39#include <linux/syscalls.h>
40#include <linux/version.h>
41#include "z90crypt.h" 40#include "z90crypt.h"
42#include "z90common.h" 41#include "z90common.h"
43 42
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 1a1c3decea72..6b63d21612ec 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -88,7 +88,6 @@
88#include <linux/tcp.h> 88#include <linux/tcp.h>
89#include <linux/timer.h> 89#include <linux/timer.h>
90#include <linux/types.h> 90#include <linux/types.h>
91#include <linux/version.h>
92 91
93#include "cu3088.h" 92#include "cu3088.h"
94#include "claw.h" 93#include "claw.h"
diff --git a/drivers/s390/net/fsm.h b/drivers/s390/net/fsm.h
index 1b8a7e7c34f3..5b98253be7aa 100644
--- a/drivers/s390/net/fsm.h
+++ b/drivers/s390/net/fsm.h
@@ -140,7 +140,7 @@ fsm_record_history(fsm_instance *fi, int state, int event);
140 * 1 if current state or event is out of range 140 * 1 if current state or event is out of range
141 * !0 if state and event in range, but no action defined. 141 * !0 if state and event in range, but no action defined.
142 */ 142 */
143extern __inline__ int 143static inline int
144fsm_event(fsm_instance *fi, int event, void *arg) 144fsm_event(fsm_instance *fi, int event, void *arg)
145{ 145{
146 fsm_function_t r; 146 fsm_function_t r;
@@ -188,7 +188,7 @@ fsm_event(fsm_instance *fi, int event, void *arg)
188 * @param fi Pointer to FSM 188 * @param fi Pointer to FSM
189 * @param state The new state for this FSM. 189 * @param state The new state for this FSM.
190 */ 190 */
191extern __inline__ void 191static inline void
192fsm_newstate(fsm_instance *fi, int newstate) 192fsm_newstate(fsm_instance *fi, int newstate)
193{ 193{
194 atomic_set(&fi->state,newstate); 194 atomic_set(&fi->state,newstate);
@@ -208,7 +208,7 @@ fsm_newstate(fsm_instance *fi, int newstate)
208 * 208 *
209 * @return The current state of the FSM. 209 * @return The current state of the FSM.
210 */ 210 */
211extern __inline__ int 211static inline int
212fsm_getstate(fsm_instance *fi) 212fsm_getstate(fsm_instance *fi)
213{ 213{
214 return atomic_read(&fi->state); 214 return atomic_read(&fi->state);
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
index 4eaa70179182..d9ea7ed2e46e 100644
--- a/drivers/s390/s390mach.h
+++ b/drivers/s390/s390mach.h
@@ -88,7 +88,7 @@ struct crw {
88#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */ 88#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
89#define CRW_ERC_PMOD 0x08 /* installed parameters modified */ 89#define CRW_ERC_PMOD 0x08 /* installed parameters modified */
90 90
91extern __inline__ int stcrw(struct crw *pcrw ) 91static inline int stcrw(struct crw *pcrw )
92{ 92{
93 int ccode; 93 int ccode;
94 94
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
index 071ae24be892..fd2cc7782f76 100644
--- a/drivers/sbus/char/cpwatchdog.c
+++ b/drivers/sbus/char/cpwatchdog.c
@@ -407,7 +407,7 @@ static long wd_compat_ioctl(struct file *file, unsigned int cmd,
407 case WIOCGSTAT: 407 case WIOCGSTAT:
408 lock_kernel(); 408 lock_kernel();
409 rval = wd_ioctl(file->f_dentry->d_inode, file, cmd, arg); 409 rval = wd_ioctl(file->f_dentry->d_inode, file, cmd, arg);
410 lock_kernel(); 410 unlock_kernel();
411 break; 411 break;
412 /* everything else is handled by the generic compat layer */ 412 /* everything else is handled by the generic compat layer */
413 default: 413 default:
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 39f54213a6d5..2c86a4b809cd 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -161,7 +161,7 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
161 writeb(regs, d7s_regs); 161 writeb(regs, d7s_regs);
162 break; 162 break;
163 }; 163 };
164 lock_kernel(); 164 unlock_kernel();
165 165
166 return error; 166 return error;
167} 167}
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 5028ac214326..383a95f34a0d 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -596,6 +596,8 @@ static long openprom_compat_ioctl(struct file *file, unsigned int cmd,
596 lock_kernel(); 596 lock_kernel();
597 break; 597 break;
598 } 598 }
599
600 return rval;
599} 601}
600 602
601static int openprom_open(struct inode * inode, struct file * file) 603static int openprom_open(struct inode * inode, struct file * file)
@@ -623,6 +625,7 @@ static struct file_operations openprom_fops = {
623 .owner = THIS_MODULE, 625 .owner = THIS_MODULE,
624 .llseek = no_llseek, 626 .llseek = no_llseek,
625 .ioctl = openprom_ioctl, 627 .ioctl = openprom_ioctl,
628 .compat_ioctl = openprom_compat_ioctl,
626 .open = openprom_open, 629 .open = openprom_open,
627 .release = openprom_release, 630 .release = openprom_release,
628}; 631};
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 9b988baf0b51..5774bdd0e26f 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -210,6 +210,27 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
210 } 210 }
211} 211}
212 212
213static long rtc_compat_ioctl(struct file *file, unsigned int cmd,
214 unsigned long arg)
215{
216 int rval = -ENOIOCTLCMD;
217
218 switch (cmd) {
219 /*
220 * These two are specific to this driver, the generic rtc ioctls
221 * are hanlded elsewhere.
222 */
223 case RTCGET:
224 case RTCSET:
225 lock_kernel();
226 rval = rtc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
227 unlock_kernel();
228 break;
229 }
230
231 return rval;
232}
233
213static int rtc_open(struct inode *inode, struct file *file) 234static int rtc_open(struct inode *inode, struct file *file)
214{ 235{
215 int ret; 236 int ret;
@@ -237,6 +258,7 @@ static struct file_operations rtc_fops = {
237 .owner = THIS_MODULE, 258 .owner = THIS_MODULE,
238 .llseek = no_llseek, 259 .llseek = no_llseek,
239 .ioctl = rtc_ioctl, 260 .ioctl = rtc_ioctl,
261 .compat_ioctl = rtc_compat_ioctl,
240 .open = rtc_open, 262 .open = rtc_open,
241 .release = rtc_release, 263 .release = rtc_release,
242}; 264};
diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
index 98bad773f240..4f81fc39ec57 100644
--- a/drivers/scsi/3w-xxxx.h
+++ b/drivers/scsi/3w-xxxx.h
@@ -54,7 +54,6 @@
54#ifndef _3W_XXXX_H 54#ifndef _3W_XXXX_H
55#define _3W_XXXX_H 55#define _3W_XXXX_H
56 56
57#include <linux/version.h>
58#include <linux/types.h> 57#include <linux/types.h>
59 58
60/* AEN strings */ 59/* AEN strings */
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index 1589007e5a2a..54996eaae979 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/init.h> 5#include <linux/init.h>
7#include <linux/interrupt.h> 6#include <linux/interrupt.h>
8 7
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 10f90d39374a..10c470e7d316 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -42,8 +42,8 @@
42#include <linux/sched.h> 42#include <linux/sched.h>
43#include <linux/dma-mapping.h> 43#include <linux/dma-mapping.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
46#include <scsi/scsi_cmnd.h>
47#include <linux/libata.h> 47#include <linux/libata.h>
48#include <asm/io.h> 48#include <asm/io.h>
49 49
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 052c6619accc..bc44222d6cc3 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -49,7 +49,6 @@
49#include <linux/ioport.h> 49#include <linux/ioport.h>
50#include <linux/pci.h> 50#include <linux/pci.h>
51#include <linux/smp_lock.h> 51#include <linux/smp_lock.h>
52#include <linux/version.h>
53#include <linux/interrupt.h> 52#include <linux/interrupt.h>
54#include <linux/module.h> 53#include <linux/module.h>
55#include <linux/slab.h> 54#include <linux/slab.h>
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index be9edbe26dbe..f2a95447142c 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -66,7 +66,6 @@
66#include <linux/ioport.h> 66#include <linux/ioport.h>
67#include <linux/pci.h> 67#include <linux/pci.h>
68#include <linux/smp_lock.h> 68#include <linux/smp_lock.h>
69#include <linux/version.h>
70#include <linux/interrupt.h> 69#include <linux/interrupt.h>
71#include <linux/module.h> 70#include <linux/module.h>
72#include <linux/slab.h> 71#include <linux/slab.h>
diff --git a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
index e02db80cab33..c0844fa32c5d 100644
--- a/drivers/scsi/amiga7xx.c
+++ b/drivers/scsi/amiga7xx.c
@@ -11,7 +11,6 @@
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/blkdev.h> 12#include <linux/blkdev.h>
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/version.h>
15#include <linux/config.h> 14#include <linux/config.h>
16#include <linux/zorro.h> 15#include <linux/zorro.h>
17#include <linux/stat.h> 16#include <linux/stat.h>
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 7fc8873de0b6..a1bd8d95623c 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -46,7 +46,6 @@
46#include <linux/blkdev.h> 46#include <linux/blkdev.h>
47#include <linux/delay.h> 47#include <linux/delay.h>
48#include <linux/device.h> 48#include <linux/device.h>
49#include "scsi.h"
50#include <scsi/scsi_host.h> 49#include <scsi/scsi_host.h>
51#include <linux/libata.h> 50#include <linux/libata.h>
52 51
diff --git a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c
index 3c43928ab402..2958b8c2bfb7 100644
--- a/drivers/scsi/bvme6000.c
+++ b/drivers/scsi/bvme6000.c
@@ -7,7 +7,6 @@
7#include <linux/mm.h> 7#include <linux/mm.h>
8#include <linux/blkdev.h> 8#include <linux/blkdev.h>
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/version.h>
11#include <linux/zorro.h> 10#include <linux/zorro.h>
12 11
13#include <asm/setup.h> 12#include <asm/setup.h>
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index 4b310cb7c93a..5b154498056d 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/init.h> 5#include <linux/init.h>
7#include <linux/interrupt.h> 6#include <linux/interrupt.h>
8 7
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 05ecc911e94c..b60c1b9270f1 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -18,12 +18,6 @@
18 */ 18 */
19 19
20#include <linux/config.h> 20#include <linux/config.h>
21#ifndef LINUX_VERSION_CODE
22#include <linux/version.h>
23#endif
24#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
25#error "This driver works only with kernel 2.5.45 or higher!"
26#endif
27#include <linux/module.h> 21#include <linux/module.h>
28#include <linux/kernel.h> 22#include <linux/kernel.h>
29#include <linux/types.h> 23#include <linux/types.h>
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
index 179140f48a91..f46c382e5599 100644
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -50,6 +50,7 @@
50#ifndef _IPS_H_ 50#ifndef _IPS_H_
51 #define _IPS_H_ 51 #define _IPS_H_
52 52
53#include <linux/version.h>
53 #include <asm/uaccess.h> 54 #include <asm/uaccess.h>
54 #include <asm/io.h> 55 #include <asm/io.h>
55 56
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 1c1a7caf785e..a74b4071a662 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -51,8 +51,8 @@
51#include <linux/jiffies.h> 51#include <linux/jiffies.h>
52#include <linux/scatterlist.h> 52#include <linux/scatterlist.h>
53#include <scsi/scsi.h> 53#include <scsi/scsi.h>
54#include "scsi.h"
55#include "scsi_priv.h" 54#include "scsi_priv.h"
55#include <scsi/scsi_cmnd.h>
56#include <scsi/scsi_host.h> 56#include <scsi/scsi_host.h>
57#include <linux/libata.h> 57#include <linux/libata.h>
58#include <asm/io.h> 58#include <asm/io.h>
@@ -1144,7 +1144,7 @@ retry:
1144 * ATA software reset (SRST, the default) does not appear 1144 * ATA software reset (SRST, the default) does not appear
1145 * to have this problem. 1145 * to have this problem.
1146 */ 1146 */
1147 if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) { 1147 if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
1148 u8 err = qc->tf.feature; 1148 u8 err = qc->tf.feature;
1149 if (err & ATA_ABORTED) { 1149 if (err & ATA_ABORTED) {
1150 dev->class = ATA_DEV_ATAPI; 1150 dev->class = ATA_DEV_ATAPI;
@@ -2713,7 +2713,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
2713/** 2713/**
2714 * ata_poll_qc_complete - turn irq back on and finish qc 2714 * ata_poll_qc_complete - turn irq back on and finish qc
2715 * @qc: Command to complete 2715 * @qc: Command to complete
2716 * @drv_stat: ATA status register content 2716 * @err_mask: ATA status register content
2717 * 2717 *
2718 * LOCKING: 2718 * LOCKING:
2719 * None. (grabs host lock) 2719 * None. (grabs host lock)
@@ -2747,7 +2747,6 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
2747 u8 status; 2747 u8 status;
2748 unsigned int poll_state = HSM_ST_UNKNOWN; 2748 unsigned int poll_state = HSM_ST_UNKNOWN;
2749 unsigned int reg_state = HSM_ST_UNKNOWN; 2749 unsigned int reg_state = HSM_ST_UNKNOWN;
2750 const unsigned int tmout_state = HSM_ST_TMOUT;
2751 2750
2752 switch (ap->hsm_task_state) { 2751 switch (ap->hsm_task_state) {
2753 case HSM_ST: 2752 case HSM_ST:
@@ -2768,7 +2767,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
2768 status = ata_chk_status(ap); 2767 status = ata_chk_status(ap);
2769 if (status & ATA_BUSY) { 2768 if (status & ATA_BUSY) {
2770 if (time_after(jiffies, ap->pio_task_timeout)) { 2769 if (time_after(jiffies, ap->pio_task_timeout)) {
2771 ap->hsm_task_state = tmout_state; 2770 ap->hsm_task_state = HSM_ST_TMOUT;
2772 return 0; 2771 return 0;
2773 } 2772 }
2774 ap->hsm_task_state = poll_state; 2773 ap->hsm_task_state = poll_state;
@@ -3478,7 +3477,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
3478/** 3477/**
3479 * ata_qc_complete - Complete an active ATA command 3478 * ata_qc_complete - Complete an active ATA command
3480 * @qc: Command to complete 3479 * @qc: Command to complete
3481 * @drv_stat: ATA Status register contents 3480 * @err_mask: ATA Status register contents
3482 * 3481 *
3483 * Indicate to the mid and upper layers that an ATA 3482 * Indicate to the mid and upper layers that an ATA
3484 * command has completed, with either an ok or not-ok status. 3483 * command has completed, with either an ok or not-ok status.
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index eb604b0a8990..bb30fcdc9297 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -37,9 +37,9 @@
37#include <linux/blkdev.h> 37#include <linux/blkdev.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <scsi/scsi.h> 39#include <scsi/scsi.h>
40#include "scsi.h"
41#include <scsi/scsi_host.h> 40#include <scsi/scsi_host.h>
42#include <scsi/scsi_device.h> 41#include <scsi/scsi_device.h>
42#include <scsi/scsi_request.h>
43#include <linux/libata.h> 43#include <linux/libata.h>
44#include <linux/hdreg.h> 44#include <linux/hdreg.h>
45#include <asm/uaccess.h> 45#include <asm/uaccess.h>
@@ -131,7 +131,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
131 131
132/** 132/**
133 * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl 133 * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
134 * @dev: Device to whom we are issuing command 134 * @scsidev: Device to which we are issuing command
135 * @arg: User provided data for issuing command 135 * @arg: User provided data for issuing command
136 * 136 *
137 * LOCKING: 137 * LOCKING:
@@ -217,7 +217,7 @@ error:
217 217
218/** 218/**
219 * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl 219 * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl
220 * @dev: Device to whom we are issuing command 220 * @scsidev: Device to which we are issuing command
221 * @arg: User provided data for issuing command 221 * @arg: User provided data for issuing command
222 * 222 *
223 * LOCKING: 223 * LOCKING:
@@ -416,6 +416,7 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf)
416 416
417/** 417/**
418 * ata_to_sense_error - convert ATA error to SCSI error 418 * ata_to_sense_error - convert ATA error to SCSI error
419 * @id: ATA device number
419 * @drv_stat: value contained in ATA status register 420 * @drv_stat: value contained in ATA status register
420 * @drv_err: value contained in ATA error register 421 * @drv_err: value contained in ATA error register
421 * @sk: the sense key we'll fill out 422 * @sk: the sense key we'll fill out
@@ -2231,7 +2232,7 @@ ata_scsi_map_proto(u8 byte1)
2231/** 2232/**
2232 * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile 2233 * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
2233 * @qc: command structure to be initialized 2234 * @qc: command structure to be initialized
2234 * @cmd: SCSI command to convert 2235 * @scsicmd: SCSI command to convert
2235 * 2236 *
2236 * Handles either 12 or 16-byte versions of the CDB. 2237 * Handles either 12 or 16-byte versions of the CDB.
2237 * 2238 *
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h
index 5accdee9bbfb..4675343228ad 100644
--- a/drivers/scsi/megaraid/mega_common.h
+++ b/drivers/scsi/megaraid/mega_common.h
@@ -25,7 +25,6 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/blkdev.h> 26#include <linux/blkdev.h>
27#include <linux/list.h> 27#include <linux/list.h>
28#include <linux/version.h>
29#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
30#include <linux/dma-mapping.h> 29#include <linux/dma-mapping.h>
31#include <asm/semaphore.h> 30#include <asm/semaphore.h>
diff --git a/drivers/scsi/megaraid/megaraid_mm.h b/drivers/scsi/megaraid/megaraid_mm.h
index 7e36c46e7c43..eb8c390a0fa3 100644
--- a/drivers/scsi/megaraid/megaraid_mm.h
+++ b/drivers/scsi/megaraid/megaraid_mm.h
@@ -18,7 +18,6 @@
18#include <linux/spinlock.h> 18#include <linux/spinlock.h>
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/moduleparam.h> 22#include <linux/moduleparam.h>
24#include <linux/pci.h> 23#include <linux/pci.h>
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 2463f47adfda..3c32e69afcd9 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -26,7 +26,6 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/version.h>
30#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/spinlock.h> 31#include <linux/spinlock.h>
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index c44382d6ae5d..cb367c2c5c78 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/interrupt.h> 5#include <linux/interrupt.h>
7 6
8#include <asm/page.h> 7#include <asm/page.h>
diff --git a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c
index 9b43dc4148f5..890e9e232dab 100644
--- a/drivers/scsi/mvme16x.c
+++ b/drivers/scsi/mvme16x.c
@@ -7,7 +7,6 @@
7#include <linux/mm.h> 7#include <linux/mm.h>
8#include <linux/blkdev.h> 8#include <linux/blkdev.h>
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/version.h>
11 10
12#include <asm/page.h> 11#include <asm/page.h>
13#include <asm/pgtable.h> 12#include <asm/pgtable.h>
diff --git a/drivers/scsi/nsp32.h b/drivers/scsi/nsp32.h
index 5664398fa0ad..5addf9fb1e15 100644
--- a/drivers/scsi/nsp32.h
+++ b/drivers/scsi/nsp32.h
@@ -16,6 +16,7 @@
16#ifndef _NSP32_H 16#ifndef _NSP32_H
17#define _NSP32_H 17#define _NSP32_H
18 18
19#include <linux/version.h>
19//#define NSP32_DEBUG 9 20//#define NSP32_DEBUG 9
20 21
21/* 22/*
diff --git a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h
index f945a4232e5d..0ebd8ce9e1de 100644
--- a/drivers/scsi/pci2000.h
+++ b/drivers/scsi/pci2000.h
@@ -26,9 +26,6 @@
26#ifndef PSI_EIDE_SCSIOP 26#ifndef PSI_EIDE_SCSIOP
27#define PSI_EIDE_SCSIOP 1 27#define PSI_EIDE_SCSIOP 1
28 28
29#ifndef LINUX_VERSION_CODE
30#include <linux/version.h>
31#endif
32#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s)) 29#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s))
33 30
34/************************************************/ 31/************************************************/
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index 340ef38b4521..78b4ff117af6 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -41,7 +41,6 @@
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/sched.h> 42#include <linux/sched.h>
43#include <linux/device.h> 43#include <linux/device.h>
44#include "scsi.h"
45#include <scsi/scsi_host.h> 44#include <scsi/scsi_host.h>
46#include <asm/io.h> 45#include <asm/io.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 1066c2610eb4..93d55233af7b 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -30,8 +30,8 @@
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/device.h> 32#include <linux/device.h>
33#include "scsi.h"
34#include <scsi/scsi_host.h> 33#include <scsi/scsi_host.h>
34#include <scsi/scsi_cmnd.h>
35#include <linux/libata.h> 35#include <linux/libata.h>
36#include <asm/io.h> 36#include <asm/io.h>
37 37
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index f57aa2607918..37a4fae95ed4 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -62,7 +62,6 @@
62#include <linux/delay.h> 62#include <linux/delay.h>
63#include <linux/interrupt.h> 63#include <linux/interrupt.h>
64#include <linux/device.h> 64#include <linux/device.h>
65#include "scsi.h"
66#include <scsi/scsi_host.h> 65#include <scsi/scsi_host.h>
67#include <linux/libata.h> 66#include <linux/libata.h>
68 67
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 0bfb82b669d5..9edc9d91efc3 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -39,8 +39,8 @@
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/sched.h> 40#include <linux/sched.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
43#include <scsi/scsi_cmnd.h>
44#include <linux/libata.h> 44#include <linux/libata.h>
45#include <asm/io.h> 45#include <asm/io.h>
46#include "sata_promise.h" 46#include "sata_promise.h"
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index c9aed15c8f4d..d274ab235781 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -36,7 +36,6 @@
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/sched.h> 37#include <linux/sched.h>
38#include <linux/device.h> 38#include <linux/device.h>
39#include "scsi.h"
40#include <scsi/scsi_host.h> 39#include <scsi/scsi_host.h>
41#include <asm/io.h> 40#include <asm/io.h>
42#include <linux/libata.h> 41#include <linux/libata.h>
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 6c986a0824b1..d0e3c3c6c25f 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -42,7 +42,6 @@
42#include <linux/delay.h> 42#include <linux/delay.h>
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
48 47
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 0c2d2fd0ec76..4682a50650b4 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -37,7 +37,7 @@
37#include <linux/dma-mapping.h> 37#include <linux/dma-mapping.h>
38#include <linux/device.h> 38#include <linux/device.h>
39#include <scsi/scsi_host.h> 39#include <scsi/scsi_host.h>
40#include "scsi.h" 40#include <scsi/scsi_cmnd.h>
41#include <linux/libata.h> 41#include <linux/libata.h>
42#include <asm/io.h> 42#include <asm/io.h>
43 43
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 223c835842e0..42d7c4e92501 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -39,7 +39,6 @@
39#include <linux/delay.h> 39#include <linux/delay.h>
40#include <linux/interrupt.h> 40#include <linux/interrupt.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
44#include <linux/libata.h> 43#include <linux/libata.h>
45 44
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 86644f91f898..9895d1caefcf 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -45,7 +45,6 @@
45#include <linux/delay.h> 45#include <linux/delay.h>
46#include <linux/interrupt.h> 46#include <linux/interrupt.h>
47#include <linux/device.h> 47#include <linux/device.h>
48#include "scsi.h"
49#include <scsi/scsi_host.h> 48#include <scsi/scsi_host.h>
50#include <linux/libata.h> 49#include <linux/libata.h>
51 50
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index 8e79745e4e9f..d5a38784352b 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -39,8 +39,8 @@
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/sched.h> 40#include <linux/sched.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
43#include <scsi/scsi_cmnd.h>
44#include <linux/libata.h> 44#include <linux/libata.h>
45#include <asm/io.h> 45#include <asm/io.h>
46#include "sata_promise.h" 46#include "sata_promise.h"
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index 8c1d71495bd5..cf0baaa4e045 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -33,7 +33,6 @@
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/interrupt.h> 34#include <linux/interrupt.h>
35#include <linux/device.h> 35#include <linux/device.h>
36#include "scsi.h"
37#include <scsi/scsi_host.h> 36#include <scsi/scsi_host.h>
38#include <linux/libata.h> 37#include <linux/libata.h>
39 38
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index 09d3d96de0c3..ab19d2ba2a4b 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -42,7 +42,6 @@
42#include <linux/blkdev.h> 42#include <linux/blkdev.h>
43#include <linux/delay.h> 43#include <linux/delay.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
48#include <asm/io.h> 47#include <asm/io.h>
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index bbc3d8abbd64..ce8a2fd7da84 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -43,7 +43,6 @@
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/dma-mapping.h> 44#include <linux/dma-mapping.h>
45#include <linux/device.h> 45#include <linux/device.h>
46#include "scsi.h"
47#include <scsi/scsi_host.h> 46#include <scsi/scsi_host.h>
48#include <linux/libata.h> 47#include <linux/libata.h>
49 48
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 9eb08b15c0b1..3ded9daaf4a0 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -48,10 +48,6 @@
48 48
49#include <linux/stat.h> 49#include <linux/stat.h>
50 50
51#ifndef LINUX_VERSION_CODE
52#include <linux/version.h>
53#endif
54
55#include "scsi_logging.h" 51#include "scsi_logging.h"
56#include "scsi_debug.h" 52#include "scsi_debug.h"
57 53
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 62e3f340cc52..72ec59456e69 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -68,10 +68,6 @@ static int sg_proc_init(void);
68static void sg_proc_cleanup(void); 68static void sg_proc_cleanup(void);
69#endif 69#endif
70 70
71#ifndef LINUX_VERSION_CODE
72#include <linux/version.h>
73#endif /* LINUX_VERSION_CODE */
74
75#define SG_ALLOW_DIO_DEF 0 71#define SG_ALLOW_DIO_DEF 0
76#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */ 72#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
77 73
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index 0a0d8a908c74..bf2ceb54354c 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -15,7 +15,6 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/blkdev.h> 17#include <linux/blkdev.h>
18#include <linux/version.h>
19#include <linux/delay.h> 18#include <linux/delay.h>
20#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
21#include <linux/spinlock.h> 20#include <linux/spinlock.h>
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 5754445fb36a..fd63add6a577 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -77,7 +77,6 @@
77#include <linux/sched.h> 77#include <linux/sched.h>
78#include <linux/string.h> 78#include <linux/string.h>
79#include <linux/delay.h> 79#include <linux/delay.h>
80#include <linux/version.h>
81#include <linux/init.h> 80#include <linux/init.h>
82#include <linux/blkdev.h> 81#include <linux/blkdev.h>
83#include <asm/irq.h> 82#include <asm/irq.h>
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h
index 51e3f7f6597b..fbea4541c234 100644
--- a/drivers/telephony/ixj.h
+++ b/drivers/telephony/ixj.h
@@ -40,7 +40,6 @@
40 *****************************************************************************/ 40 *****************************************************************************/
41#define IXJ_VERSION 3031 41#define IXJ_VERSION 3031
42 42
43#include <linux/version.h>
44#include <linux/types.h> 43#include <linux/types.h>
45 44
46#include <linux/ixjuser.h> 45#include <linux/ixjuser.h>
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 975ace3f5b1e..904519085334 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -49,7 +49,6 @@
49#include <linux/timer.h> 49#include <linux/timer.h>
50#include <linux/list.h> 50#include <linux/list.h>
51#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/version.h>
53#include <linux/platform_device.h> 52#include <linux/platform_device.h>
54#include <linux/usb.h> 53#include <linux/usb.h>
55#include <linux/usb_gadget.h> 54#include <linux/usb_gadget.h>
diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h
index 1bb455c045a9..9b2e6f7cbb8b 100644
--- a/drivers/usb/gadget/lh7a40x_udc.h
+++ b/drivers/usb/gadget/lh7a40x_udc.h
@@ -29,7 +29,6 @@
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/version.h>
33#include <linux/errno.h> 32#include <linux/errno.h>
34#include <linux/delay.h> 33#include <linux/delay.h>
35#include <linux/sched.h> 34#include <linux/sched.h>
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index ee9cd7869d92..510d28a924db 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -32,7 +32,6 @@
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/ioport.h> 33#include <linux/ioport.h>
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/version.h>
36#include <linux/errno.h> 35#include <linux/errno.h>
37#include <linux/delay.h> 36#include <linux/delay.h>
38#include <linux/sched.h> 37#include <linux/sched.h>
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 06b6eba925b5..9689efeb364c 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -28,7 +28,6 @@
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/errno.h> 30#include <linux/errno.h>
31#include <linux/version.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/list.h> 32#include <linux/list.h>
34#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index a8267cf17db4..0eaabeb37ac3 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -14,7 +14,6 @@
14#include <linux/unistd.h> 14#include <linux/unistd.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/version.h>
18#include <linux/list.h> 17#include <linux/list.h>
19#include <linux/spinlock.h> 18#include <linux/spinlock.h>
20 19
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index b77e65c03659..5524fd70210b 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -62,6 +62,7 @@
62#include <linux/poll.h> 62#include <linux/poll.h>
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/vmalloc.h> 64#include <linux/vmalloc.h>
65#include <linux/version.h>
65#include <asm/io.h> 66#include <asm/io.h>
66 67
67#include "pwc.h" 68#include "pwc.h"
diff --git a/drivers/usb/media/pwc/pwc.h b/drivers/usb/media/pwc/pwc.h
index 267869dab185..6dd76bb3dff1 100644
--- a/drivers/usb/media/pwc/pwc.h
+++ b/drivers/usb/media/pwc/pwc.h
@@ -25,8 +25,6 @@
25#ifndef PWC_H 25#ifndef PWC_H
26#define PWC_H 26#define PWC_H
27 27
28#include <linux/version.h>
29
30#include <linux/config.h> 28#include <linux/config.h>
31#include <linux/module.h> 29#include <linux/module.h>
32#include <linux/usb.h> 30#include <linux/usb.h>
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index f36c0b6c6e36..67612c81cb9f 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -25,7 +25,6 @@
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
26 ***************************************************************************/ 26 ***************************************************************************/
27 27
28#include <linux/version.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/kmod.h> 30#include <linux/kmod.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index c946c9a538a0..41ef2b606751 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -37,7 +37,6 @@
37 */ 37 */
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/version.h>
41#include <linux/module.h> 40#include <linux/module.h>
42#include <linux/kernel.h> 41#include <linux/kernel.h>
43#include <linux/signal.h> 42#include <linux/signal.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h
index 401ff21d7881..1d7a77cc7c4a 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.h
+++ b/drivers/usb/misc/sisusbvga/sisusb.h
@@ -37,6 +37,7 @@
37#ifndef _SISUSB_H_ 37#ifndef _SISUSB_H_
38#define _SISUSB_H_ 38#define _SISUSB_H_
39 39
40#include <linux/version.h>
40#ifdef CONFIG_COMPAT 41#ifdef CONFIG_COMPAT
41#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10) 42#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
42#include <linux/ioctl32.h> 43#include <linux/ioctl32.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 24584463553d..be5c1a25ae21 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -48,7 +48,6 @@
48 */ 48 */
49 49
50#include <linux/config.h> 50#include <linux/config.h>
51#include <linux/version.h>
52#include <linux/module.h> 51#include <linux/module.h>
53#include <linux/kernel.h> 52#include <linux/kernel.h>
54#include <linux/signal.h> 53#include <linux/signal.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c
index f28bc240f9b6..044fa4482f9f 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_init.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_init.c
@@ -37,7 +37,6 @@
37 */ 37 */
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/version.h>
41#include <linux/module.h> 40#include <linux/module.h>
42#include <linux/kernel.h> 41#include <linux/kernel.h>
43#include <linux/errno.h> 42#include <linux/errno.h>
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 44b6ca290ce3..25b6ca6ad081 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -593,38 +593,6 @@ config FB_EPSON1355
593 framebuffer. Product specs at 593 framebuffer. Product specs at
594 <http://www.erd.epson.com/vdc/html/products.htm>. 594 <http://www.erd.epson.com/vdc/html/products.htm>.
595 595
596config FB_E1356
597 tristate "Epson SED1356 framebuffer support"
598 depends on FB && EXPERIMENTAL && PCI && MIPS
599
600config PB1000_CRT
601 bool "Use CRT on Pb1000 (J65)"
602 depends on MIPS_PB1000=y && FB_E1356
603
604config PB1000_NTSC
605 bool "Use Compsite NTSC on Pb1000 (J63)"
606 depends on MIPS_PB1000=y && FB_E1356
607
608config PB1000_TFT
609 bool "Use TFT Panel on Pb1000 (J64)"
610 depends on MIPS_PB1000=y && FB_E1356
611
612config PB1500_CRT
613 bool "Use CRT on Pb1500 " if MIPS_PB1500=y
614 depends on FB_E1356
615
616config PB1500_CRT
617 prompt "Use CRT on Pb1100 "
618 depends on FB_E1356 && MIPS_PB1100=y
619
620config PB1500_TFT
621 bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y
622 depends on FB_E1356
623
624config PB1500_TFT
625 prompt "Use TFT Panel on Pb1100 "
626 depends on FB_E1356 && MIPS_PB1100=y
627
628config FB_S1D13XXX 596config FB_S1D13XXX
629 tristate "Epson S1D13XXX framebuffer support" 597 tristate "Epson S1D13XXX framebuffer support"
630 depends on FB 598 depends on FB
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 467a1d7ebbde..a3c2c45e29e0 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -518,7 +518,7 @@ static struct amba_driver clcd_driver = {
518 .id_table = clcdfb_id_table, 518 .id_table = clcdfb_id_table,
519}; 519};
520 520
521int __init amba_clcdfb_init(void) 521static int __init amba_clcdfb_init(void)
522{ 522{
523 if (fb_get_options("ambafb", NULL)) 523 if (fb_get_options("ambafb", NULL))
524 return -ENODEV; 524 return -ENODEV;
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index acc81cb01d56..9d5015e99372 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -5,7 +5,6 @@
5 * 5 *
6 */ 6 */
7 7
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/device.h> 10#include <linux/device.h>
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 470e6f0ee4dd..68c690605aa7 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -5,7 +5,6 @@
5 * 5 *
6 */ 6 */
7 7
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/device.h> 10#include <linux/device.h>
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index da664cea7eca..a7770c4f17d0 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -80,10 +80,12 @@ static u32 cfb_tab32[] = {
80#define LEFT_POS(bpp) (32 - bpp) 80#define LEFT_POS(bpp) (32 - bpp)
81#define SHIFT_HIGH(val, bits) ((val) >> (bits)) 81#define SHIFT_HIGH(val, bits) ((val) >> (bits))
82#define SHIFT_LOW(val, bits) ((val) << (bits)) 82#define SHIFT_LOW(val, bits) ((val) << (bits))
83#define BIT_NR(b) (7 - (b))
83#else 84#else
84#define LEFT_POS(bpp) (0) 85#define LEFT_POS(bpp) (0)
85#define SHIFT_HIGH(val, bits) ((val) << (bits)) 86#define SHIFT_HIGH(val, bits) ((val) << (bits))
86#define SHIFT_LOW(val, bits) ((val) >> (bits)) 87#define SHIFT_LOW(val, bits) ((val) >> (bits))
88#define BIT_NR(b) (b)
87#endif 89#endif
88 90
89static inline void color_imageblit(const struct fb_image *image, 91static inline void color_imageblit(const struct fb_image *image,
@@ -177,7 +179,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
177 179
178 while (j--) { 180 while (j--) {
179 l--; 181 l--;
180 color = (*s & (1 << l)) ? fgcolor : bgcolor; 182 color = (*s & 1 << (BIT_NR(l))) ? fgcolor : bgcolor;
181 color <<= LEFT_POS(bpp); 183 color <<= LEFT_POS(bpp);
182 val |= SHIFT_HIGH(color, shift); 184 val |= SHIFT_HIGH(color, shift);
183 185
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index fadf7c5d216e..94c5f1392cce 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -101,6 +101,16 @@ config FRAMEBUFFER_CONSOLE
101 help 101 help
102 Low-level framebuffer-based console driver. 102 Low-level framebuffer-based console driver.
103 103
104config FRAMEBUFFER_CONSOLE_ROTATION
105 bool "Framebuffer Console Rotation"
106 depends on FRAMEBUFFER_CONSOLE
107 help
108 Enable display rotation for the framebuffer console. This is done
109 in software and may be significantly slower than a normally oriented
110 display. Note that the rotation is done at the console level only
111 such that other users of the framebuffer will remain normally
112 oriented.
113
104config STI_CONSOLE 114config STI_CONSOLE
105 tristate "STI text console" 115 tristate "STI text console"
106 depends on PARISC 116 depends on PARISC
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index 5222628accce..fed600c9ca55 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -31,6 +31,10 @@ obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o softcursor.o
31ifeq ($(CONFIG_FB_TILEBLITTING),y) 31ifeq ($(CONFIG_FB_TILEBLITTING),y)
32obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o 32obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o
33endif 33endif
34ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y)
35obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
36 fbcon_ccw.o
37endif
34 38
35obj-$(CONFIG_FB_STI) += sticore.o font.o 39obj-$(CONFIG_FB_STI) += sticore.o font.o
36 40
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 67857b3cfc8b..e65fc3ef7630 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -22,35 +22,6 @@
22/* 22/*
23 * Accelerated handlers. 23 * Accelerated handlers.
24 */ 24 */
25#define FBCON_ATTRIBUTE_UNDERLINE 1
26#define FBCON_ATTRIBUTE_REVERSE 2
27#define FBCON_ATTRIBUTE_BOLD 4
28
29static inline int real_y(struct display *p, int ypos)
30{
31 int rows = p->vrows;
32
33 ypos += p->yscroll;
34 return ypos < rows ? ypos : ypos - rows;
35}
36
37
38static inline int get_attribute(struct fb_info *info, u16 c)
39{
40 int attribute = 0;
41
42 if (fb_get_color_depth(&info->var, &info->fix) == 1) {
43 if (attr_underline(c))
44 attribute |= FBCON_ATTRIBUTE_UNDERLINE;
45 if (attr_reverse(c))
46 attribute |= FBCON_ATTRIBUTE_REVERSE;
47 if (attr_bold(c))
48 attribute |= FBCON_ATTRIBUTE_BOLD;
49 }
50
51 return attribute;
52}
53
54static inline void update_attr(u8 *dst, u8 *src, int attribute, 25static inline void update_attr(u8 *dst, u8 *src, int attribute,
55 struct vc_data *vc) 26 struct vc_data *vc)
56{ 27{
@@ -418,6 +389,18 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
418 ops->cursor_reset = 0; 389 ops->cursor_reset = 0;
419} 390}
420 391
392static int bit_update_start(struct fb_info *info)
393{
394 struct fbcon_ops *ops = info->fbcon_par;
395 int err;
396
397 err = fb_pan_display(info, &ops->var);
398 ops->var.xoffset = info->var.xoffset;
399 ops->var.yoffset = info->var.yoffset;
400 ops->var.vmode = info->var.vmode;
401 return err;
402}
403
421void fbcon_set_bitops(struct fbcon_ops *ops) 404void fbcon_set_bitops(struct fbcon_ops *ops)
422{ 405{
423 ops->bmove = bit_bmove; 406 ops->bmove = bit_bmove;
@@ -425,6 +408,11 @@ void fbcon_set_bitops(struct fbcon_ops *ops)
425 ops->putcs = bit_putcs; 408 ops->putcs = bit_putcs;
426 ops->clear_margins = bit_clear_margins; 409 ops->clear_margins = bit_clear_margins;
427 ops->cursor = bit_cursor; 410 ops->cursor = bit_cursor;
411 ops->update_start = bit_update_start;
412 ops->rotate_font = NULL;
413
414 if (ops->rotate)
415 fbcon_set_rotate(ops);
428} 416}
429 417
430EXPORT_SYMBOL(fbcon_set_bitops); 418EXPORT_SYMBOL(fbcon_set_bitops);
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3cf1b61ff1f8..e7802ffe549a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,6 +107,8 @@ enum {
107}; 107};
108 108
109struct display fb_display[MAX_NR_CONSOLES]; 109struct display fb_display[MAX_NR_CONSOLES];
110EXPORT_SYMBOL(fb_display);
111
110static signed char con2fb_map[MAX_NR_CONSOLES]; 112static signed char con2fb_map[MAX_NR_CONSOLES];
111static signed char con2fb_map_boot[MAX_NR_CONSOLES]; 113static signed char con2fb_map_boot[MAX_NR_CONSOLES];
112static int logo_height; 114static int logo_height;
@@ -130,6 +132,9 @@ static char fontname[40];
130/* current fb_info */ 132/* current fb_info */
131static int info_idx = -1; 133static int info_idx = -1;
132 134
135/* console rotation */
136static int rotate;
137
133static const struct consw fb_con; 138static const struct consw fb_con;
134 139
135#define CM_SOFTBACK (8) 140#define CM_SOFTBACK (8)
@@ -176,7 +181,6 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines);
176/* 181/*
177 * Internal routines 182 * Internal routines
178 */ 183 */
179static __inline__ int real_y(struct display *p, int ypos);
180static __inline__ void ywrap_up(struct vc_data *vc, int count); 184static __inline__ void ywrap_up(struct vc_data *vc, int count);
181static __inline__ void ywrap_down(struct vc_data *vc, int count); 185static __inline__ void ywrap_down(struct vc_data *vc, int count);
182static __inline__ void ypan_up(struct vc_data *vc, int count); 186static __inline__ void ypan_up(struct vc_data *vc, int count);
@@ -189,6 +193,8 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
189 int unit); 193 int unit);
190static void fbcon_redraw_move(struct vc_data *vc, struct display *p, 194static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
191 int line, int count, int dy); 195 int line, int count, int dy);
196static void fbcon_modechanged(struct fb_info *info);
197static void fbcon_set_all_vcs(struct fb_info *info);
192 198
193#ifdef CONFIG_MAC 199#ifdef CONFIG_MAC
194/* 200/*
@@ -203,6 +209,88 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
203} 209}
204#endif 210#endif
205 211
212#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
213static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
214{
215 struct fbcon_ops *ops = info->fbcon_par;
216
217 if (!(info->flags & FBINFO_MISC_TILEBLITTING) &&
218 p->con_rotate < 4)
219 ops->rotate = p->con_rotate;
220 else
221 ops->rotate = 0;
222}
223
224static void fbcon_rotate(struct fb_info *info, u32 rotate)
225{
226 struct fbcon_ops *ops= info->fbcon_par;
227 struct fb_info *fb_info;
228
229 if (!ops || ops->currcon == -1)
230 return;
231
232 fb_info = registered_fb[con2fb_map[ops->currcon]];
233
234 if (info == fb_info) {
235 struct display *p = &fb_display[ops->currcon];
236
237 if (rotate < 4)
238 p->con_rotate = rotate;
239 else
240 p->con_rotate = 0;
241
242 fbcon_modechanged(info);
243 }
244}
245
246static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
247{
248 struct fbcon_ops *ops = info->fbcon_par;
249 struct vc_data *vc;
250 struct display *p;
251 int i;
252
253 if (!ops || ops->currcon < 0 || rotate > 3)
254 return;
255
256 for (i = 0; i < MAX_NR_CONSOLES; i++) {
257 vc = vc_cons[i].d;
258 if (!vc || vc->vc_mode != KD_TEXT ||
259 registered_fb[con2fb_map[i]] != info)
260 continue;
261
262 p = &fb_display[vc->vc_num];
263 p->con_rotate = rotate;
264 }
265
266 fbcon_set_all_vcs(info);
267}
268#else
269static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
270{
271 struct fbcon_ops *ops = info->fbcon_par;
272
273 ops->rotate = FB_ROTATE_UR;
274}
275
276static void fbcon_rotate(struct fb_info *info, u32 rotate)
277{
278 return;
279}
280
281static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
282{
283 return;
284}
285#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
286
287static int fbcon_get_rotate(struct fb_info *info)
288{
289 struct fbcon_ops *ops = info->fbcon_par;
290
291 return (ops) ? ops->rotate : 0;
292}
293
206static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) 294static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
207{ 295{
208 struct fbcon_ops *ops = info->fbcon_par; 296 struct fbcon_ops *ops = info->fbcon_par;
@@ -422,6 +510,14 @@ static int __init fb_console_setup(char *this_opt)
422 last_fb_vc = simple_strtoul(options, &options, 10) - 1; 510 last_fb_vc = simple_strtoul(options, &options, 10) - 1;
423 fbcon_is_default = 0; 511 fbcon_is_default = 0;
424 } 512 }
513
514 if (!strncmp(options, "rotate:", 7)) {
515 options += 7;
516 if (*options)
517 rotate = simple_strtoul(options, &options, 0);
518 if (rotate > 3)
519 rotate = 0;
520 }
425 } 521 }
426 return 0; 522 return 0;
427} 523}
@@ -480,6 +576,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
480 int cols, int rows, int new_cols, int new_rows) 576 int cols, int rows, int new_cols, int new_rows)
481{ 577{
482 /* Need to make room for the logo */ 578 /* Need to make room for the logo */
579 struct fbcon_ops *ops = info->fbcon_par;
483 int cnt, erase = vc->vc_video_erase_char, step; 580 int cnt, erase = vc->vc_video_erase_char, step;
484 unsigned short *save = NULL, *r, *q; 581 unsigned short *save = NULL, *r, *q;
485 582
@@ -489,7 +586,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
489 */ 586 */
490 if (fb_get_color_depth(&info->var, &info->fix) == 1) 587 if (fb_get_color_depth(&info->var, &info->fix) == 1)
491 erase &= ~0x400; 588 erase &= ~0x400;
492 logo_height = fb_prepare_logo(info); 589 logo_height = fb_prepare_logo(info, ops->rotate);
493 logo_lines = (logo_height + vc->vc_font.height - 1) / 590 logo_lines = (logo_height + vc->vc_font.height - 1) /
494 vc->vc_font.height; 591 vc->vc_font.height;
495 q = (unsigned short *) (vc->vc_origin + 592 q = (unsigned short *) (vc->vc_origin +
@@ -558,16 +655,24 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
558 655
559 if ((info->flags & FBINFO_MISC_TILEBLITTING)) 656 if ((info->flags & FBINFO_MISC_TILEBLITTING))
560 fbcon_set_tileops(vc, info, p, ops); 657 fbcon_set_tileops(vc, info, p, ops);
561 else 658 else {
659 struct display *disp;
660
661 disp = (p) ? p : &fb_display[vc->vc_num];
662 fbcon_set_rotation(info, disp);
562 fbcon_set_bitops(ops); 663 fbcon_set_bitops(ops);
664 }
563} 665}
564#else 666#else
565static void set_blitting_type(struct vc_data *vc, struct fb_info *info, 667static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
566 struct display *p) 668 struct display *p)
567{ 669{
568 struct fbcon_ops *ops = info->fbcon_par; 670 struct fbcon_ops *ops = info->fbcon_par;
671 struct display *disp;
569 672
570 info->flags &= ~FBINFO_MISC_TILEBLITTING; 673 info->flags &= ~FBINFO_MISC_TILEBLITTING;
674 disp = (p) ? p : &fb_display[vc->vc_num];
675 fbcon_set_rotation(info, disp);
571 fbcon_set_bitops(ops); 676 fbcon_set_bitops(ops);
572} 677}
573#endif /* CONFIG_MISC_TILEBLITTING */ 678#endif /* CONFIG_MISC_TILEBLITTING */
@@ -627,6 +732,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
627 fbcon_del_cursor_timer(oldinfo); 732 fbcon_del_cursor_timer(oldinfo);
628 kfree(ops->cursor_state.mask); 733 kfree(ops->cursor_state.mask);
629 kfree(ops->cursor_data); 734 kfree(ops->cursor_data);
735 kfree(ops->fontbuffer);
630 kfree(oldinfo->fbcon_par); 736 kfree(oldinfo->fbcon_par);
631 oldinfo->fbcon_par = NULL; 737 oldinfo->fbcon_par = NULL;
632 module_put(oldinfo->fbops->owner); 738 module_put(oldinfo->fbops->owner);
@@ -827,7 +933,9 @@ static const char *fbcon_startup(void)
827 memset(ops, 0, sizeof(struct fbcon_ops)); 933 memset(ops, 0, sizeof(struct fbcon_ops));
828 ops->currcon = -1; 934 ops->currcon = -1;
829 ops->graphics = 1; 935 ops->graphics = 1;
936 ops->cur_rotate = -1;
830 info->fbcon_par = ops; 937 info->fbcon_par = ops;
938 p->con_rotate = rotate;
831 set_blitting_type(vc, info, NULL); 939 set_blitting_type(vc, info, NULL);
832 940
833 if (info->fix.type != FB_TYPE_TEXT) { 941 if (info->fix.type != FB_TYPE_TEXT) {
@@ -866,8 +974,10 @@ static const char *fbcon_startup(void)
866 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ 974 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
867 } 975 }
868 976
869 cols = info->var.xres / vc->vc_font.width; 977 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
870 rows = info->var.yres / vc->vc_font.height; 978 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
979 cols /= vc->vc_font.width;
980 rows /= vc->vc_font.height;
871 vc_resize(vc, cols, rows); 981 vc_resize(vc, cols, rows);
872 982
873 DPRINTK("mode: %s\n", info->fix.id); 983 DPRINTK("mode: %s\n", info->fix.id);
@@ -953,8 +1063,6 @@ static void fbcon_init(struct vc_data *vc, int init)
953 (info->fix.type == FB_TYPE_TEXT)) 1063 (info->fix.type == FB_TYPE_TEXT))
954 logo = 0; 1064 logo = 0;
955 1065
956 info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
957
958 if (var_to_display(p, &info->var, info)) 1066 if (var_to_display(p, &info->var, info))
959 return; 1067 return;
960 1068
@@ -986,13 +1094,18 @@ static void fbcon_init(struct vc_data *vc, int init)
986 if (!*vc->vc_uni_pagedir_loc) 1094 if (!*vc->vc_uni_pagedir_loc)
987 con_copy_unimap(vc, svc); 1095 con_copy_unimap(vc, svc);
988 1096
1097 ops = info->fbcon_par;
1098 p->con_rotate = rotate;
1099 set_blitting_type(vc, info, NULL);
1100
989 cols = vc->vc_cols; 1101 cols = vc->vc_cols;
990 rows = vc->vc_rows; 1102 rows = vc->vc_rows;
991 new_cols = info->var.xres / vc->vc_font.width; 1103 new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
992 new_rows = info->var.yres / vc->vc_font.height; 1104 new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1105 new_cols /= vc->vc_font.width;
1106 new_rows /= vc->vc_font.height;
993 vc_resize(vc, new_cols, new_rows); 1107 vc_resize(vc, new_cols, new_rows);
994 1108
995 ops = info->fbcon_par;
996 /* 1109 /*
997 * We must always set the mode. The mode of the previous console 1110 * We must always set the mode. The mode of the previous console
998 * driver could be in the same resolution but we are using different 1111 * driver could be in the same resolution but we are using different
@@ -1030,6 +1143,12 @@ static void fbcon_init(struct vc_data *vc, int init)
1030 1143
1031 if (vc == svc && softback_buf) 1144 if (vc == svc && softback_buf)
1032 fbcon_update_softback(vc); 1145 fbcon_update_softback(vc);
1146
1147 if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
1148 ops->rotate = FB_ROTATE_UR;
1149 set_blitting_type(vc, info, p);
1150 }
1151
1033} 1152}
1034 1153
1035static void fbcon_deinit(struct vc_data *vc) 1154static void fbcon_deinit(struct vc_data *vc)
@@ -1066,15 +1185,6 @@ static void fbcon_deinit(struct vc_data *vc)
1066 * restriction is simplicity & efficiency at the moment. 1185 * restriction is simplicity & efficiency at the moment.
1067 */ 1186 */
1068 1187
1069static __inline__ int real_y(struct display *p, int ypos)
1070{
1071 int rows = p->vrows;
1072
1073 ypos += p->yscroll;
1074 return ypos < rows ? ypos : ypos - rows;
1075}
1076
1077
1078static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, 1188static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
1079 int width) 1189 int width)
1080{ 1190{
@@ -1162,13 +1272,6 @@ static int scrollback_phys_max = 0;
1162static int scrollback_max = 0; 1272static int scrollback_max = 0;
1163static int scrollback_current = 0; 1273static int scrollback_current = 0;
1164 1274
1165static int update_var(int con, struct fb_info *info)
1166{
1167 if (con == ((struct fbcon_ops *)info->fbcon_par)->currcon)
1168 return fb_pan_display(info, &info->var);
1169 return 0;
1170}
1171
1172/* 1275/*
1173 * If no vc is existent yet, just set struct display 1276 * If no vc is existent yet, just set struct display
1174 */ 1277 */
@@ -1178,7 +1281,6 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
1178 struct display *p = &fb_display[unit]; 1281 struct display *p = &fb_display[unit];
1179 struct display *t = &fb_display[fg_console]; 1282 struct display *t = &fb_display[fg_console];
1180 1283
1181 var->xoffset = var->yoffset = p->yscroll = 0;
1182 if (var_to_display(p, var, info)) 1284 if (var_to_display(p, var, info))
1183 return; 1285 return;
1184 1286
@@ -1194,9 +1296,9 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1194 struct display *p = &fb_display[vc->vc_num], *t; 1296 struct display *p = &fb_display[vc->vc_num], *t;
1195 struct vc_data **default_mode = vc->vc_display_fg; 1297 struct vc_data **default_mode = vc->vc_display_fg;
1196 struct vc_data *svc = *default_mode; 1298 struct vc_data *svc = *default_mode;
1299 struct fbcon_ops *ops = info->fbcon_par;
1197 int rows, cols, charcnt = 256; 1300 int rows, cols, charcnt = 256;
1198 1301
1199 var->xoffset = var->yoffset = p->yscroll = 0;
1200 if (var_to_display(p, var, info)) 1302 if (var_to_display(p, var, info))
1201 return; 1303 return;
1202 t = &fb_display[svc->vc_num]; 1304 t = &fb_display[svc->vc_num];
@@ -1213,9 +1315,10 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1213 1315
1214 var->activate = FB_ACTIVATE_NOW; 1316 var->activate = FB_ACTIVATE_NOW;
1215 info->var.activate = var->activate; 1317 info->var.activate = var->activate;
1216 info->var.yoffset = info->var.xoffset = 0; 1318 var->yoffset = info->var.yoffset;
1319 var->xoffset = info->var.xoffset;
1217 fb_set_var(info, var); 1320 fb_set_var(info, var);
1218 1321 ops->var = info->var;
1219 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 1322 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1220 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 1323 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1221 if (charcnt == 256) { 1324 if (charcnt == 256) {
@@ -1231,9 +1334,12 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1231 if (!*vc->vc_uni_pagedir_loc) 1334 if (!*vc->vc_uni_pagedir_loc)
1232 con_copy_unimap(vc, svc); 1335 con_copy_unimap(vc, svc);
1233 1336
1234 cols = var->xres / vc->vc_font.width; 1337 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
1235 rows = var->yres / vc->vc_font.height; 1338 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1339 cols /= vc->vc_font.width;
1340 rows /= vc->vc_font.height;
1236 vc_resize(vc, cols, rows); 1341 vc_resize(vc, cols, rows);
1342
1237 if (CON_IS_VISIBLE(vc)) { 1343 if (CON_IS_VISIBLE(vc)) {
1238 update_screen(vc); 1344 update_screen(vc);
1239 if (softback_buf) 1345 if (softback_buf)
@@ -1244,15 +1350,16 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1244static __inline__ void ywrap_up(struct vc_data *vc, int count) 1350static __inline__ void ywrap_up(struct vc_data *vc, int count)
1245{ 1351{
1246 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1352 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1353 struct fbcon_ops *ops = info->fbcon_par;
1247 struct display *p = &fb_display[vc->vc_num]; 1354 struct display *p = &fb_display[vc->vc_num];
1248 1355
1249 p->yscroll += count; 1356 p->yscroll += count;
1250 if (p->yscroll >= p->vrows) /* Deal with wrap */ 1357 if (p->yscroll >= p->vrows) /* Deal with wrap */
1251 p->yscroll -= p->vrows; 1358 p->yscroll -= p->vrows;
1252 info->var.xoffset = 0; 1359 ops->var.xoffset = 0;
1253 info->var.yoffset = p->yscroll * vc->vc_font.height; 1360 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1254 info->var.vmode |= FB_VMODE_YWRAP; 1361 ops->var.vmode |= FB_VMODE_YWRAP;
1255 update_var(vc->vc_num, info); 1362 ops->update_start(info);
1256 scrollback_max += count; 1363 scrollback_max += count;
1257 if (scrollback_max > scrollback_phys_max) 1364 if (scrollback_max > scrollback_phys_max)
1258 scrollback_max = scrollback_phys_max; 1365 scrollback_max = scrollback_phys_max;
@@ -1262,15 +1369,16 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count)
1262static __inline__ void ywrap_down(struct vc_data *vc, int count) 1369static __inline__ void ywrap_down(struct vc_data *vc, int count)
1263{ 1370{
1264 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1371 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1372 struct fbcon_ops *ops = info->fbcon_par;
1265 struct display *p = &fb_display[vc->vc_num]; 1373 struct display *p = &fb_display[vc->vc_num];
1266 1374
1267 p->yscroll -= count; 1375 p->yscroll -= count;
1268 if (p->yscroll < 0) /* Deal with wrap */ 1376 if (p->yscroll < 0) /* Deal with wrap */
1269 p->yscroll += p->vrows; 1377 p->yscroll += p->vrows;
1270 info->var.xoffset = 0; 1378 ops->var.xoffset = 0;
1271 info->var.yoffset = p->yscroll * vc->vc_font.height; 1379 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1272 info->var.vmode |= FB_VMODE_YWRAP; 1380 ops->var.vmode |= FB_VMODE_YWRAP;
1273 update_var(vc->vc_num, info); 1381 ops->update_start(info);
1274 scrollback_max -= count; 1382 scrollback_max -= count;
1275 if (scrollback_max < 0) 1383 if (scrollback_max < 0)
1276 scrollback_max = 0; 1384 scrollback_max = 0;
@@ -1289,10 +1397,11 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
1289 0, 0, 0, vc->vc_rows, vc->vc_cols); 1397 0, 0, 0, vc->vc_rows, vc->vc_cols);
1290 p->yscroll -= p->vrows - vc->vc_rows; 1398 p->yscroll -= p->vrows - vc->vc_rows;
1291 } 1399 }
1292 info->var.xoffset = 0; 1400
1293 info->var.yoffset = p->yscroll * vc->vc_font.height; 1401 ops->var.xoffset = 0;
1294 info->var.vmode &= ~FB_VMODE_YWRAP; 1402 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1295 update_var(vc->vc_num, info); 1403 ops->var.vmode &= ~FB_VMODE_YWRAP;
1404 ops->update_start(info);
1296 fbcon_clear_margins(vc, 1); 1405 fbcon_clear_margins(vc, 1);
1297 scrollback_max += count; 1406 scrollback_max += count;
1298 if (scrollback_max > scrollback_phys_max) 1407 if (scrollback_max > scrollback_phys_max)
@@ -1303,6 +1412,7 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
1303static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) 1412static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
1304{ 1413{
1305 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1414 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1415 struct fbcon_ops *ops = info->fbcon_par;
1306 struct display *p = &fb_display[vc->vc_num]; 1416 struct display *p = &fb_display[vc->vc_num];
1307 int redraw = 0; 1417 int redraw = 0;
1308 1418
@@ -1312,12 +1422,13 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
1312 redraw = 1; 1422 redraw = 1;
1313 } 1423 }
1314 1424
1315 info->var.xoffset = 0;
1316 info->var.yoffset = p->yscroll * vc->vc_font.height;
1317 info->var.vmode &= ~FB_VMODE_YWRAP;
1318 if (redraw) 1425 if (redraw)
1319 fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t); 1426 fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
1320 update_var(vc->vc_num, info); 1427
1428 ops->var.xoffset = 0;
1429 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1430 ops->var.vmode &= ~FB_VMODE_YWRAP;
1431 ops->update_start(info);
1321 fbcon_clear_margins(vc, 1); 1432 fbcon_clear_margins(vc, 1);
1322 scrollback_max += count; 1433 scrollback_max += count;
1323 if (scrollback_max > scrollback_phys_max) 1434 if (scrollback_max > scrollback_phys_max)
@@ -1337,10 +1448,11 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
1337 0, vc->vc_rows, vc->vc_cols); 1448 0, vc->vc_rows, vc->vc_cols);
1338 p->yscroll += p->vrows - vc->vc_rows; 1449 p->yscroll += p->vrows - vc->vc_rows;
1339 } 1450 }
1340 info->var.xoffset = 0; 1451
1341 info->var.yoffset = p->yscroll * vc->vc_font.height; 1452 ops->var.xoffset = 0;
1342 info->var.vmode &= ~FB_VMODE_YWRAP; 1453 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1343 update_var(vc->vc_num, info); 1454 ops->var.vmode &= ~FB_VMODE_YWRAP;
1455 ops->update_start(info);
1344 fbcon_clear_margins(vc, 1); 1456 fbcon_clear_margins(vc, 1);
1345 scrollback_max -= count; 1457 scrollback_max -= count;
1346 if (scrollback_max < 0) 1458 if (scrollback_max < 0)
@@ -1351,6 +1463,7 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
1351static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) 1463static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
1352{ 1464{
1353 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1465 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1466 struct fbcon_ops *ops = info->fbcon_par;
1354 struct display *p = &fb_display[vc->vc_num]; 1467 struct display *p = &fb_display[vc->vc_num];
1355 int redraw = 0; 1468 int redraw = 0;
1356 1469
@@ -1359,12 +1472,14 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
1359 p->yscroll += p->vrows - vc->vc_rows; 1472 p->yscroll += p->vrows - vc->vc_rows;
1360 redraw = 1; 1473 redraw = 1;
1361 } 1474 }
1362 info->var.xoffset = 0; 1475
1363 info->var.yoffset = p->yscroll * vc->vc_font.height;
1364 info->var.vmode &= ~FB_VMODE_YWRAP;
1365 if (redraw) 1476 if (redraw)
1366 fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count); 1477 fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
1367 update_var(vc->vc_num, info); 1478
1479 ops->var.xoffset = 0;
1480 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1481 ops->var.vmode &= ~FB_VMODE_YWRAP;
1482 ops->update_start(info);
1368 fbcon_clear_margins(vc, 1); 1483 fbcon_clear_margins(vc, 1);
1369 scrollback_max -= count; 1484 scrollback_max -= count;
1370 if (scrollback_max < 0) 1485 if (scrollback_max < 0)
@@ -1838,31 +1953,41 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s
1838 height, width); 1953 height, width);
1839} 1954}
1840 1955
1841static __inline__ void updatescrollmode(struct display *p, struct fb_info *info, 1956static __inline__ void updatescrollmode(struct display *p,
1957 struct fb_info *info,
1842 struct vc_data *vc) 1958 struct vc_data *vc)
1843{ 1959{
1960 struct fbcon_ops *ops = info->fbcon_par;
1844 int fh = vc->vc_font.height; 1961 int fh = vc->vc_font.height;
1845 int cap = info->flags; 1962 int cap = info->flags;
1846 int good_pan = (cap & FBINFO_HWACCEL_YPAN) 1963 u16 t = 0;
1847 && divides(info->fix.ypanstep, vc->vc_font.height) 1964 int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
1848 && info->var.yres_virtual > info->var.yres; 1965 info->fix.xpanstep);
1849 int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) 1966 int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
1850 && divides(info->fix.ywrapstep, vc->vc_font.height) 1967 int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1851 && divides(vc->vc_font.height, info->var.yres_virtual); 1968 int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
1969 info->var.xres_virtual);
1970 int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
1971 divides(ypan, vc->vc_font.height) && vyres > yres;
1972 int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
1973 divides(ywrap, vc->vc_font.height) &&
1974 divides(vc->vc_font.height, vyres);
1852 int reading_fast = cap & FBINFO_READS_FAST; 1975 int reading_fast = cap & FBINFO_READS_FAST;
1853 int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED); 1976 int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
1854 int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) && !(cap & FBINFO_HWACCEL_DISABLED); 1977 !(cap & FBINFO_HWACCEL_DISABLED);
1855 1978 int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
1856 p->vrows = info->var.yres_virtual/fh; 1979 !(cap & FBINFO_HWACCEL_DISABLED);
1857 if (info->var.yres > (fh * (vc->vc_rows + 1))) 1980
1858 p->vrows -= (info->var.yres - (fh * vc->vc_rows)) / fh; 1981 p->vrows = vyres/fh;
1859 if ((info->var.yres % fh) && (info->var.yres_virtual % fh < 1982 if (yres > (fh * (vc->vc_rows + 1)))
1860 info->var.yres % fh)) 1983 p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
1984 if ((yres % fh) && (vyres % fh < yres % fh))
1861 p->vrows--; 1985 p->vrows--;
1862 1986
1863 if (good_wrap || good_pan) { 1987 if (good_wrap || good_pan) {
1864 if (reading_fast || fast_copyarea) 1988 if (reading_fast || fast_copyarea)
1865 p->scrollmode = good_wrap ? SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE; 1989 p->scrollmode = good_wrap ?
1990 SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;
1866 else 1991 else
1867 p->scrollmode = good_wrap ? SCROLL_REDRAW : 1992 p->scrollmode = good_wrap ? SCROLL_REDRAW :
1868 SCROLL_PAN_REDRAW; 1993 SCROLL_PAN_REDRAW;
@@ -1878,17 +2003,23 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1878 unsigned int height) 2003 unsigned int height)
1879{ 2004{
1880 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2005 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2006 struct fbcon_ops *ops = info->fbcon_par;
1881 struct display *p = &fb_display[vc->vc_num]; 2007 struct display *p = &fb_display[vc->vc_num];
1882 struct fb_var_screeninfo var = info->var; 2008 struct fb_var_screeninfo var = info->var;
1883 int x_diff, y_diff; 2009 int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
1884 int fw = vc->vc_font.width; 2010
1885 int fh = vc->vc_font.height; 2011 virt_w = FBCON_SWAP(ops->rotate, width, height);
1886 2012 virt_h = FBCON_SWAP(ops->rotate, height, width);
1887 var.xres = width * fw; 2013 virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
1888 var.yres = height * fh; 2014 vc->vc_font.height);
2015 virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height,
2016 vc->vc_font.width);
2017 var.xres = virt_w * virt_fw;
2018 var.yres = virt_h * virt_fh;
1889 x_diff = info->var.xres - var.xres; 2019 x_diff = info->var.xres - var.xres;
1890 y_diff = info->var.yres - var.yres; 2020 y_diff = info->var.yres - var.yres;
1891 if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) { 2021 if (x_diff < 0 || x_diff > virt_fw ||
2022 y_diff < 0 || y_diff > virt_fh) {
1892 struct fb_videomode *mode; 2023 struct fb_videomode *mode;
1893 2024
1894 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); 2025 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
@@ -1898,7 +2029,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1898 display_to_var(&var, p); 2029 display_to_var(&var, p);
1899 fb_videomode_to_var(&var, mode); 2030 fb_videomode_to_var(&var, mode);
1900 2031
1901 if (width > var.xres/fw || height > var.yres/fh) 2032 if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh)
1902 return -EINVAL; 2033 return -EINVAL;
1903 2034
1904 DPRINTK("resize now %ix%i\n", var.xres, var.yres); 2035 DPRINTK("resize now %ix%i\n", var.xres, var.yres);
@@ -1908,6 +2039,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1908 fb_set_var(info, &var); 2039 fb_set_var(info, &var);
1909 } 2040 }
1910 var_to_display(p, &info->var, info); 2041 var_to_display(p, &info->var, info);
2042 ops->var = info->var;
1911 } 2043 }
1912 updatescrollmode(p, info, vc); 2044 updatescrollmode(p, info, vc);
1913 return 0; 2045 return 0;
@@ -1916,11 +2048,13 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1916static int fbcon_switch(struct vc_data *vc) 2048static int fbcon_switch(struct vc_data *vc)
1917{ 2049{
1918 struct fb_info *info, *old_info = NULL; 2050 struct fb_info *info, *old_info = NULL;
2051 struct fbcon_ops *ops;
1919 struct display *p = &fb_display[vc->vc_num]; 2052 struct display *p = &fb_display[vc->vc_num];
1920 struct fb_var_screeninfo var; 2053 struct fb_var_screeninfo var;
1921 int i, prev_console; 2054 int i, prev_console;
1922 2055
1923 info = registered_fb[con2fb_map[vc->vc_num]]; 2056 info = registered_fb[con2fb_map[vc->vc_num]];
2057 ops = info->fbcon_par;
1924 2058
1925 if (softback_top) { 2059 if (softback_top) {
1926 if (softback_lines) 2060 if (softback_lines)
@@ -1939,7 +2073,7 @@ static int fbcon_switch(struct vc_data *vc)
1939 logo_shown = FBCON_LOGO_CANSHOW; 2073 logo_shown = FBCON_LOGO_CANSHOW;
1940 } 2074 }
1941 2075
1942 prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon; 2076 prev_console = ops->currcon;
1943 if (prev_console != -1) 2077 if (prev_console != -1)
1944 old_info = registered_fb[con2fb_map[prev_console]]; 2078 old_info = registered_fb[con2fb_map[prev_console]];
1945 /* 2079 /*
@@ -1952,9 +2086,9 @@ static int fbcon_switch(struct vc_data *vc)
1952 */ 2086 */
1953 for (i = 0; i < FB_MAX; i++) { 2087 for (i = 0; i < FB_MAX; i++) {
1954 if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) { 2088 if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) {
1955 struct fbcon_ops *ops = registered_fb[i]->fbcon_par; 2089 struct fbcon_ops *o = registered_fb[i]->fbcon_par;
1956 2090
1957 ops->currcon = vc->vc_num; 2091 o->currcon = vc->vc_num;
1958 } 2092 }
1959 } 2093 }
1960 memset(&var, 0, sizeof(struct fb_var_screeninfo)); 2094 memset(&var, 0, sizeof(struct fb_var_screeninfo));
@@ -1966,8 +2100,11 @@ static int fbcon_switch(struct vc_data *vc)
1966 * in fb_set_var() 2100 * in fb_set_var()
1967 */ 2101 */
1968 info->var.activate = var.activate; 2102 info->var.activate = var.activate;
1969 info->var.yoffset = info->var.xoffset = p->yscroll = 0; 2103 var.yoffset = info->var.yoffset;
2104 var.xoffset = info->var.xoffset;
2105 var.vmode = info->var.vmode;
1970 fb_set_var(info, &var); 2106 fb_set_var(info, &var);
2107 ops->var = info->var;
1971 2108
1972 if (old_info != NULL && old_info != info) { 2109 if (old_info != NULL && old_info != info) {
1973 if (info->fbops->fb_set_par) 2110 if (info->fbops->fb_set_par)
@@ -1977,7 +2114,12 @@ static int fbcon_switch(struct vc_data *vc)
1977 } 2114 }
1978 2115
1979 set_blitting_type(vc, info, p); 2116 set_blitting_type(vc, info, p);
1980 ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1; 2117 ops->cursor_reset = 1;
2118
2119 if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
2120 ops->rotate = FB_ROTATE_UR;
2121 set_blitting_type(vc, info, p);
2122 }
1981 2123
1982 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 2124 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1983 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 2125 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
@@ -1997,10 +2139,11 @@ static int fbcon_switch(struct vc_data *vc)
1997 scrollback_phys_max = 0; 2139 scrollback_phys_max = 0;
1998 break; 2140 break;
1999 } 2141 }
2142
2000 scrollback_max = 0; 2143 scrollback_max = 0;
2001 scrollback_current = 0; 2144 scrollback_current = 0;
2002 2145 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2003 update_var(vc->vc_num, info); 2146 ops->update_start(info);
2004 fbcon_set_palette(vc, color_table); 2147 fbcon_set_palette(vc, color_table);
2005 fbcon_clear_margins(vc, 0); 2148 fbcon_clear_margins(vc, 0);
2006 2149
@@ -2008,7 +2151,7 @@ static int fbcon_switch(struct vc_data *vc)
2008 2151
2009 logo_shown = fg_console; 2152 logo_shown = fg_console;
2010 /* This is protected above by initmem_freed */ 2153 /* This is protected above by initmem_freed */
2011 fb_show_logo(info); 2154 fb_show_logo(info, ops->rotate);
2012 update_region(vc, 2155 update_region(vc,
2013 vc->vc_origin + vc->vc_size_row * vc->vc_top, 2156 vc->vc_origin + vc->vc_size_row * vc->vc_top,
2014 vc->vc_size_row * (vc->vc_bottom - 2157 vc->vc_size_row * (vc->vc_bottom -
@@ -2047,6 +2190,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
2047 var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; 2190 var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
2048 fb_set_var(info, &var); 2191 fb_set_var(info, &var);
2049 ops->graphics = 0; 2192 ops->graphics = 0;
2193 ops->var = info->var;
2050 } 2194 }
2051 } 2195 }
2052 2196
@@ -2135,6 +2279,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2135 const u8 * data, int userfont) 2279 const u8 * data, int userfont)
2136{ 2280{
2137 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2281 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2282 struct fbcon_ops *ops = info->fbcon_par;
2138 struct display *p = &fb_display[vc->vc_num]; 2283 struct display *p = &fb_display[vc->vc_num];
2139 int resize; 2284 int resize;
2140 int cnt; 2285 int cnt;
@@ -2214,9 +2359,13 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2214 } 2359 }
2215 2360
2216 if (resize) { 2361 if (resize) {
2217 /* reset wrap/pan */ 2362 int cols, rows;
2218 info->var.xoffset = info->var.yoffset = p->yscroll = 0; 2363
2219 vc_resize(vc, info->var.xres / w, info->var.yres / h); 2364 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2365 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2366 cols /= w;
2367 rows /= h;
2368 vc_resize(vc, cols, rows);
2220 if (CON_IS_VISIBLE(vc) && softback_buf) 2369 if (CON_IS_VISIBLE(vc) && softback_buf)
2221 fbcon_update_softback(vc); 2370 fbcon_update_softback(vc);
2222 } else if (CON_IS_VISIBLE(vc) 2371 } else if (CON_IS_VISIBLE(vc)
@@ -2444,6 +2593,7 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
2444static int fbcon_scrolldelta(struct vc_data *vc, int lines) 2593static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2445{ 2594{
2446 struct fb_info *info = registered_fb[con2fb_map[fg_console]]; 2595 struct fb_info *info = registered_fb[con2fb_map[fg_console]];
2596 struct fbcon_ops *ops = info->fbcon_par;
2447 struct display *p = &fb_display[fg_console]; 2597 struct display *p = &fb_display[fg_console];
2448 int offset, limit, scrollback_old; 2598 int offset, limit, scrollback_old;
2449 2599
@@ -2520,9 +2670,11 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2520 offset += limit; 2670 offset += limit;
2521 else if (offset >= limit) 2671 else if (offset >= limit)
2522 offset -= limit; 2672 offset -= limit;
2523 info->var.xoffset = 0; 2673
2524 info->var.yoffset = offset * vc->vc_font.height; 2674 ops->var.xoffset = 0;
2525 update_var(vc->vc_num, info); 2675 ops->var.yoffset = offset * vc->vc_font.height;
2676 ops->update_start(info);
2677
2526 if (!scrollback_current) 2678 if (!scrollback_current)
2527 fbcon_cursor(vc, CM_DRAW); 2679 fbcon_cursor(vc, CM_DRAW);
2528 return 0; 2680 return 0;
@@ -2570,22 +2722,25 @@ static void fbcon_modechanged(struct fb_info *info)
2570 if (!ops || ops->currcon < 0) 2722 if (!ops || ops->currcon < 0)
2571 return; 2723 return;
2572 vc = vc_cons[ops->currcon].d; 2724 vc = vc_cons[ops->currcon].d;
2573 if (vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[ops->currcon]] != info) 2725 if (vc->vc_mode != KD_TEXT ||
2726 registered_fb[con2fb_map[ops->currcon]] != info)
2574 return; 2727 return;
2575 2728
2576 p = &fb_display[vc->vc_num]; 2729 p = &fb_display[vc->vc_num];
2577 2730 set_blitting_type(vc, info, p);
2578 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2579 2731
2580 if (CON_IS_VISIBLE(vc)) { 2732 if (CON_IS_VISIBLE(vc)) {
2581 var_to_display(p, &info->var, info); 2733 var_to_display(p, &info->var, info);
2582 cols = info->var.xres / vc->vc_font.width; 2734 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2583 rows = info->var.yres / vc->vc_font.height; 2735 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2736 cols /= vc->vc_font.width;
2737 rows /= vc->vc_font.height;
2584 vc_resize(vc, cols, rows); 2738 vc_resize(vc, cols, rows);
2585 updatescrollmode(p, info, vc); 2739 updatescrollmode(p, info, vc);
2586 scrollback_max = 0; 2740 scrollback_max = 0;
2587 scrollback_current = 0; 2741 scrollback_current = 0;
2588 update_var(vc->vc_num, info); 2742 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2743 ops->update_start(info);
2589 fbcon_set_palette(vc, color_table); 2744 fbcon_set_palette(vc, color_table);
2590 update_screen(vc); 2745 update_screen(vc);
2591 if (softback_buf) 2746 if (softback_buf)
@@ -2610,18 +2765,20 @@ static void fbcon_set_all_vcs(struct fb_info *info)
2610 continue; 2765 continue;
2611 2766
2612 p = &fb_display[vc->vc_num]; 2767 p = &fb_display[vc->vc_num];
2613 2768 set_blitting_type(vc, info, p);
2614 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2615 var_to_display(p, &info->var, info); 2769 var_to_display(p, &info->var, info);
2616 cols = info->var.xres / vc->vc_font.width; 2770 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2617 rows = info->var.yres / vc->vc_font.height; 2771 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2772 cols /= vc->vc_font.width;
2773 rows /= vc->vc_font.height;
2618 vc_resize(vc, cols, rows); 2774 vc_resize(vc, cols, rows);
2619 2775
2620 if (CON_IS_VISIBLE(vc)) { 2776 if (CON_IS_VISIBLE(vc)) {
2621 updatescrollmode(p, info, vc); 2777 updatescrollmode(p, info, vc);
2622 scrollback_max = 0; 2778 scrollback_max = 0;
2623 scrollback_current = 0; 2779 scrollback_current = 0;
2624 update_var(vc->vc_num, info); 2780 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2781 ops->update_start(info);
2625 fbcon_set_palette(vc, color_table); 2782 fbcon_set_palette(vc, color_table);
2626 update_screen(vc); 2783 update_screen(vc);
2627 if (softback_buf) 2784 if (softback_buf)
@@ -2771,6 +2928,14 @@ static int fbcon_event_notify(struct notifier_block *self,
2771 case FB_EVENT_NEW_MODELIST: 2928 case FB_EVENT_NEW_MODELIST:
2772 fbcon_new_modelist(info); 2929 fbcon_new_modelist(info);
2773 break; 2930 break;
2931 case FB_EVENT_SET_CON_ROTATE:
2932 fbcon_rotate(info, *(int *)event->data);
2933 break;
2934 case FB_EVENT_GET_CON_ROTATE:
2935 ret = fbcon_get_rotate(info);
2936 break;
2937 case FB_EVENT_SET_CON_ROTATE_ALL:
2938 fbcon_rotate_all(info, *(int *)event->data);
2774 } 2939 }
2775 2940
2776 return ret; 2941 return ret;
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index b68e0e2c2d16..accfd7bd8e93 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -27,15 +27,15 @@
27 */ 27 */
28 28
29struct display { 29struct display {
30 /* Filled in by the frame buffer device */
31 u_short inverse; /* != 0 text black on white as default */
32 /* Filled in by the low-level console driver */ 30 /* Filled in by the low-level console driver */
33 const u_char *fontdata; 31 const u_char *fontdata;
34 int userfont; /* != 0 if fontdata kmalloc()ed */ 32 int userfont; /* != 0 if fontdata kmalloc()ed */
35 u_short scrollmode; /* Scroll Method */ 33 u_short scrollmode; /* Scroll Method */
34 u_short inverse; /* != 0 text black on white as default */
36 short yscroll; /* Hardware scrolling */ 35 short yscroll; /* Hardware scrolling */
37 int vrows; /* number of virtual rows */ 36 int vrows; /* number of virtual rows */
38 int cursor_shape; 37 int cursor_shape;
38 int con_rotate;
39 u32 xres_virtual; 39 u32 xres_virtual;
40 u32 yres_virtual; 40 u32 yres_virtual;
41 u32 height; 41 u32 height;
@@ -52,6 +52,8 @@ struct display {
52 struct fb_videomode *mode; 52 struct fb_videomode *mode;
53}; 53};
54 54
55extern struct display fb_display[];
56
55struct fbcon_ops { 57struct fbcon_ops {
56 void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy, 58 void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
57 int sx, int dy, int dx, int height, int width); 59 int sx, int dy, int dx, int height, int width);
@@ -63,8 +65,12 @@ struct fbcon_ops {
63 void (*clear_margins)(struct vc_data *vc, struct fb_info *info, 65 void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
64 int bottom_only); 66 int bottom_only);
65 void (*cursor)(struct vc_data *vc, struct fb_info *info, 67 void (*cursor)(struct vc_data *vc, struct fb_info *info,
66 struct display *p, int mode, int softback_lines, int fg, int bg); 68 struct display *p, int mode, int softback_lines,
67 69 int fg, int bg);
70 int (*update_start)(struct fb_info *info);
71 int (*rotate_font)(struct fb_info *info, struct vc_data *vc,
72 struct display *p);
73 struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */
68 struct timer_list cursor_timer; /* Cursor timer */ 74 struct timer_list cursor_timer; /* Cursor timer */
69 struct fb_cursor cursor_state; 75 struct fb_cursor cursor_state;
70 int currcon; /* Current VC. */ 76 int currcon; /* Current VC. */
@@ -73,7 +79,12 @@ struct fbcon_ops {
73 int blank_state; 79 int blank_state;
74 int graphics; 80 int graphics;
75 int flags; 81 int flags;
82 int rotate;
83 int cur_rotate;
76 char *cursor_data; 84 char *cursor_data;
85 u8 *fontbuffer;
86 u8 *fontdata;
87 u32 fd_size;
77}; 88};
78 /* 89 /*
79 * Attribute Decoding 90 * Attribute Decoding
@@ -168,4 +179,47 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
168#endif 179#endif
169extern void fbcon_set_bitops(struct fbcon_ops *ops); 180extern void fbcon_set_bitops(struct fbcon_ops *ops);
170extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); 181extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
182
183#define FBCON_ATTRIBUTE_UNDERLINE 1
184#define FBCON_ATTRIBUTE_REVERSE 2
185#define FBCON_ATTRIBUTE_BOLD 4
186
187static inline int real_y(struct display *p, int ypos)
188{
189 int rows = p->vrows;
190
191 ypos += p->yscroll;
192 return ypos < rows ? ypos : ypos - rows;
193}
194
195
196static inline int get_attribute(struct fb_info *info, u16 c)
197{
198 int attribute = 0;
199
200 if (fb_get_color_depth(&info->var, &info->fix) == 1) {
201 if (attr_underline(c))
202 attribute |= FBCON_ATTRIBUTE_UNDERLINE;
203 if (attr_reverse(c))
204 attribute |= FBCON_ATTRIBUTE_REVERSE;
205 if (attr_bold(c))
206 attribute |= FBCON_ATTRIBUTE_BOLD;
207 }
208
209 return attribute;
210}
211
212#define FBCON_SWAP(i,r,v) ({ \
213 typeof(r) _r = (r); \
214 typeof(v) _v = (v); \
215 (void) (&_r == &_v); \
216 (i == FB_ROTATE_UR || i == FB_ROTATE_UD) ? _r : _v; })
217
218#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
219extern void fbcon_set_rotate(struct fbcon_ops *ops);
220#else
221#define fbcon_set_rotate(x) do {} while(0)
222#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
223
171#endif /* _VIDEO_FBCON_H */ 224#endif /* _VIDEO_FBCON_H */
225
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
new file mode 100644
index 000000000000..680aabab73c5
--- /dev/null
+++ b/drivers/video/console/fbcon_ccw.c
@@ -0,0 +1,428 @@
1/*
2 * linux/drivers/video/console/fbcon_ccw.c -- Software Rotation - 270 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 270 degrees
23 */
24
25static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.height + 7) >> 3;
30 int mod = vc->vc_font.height % 8;
31 u8 c, msk = ~(0xff << offset), msk1 = 0;
32
33 if (mod)
34 msk <<= (8 - mod);
35
36 if (offset > mod)
37 set_bit(FBCON_BIT(7), (void *)&msk1);
38
39 for (i = 0; i < vc->vc_font.width; i++) {
40 for (j = 0; j < width; j++) {
41 c = *src;
42
43 if (attribute & FBCON_ATTRIBUTE_UNDERLINE) {
44 if (j == width - 1)
45 c |= msk;
46
47 if (msk1 && j == width - 2)
48 c |= msk1;
49 }
50
51 if (attribute & FBCON_ATTRIBUTE_BOLD && i)
52 *(dst - width) |= c;
53
54 if (attribute & FBCON_ATTRIBUTE_REVERSE)
55 c = ~c;
56 src++;
57 *dst++ = c;
58 }
59 }
60}
61
62
63static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
64 int sx, int dy, int dx, int height, int width)
65{
66 struct display *p = &fb_display[vc->vc_num];
67 struct fb_copyarea area;
68 u32 vyres = GETVYRES(p->scrollmode, info);
69
70 area.sx = sy * vc->vc_font.height;
71 area.sy = vyres - ((sx + width) * vc->vc_font.width);
72 area.dx = dy * vc->vc_font.height;
73 area.dy = vyres - ((dx + width) * vc->vc_font.width);
74 area.width = height * vc->vc_font.height;
75 area.height = width * vc->vc_font.width;
76
77 info->fbops->fb_copyarea(info, &area);
78}
79
80static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
81 int sx, int height, int width)
82{
83 struct display *p = &fb_display[vc->vc_num];
84 struct fb_fillrect region;
85 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
86 u32 vyres = GETVYRES(p->scrollmode, info);
87
88 region.color = attr_bgcol_ec(bgshift,vc);
89 region.dx = sy * vc->vc_font.height;
90 region.dy = vyres - ((sx + width) * vc->vc_font.width);
91 region.height = width * vc->vc_font.width;
92 region.width = height * vc->vc_font.height;
93 region.rop = ROP_COPY;
94
95 info->fbops->fb_fillrect(info, &region);
96}
97
98static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
99 const u16 *s, u32 attr, u32 cnt,
100 u32 d_pitch, u32 s_pitch, u32 cellsize,
101 struct fb_image *image, u8 *buf, u8 *dst)
102{
103 struct fbcon_ops *ops = info->fbcon_par;
104 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
105 u32 idx = (vc->vc_font.height + 7) >> 3;
106 u8 *src;
107
108 while (cnt--) {
109 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
110
111 if (attr) {
112 ccw_update_attr(buf, src, attr, vc);
113 src = buf;
114 }
115
116 if (likely(idx == 1))
117 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
118 vc->vc_font.width);
119 else
120 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
121 vc->vc_font.width);
122
123 dst += d_pitch * vc->vc_font.width;
124 }
125
126 info->fbops->fb_imageblit(info, image);
127}
128
129static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
130 const unsigned short *s, int count, int yy, int xx,
131 int fg, int bg)
132{
133 struct fb_image image;
134 struct display *p = &fb_display[vc->vc_num];
135 struct fbcon_ops *ops = info->fbcon_par;
136 u32 width = (vc->vc_font.height + 7)/8;
137 u32 cellsize = width * vc->vc_font.width;
138 u32 maxcnt = info->pixmap.size/cellsize;
139 u32 scan_align = info->pixmap.scan_align - 1;
140 u32 buf_align = info->pixmap.buf_align - 1;
141 u32 cnt, pitch, size;
142 u32 attribute = get_attribute(info, scr_readw(s));
143 u8 *dst, *buf = NULL;
144 u32 vyres = GETVYRES(p->scrollmode, info);
145
146 if (!ops->fontbuffer)
147 return;
148
149 image.fg_color = fg;
150 image.bg_color = bg;
151 image.dx = yy * vc->vc_font.height;
152 image.dy = vyres - ((xx + count) * vc->vc_font.width);
153 image.width = vc->vc_font.height;
154 image.depth = 1;
155
156 if (attribute) {
157 buf = kmalloc(cellsize, GFP_KERNEL);
158 if (!buf)
159 return;
160 }
161
162 s += count - 1;
163
164 while (count) {
165 if (count > maxcnt)
166 cnt = maxcnt;
167 else
168 cnt = count;
169
170 image.height = vc->vc_font.width * cnt;
171 pitch = ((image.width + 7) >> 3) + scan_align;
172 pitch &= ~scan_align;
173 size = pitch * image.height + buf_align;
174 size &= ~buf_align;
175 dst = fb_get_buffer_offset(info, &info->pixmap, size);
176 image.data = dst;
177 ccw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
178 width, cellsize, &image, buf, dst);
179 image.dy += image.height;
180 count -= cnt;
181 s -= cnt;
182 }
183
184 /* buf is always NULL except when in monochrome mode, so in this case
185 it's a gain to check buf against NULL even though kfree() handles
186 NULL pointers just fine */
187 if (unlikely(buf))
188 kfree(buf);
189
190}
191
192static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info,
193 int bottom_only)
194{
195 unsigned int cw = vc->vc_font.width;
196 unsigned int ch = vc->vc_font.height;
197 unsigned int rw = info->var.yres - (vc->vc_cols*cw);
198 unsigned int bh = info->var.xres - (vc->vc_rows*ch);
199 unsigned int bs = vc->vc_rows*ch;
200 struct fb_fillrect region;
201 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
202
203 region.color = attr_bgcol_ec(bgshift,vc);
204 region.rop = ROP_COPY;
205
206 if (rw && !bottom_only) {
207 region.dx = 0;
208 region.dy = info->var.yoffset;
209 region.height = rw;
210 region.width = info->var.xres_virtual;
211 info->fbops->fb_fillrect(info, &region);
212 }
213
214 if (bh) {
215 region.dx = info->var.xoffset + bs;
216 region.dy = 0;
217 region.height = info->var.yres_virtual;
218 region.width = bh;
219 info->fbops->fb_fillrect(info, &region);
220 }
221}
222
223static void ccw_cursor(struct vc_data *vc, struct fb_info *info,
224 struct display *p, int mode, int softback_lines,
225 int fg, int bg)
226{
227 struct fb_cursor cursor;
228 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
229 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
230 int w = (vc->vc_font.height + 7) >> 3, c;
231 int y = real_y(p, vc->vc_y);
232 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
233 int err = 1, dx, dy;
234 char *src;
235 u32 vyres = GETVYRES(p->scrollmode, info);
236
237 if (!ops->fontbuffer)
238 return;
239
240 cursor.set = 0;
241
242 if (softback_lines) {
243 if (y + softback_lines >= vc->vc_rows) {
244 mode = CM_ERASE;
245 ops->cursor_flash = 0;
246 return;
247 } else
248 y += softback_lines;
249 }
250
251 c = scr_readw((u16 *) vc->vc_pos);
252 attribute = get_attribute(info, c);
253 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
254
255 if (ops->cursor_state.image.data != src ||
256 ops->cursor_reset) {
257 ops->cursor_state.image.data = src;
258 cursor.set |= FB_CUR_SETIMAGE;
259 }
260
261 if (attribute) {
262 u8 *dst;
263
264 dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
265 if (!dst)
266 return;
267 kfree(ops->cursor_data);
268 ops->cursor_data = dst;
269 ccw_update_attr(dst, src, attribute, vc);
270 src = dst;
271 }
272
273 if (ops->cursor_state.image.fg_color != fg ||
274 ops->cursor_state.image.bg_color != bg ||
275 ops->cursor_reset) {
276 ops->cursor_state.image.fg_color = fg;
277 ops->cursor_state.image.bg_color = bg;
278 cursor.set |= FB_CUR_SETCMAP;
279 }
280
281 if (ops->cursor_state.image.height != vc->vc_font.width ||
282 ops->cursor_state.image.width != vc->vc_font.height ||
283 ops->cursor_reset) {
284 ops->cursor_state.image.height = vc->vc_font.width;
285 ops->cursor_state.image.width = vc->vc_font.height;
286 cursor.set |= FB_CUR_SETSIZE;
287 }
288
289 dx = y * vc->vc_font.height;
290 dy = vyres - ((vc->vc_x + 1) * vc->vc_font.width);
291
292 if (ops->cursor_state.image.dx != dx ||
293 ops->cursor_state.image.dy != dy ||
294 ops->cursor_reset) {
295 ops->cursor_state.image.dx = dx;
296 ops->cursor_state.image.dy = dy;
297 cursor.set |= FB_CUR_SETPOS;
298 }
299
300 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
301 ops->cursor_reset) {
302 ops->cursor_state.hot.x = cursor.hot.y = 0;
303 cursor.set |= FB_CUR_SETHOT;
304 }
305
306 if (cursor.set & FB_CUR_SETSIZE ||
307 vc->vc_cursor_type != p->cursor_shape ||
308 ops->cursor_state.mask == NULL ||
309 ops->cursor_reset) {
310 char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
311 int cur_height, size, i = 0;
312 int width = (vc->vc_font.width + 7)/8;
313
314 if (!mask)
315 return;
316
317 tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
318
319 if (!tmp) {
320 kfree(mask);
321 return;
322 }
323
324 kfree(ops->cursor_state.mask);
325 ops->cursor_state.mask = mask;
326
327 p->cursor_shape = vc->vc_cursor_type;
328 cursor.set |= FB_CUR_SETSHAPE;
329
330 switch (p->cursor_shape & CUR_HWMASK) {
331 case CUR_NONE:
332 cur_height = 0;
333 break;
334 case CUR_UNDERLINE:
335 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
336 break;
337 case CUR_LOWER_THIRD:
338 cur_height = vc->vc_font.height/3;
339 break;
340 case CUR_LOWER_HALF:
341 cur_height = vc->vc_font.height >> 1;
342 break;
343 case CUR_TWO_THIRDS:
344 cur_height = (vc->vc_font.height << 1)/3;
345 break;
346 case CUR_BLOCK:
347 default:
348 cur_height = vc->vc_font.height;
349 break;
350 }
351
352 size = (vc->vc_font.height - cur_height) * width;
353 while (size--)
354 tmp[i++] = 0;
355 size = cur_height * width;
356 while (size--)
357 tmp[i++] = 0xff;
358 memset(mask, 0, w * vc->vc_font.width);
359 rotate_ccw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
360 kfree(tmp);
361 }
362
363 switch (mode) {
364 case CM_ERASE:
365 ops->cursor_state.enable = 0;
366 break;
367 case CM_DRAW:
368 case CM_MOVE:
369 default:
370 ops->cursor_state.enable = (use_sw) ? 0 : 1;
371 break;
372 }
373
374 cursor.image.data = src;
375 cursor.image.fg_color = ops->cursor_state.image.fg_color;
376 cursor.image.bg_color = ops->cursor_state.image.bg_color;
377 cursor.image.dx = ops->cursor_state.image.dx;
378 cursor.image.dy = ops->cursor_state.image.dy;
379 cursor.image.height = ops->cursor_state.image.height;
380 cursor.image.width = ops->cursor_state.image.width;
381 cursor.hot.x = ops->cursor_state.hot.x;
382 cursor.hot.y = ops->cursor_state.hot.y;
383 cursor.mask = ops->cursor_state.mask;
384 cursor.enable = ops->cursor_state.enable;
385 cursor.image.depth = 1;
386 cursor.rop = ROP_XOR;
387
388 if (info->fbops->fb_cursor)
389 err = info->fbops->fb_cursor(info, &cursor);
390
391 if (err)
392 soft_cursor(info, &cursor);
393
394 ops->cursor_reset = 0;
395}
396
397int ccw_update_start(struct fb_info *info)
398{
399 struct fbcon_ops *ops = info->fbcon_par;
400 struct display *p = &fb_display[ops->currcon];
401 u32 yoffset;
402 u32 vyres = GETVYRES(p->scrollmode, info);
403 int err;
404
405 yoffset = (vyres - info->var.yres) - ops->var.xoffset;
406 ops->var.xoffset = ops->var.yoffset;
407 ops->var.yoffset = yoffset;
408 err = fb_pan_display(info, &ops->var);
409 ops->var.xoffset = info->var.xoffset;
410 ops->var.yoffset = info->var.yoffset;
411 ops->var.vmode = info->var.vmode;
412 return err;
413}
414
415void fbcon_rotate_ccw(struct fbcon_ops *ops)
416{
417 ops->bmove = ccw_bmove;
418 ops->clear = ccw_clear;
419 ops->putcs = ccw_putcs;
420 ops->clear_margins = ccw_clear_margins;
421 ops->cursor = ccw_cursor;
422 ops->update_start = ccw_update_start;
423}
424EXPORT_SYMBOL(fbcon_rotate_ccw);
425
426MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
427MODULE_DESCRIPTION("Console Rotation (270 degrees) Support");
428MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
new file mode 100644
index 000000000000..6c6f3b6dd175
--- /dev/null
+++ b/drivers/video/console/fbcon_cw.c
@@ -0,0 +1,412 @@
1/*
2 * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 90 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 90 degrees
23 */
24
25static inline void cw_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.height + 7) >> 3;
30 u8 c, t = 0, msk = ~(0xff >> offset);
31
32 for (i = 0; i < vc->vc_font.width; i++) {
33 for (j = 0; j < width; j++) {
34 c = *src;
35 if (attribute & FBCON_ATTRIBUTE_UNDERLINE && !j)
36 c |= msk;
37 if (attribute & FBCON_ATTRIBUTE_BOLD && i)
38 c |= *(src-width);
39 if (attribute & FBCON_ATTRIBUTE_REVERSE)
40 c = ~c;
41 src++;
42 *dst++ = c;
43 t = c;
44 }
45 }
46}
47
48
49static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
50 int sx, int dy, int dx, int height, int width)
51{
52 struct display *p = &fb_display[vc->vc_num];
53 struct fb_copyarea area;
54 u32 vxres = GETVXRES(p->scrollmode, info);
55
56 area.sx = vxres - ((sy + height) * vc->vc_font.height);
57 area.sy = sx * vc->vc_font.width;
58 area.dx = vxres - ((dy + height) * vc->vc_font.height);
59 area.dy = dx * vc->vc_font.width;
60 area.width = height * vc->vc_font.height;
61 area.height = width * vc->vc_font.width;
62
63 info->fbops->fb_copyarea(info, &area);
64}
65
66static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
67 int sx, int height, int width)
68{
69 struct display *p = &fb_display[vc->vc_num];
70 struct fb_fillrect region;
71 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
72 u32 vxres = GETVXRES(p->scrollmode, info);
73
74 region.color = attr_bgcol_ec(bgshift,vc);
75 region.dx = vxres - ((sy + height) * vc->vc_font.height);
76 region.dy = sx * vc->vc_font.width;
77 region.height = width * vc->vc_font.width;
78 region.width = height * vc->vc_font.height;
79 region.rop = ROP_COPY;
80
81 info->fbops->fb_fillrect(info, &region);
82}
83
84static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
85 const u16 *s, u32 attr, u32 cnt,
86 u32 d_pitch, u32 s_pitch, u32 cellsize,
87 struct fb_image *image, u8 *buf, u8 *dst)
88{
89 struct fbcon_ops *ops = info->fbcon_par;
90 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
91 u32 idx = (vc->vc_font.height + 7) >> 3;
92 u8 *src;
93
94 while (cnt--) {
95 src = ops->fontbuffer + (scr_readw(s++) & charmask)*cellsize;
96
97 if (attr) {
98 cw_update_attr(buf, src, attr, vc);
99 src = buf;
100 }
101
102 if (likely(idx == 1))
103 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
104 vc->vc_font.width);
105 else
106 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
107 vc->vc_font.width);
108
109 dst += d_pitch * vc->vc_font.width;
110 }
111
112 info->fbops->fb_imageblit(info, image);
113}
114
115static void cw_putcs(struct vc_data *vc, struct fb_info *info,
116 const unsigned short *s, int count, int yy, int xx,
117 int fg, int bg)
118{
119 struct fb_image image;
120 struct display *p = &fb_display[vc->vc_num];
121 struct fbcon_ops *ops = info->fbcon_par;
122 u32 width = (vc->vc_font.height + 7)/8;
123 u32 cellsize = width * vc->vc_font.width;
124 u32 maxcnt = info->pixmap.size/cellsize;
125 u32 scan_align = info->pixmap.scan_align - 1;
126 u32 buf_align = info->pixmap.buf_align - 1;
127 u32 cnt, pitch, size;
128 u32 attribute = get_attribute(info, scr_readw(s));
129 u8 *dst, *buf = NULL;
130 u32 vxres = GETVXRES(p->scrollmode, info);
131
132 if (!ops->fontbuffer)
133 return;
134
135 image.fg_color = fg;
136 image.bg_color = bg;
137 image.dx = vxres - ((yy + 1) * vc->vc_font.height);
138 image.dy = xx * vc->vc_font.width;
139 image.width = vc->vc_font.height;
140 image.depth = 1;
141
142 if (attribute) {
143 buf = kmalloc(cellsize, GFP_KERNEL);
144 if (!buf)
145 return;
146 }
147
148 while (count) {
149 if (count > maxcnt)
150 cnt = maxcnt;
151 else
152 cnt = count;
153
154 image.height = vc->vc_font.width * cnt;
155 pitch = ((image.width + 7) >> 3) + scan_align;
156 pitch &= ~scan_align;
157 size = pitch * image.height + buf_align;
158 size &= ~buf_align;
159 dst = fb_get_buffer_offset(info, &info->pixmap, size);
160 image.data = dst;
161 cw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
162 width, cellsize, &image, buf, dst);
163 image.dy += image.height;
164 count -= cnt;
165 s += cnt;
166 }
167
168 /* buf is always NULL except when in monochrome mode, so in this case
169 it's a gain to check buf against NULL even though kfree() handles
170 NULL pointers just fine */
171 if (unlikely(buf))
172 kfree(buf);
173
174}
175
176static void cw_clear_margins(struct vc_data *vc, struct fb_info *info,
177 int bottom_only)
178{
179 unsigned int cw = vc->vc_font.width;
180 unsigned int ch = vc->vc_font.height;
181 unsigned int rw = info->var.yres - (vc->vc_cols*cw);
182 unsigned int bh = info->var.xres - (vc->vc_rows*ch);
183 unsigned int rs = info->var.yres - rw;
184 struct fb_fillrect region;
185 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
186
187 region.color = attr_bgcol_ec(bgshift,vc);
188 region.rop = ROP_COPY;
189
190 if (rw && !bottom_only) {
191 region.dx = 0;
192 region.dy = info->var.yoffset + rs;
193 region.height = rw;
194 region.width = info->var.xres_virtual;
195 info->fbops->fb_fillrect(info, &region);
196 }
197
198 if (bh) {
199 region.dx = info->var.xoffset;
200 region.dy = info->var.yoffset;
201 region.height = info->var.yres;
202 region.width = bh;
203 info->fbops->fb_fillrect(info, &region);
204 }
205}
206
207static void cw_cursor(struct vc_data *vc, struct fb_info *info,
208 struct display *p, int mode, int softback_lines,
209 int fg, int bg)
210{
211 struct fb_cursor cursor;
212 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
213 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
214 int w = (vc->vc_font.height + 7) >> 3, c;
215 int y = real_y(p, vc->vc_y);
216 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
217 int err = 1, dx, dy;
218 char *src;
219 u32 vxres = GETVXRES(p->scrollmode, info);
220
221 if (!ops->fontbuffer)
222 return;
223
224 cursor.set = 0;
225
226 if (softback_lines) {
227 if (y + softback_lines >= vc->vc_rows) {
228 mode = CM_ERASE;
229 ops->cursor_flash = 0;
230 return;
231 } else
232 y += softback_lines;
233 }
234
235 c = scr_readw((u16 *) vc->vc_pos);
236 attribute = get_attribute(info, c);
237 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
238
239 if (ops->cursor_state.image.data != src ||
240 ops->cursor_reset) {
241 ops->cursor_state.image.data = src;
242 cursor.set |= FB_CUR_SETIMAGE;
243 }
244
245 if (attribute) {
246 u8 *dst;
247
248 dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
249 if (!dst)
250 return;
251 kfree(ops->cursor_data);
252 ops->cursor_data = dst;
253 cw_update_attr(dst, src, attribute, vc);
254 src = dst;
255 }
256
257 if (ops->cursor_state.image.fg_color != fg ||
258 ops->cursor_state.image.bg_color != bg ||
259 ops->cursor_reset) {
260 ops->cursor_state.image.fg_color = fg;
261 ops->cursor_state.image.bg_color = bg;
262 cursor.set |= FB_CUR_SETCMAP;
263 }
264
265 if (ops->cursor_state.image.height != vc->vc_font.width ||
266 ops->cursor_state.image.width != vc->vc_font.height ||
267 ops->cursor_reset) {
268 ops->cursor_state.image.height = vc->vc_font.width;
269 ops->cursor_state.image.width = vc->vc_font.height;
270 cursor.set |= FB_CUR_SETSIZE;
271 }
272
273 dx = vxres - ((y * vc->vc_font.height) + vc->vc_font.height);
274 dy = vc->vc_x * vc->vc_font.width;
275
276 if (ops->cursor_state.image.dx != dx ||
277 ops->cursor_state.image.dy != dy ||
278 ops->cursor_reset) {
279 ops->cursor_state.image.dx = dx;
280 ops->cursor_state.image.dy = dy;
281 cursor.set |= FB_CUR_SETPOS;
282 }
283
284 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
285 ops->cursor_reset) {
286 ops->cursor_state.hot.x = cursor.hot.y = 0;
287 cursor.set |= FB_CUR_SETHOT;
288 }
289
290 if (cursor.set & FB_CUR_SETSIZE ||
291 vc->vc_cursor_type != p->cursor_shape ||
292 ops->cursor_state.mask == NULL ||
293 ops->cursor_reset) {
294 char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
295 int cur_height, size, i = 0;
296 int width = (vc->vc_font.width + 7)/8;
297
298 if (!mask)
299 return;
300
301 tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
302
303 if (!tmp) {
304 kfree(mask);
305 return;
306 }
307
308 kfree(ops->cursor_state.mask);
309 ops->cursor_state.mask = mask;
310
311 p->cursor_shape = vc->vc_cursor_type;
312 cursor.set |= FB_CUR_SETSHAPE;
313
314 switch (p->cursor_shape & CUR_HWMASK) {
315 case CUR_NONE:
316 cur_height = 0;
317 break;
318 case CUR_UNDERLINE:
319 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
320 break;
321 case CUR_LOWER_THIRD:
322 cur_height = vc->vc_font.height/3;
323 break;
324 case CUR_LOWER_HALF:
325 cur_height = vc->vc_font.height >> 1;
326 break;
327 case CUR_TWO_THIRDS:
328 cur_height = (vc->vc_font.height << 1)/3;
329 break;
330 case CUR_BLOCK:
331 default:
332 cur_height = vc->vc_font.height;
333 break;
334 }
335
336 size = (vc->vc_font.height - cur_height) * width;
337 while (size--)
338 tmp[i++] = 0;
339 size = cur_height * width;
340 while (size--)
341 tmp[i++] = 0xff;
342 memset(mask, 0, w * vc->vc_font.width);
343 rotate_cw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
344 kfree(tmp);
345 }
346
347 switch (mode) {
348 case CM_ERASE:
349 ops->cursor_state.enable = 0;
350 break;
351 case CM_DRAW:
352 case CM_MOVE:
353 default:
354 ops->cursor_state.enable = (use_sw) ? 0 : 1;
355 break;
356 }
357
358 cursor.image.data = src;
359 cursor.image.fg_color = ops->cursor_state.image.fg_color;
360 cursor.image.bg_color = ops->cursor_state.image.bg_color;
361 cursor.image.dx = ops->cursor_state.image.dx;
362 cursor.image.dy = ops->cursor_state.image.dy;
363 cursor.image.height = ops->cursor_state.image.height;
364 cursor.image.width = ops->cursor_state.image.width;
365 cursor.hot.x = ops->cursor_state.hot.x;
366 cursor.hot.y = ops->cursor_state.hot.y;
367 cursor.mask = ops->cursor_state.mask;
368 cursor.enable = ops->cursor_state.enable;
369 cursor.image.depth = 1;
370 cursor.rop = ROP_XOR;
371
372 if (info->fbops->fb_cursor)
373 err = info->fbops->fb_cursor(info, &cursor);
374
375 if (err)
376 soft_cursor(info, &cursor);
377
378 ops->cursor_reset = 0;
379}
380
381int cw_update_start(struct fb_info *info)
382{
383 struct fbcon_ops *ops = info->fbcon_par;
384 struct display *p = &fb_display[ops->currcon];
385 u32 vxres = GETVXRES(p->scrollmode, info);
386 u32 xoffset;
387 int err;
388
389 xoffset = vxres - (info->var.xres + ops->var.yoffset);
390 ops->var.yoffset = ops->var.xoffset;
391 ops->var.xoffset = xoffset;
392 err = fb_pan_display(info, &ops->var);
393 ops->var.xoffset = info->var.xoffset;
394 ops->var.yoffset = info->var.yoffset;
395 ops->var.vmode = info->var.vmode;
396 return err;
397}
398
399void fbcon_rotate_cw(struct fbcon_ops *ops)
400{
401 ops->bmove = cw_bmove;
402 ops->clear = cw_clear;
403 ops->putcs = cw_putcs;
404 ops->clear_margins = cw_clear_margins;
405 ops->cursor = cw_cursor;
406 ops->update_start = cw_update_start;
407}
408EXPORT_SYMBOL(fbcon_rotate_cw);
409
410MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
411MODULE_DESCRIPTION("Console Rotation (90 degrees) Support");
412MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/console/fbcon_rotate.c
new file mode 100644
index 000000000000..ec0dd8fe241c
--- /dev/null
+++ b/drivers/video/console/fbcon_rotate.c
@@ -0,0 +1,117 @@
1/*
2 * linux/drivers/video/console/fbcon_rotate.c -- Software Rotation
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc,
22 struct display *p)
23{
24 struct fbcon_ops *ops = info->fbcon_par;
25 int len, err = 0;
26 int s_cellsize, d_cellsize, i;
27 const u8 *src;
28 u8 *dst;
29
30 if (vc->vc_font.data == ops->fontdata &&
31 p->con_rotate == ops->cur_rotate)
32 goto finished;
33
34 src = ops->fontdata = vc->vc_font.data;
35 ops->cur_rotate = p->con_rotate;
36 len = (!p->userfont) ? 256 : FNTCHARCNT(src);
37 s_cellsize = ((vc->vc_font.width + 7)/8) *
38 vc->vc_font.height;
39 d_cellsize = s_cellsize;
40
41 if (ops->rotate == FB_ROTATE_CW ||
42 ops->rotate == FB_ROTATE_CCW)
43 d_cellsize = ((vc->vc_font.height + 7)/8) *
44 vc->vc_font.width;
45
46 if (info->fbops->fb_sync)
47 info->fbops->fb_sync(info);
48
49 if (ops->fd_size < d_cellsize * len) {
50 dst = kmalloc(d_cellsize * len, GFP_KERNEL);
51
52 if (dst == NULL) {
53 err = -ENOMEM;
54 goto finished;
55 }
56
57 ops->fd_size = d_cellsize * len;
58 kfree(ops->fontbuffer);
59 ops->fontbuffer = dst;
60 }
61
62 dst = ops->fontbuffer;
63 memset(dst, 0, ops->fd_size);
64
65 switch (ops->rotate) {
66 case FB_ROTATE_UD:
67 for (i = len; i--; ) {
68 rotate_ud(src, dst, vc->vc_font.width,
69 vc->vc_font.height);
70
71 src += s_cellsize;
72 dst += d_cellsize;
73 }
74 break;
75 case FB_ROTATE_CW:
76 for (i = len; i--; ) {
77 rotate_cw(src, dst, vc->vc_font.width,
78 vc->vc_font.height);
79 src += s_cellsize;
80 dst += d_cellsize;
81 }
82 break;
83 case FB_ROTATE_CCW:
84 for (i = len; i--; ) {
85 rotate_ccw(src, dst, vc->vc_font.width,
86 vc->vc_font.height);
87 src += s_cellsize;
88 dst += d_cellsize;
89 }
90 break;
91 }
92
93finished:
94 return err;
95}
96
97void fbcon_set_rotate(struct fbcon_ops *ops)
98{
99 ops->rotate_font = fbcon_rotate_font;
100
101 switch(ops->rotate) {
102 case FB_ROTATE_CW:
103 fbcon_rotate_cw(ops);
104 break;
105 case FB_ROTATE_UD:
106 fbcon_rotate_ud(ops);
107 break;
108 case FB_ROTATE_CCW:
109 fbcon_rotate_ccw(ops);
110 break;
111 }
112}
113EXPORT_SYMBOL(fbcon_set_rotate);
114
115MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
116MODULE_DESCRIPTION("Console Rotation Support");
117MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/console/fbcon_rotate.h
new file mode 100644
index 000000000000..90c672096c2e
--- /dev/null
+++ b/drivers/video/console/fbcon_rotate.h
@@ -0,0 +1,105 @@
1/*
2 * linux/drivers/video/console/fbcon_rotate.h -- Software Display Rotation
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas@pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#ifndef _FBCON_ROTATE_H
12#define _FBCON_ROTATE_H
13
14#define FNTCHARCNT(fd) (((int *)(fd))[-3])
15
16#define GETVYRES(s,i) ({ \
17 (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
18 (i)->var.yres : (i)->var.yres_virtual; })
19
20#define GETVXRES(s,i) ({ \
21 (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
22 (i)->var.xres : (i)->var.xres_virtual; })
23
24/*
25 * The bitmap is always big endian
26 */
27#if defined(__LITTLE_ENDIAN)
28#define FBCON_BIT(b) (7 - (b))
29#else
30#define FBCON_BIT(b) (b)
31#endif
32
33static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
34{
35 u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
36
37 pat +=index;
38 return (test_bit(FBCON_BIT(bit), (void *)pat));
39}
40
41static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
42{
43 u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
44
45 pat += index;
46 set_bit(FBCON_BIT(bit), (void *)pat);
47}
48
49static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
50{
51 int i, j;
52 int shift = width % 8;
53
54 width = (width + 7) & ~7;
55
56 for (i = 0; i < height; i++) {
57 for (j = 0; j < width; j++) {
58 if (pattern_test_bit(j, i, width, in))
59 pattern_set_bit(width - (1 + j + shift),
60 height - (1 + i),
61 width, out);
62 }
63
64 }
65}
66
67static inline void rotate_cw(const char *in, char *out, u32 width, u32 height)
68{
69 int i, j, h = height, w = width;
70 int shift = (8 - (height % 8)) & 7;
71
72 width = (width + 7) & ~7;
73 height = (height + 7) & ~7;
74
75 for (i = 0; i < h; i++) {
76 for (j = 0; j < w; j++) {
77 if (pattern_test_bit(j, i, width, in))
78 pattern_set_bit(height - 1 - i - shift, j,
79 height, out);
80
81 }
82 }
83}
84
85static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height)
86{
87 int i, j, h = height, w = width;
88 int shift = width % 8;
89
90 width = (width + 7) & ~7;
91 height = (height + 7) & ~7;
92
93 for (i = 0; i < h; i++) {
94 for (j = 0; j < w; j++) {
95 if (pattern_test_bit(j, i, width, in))
96 pattern_set_bit(i, width - 1 - j - shift,
97 height, out);
98 }
99 }
100}
101
102extern void fbcon_rotate_cw(struct fbcon_ops *ops);
103extern void fbcon_rotate_ud(struct fbcon_ops *ops);
104extern void fbcon_rotate_ccw(struct fbcon_ops *ops);
105#endif
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
new file mode 100644
index 000000000000..2e1d9d4249cd
--- /dev/null
+++ b/drivers/video/console/fbcon_ud.c
@@ -0,0 +1,454 @@
1/*
2 * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 180 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 180 degrees
23 */
24
25static inline void ud_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.width + 7) >> 3;
30 unsigned int cellsize = vc->vc_font.height * width;
31 u8 c;
32
33 offset = offset * width;
34
35 for (i = 0; i < cellsize; i++) {
36 c = src[i];
37 if (attribute & FBCON_ATTRIBUTE_UNDERLINE && i < offset)
38 c = 0xff;
39 if (attribute & FBCON_ATTRIBUTE_BOLD)
40 c |= c << 1;
41 if (attribute & FBCON_ATTRIBUTE_REVERSE)
42 c = ~c;
43 dst[i] = c;
44 }
45}
46
47
48static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
49 int sx, int dy, int dx, int height, int width)
50{
51 struct display *p = &fb_display[vc->vc_num];
52 struct fb_copyarea area;
53 u32 vyres = GETVYRES(p->scrollmode, info);
54 u32 vxres = GETVXRES(p->scrollmode, info);
55
56 area.sy = vyres - ((sy + height) * vc->vc_font.height);
57 area.sx = vxres - ((sx + width) * vc->vc_font.width);
58 area.dy = vyres - ((dy + height) * vc->vc_font.height);
59 area.dx = vxres - ((dx + width) * vc->vc_font.width);
60 area.height = height * vc->vc_font.height;
61 area.width = width * vc->vc_font.width;
62
63 info->fbops->fb_copyarea(info, &area);
64}
65
66static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
67 int sx, int height, int width)
68{
69 struct display *p = &fb_display[vc->vc_num];
70 struct fb_fillrect region;
71 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
72 u32 vyres = GETVYRES(p->scrollmode, info);
73 u32 vxres = GETVXRES(p->scrollmode, info);
74
75 region.color = attr_bgcol_ec(bgshift,vc);
76 region.dy = vyres - ((sy + height) * vc->vc_font.height);
77 region.dx = vxres - ((sx + width) * vc->vc_font.width);
78 region.width = width * vc->vc_font.width;
79 region.height = height * vc->vc_font.height;
80 region.rop = ROP_COPY;
81
82 info->fbops->fb_fillrect(info, &region);
83}
84
85static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,
86 const u16 *s, u32 attr, u32 cnt,
87 u32 d_pitch, u32 s_pitch, u32 cellsize,
88 struct fb_image *image, u8 *buf, u8 *dst)
89{
90 struct fbcon_ops *ops = info->fbcon_par;
91 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
92 u32 idx = vc->vc_font.width >> 3;
93 u8 *src;
94
95 while (cnt--) {
96 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
97
98 if (attr) {
99 ud_update_attr(buf, src, attr, vc);
100 src = buf;
101 }
102
103 if (likely(idx == 1))
104 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
105 image->height);
106 else
107 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
108 image->height);
109
110 dst += s_pitch;
111 }
112
113 info->fbops->fb_imageblit(info, image);
114}
115
116static inline void ud_putcs_unaligned(struct vc_data *vc,
117 struct fb_info *info, const u16 *s,
118 u32 attr, u32 cnt, u32 d_pitch,
119 u32 s_pitch, u32 cellsize,
120 struct fb_image *image, u8 *buf,
121 u8 *dst)
122{
123 struct fbcon_ops *ops = info->fbcon_par;
124 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
125 u32 shift_low = 0, mod = vc->vc_font.width % 8;
126 u32 shift_high = 8;
127 u32 idx = vc->vc_font.width >> 3;
128 u8 *src;
129
130 while (cnt--) {
131 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
132
133 if (attr) {
134 ud_update_attr(buf, src, attr, vc);
135 src = buf;
136 }
137
138 fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
139 image->height, shift_high,
140 shift_low, mod);
141 shift_low += mod;
142 dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
143 shift_low &= 7;
144 shift_high = 8 - shift_low;
145 }
146
147 info->fbops->fb_imageblit(info, image);
148
149}
150
151static void ud_putcs(struct vc_data *vc, struct fb_info *info,
152 const unsigned short *s, int count, int yy, int xx,
153 int fg, int bg)
154{
155 struct fb_image image;
156 struct display *p = &fb_display[vc->vc_num];
157 struct fbcon_ops *ops = info->fbcon_par;
158 u32 width = (vc->vc_font.width + 7)/8;
159 u32 cellsize = width * vc->vc_font.height;
160 u32 maxcnt = info->pixmap.size/cellsize;
161 u32 scan_align = info->pixmap.scan_align - 1;
162 u32 buf_align = info->pixmap.buf_align - 1;
163 u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
164 u32 attribute = get_attribute(info, scr_readw(s));
165 u8 *dst, *buf = NULL;
166 u32 vyres = GETVYRES(p->scrollmode, info);
167 u32 vxres = GETVXRES(p->scrollmode, info);
168
169 if (!ops->fontbuffer)
170 return;
171
172 image.fg_color = fg;
173 image.bg_color = bg;
174 image.dy = vyres - ((yy * vc->vc_font.height) + vc->vc_font.height);
175 image.dx = vxres - ((xx + count) * vc->vc_font.width);
176 image.height = vc->vc_font.height;
177 image.depth = 1;
178
179 if (attribute) {
180 buf = kmalloc(cellsize, GFP_KERNEL);
181 if (!buf)
182 return;
183 }
184
185 s += count - 1;
186
187 while (count) {
188 if (count > maxcnt)
189 cnt = maxcnt;
190 else
191 cnt = count;
192
193 image.width = vc->vc_font.width * cnt;
194 pitch = ((image.width + 7) >> 3) + scan_align;
195 pitch &= ~scan_align;
196 size = pitch * image.height + buf_align;
197 size &= ~buf_align;
198 dst = fb_get_buffer_offset(info, &info->pixmap, size);
199 image.data = dst;
200
201 if (!mod)
202 ud_putcs_aligned(vc, info, s, attribute, cnt, pitch,
203 width, cellsize, &image, buf, dst);
204 else
205 ud_putcs_unaligned(vc, info, s, attribute, cnt, pitch,
206 width, cellsize, &image,
207 buf, dst);
208
209 image.dx += image.width;
210 count -= cnt;
211 s -= cnt;
212 xx += cnt;
213 }
214
215 /* buf is always NULL except when in monochrome mode, so in this case
216 it's a gain to check buf against NULL even though kfree() handles
217 NULL pointers just fine */
218 if (unlikely(buf))
219 kfree(buf);
220
221}
222
223static void ud_clear_margins(struct vc_data *vc, struct fb_info *info,
224 int bottom_only)
225{
226 unsigned int cw = vc->vc_font.width;
227 unsigned int ch = vc->vc_font.height;
228 unsigned int rw = info->var.xres - (vc->vc_cols*cw);
229 unsigned int bh = info->var.yres - (vc->vc_rows*ch);
230 struct fb_fillrect region;
231 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
232
233 region.color = attr_bgcol_ec(bgshift,vc);
234 region.rop = ROP_COPY;
235
236 if (rw && !bottom_only) {
237 region.dy = 0;
238 region.dx = info->var.xoffset;
239 region.width = rw;
240 region.height = info->var.yres_virtual;
241 info->fbops->fb_fillrect(info, &region);
242 }
243
244 if (bh) {
245 region.dy = info->var.yoffset;
246 region.dx = info->var.xoffset;
247 region.height = bh;
248 region.width = info->var.xres;
249 info->fbops->fb_fillrect(info, &region);
250 }
251}
252
253static void ud_cursor(struct vc_data *vc, struct fb_info *info,
254 struct display *p, int mode, int softback_lines,
255 int fg, int bg)
256{
257 struct fb_cursor cursor;
258 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
259 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
260 int w = (vc->vc_font.width + 7) >> 3, c;
261 int y = real_y(p, vc->vc_y);
262 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
263 int err = 1, dx, dy;
264 char *src;
265 u32 vyres = GETVYRES(p->scrollmode, info);
266 u32 vxres = GETVXRES(p->scrollmode, info);
267
268 if (!ops->fontbuffer)
269 return;
270
271 cursor.set = 0;
272
273 if (softback_lines) {
274 if (y + softback_lines >= vc->vc_rows) {
275 mode = CM_ERASE;
276 ops->cursor_flash = 0;
277 return;
278 } else
279 y += softback_lines;
280 }
281
282 c = scr_readw((u16 *) vc->vc_pos);
283 attribute = get_attribute(info, c);
284 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
285
286 if (ops->cursor_state.image.data != src ||
287 ops->cursor_reset) {
288 ops->cursor_state.image.data = src;
289 cursor.set |= FB_CUR_SETIMAGE;
290 }
291
292 if (attribute) {
293 u8 *dst;
294
295 dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC);
296 if (!dst)
297 return;
298 kfree(ops->cursor_data);
299 ops->cursor_data = dst;
300 ud_update_attr(dst, src, attribute, vc);
301 src = dst;
302 }
303
304 if (ops->cursor_state.image.fg_color != fg ||
305 ops->cursor_state.image.bg_color != bg ||
306 ops->cursor_reset) {
307 ops->cursor_state.image.fg_color = fg;
308 ops->cursor_state.image.bg_color = bg;
309 cursor.set |= FB_CUR_SETCMAP;
310 }
311
312 if (ops->cursor_state.image.height != vc->vc_font.height ||
313 ops->cursor_state.image.width != vc->vc_font.width ||
314 ops->cursor_reset) {
315 ops->cursor_state.image.height = vc->vc_font.height;
316 ops->cursor_state.image.width = vc->vc_font.width;
317 cursor.set |= FB_CUR_SETSIZE;
318 }
319
320 dy = vyres - ((y * vc->vc_font.height) + vc->vc_font.height);
321 dx = vxres - ((vc->vc_x * vc->vc_font.width) + vc->vc_font.width);
322
323 if (ops->cursor_state.image.dx != dx ||
324 ops->cursor_state.image.dy != dy ||
325 ops->cursor_reset) {
326 ops->cursor_state.image.dx = dx;
327 ops->cursor_state.image.dy = dy;
328 cursor.set |= FB_CUR_SETPOS;
329 }
330
331 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
332 ops->cursor_reset) {
333 ops->cursor_state.hot.x = cursor.hot.y = 0;
334 cursor.set |= FB_CUR_SETHOT;
335 }
336
337 if (cursor.set & FB_CUR_SETSIZE ||
338 vc->vc_cursor_type != p->cursor_shape ||
339 ops->cursor_state.mask == NULL ||
340 ops->cursor_reset) {
341 char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
342 int cur_height, size, i = 0;
343 u8 msk = 0xff;
344
345 if (!mask)
346 return;
347
348 kfree(ops->cursor_state.mask);
349 ops->cursor_state.mask = mask;
350
351 p->cursor_shape = vc->vc_cursor_type;
352 cursor.set |= FB_CUR_SETSHAPE;
353
354 switch (p->cursor_shape & CUR_HWMASK) {
355 case CUR_NONE:
356 cur_height = 0;
357 break;
358 case CUR_UNDERLINE:
359 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
360 break;
361 case CUR_LOWER_THIRD:
362 cur_height = vc->vc_font.height/3;
363 break;
364 case CUR_LOWER_HALF:
365 cur_height = vc->vc_font.height >> 1;
366 break;
367 case CUR_TWO_THIRDS:
368 cur_height = (vc->vc_font.height << 1)/3;
369 break;
370 case CUR_BLOCK:
371 default:
372 cur_height = vc->vc_font.height;
373 break;
374 }
375
376 size = cur_height * w;
377
378 while (size--)
379 mask[i++] = msk;
380
381 size = (vc->vc_font.height - cur_height) * w;
382
383 while (size--)
384 mask[i++] = ~msk;
385 }
386
387 switch (mode) {
388 case CM_ERASE:
389 ops->cursor_state.enable = 0;
390 break;
391 case CM_DRAW:
392 case CM_MOVE:
393 default:
394 ops->cursor_state.enable = (use_sw) ? 0 : 1;
395 break;
396 }
397
398 cursor.image.data = src;
399 cursor.image.fg_color = ops->cursor_state.image.fg_color;
400 cursor.image.bg_color = ops->cursor_state.image.bg_color;
401 cursor.image.dx = ops->cursor_state.image.dx;
402 cursor.image.dy = ops->cursor_state.image.dy;
403 cursor.image.height = ops->cursor_state.image.height;
404 cursor.image.width = ops->cursor_state.image.width;
405 cursor.hot.x = ops->cursor_state.hot.x;
406 cursor.hot.y = ops->cursor_state.hot.y;
407 cursor.mask = ops->cursor_state.mask;
408 cursor.enable = ops->cursor_state.enable;
409 cursor.image.depth = 1;
410 cursor.rop = ROP_XOR;
411
412 if (info->fbops->fb_cursor)
413 err = info->fbops->fb_cursor(info, &cursor);
414
415 if (err)
416 soft_cursor(info, &cursor);
417
418 ops->cursor_reset = 0;
419}
420
421int ud_update_start(struct fb_info *info)
422{
423 struct fbcon_ops *ops = info->fbcon_par;
424 struct display *p = &fb_display[ops->currcon];
425 u32 xoffset, yoffset;
426 u32 vyres = GETVYRES(p->scrollmode, info);
427 u32 vxres = GETVXRES(p->scrollmode, info);
428 int err;
429
430 xoffset = (vxres - info->var.xres) - ops->var.xoffset;
431 yoffset = (vyres - info->var.yres) - ops->var.yoffset;
432 ops->var.xoffset = xoffset;
433 ops->var.yoffset = yoffset;
434 err = fb_pan_display(info, &ops->var);
435 ops->var.xoffset = info->var.xoffset;
436 ops->var.yoffset = info->var.yoffset;
437 ops->var.vmode = info->var.vmode;
438 return err;
439}
440
441void fbcon_rotate_ud(struct fbcon_ops *ops)
442{
443 ops->bmove = ud_bmove;
444 ops->clear = ud_clear;
445 ops->putcs = ud_putcs;
446 ops->clear_margins = ud_clear_margins;
447 ops->cursor = ud_cursor;
448 ops->update_start = ud_update_start;
449}
450EXPORT_SYMBOL(fbcon_rotate_ud);
451
452MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
453MODULE_DESCRIPTION("Console Rotation (180 degrees) Support");
454MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index 7f76e2c6a4a1..cb25324a5635 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -118,6 +118,18 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info,
118 info->tileops->fb_tilecursor(info, &cursor); 118 info->tileops->fb_tilecursor(info, &cursor);
119} 119}
120 120
121static int tile_update_start(struct fb_info *info)
122{
123 struct fbcon_ops *ops = info->fbcon_par;
124 int err;
125
126 err = fb_pan_display(info, &ops->var);
127 ops->var.xoffset = info->var.xoffset;
128 ops->var.yoffset = info->var.yoffset;
129 ops->var.vmode = info->var.vmode;
130 return err;
131}
132
121void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, 133void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
122 struct display *p, struct fbcon_ops *ops) 134 struct display *p, struct fbcon_ops *ops)
123{ 135{
@@ -128,6 +140,7 @@ void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
128 ops->putcs = tile_putcs; 140 ops->putcs = tile_putcs;
129 ops->clear_margins = tile_clear_margins; 141 ops->clear_margins = tile_clear_margins;
130 ops->cursor = tile_cursor; 142 ops->cursor = tile_cursor;
143 ops->update_start = tile_update_start;
131 144
132 if (p) { 145 if (p) {
133 map.width = vc->vc_font.width; 146 map.width = vc->vc_font.width;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index e2667ddab3f1..9f180096c896 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -14,6 +14,7 @@
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/module.h> 15#include <linux/module.h>
16 16
17#include <linux/compat.h>
17#include <linux/types.h> 18#include <linux/types.h>
18#include <linux/errno.h> 19#include <linux/errno.h>
19#include <linux/sched.h> 20#include <linux/sched.h>
@@ -323,9 +324,103 @@ static struct logo_data {
323 const struct linux_logo *logo; 324 const struct linux_logo *logo;
324} fb_logo; 325} fb_logo;
325 326
326int fb_prepare_logo(struct fb_info *info) 327static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
328{
329 u32 size = width * height, i;
330
331 out += size - 1;
332
333 for (i = size; i--; )
334 *out-- = *in++;
335}
336
337static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height)
338{
339 int i, j, w = width - 1;
340
341 for (i = 0; i < height; i++)
342 for (j = 0; j < width; j++)
343 out[height * j + w - i] = *in++;
344}
345
346static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height)
347{
348 int i, j, w = width - 1;
349
350 for (i = 0; i < height; i++)
351 for (j = 0; j < width; j++)
352 out[height * (w - j) + i] = *in++;
353}
354
355static void fb_rotate_logo(struct fb_info *info, u8 *dst,
356 struct fb_image *image, int rotate)
357{
358 u32 tmp;
359
360 if (rotate == FB_ROTATE_UD) {
361 image->dx = info->var.xres - image->width;
362 image->dy = info->var.yres - image->height;
363 fb_rotate_logo_ud(image->data, dst, image->width,
364 image->height);
365 } else if (rotate == FB_ROTATE_CW) {
366 tmp = image->width;
367 image->width = image->height;
368 image->height = tmp;
369 image->dx = info->var.xres - image->height;
370 fb_rotate_logo_cw(image->data, dst, image->width,
371 image->height);
372 } else if (rotate == FB_ROTATE_CCW) {
373 tmp = image->width;
374 image->width = image->height;
375 image->height = tmp;
376 image->dy = info->var.yres - image->width;
377 fb_rotate_logo_ccw(image->data, dst, image->width,
378 image->height);
379 }
380
381 image->data = dst;
382}
383
384static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
385 int rotate)
386{
387 int x;
388
389 if (rotate == FB_ROTATE_UR) {
390 for (x = 0; x < num_online_cpus() &&
391 x * (fb_logo.logo->width + 8) <=
392 info->var.xres - fb_logo.logo->width; x++) {
393 info->fbops->fb_imageblit(info, image);
394 image->dx += fb_logo.logo->width + 8;
395 }
396 } else if (rotate == FB_ROTATE_UD) {
397 for (x = 0; x < num_online_cpus() &&
398 x * (fb_logo.logo->width + 8) <=
399 info->var.xres - fb_logo.logo->width; x++) {
400 info->fbops->fb_imageblit(info, image);
401 image->dx -= fb_logo.logo->width + 8;
402 }
403 } else if (rotate == FB_ROTATE_CW) {
404 for (x = 0; x < num_online_cpus() &&
405 x * (fb_logo.logo->width + 8) <=
406 info->var.yres - fb_logo.logo->width; x++) {
407 info->fbops->fb_imageblit(info, image);
408 image->dy += fb_logo.logo->width + 8;
409 }
410 } else if (rotate == FB_ROTATE_CCW) {
411 for (x = 0; x < num_online_cpus() &&
412 x * (fb_logo.logo->width + 8) <=
413 info->var.yres - fb_logo.logo->width; x++) {
414 info->fbops->fb_imageblit(info, image);
415 image->dy -= fb_logo.logo->width + 8;
416 }
417 }
418}
419
420int fb_prepare_logo(struct fb_info *info, int rotate)
327{ 421{
328 int depth = fb_get_color_depth(&info->var, &info->fix); 422 int depth = fb_get_color_depth(&info->var, &info->fix);
423 int yres;
329 424
330 memset(&fb_logo, 0, sizeof(struct logo_data)); 425 memset(&fb_logo, 0, sizeof(struct logo_data));
331 426
@@ -358,10 +453,16 @@ int fb_prepare_logo(struct fb_info *info)
358 /* Return if no suitable logo was found */ 453 /* Return if no suitable logo was found */
359 fb_logo.logo = fb_find_logo(depth); 454 fb_logo.logo = fb_find_logo(depth);
360 455
361 if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) { 456 if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD)
457 yres = info->var.yres;
458 else
459 yres = info->var.xres;
460
461 if (fb_logo.logo && fb_logo.logo->height > yres) {
362 fb_logo.logo = NULL; 462 fb_logo.logo = NULL;
363 return 0; 463 return 0;
364 } 464 }
465
365 /* What depth we asked for might be different from what we get */ 466 /* What depth we asked for might be different from what we get */
366 if (fb_logo.logo->type == LINUX_LOGO_CLUT224) 467 if (fb_logo.logo->type == LINUX_LOGO_CLUT224)
367 fb_logo.depth = 8; 468 fb_logo.depth = 8;
@@ -372,12 +473,11 @@ int fb_prepare_logo(struct fb_info *info)
372 return fb_logo.logo->height; 473 return fb_logo.logo->height;
373} 474}
374 475
375int fb_show_logo(struct fb_info *info) 476int fb_show_logo(struct fb_info *info, int rotate)
376{ 477{
377 u32 *palette = NULL, *saved_pseudo_palette = NULL; 478 u32 *palette = NULL, *saved_pseudo_palette = NULL;
378 unsigned char *logo_new = NULL; 479 unsigned char *logo_new = NULL, *logo_rotate = NULL;
379 struct fb_image image; 480 struct fb_image image;
380 int x;
381 481
382 /* Return if the frame buffer is not mapped or suspended */ 482 /* Return if the frame buffer is not mapped or suspended */
383 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING) 483 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
@@ -417,25 +517,30 @@ int fb_show_logo(struct fb_info *info)
417 fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth); 517 fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth);
418 } 518 }
419 519
520 image.dx = 0;
521 image.dy = 0;
420 image.width = fb_logo.logo->width; 522 image.width = fb_logo.logo->width;
421 image.height = fb_logo.logo->height; 523 image.height = fb_logo.logo->height;
422 image.dy = 0;
423 524
424 for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) && 525 if (rotate) {
425 x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) { 526 logo_rotate = kmalloc(fb_logo.logo->width *
426 image.dx = x; 527 fb_logo.logo->height, GFP_KERNEL);
427 info->fbops->fb_imageblit(info, &image); 528 if (logo_rotate)
529 fb_rotate_logo(info, logo_rotate, &image, rotate);
428 } 530 }
429 531
532 fb_do_show_logo(info, &image, rotate);
533
430 kfree(palette); 534 kfree(palette);
431 if (saved_pseudo_palette != NULL) 535 if (saved_pseudo_palette != NULL)
432 info->pseudo_palette = saved_pseudo_palette; 536 info->pseudo_palette = saved_pseudo_palette;
433 kfree(logo_new); 537 kfree(logo_new);
538 kfree(logo_rotate);
434 return fb_logo.logo->height; 539 return fb_logo.logo->height;
435} 540}
436#else 541#else
437int fb_prepare_logo(struct fb_info *info) { return 0; } 542int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }
438int fb_show_logo(struct fb_info *info) { return 0; } 543int fb_show_logo(struct fb_info *info, int rotate) { return 0; }
439#endif /* CONFIG_LOGO */ 544#endif /* CONFIG_LOGO */
440 545
441static int fbmem_read_proc(char *buf, char **start, off_t offset, 546static int fbmem_read_proc(char *buf, char **start, off_t offset,
@@ -829,18 +934,154 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
829} 934}
830 935
831#ifdef CONFIG_COMPAT 936#ifdef CONFIG_COMPAT
937struct fb_fix_screeninfo32 {
938 char id[16];
939 compat_caddr_t smem_start;
940 u32 smem_len;
941 u32 type;
942 u32 type_aux;
943 u32 visual;
944 u16 xpanstep;
945 u16 ypanstep;
946 u16 ywrapstep;
947 u32 line_length;
948 compat_caddr_t mmio_start;
949 u32 mmio_len;
950 u32 accel;
951 u16 reserved[3];
952};
953
954struct fb_cmap32 {
955 u32 start;
956 u32 len;
957 compat_caddr_t red;
958 compat_caddr_t green;
959 compat_caddr_t blue;
960 compat_caddr_t transp;
961};
962
963static int fb_getput_cmap(struct inode *inode, struct file *file,
964 unsigned int cmd, unsigned long arg)
965{
966 struct fb_cmap_user __user *cmap;
967 struct fb_cmap32 __user *cmap32;
968 __u32 data;
969 int err;
970
971 cmap = compat_alloc_user_space(sizeof(*cmap));
972 cmap32 = compat_ptr(arg);
973
974 if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
975 return -EFAULT;
976
977 if (get_user(data, &cmap32->red) ||
978 put_user(compat_ptr(data), &cmap->red) ||
979 get_user(data, &cmap32->green) ||
980 put_user(compat_ptr(data), &cmap->green) ||
981 get_user(data, &cmap32->blue) ||
982 put_user(compat_ptr(data), &cmap->blue) ||
983 get_user(data, &cmap32->transp) ||
984 put_user(compat_ptr(data), &cmap->transp))
985 return -EFAULT;
986
987 err = fb_ioctl(inode, file, cmd, (unsigned long) cmap);
988
989 if (!err) {
990 if (copy_in_user(&cmap32->start,
991 &cmap->start,
992 2 * sizeof(__u32)))
993 err = -EFAULT;
994 }
995 return err;
996}
997
998static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
999 struct fb_fix_screeninfo32 __user *fix32)
1000{
1001 __u32 data;
1002 int err;
1003
1004 err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id));
1005
1006 data = (__u32) (unsigned long) fix->smem_start;
1007 err |= put_user(data, &fix32->smem_start);
1008
1009 err |= put_user(fix->smem_len, &fix32->smem_len);
1010 err |= put_user(fix->type, &fix32->type);
1011 err |= put_user(fix->type_aux, &fix32->type_aux);
1012 err |= put_user(fix->visual, &fix32->visual);
1013 err |= put_user(fix->xpanstep, &fix32->xpanstep);
1014 err |= put_user(fix->ypanstep, &fix32->ypanstep);
1015 err |= put_user(fix->ywrapstep, &fix32->ywrapstep);
1016 err |= put_user(fix->line_length, &fix32->line_length);
1017
1018 data = (__u32) (unsigned long) fix->mmio_start;
1019 err |= put_user(data, &fix32->mmio_start);
1020
1021 err |= put_user(fix->mmio_len, &fix32->mmio_len);
1022 err |= put_user(fix->accel, &fix32->accel);
1023 err |= copy_to_user(fix32->reserved, fix->reserved,
1024 sizeof(fix->reserved));
1025
1026 return err;
1027}
1028
1029static int fb_get_fscreeninfo(struct inode *inode, struct file *file,
1030 unsigned int cmd, unsigned long arg)
1031{
1032 mm_segment_t old_fs;
1033 struct fb_fix_screeninfo fix;
1034 struct fb_fix_screeninfo32 __user *fix32;
1035 int err;
1036
1037 fix32 = compat_ptr(arg);
1038
1039 old_fs = get_fs();
1040 set_fs(KERNEL_DS);
1041 err = fb_ioctl(inode, file, cmd, (unsigned long) &fix);
1042 set_fs(old_fs);
1043
1044 if (!err)
1045 err = do_fscreeninfo_to_user(&fix, fix32);
1046
1047 return err;
1048}
1049
832static long 1050static long
833fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1051fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
834{ 1052{
835 int fbidx = iminor(file->f_dentry->d_inode); 1053 struct inode *inode = file->f_dentry->d_inode;
1054 int fbidx = iminor(inode);
836 struct fb_info *info = registered_fb[fbidx]; 1055 struct fb_info *info = registered_fb[fbidx];
837 struct fb_ops *fb = info->fbops; 1056 struct fb_ops *fb = info->fbops;
838 long ret; 1057 long ret = -ENOIOCTLCMD;
839 1058
840 if (fb->fb_compat_ioctl == NULL)
841 return -ENOIOCTLCMD;
842 lock_kernel(); 1059 lock_kernel();
843 ret = fb->fb_compat_ioctl(file, cmd, arg, info); 1060 switch(cmd) {
1061 case FBIOGET_VSCREENINFO:
1062 case FBIOPUT_VSCREENINFO:
1063 case FBIOPAN_DISPLAY:
1064 case FBIOGET_CON2FBMAP:
1065 case FBIOPUT_CON2FBMAP:
1066 arg = (unsigned long) compat_ptr(arg);
1067 case FBIOBLANK:
1068 ret = fb_ioctl(inode, file, cmd, arg);
1069 break;
1070
1071 case FBIOGET_FSCREENINFO:
1072 ret = fb_get_fscreeninfo(inode, file, cmd, arg);
1073 break;
1074
1075 case FBIOGETCMAP:
1076 case FBIOPUTCMAP:
1077 ret = fb_getput_cmap(inode, file, cmd, arg);
1078 break;
1079
1080 default:
1081 if (fb->fb_compat_ioctl)
1082 ret = fb->fb_compat_ioctl(file, cmd, arg, info);
1083 break;
1084 }
844 unlock_kernel(); 1085 unlock_kernel();
845 return ret; 1086 return ret;
846} 1087}
@@ -1215,6 +1456,28 @@ int fb_new_modelist(struct fb_info *info)
1215 return err; 1456 return err;
1216} 1457}
1217 1458
1459/**
1460 * fb_con_duit - user<->fbcon passthrough
1461 * @info: struct fb_info
1462 * @event: notification event to be passed to fbcon
1463 * @data: private data
1464 *
1465 * DESCRIPTION
1466 * This function is an fbcon-user event passing channel
1467 * which bypasses fbdev. This is hopefully temporary
1468 * until a user interface for fbcon is created
1469 */
1470int fb_con_duit(struct fb_info *info, int event, void *data)
1471{
1472 struct fb_event evnt;
1473
1474 evnt.info = info;
1475 evnt.data = data;
1476
1477 return notifier_call_chain(&fb_notifier_list, event, &evnt);
1478}
1479EXPORT_SYMBOL(fb_con_duit);
1480
1218static char *video_options[FB_MAX]; 1481static char *video_options[FB_MAX];
1219static int ofonly; 1482static int ofonly;
1220 1483
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 007c8e9b2b39..08dac9580d15 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -213,6 +213,70 @@ static ssize_t show_bpp(struct class_device *class_device, char *buf)
213 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); 213 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel);
214} 214}
215 215
216static ssize_t store_rotate(struct class_device *class_device, const char *buf,
217 size_t count)
218{
219 struct fb_info *fb_info = class_get_devdata(class_device);
220 struct fb_var_screeninfo var;
221 char **last = NULL;
222 int err;
223
224 var = fb_info->var;
225 var.rotate = simple_strtoul(buf, last, 0);
226
227 if ((err = activate(fb_info, &var)))
228 return err;
229
230 return count;
231}
232
233
234static ssize_t show_rotate(struct class_device *class_device, char *buf)
235{
236 struct fb_info *fb_info = class_get_devdata(class_device);
237
238 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate);
239}
240
241static ssize_t store_con_rotate(struct class_device *class_device,
242 const char *buf, size_t count)
243{
244 struct fb_info *fb_info = class_get_devdata(class_device);
245 int rotate;
246 char **last = NULL;
247
248 acquire_console_sem();
249 rotate = simple_strtoul(buf, last, 0);
250 fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE, &rotate);
251 release_console_sem();
252 return count;
253}
254
255static ssize_t store_con_rotate_all(struct class_device *class_device,
256 const char *buf, size_t count)
257{
258 struct fb_info *fb_info = class_get_devdata(class_device);
259 int rotate;
260 char **last = NULL;
261
262 acquire_console_sem();
263 rotate = simple_strtoul(buf, last, 0);
264 fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE_ALL, &rotate);
265 release_console_sem();
266 return count;
267}
268
269static ssize_t show_con_rotate(struct class_device *class_device, char *buf)
270{
271 struct fb_info *fb_info = class_get_devdata(class_device);
272 int rotate;
273
274 acquire_console_sem();
275 rotate = fb_con_duit(fb_info, FB_EVENT_GET_CON_ROTATE, NULL);
276 release_console_sem();
277 return snprintf(buf, PAGE_SIZE, "%d\n", rotate);
278}
279
216static ssize_t store_virtual(struct class_device *class_device, 280static ssize_t store_virtual(struct class_device *class_device,
217 const char * buf, size_t count) 281 const char * buf, size_t count)
218{ 282{
@@ -440,6 +504,9 @@ static struct class_device_attribute class_device_attrs[] = {
440 __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual), 504 __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
441 __ATTR(name, S_IRUGO, show_name, NULL), 505 __ATTR(name, S_IRUGO, show_name, NULL),
442 __ATTR(stride, S_IRUGO, show_stride, NULL), 506 __ATTR(stride, S_IRUGO, show_stride, NULL),
507 __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
508 __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate),
509 __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all),
443}; 510};
444 511
445int fb_init_class_device(struct fb_info *fb_info) 512int fb_init_class_device(struct fb_info *fb_info)
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 0799b999b314..427689e584da 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -122,7 +122,6 @@
122#include <linux/pci.h> 122#include <linux/pci.h>
123#include <linux/vmalloc.h> 123#include <linux/vmalloc.h>
124#include <linux/pagemap.h> 124#include <linux/pagemap.h>
125#include <linux/version.h>
126 125
127#include <asm/io.h> 126#include <asm/io.h>
128 127
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index ac94c2e5ff85..624c4bc96f0d 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -34,7 +34,6 @@
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/vmalloc.h> 35#include <linux/vmalloc.h>
36#include <linux/pagemap.h> 36#include <linux/pagemap.h>
37#include <linux/version.h>
38 37
39#include <asm/io.h> 38#include <asm/io.h>
40 39
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 1789a52d776a..1da2f84bdc25 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -251,6 +251,10 @@ static const struct fb_videomode modedb[] = {
251 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, 251 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
253 FB_VMODE_NONINTERLACED 253 FB_VMODE_NONINTERLACED
254 }, {
255 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
256 NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
257 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
254 }, 258 },
255}; 259};
256 260
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index f0dfb35e3191..09e2f2841901 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1315,10 +1315,14 @@ static void savagefb_set_fix(struct fb_info *info)
1315 info->fix.line_length = info->var.xres_virtual * 1315 info->fix.line_length = info->var.xres_virtual *
1316 info->var.bits_per_pixel / 8; 1316 info->var.bits_per_pixel / 8;
1317 1317
1318 if (info->var.bits_per_pixel == 8) 1318 if (info->var.bits_per_pixel == 8) {
1319 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 1319 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
1320 else 1320 info->fix.xpanstep = 4;
1321 } else {
1321 info->fix.visual = FB_VISUAL_TRUECOLOR; 1322 info->fix.visual = FB_VISUAL_TRUECOLOR;
1323 info->fix.xpanstep = 2;
1324 }
1325
1322} 1326}
1323 1327
1324#if defined(CONFIG_FB_SAVAGE_ACCEL) 1328#if defined(CONFIG_FB_SAVAGE_ACCEL)
@@ -1363,7 +1367,6 @@ static int savagefb_set_par (struct fb_info *info)
1363 par->minClock = 10000; 1367 par->minClock = 10000;
1364 1368
1365 savagefb_set_par_int (par); 1369 savagefb_set_par_int (par);
1366 savagefb_update_start (par, var);
1367 fb_set_cmap (&info->cmap, info); 1370 fb_set_cmap (&info->cmap, info);
1368 savagefb_set_fix(info); 1371 savagefb_set_fix(info);
1369 savagefb_set_clip(info); 1372 savagefb_set_clip(info);
@@ -1873,7 +1876,6 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
1873 1876
1874 info->fix.type = FB_TYPE_PACKED_PIXELS; 1877 info->fix.type = FB_TYPE_PACKED_PIXELS;
1875 info->fix.type_aux = 0; 1878 info->fix.type_aux = 0;
1876 info->fix.xpanstep = 2;
1877 info->fix.ypanstep = 1; 1879 info->fix.ypanstep = 1;
1878 info->fix.ywrapstep = 0; 1880 info->fix.ywrapstep = 0;
1879 info->fix.accel = id->driver_data; 1881 info->fix.accel = id->driver_data;
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 690bb6fe8281..226ae8a88482 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -21,6 +21,7 @@
21#include <linux/fb.h> 21#include <linux/fb.h>
22#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/platform_device.h>
24 25
25#include <asm/io.h> 26#include <asm/io.h>
26#include <video/vga.h> 27#include <video/vga.h>
@@ -51,35 +52,33 @@
51 * card parameters 52 * card parameters
52 */ 53 */
53 54
54static struct fb_info vga16fb; 55struct vga16fb_par {
55
56static struct vga16fb_par {
57 /* structure holding original VGA register settings when the 56 /* structure holding original VGA register settings when the
58 screen is blanked */ 57 screen is blanked */
59 struct { 58 struct {
60 unsigned char SeqCtrlIndex; /* Sequencer Index reg. */ 59 unsigned char SeqCtrlIndex; /* Sequencer Index reg. */
61 unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */ 60 unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */
62 unsigned char CrtMiscIO; /* Miscellaneous register */ 61 unsigned char CrtMiscIO; /* Miscellaneous register */
63 unsigned char HorizontalTotal; /* CRT-Controller:00h */ 62 unsigned char HorizontalTotal; /* CRT-Controller:00h */
64 unsigned char HorizDisplayEnd; /* CRT-Controller:01h */ 63 unsigned char HorizDisplayEnd; /* CRT-Controller:01h */
65 unsigned char StartHorizRetrace; /* CRT-Controller:04h */ 64 unsigned char StartHorizRetrace;/* CRT-Controller:04h */
66 unsigned char EndHorizRetrace; /* CRT-Controller:05h */ 65 unsigned char EndHorizRetrace; /* CRT-Controller:05h */
67 unsigned char Overflow; /* CRT-Controller:07h */ 66 unsigned char Overflow; /* CRT-Controller:07h */
68 unsigned char StartVertRetrace; /* CRT-Controller:10h */ 67 unsigned char StartVertRetrace; /* CRT-Controller:10h */
69 unsigned char EndVertRetrace; /* CRT-Controller:11h */ 68 unsigned char EndVertRetrace; /* CRT-Controller:11h */
70 unsigned char ModeControl; /* CRT-Controller:17h */ 69 unsigned char ModeControl; /* CRT-Controller:17h */
71 unsigned char ClockingMode; /* Seq-Controller:01h */ 70 unsigned char ClockingMode; /* Seq-Controller:01h */
72 } vga_state; 71 } vga_state;
73 struct vgastate state; 72 struct vgastate state;
74 atomic_t ref_count; 73 atomic_t ref_count;
75 int palette_blanked, vesa_blanked, mode, isVGA; 74 int palette_blanked, vesa_blanked, mode, isVGA;
76 u8 misc, pel_msk, vss, clkdiv; 75 u8 misc, pel_msk, vss, clkdiv;
77 u8 crtc[VGA_CRT_C]; 76 u8 crtc[VGA_CRT_C];
78} vga16_par; 77};
79 78
80/* --------------------------------------------------------------------- */ 79/* --------------------------------------------------------------------- */
81 80
82static struct fb_var_screeninfo vga16fb_defined = { 81static struct fb_var_screeninfo vga16fb_defined __initdata = {
83 .xres = 640, 82 .xres = 640,
84 .yres = 480, 83 .yres = 480,
85 .xres_virtual = 640, 84 .xres_virtual = 640,
@@ -205,7 +204,7 @@ static inline void setindex(int index)
205static void vga16fb_pan_var(struct fb_info *info, 204static void vga16fb_pan_var(struct fb_info *info,
206 struct fb_var_screeninfo *var) 205 struct fb_var_screeninfo *var)
207{ 206{
208 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 207 struct vga16fb_par *par = info->par;
209 u32 xoffset, pos; 208 u32 xoffset, pos;
210 209
211 xoffset = var->xoffset; 210 xoffset = var->xoffset;
@@ -300,7 +299,7 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
300 299
301static int vga16fb_open(struct fb_info *info, int user) 300static int vga16fb_open(struct fb_info *info, int user)
302{ 301{
303 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 302 struct vga16fb_par *par = info->par;
304 int cnt = atomic_read(&par->ref_count); 303 int cnt = atomic_read(&par->ref_count);
305 304
306 if (!cnt) { 305 if (!cnt) {
@@ -315,7 +314,7 @@ static int vga16fb_open(struct fb_info *info, int user)
315 314
316static int vga16fb_release(struct fb_info *info, int user) 315static int vga16fb_release(struct fb_info *info, int user)
317{ 316{
318 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 317 struct vga16fb_par *par = info->par;
319 int cnt = atomic_read(&par->ref_count); 318 int cnt = atomic_read(&par->ref_count);
320 319
321 if (!cnt) 320 if (!cnt)
@@ -330,7 +329,7 @@ static int vga16fb_release(struct fb_info *info, int user)
330static int vga16fb_check_var(struct fb_var_screeninfo *var, 329static int vga16fb_check_var(struct fb_var_screeninfo *var,
331 struct fb_info *info) 330 struct fb_info *info)
332{ 331{
333 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 332 struct vga16fb_par *par = info->par;
334 u32 xres, right, hslen, left, xtotal; 333 u32 xres, right, hslen, left, xtotal;
335 u32 yres, lower, vslen, upper, ytotal; 334 u32 yres, lower, vslen, upper, ytotal;
336 u32 vxres, xoffset, vyres, yoffset; 335 u32 vxres, xoffset, vyres, yoffset;
@@ -535,7 +534,7 @@ static int vga16fb_check_var(struct fb_var_screeninfo *var,
535 534
536static int vga16fb_set_par(struct fb_info *info) 535static int vga16fb_set_par(struct fb_info *info)
537{ 536{
538 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 537 struct vga16fb_par *par = info->par;
539 u8 gdc[VGA_GFX_C]; 538 u8 gdc[VGA_GFX_C];
540 u8 seq[VGA_SEQ_C]; 539 u8 seq[VGA_SEQ_C];
541 u8 atc[VGA_ATT_C]; 540 u8 atc[VGA_ATT_C];
@@ -677,7 +676,7 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
677 unsigned blue, unsigned transp, 676 unsigned blue, unsigned transp,
678 struct fb_info *info) 677 struct fb_info *info)
679{ 678{
680 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 679 struct vga16fb_par *par = info->par;
681 int gray; 680 int gray;
682 681
683 /* 682 /*
@@ -850,7 +849,7 @@ static void vga_pal_blank(void)
850/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ 849/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
851static int vga16fb_blank(int blank, struct fb_info *info) 850static int vga16fb_blank(int blank, struct fb_info *info)
852{ 851{
853 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 852 struct vga16fb_par *par = info->par;
854 853
855 switch (blank) { 854 switch (blank) {
856 case FB_BLANK_UNBLANK: /* Unblank */ 855 case FB_BLANK_UNBLANK: /* Unblank */
@@ -1201,7 +1200,7 @@ static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *im
1201{ 1200{
1202 char __iomem *where = info->screen_base + (image->dx/8) + 1201 char __iomem *where = info->screen_base + (image->dx/8) +
1203 image->dy * info->fix.line_length; 1202 image->dy * info->fix.line_length;
1204 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 1203 struct vga16fb_par *par = info->par;
1205 char *cdat = (char *) image->data; 1204 char *cdat = (char *) image->data;
1206 char __iomem *dst; 1205 char __iomem *dst;
1207 int x, y; 1206 int x, y;
@@ -1266,7 +1265,7 @@ static void vga_imageblit_color(struct fb_info *info, const struct fb_image *ima
1266 /* 1265 /*
1267 * Draw logo 1266 * Draw logo
1268 */ 1267 */
1269 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 1268 struct vga16fb_par *par = info->par;
1270 char __iomem *where = 1269 char __iomem *where =
1271 info->screen_base + image->dy * info->fix.line_length + 1270 info->screen_base + image->dy * info->fix.line_length +
1272 image->dx/8; 1271 image->dx/8;
@@ -1343,89 +1342,141 @@ static int vga16fb_setup(char *options)
1343} 1342}
1344#endif 1343#endif
1345 1344
1346static int __init vga16fb_init(void) 1345static int __init vga16fb_probe(struct device *device)
1347{ 1346{
1347 struct platform_device *dev = to_platform_device(device);
1348 struct fb_info *info;
1349 struct vga16fb_par *par;
1348 int i; 1350 int i;
1349 int ret; 1351 int ret = 0;
1350#ifndef MODULE
1351 char *option = NULL;
1352 1352
1353 if (fb_get_options("vga16fb", &option))
1354 return -ENODEV;
1355
1356 vga16fb_setup(option);
1357#endif
1358 printk(KERN_DEBUG "vga16fb: initializing\n"); 1353 printk(KERN_DEBUG "vga16fb: initializing\n");
1354 info = framebuffer_alloc(sizeof(struct vga16fb_par), &dev->dev);
1355
1356 if (!info) {
1357 ret = -ENOMEM;
1358 goto err_fb_alloc;
1359 }
1359 1360
1360 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */ 1361 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
1362 info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS);
1361 1363
1362 vga16fb.screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS); 1364 if (!info->screen_base) {
1363 if (!vga16fb.screen_base) {
1364 printk(KERN_ERR "vga16fb: unable to map device\n"); 1365 printk(KERN_ERR "vga16fb: unable to map device\n");
1365 ret = -ENOMEM; 1366 ret = -ENOMEM;
1366 goto err_ioremap; 1367 goto err_ioremap;
1367 } 1368 }
1368 printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.screen_base);
1369 1369
1370 vga16_par.isVGA = ORIG_VIDEO_ISVGA; 1370 printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
1371 vga16_par.palette_blanked = 0; 1371 par = info->par;
1372 vga16_par.vesa_blanked = 0;
1373 1372
1374 i = vga16_par.isVGA? 6 : 2; 1373 par->isVGA = ORIG_VIDEO_ISVGA;
1374 par->palette_blanked = 0;
1375 par->vesa_blanked = 0;
1376
1377 i = par->isVGA? 6 : 2;
1375 1378
1376 vga16fb_defined.red.length = i; 1379 vga16fb_defined.red.length = i;
1377 vga16fb_defined.green.length = i; 1380 vga16fb_defined.green.length = i;
1378 vga16fb_defined.blue.length = i; 1381 vga16fb_defined.blue.length = i;
1379 1382
1380 /* name should not depend on EGA/VGA */ 1383 /* name should not depend on EGA/VGA */
1381 vga16fb.fbops = &vga16fb_ops; 1384 info->fbops = &vga16fb_ops;
1382 vga16fb.var = vga16fb_defined; 1385 info->var = vga16fb_defined;
1383 vga16fb.fix = vga16fb_fix; 1386 info->fix = vga16fb_fix;
1384 vga16fb.par = &vga16_par; 1387 info->flags = FBINFO_FLAG_DEFAULT |
1385 vga16fb.flags = FBINFO_FLAG_DEFAULT |
1386 FBINFO_HWACCEL_YPAN; 1388 FBINFO_HWACCEL_YPAN;
1387 1389
1388 i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16; 1390 i = (info->var.bits_per_pixel == 8) ? 256 : 16;
1389 ret = fb_alloc_cmap(&vga16fb.cmap, i, 0); 1391 ret = fb_alloc_cmap(&info->cmap, i, 0);
1390 if (ret) { 1392 if (ret) {
1391 printk(KERN_ERR "vga16fb: unable to allocate colormap\n"); 1393 printk(KERN_ERR "vga16fb: unable to allocate colormap\n");
1392 ret = -ENOMEM; 1394 ret = -ENOMEM;
1393 goto err_alloc_cmap; 1395 goto err_alloc_cmap;
1394 } 1396 }
1395 1397
1396 if (vga16fb_check_var(&vga16fb.var, &vga16fb)) { 1398 if (vga16fb_check_var(&info->var, info)) {
1397 printk(KERN_ERR "vga16fb: unable to validate variable\n"); 1399 printk(KERN_ERR "vga16fb: unable to validate variable\n");
1398 ret = -EINVAL; 1400 ret = -EINVAL;
1399 goto err_check_var; 1401 goto err_check_var;
1400 } 1402 }
1401 1403
1402 vga16fb_update_fix(&vga16fb); 1404 vga16fb_update_fix(info);
1403 1405
1404 if (register_framebuffer(&vga16fb) < 0) { 1406 if (register_framebuffer(info) < 0) {
1405 printk(KERN_ERR "vga16fb: unable to register framebuffer\n"); 1407 printk(KERN_ERR "vga16fb: unable to register framebuffer\n");
1406 ret = -EINVAL; 1408 ret = -EINVAL;
1407 goto err_check_var; 1409 goto err_check_var;
1408 } 1410 }
1409 1411
1410 printk(KERN_INFO "fb%d: %s frame buffer device\n", 1412 printk(KERN_INFO "fb%d: %s frame buffer device\n",
1411 vga16fb.node, vga16fb.fix.id); 1413 info->node, info->fix.id);
1414 dev_set_drvdata(device, info);
1412 1415
1413 return 0; 1416 return 0;
1414 1417
1415 err_check_var: 1418 err_check_var:
1416 fb_dealloc_cmap(&vga16fb.cmap); 1419 fb_dealloc_cmap(&info->cmap);
1417 err_alloc_cmap: 1420 err_alloc_cmap:
1418 iounmap(vga16fb.screen_base); 1421 iounmap(info->screen_base);
1419 err_ioremap: 1422 err_ioremap:
1423 framebuffer_release(info);
1424 err_fb_alloc:
1425 return ret;
1426}
1427
1428static int vga16fb_remove(struct device *device)
1429{
1430 struct fb_info *info = dev_get_drvdata(device);
1431
1432 if (info) {
1433 unregister_framebuffer(info);
1434 iounmap(info->screen_base);
1435 fb_dealloc_cmap(&info->cmap);
1436 /* XXX unshare VGA regions */
1437 framebuffer_release(info);
1438 }
1439
1440 return 0;
1441}
1442
1443static struct device_driver vga16fb_driver = {
1444 .name = "vga16fb",
1445 .bus = &platform_bus_type,
1446 .probe = vga16fb_probe,
1447 .remove = vga16fb_remove,
1448};
1449
1450static struct platform_device vga16fb_device = {
1451 .name = "vga16fb",
1452};
1453
1454static int __init vga16fb_init(void)
1455{
1456 int ret;
1457#ifndef MODULE
1458 char *option = NULL;
1459
1460 if (fb_get_options("vga16fb", &option))
1461 return -ENODEV;
1462
1463 vga16fb_setup(option);
1464#endif
1465 ret = driver_register(&vga16fb_driver);
1466
1467 if (!ret) {
1468 ret = platform_device_register(&vga16fb_device);
1469 if (ret)
1470 driver_unregister(&vga16fb_driver);
1471 }
1472
1420 return ret; 1473 return ret;
1421} 1474}
1422 1475
1423static void __exit vga16fb_exit(void) 1476static void __exit vga16fb_exit(void)
1424{ 1477{
1425 unregister_framebuffer(&vga16fb); 1478 platform_device_unregister(&vga16fb_device);
1426 iounmap(vga16fb.screen_base); 1479 driver_unregister(&vga16fb_driver);
1427 fb_dealloc_cmap(&vga16fb.cmap);
1428 /* XXX unshare VGA regions */
1429} 1480}
1430 1481
1431MODULE_LICENSE("GPL"); 1482MODULE_LICENSE("GPL");
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c
index ca92940f3943..d9e01daee630 100644
--- a/drivers/video/vgastate.c
+++ b/drivers/video/vgastate.c
@@ -485,11 +485,6 @@ int restore_vga (struct vgastate *state)
485 return 0; 485 return 0;
486} 486}
487 487
488#ifdef MODULE
489int init_module(void) { return 0; };
490void cleanup_module(void) {};
491#endif
492
493EXPORT_SYMBOL(save_vga); 488EXPORT_SYMBOL(save_vga);
494EXPORT_SYMBOL(restore_vga); 489EXPORT_SYMBOL(restore_vga);
495 490
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index bbc3cc63854f..89c849da8504 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -32,7 +32,6 @@
32#include <linux/string.h> 32#include <linux/string.h>
33#include <linux/smp_lock.h> 33#include <linux/smp_lock.h>
34#include <linux/inet.h> 34#include <linux/inet.h>
35#include <linux/version.h>
36#include <linux/list.h> 35#include <linux/list.h>
37#include <asm/uaccess.h> 36#include <asm/uaccess.h>
38#include <linux/idr.h> 37#include <linux/idr.h>
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h
index fd528433de43..f6cd01352cc8 100644
--- a/fs/adfs/adfs.h
+++ b/fs/adfs/adfs.h
@@ -12,7 +12,6 @@
12#define ADFS_NDA_PUBLIC_READ (1 << 5) 12#define ADFS_NDA_PUBLIC_READ (1 << 5)
13#define ADFS_NDA_PUBLIC_WRITE (1 << 6) 13#define ADFS_NDA_PUBLIC_WRITE (1 << 6)
14 14
15#include <linux/version.h>
16#include "dir_f.h" 15#include "dir_f.h"
17 16
18struct buffer_head; 17struct buffer_head;
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 8ae0db6cd69c..2568eb41cb3a 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -150,7 +150,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
150 150
151 /* if the binary is not readable than enforce mm->dumpable=0 151 /* if the binary is not readable than enforce mm->dumpable=0
152 regardless of the interpreter's permissions */ 152 regardless of the interpreter's permissions */
153 if (permission(bprm->file->f_dentry->d_inode, MAY_READ, NULL)) 153 if (file_permission(bprm->file, MAY_READ))
154 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; 154 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
155 155
156 allow_write_access(bprm->file); 156 allow_write_access(bprm->file);
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 4909754ea84a..26300fccb4fc 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -840,146 +840,6 @@ static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
840 return err ? -EFAULT : 0; 840 return err ? -EFAULT : 0;
841} 841}
842 842
843struct fb_fix_screeninfo32 {
844 char id[16];
845 compat_caddr_t smem_start;
846 u32 smem_len;
847 u32 type;
848 u32 type_aux;
849 u32 visual;
850 u16 xpanstep;
851 u16 ypanstep;
852 u16 ywrapstep;
853 u32 line_length;
854 compat_caddr_t mmio_start;
855 u32 mmio_len;
856 u32 accel;
857 u16 reserved[3];
858};
859
860struct fb_cmap32 {
861 u32 start;
862 u32 len;
863 compat_caddr_t red;
864 compat_caddr_t green;
865 compat_caddr_t blue;
866 compat_caddr_t transp;
867};
868
869static int fb_getput_cmap(unsigned int fd, unsigned int cmd, unsigned long arg)
870{
871 struct fb_cmap_user __user *cmap;
872 struct fb_cmap32 __user *cmap32;
873 __u32 data;
874 int err;
875
876 cmap = compat_alloc_user_space(sizeof(*cmap));
877 cmap32 = compat_ptr(arg);
878
879 if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
880 return -EFAULT;
881
882 if (get_user(data, &cmap32->red) ||
883 put_user(compat_ptr(data), &cmap->red) ||
884 get_user(data, &cmap32->green) ||
885 put_user(compat_ptr(data), &cmap->green) ||
886 get_user(data, &cmap32->blue) ||
887 put_user(compat_ptr(data), &cmap->blue) ||
888 get_user(data, &cmap32->transp) ||
889 put_user(compat_ptr(data), &cmap->transp))
890 return -EFAULT;
891
892 err = sys_ioctl(fd, cmd, (unsigned long) cmap);
893
894 if (!err) {
895 if (copy_in_user(&cmap32->start,
896 &cmap->start,
897 2 * sizeof(__u32)))
898 err = -EFAULT;
899 }
900 return err;
901}
902
903static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
904 struct fb_fix_screeninfo32 __user *fix32)
905{
906 __u32 data;
907 int err;
908
909 err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id));
910
911 data = (__u32) (unsigned long) fix->smem_start;
912 err |= put_user(data, &fix32->smem_start);
913
914 err |= put_user(fix->smem_len, &fix32->smem_len);
915 err |= put_user(fix->type, &fix32->type);
916 err |= put_user(fix->type_aux, &fix32->type_aux);
917 err |= put_user(fix->visual, &fix32->visual);
918 err |= put_user(fix->xpanstep, &fix32->xpanstep);
919 err |= put_user(fix->ypanstep, &fix32->ypanstep);
920 err |= put_user(fix->ywrapstep, &fix32->ywrapstep);
921 err |= put_user(fix->line_length, &fix32->line_length);
922
923 data = (__u32) (unsigned long) fix->mmio_start;
924 err |= put_user(data, &fix32->mmio_start);
925
926 err |= put_user(fix->mmio_len, &fix32->mmio_len);
927 err |= put_user(fix->accel, &fix32->accel);
928 err |= copy_to_user(fix32->reserved, fix->reserved,
929 sizeof(fix->reserved));
930
931 return err;
932}
933
934static int fb_get_fscreeninfo(unsigned int fd, unsigned int cmd, unsigned long arg)
935{
936 mm_segment_t old_fs;
937 struct fb_fix_screeninfo fix;
938 struct fb_fix_screeninfo32 __user *fix32;
939 int err;
940
941 fix32 = compat_ptr(arg);
942
943 old_fs = get_fs();
944 set_fs(KERNEL_DS);
945 err = sys_ioctl(fd, cmd, (unsigned long) &fix);
946 set_fs(old_fs);
947
948 if (!err)
949 err = do_fscreeninfo_to_user(&fix, fix32);
950
951 return err;
952}
953
954static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
955{
956 int err;
957
958 switch (cmd) {
959 case FBIOGET_FSCREENINFO:
960 err = fb_get_fscreeninfo(fd,cmd, arg);
961 break;
962
963 case FBIOGETCMAP:
964 case FBIOPUTCMAP:
965 err = fb_getput_cmap(fd, cmd, arg);
966 break;
967
968 default:
969 do {
970 static int count;
971 if (++count <= 20)
972 printk("%s: Unknown fb ioctl cmd fd(%d) "
973 "cmd(%08x) arg(%08lx)\n",
974 __FUNCTION__, fd, cmd, arg);
975 } while(0);
976 err = -ENOSYS;
977 break;
978 };
979
980 return err;
981}
982
983static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 843static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
984{ 844{
985 mm_segment_t old_fs = get_fs(); 845 mm_segment_t old_fs = get_fs();
@@ -2953,10 +2813,7 @@ HANDLE_IOCTL(BLKGETSIZE, w_long)
2953HANDLE_IOCTL(0x1260, broken_blkgetsize) 2813HANDLE_IOCTL(0x1260, broken_blkgetsize)
2954HANDLE_IOCTL(BLKFRAGET, w_long) 2814HANDLE_IOCTL(BLKFRAGET, w_long)
2955HANDLE_IOCTL(BLKSECTGET, w_long) 2815HANDLE_IOCTL(BLKSECTGET, w_long)
2956HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans)
2957HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans) 2816HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
2958HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans)
2959HANDLE_IOCTL(FBIOPUTCMAP, fb_ioctl_trans)
2960HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans) 2817HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
2961HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans) 2818HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
2962HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans) 2819HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
@@ -3051,6 +2908,16 @@ HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
3051COMPATIBLE_IOCTL(TIOCGLTC) 2908COMPATIBLE_IOCTL(TIOCGLTC)
3052COMPATIBLE_IOCTL(TIOCSLTC) 2909COMPATIBLE_IOCTL(TIOCSLTC)
3053#endif 2910#endif
2911#ifdef TIOCSTART
2912/*
2913 * For these two we have defintions in ioctls.h and/or termios.h on
2914 * some architectures but no actual implemention. Some applications
2915 * like bash call them if they are defined in the headers, so we provide
2916 * entries here to avoid syslog message spew.
2917 */
2918COMPATIBLE_IOCTL(TIOCSTART)
2919COMPATIBLE_IOCTL(TIOCSTOP)
2920#endif
3054/* Usbdevfs */ 2921/* Usbdevfs */
3055HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control) 2922HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
3056HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk) 2923HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
diff --git a/fs/exec.c b/fs/exec.c
index cd6c574557dc..c466fec5de20 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -135,7 +135,7 @@ asmlinkage long sys_uselib(const char __user * library)
135 if (!S_ISREG(nd.dentry->d_inode->i_mode)) 135 if (!S_ISREG(nd.dentry->d_inode->i_mode))
136 goto exit; 136 goto exit;
137 137
138 error = permission(nd.dentry->d_inode, MAY_READ | MAY_EXEC, &nd); 138 error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
139 if (error) 139 if (error)
140 goto exit; 140 goto exit;
141 141
@@ -495,7 +495,7 @@ struct file *open_exec(const char *name)
495 file = ERR_PTR(-EACCES); 495 file = ERR_PTR(-EACCES);
496 if (!(nd.mnt->mnt_flags & MNT_NOEXEC) && 496 if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
497 S_ISREG(inode->i_mode)) { 497 S_ISREG(inode->i_mode)) {
498 int err = permission(inode, MAY_EXEC, &nd); 498 int err = vfs_permission(&nd, MAY_EXEC);
499 if (!err && !(inode->i_mode & 0111)) 499 if (!err && !(inode->i_mode & 0111))
500 err = -EACCES; 500 err = -EACCES;
501 file = ERR_PTR(err); 501 file = ERR_PTR(err);
@@ -590,6 +590,7 @@ static inline int de_thread(struct task_struct *tsk)
590 struct signal_struct *sig = tsk->signal; 590 struct signal_struct *sig = tsk->signal;
591 struct sighand_struct *newsighand, *oldsighand = tsk->sighand; 591 struct sighand_struct *newsighand, *oldsighand = tsk->sighand;
592 spinlock_t *lock = &oldsighand->siglock; 592 spinlock_t *lock = &oldsighand->siglock;
593 struct task_struct *leader = NULL;
593 int count; 594 int count;
594 595
595 /* 596 /*
@@ -665,7 +666,7 @@ static inline int de_thread(struct task_struct *tsk)
665 * and to assume its PID: 666 * and to assume its PID:
666 */ 667 */
667 if (!thread_group_leader(current)) { 668 if (!thread_group_leader(current)) {
668 struct task_struct *leader = current->group_leader, *parent; 669 struct task_struct *parent;
669 struct dentry *proc_dentry1, *proc_dentry2; 670 struct dentry *proc_dentry1, *proc_dentry2;
670 unsigned long exit_state, ptrace; 671 unsigned long exit_state, ptrace;
671 672
@@ -674,6 +675,7 @@ static inline int de_thread(struct task_struct *tsk)
674 * It should already be zombie at this point, most 675 * It should already be zombie at this point, most
675 * of the time. 676 * of the time.
676 */ 677 */
678 leader = current->group_leader;
677 while (leader->exit_state != EXIT_ZOMBIE) 679 while (leader->exit_state != EXIT_ZOMBIE)
678 yield(); 680 yield();
679 681
@@ -733,7 +735,6 @@ static inline int de_thread(struct task_struct *tsk)
733 proc_pid_flush(proc_dentry2); 735 proc_pid_flush(proc_dentry2);
734 736
735 BUG_ON(exit_state != EXIT_ZOMBIE); 737 BUG_ON(exit_state != EXIT_ZOMBIE);
736 release_task(leader);
737 } 738 }
738 739
739 /* 740 /*
@@ -743,8 +744,11 @@ static inline int de_thread(struct task_struct *tsk)
743 sig->flags = 0; 744 sig->flags = 0;
744 745
745no_thread_group: 746no_thread_group:
746 BUG_ON(atomic_read(&sig->count) != 1);
747 exit_itimers(sig); 747 exit_itimers(sig);
748 if (leader)
749 release_task(leader);
750
751 BUG_ON(atomic_read(&sig->count) != 1);
748 752
749 if (atomic_read(&oldsighand->count) == 1) { 753 if (atomic_read(&oldsighand->count) == 1) {
750 /* 754 /*
@@ -892,7 +896,7 @@ int flush_old_exec(struct linux_binprm * bprm)
892 flush_thread(); 896 flush_thread();
893 897
894 if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 898 if (bprm->e_uid != current->euid || bprm->e_gid != current->egid ||
895 permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) || 899 file_permission(bprm->file, MAY_READ) ||
896 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { 900 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
897 suid_keys(current); 901 suid_keys(current);
898 current->mm->dumpable = suid_dumpable; 902 current->mm->dumpable = suid_dumpable;
diff --git a/fs/ext2/CHANGES b/fs/ext2/CHANGES
deleted file mode 100644
index aa5aaf0e5911..000000000000
--- a/fs/ext2/CHANGES
+++ /dev/null
@@ -1,157 +0,0 @@
1Changes from version 0.5a to version 0.5b
2=========================================
3 - Now that we have sysctl(), the immutable flag cannot be changed when
4 the system is running at security level > 0.
5 - Some cleanups in the code.
6 - More consistency checks on directories.
7 - The ext2.diff patch from Tom May <ftom@netcom.com> has been
8 integrated. This patch replaces expensive "/" and "%" with
9 cheap ">>" and "&" where possible.
10
11Changes from version 0.5 to version 0.5a
12========================================
13 - Zero the partial block following the end of the file when a file
14 is truncated.
15 - Dates updated in the copyright.
16 - More checks when the filesystem is mounted: the count of blocks,
17 fragments, and inodes per group is checked against the block size.
18 - The buffers used by the error routines are now static variables, to
19 avoid using space on the kernel stack, as requested by Linus.
20 - Some cleanups in the error messages (some versions of syslog contain
21 a bug which truncates an error message if it contains '\n').
22 - Check that no data can be written to a file past the 2GB limit.
23 - The famous readdir() bug has been fixed by Stephen Tweedie.
24 - Added a revision level in the superblock.
25 - Full support for O_SYNC flag of the open system call.
26 - New mount options: `resuid=#uid' and `resgid=#gid'. `resuid' causes
27 ext2fs to consider user #uid like root for the reserved blocks.
28 `resgid' acts the same way with group #gid. New fields in the
29 superblock contain default values for resuid and resgid and can
30 be modified by tune2fs.
31 Idea comes from Rene Cougnenc <cougnenc@renux.frmug.fr.net>.
32 - New mount options: `bsddf' and `minixdf'. `bsddf' causes ext2fs
33 to remove the blocks used for FS structures from the total block
34 count in statfs. With `minixdf', ext2fs mimics Minix behavior
35 in statfs (i.e. it returns the total number of blocks on the
36 partition). This is intended to make bde happy :-)
37 - New file attributes:
38 - Immutable files cannot be modified. Data cannot be written to
39 these files. They cannot be removed, renamed and new links cannot
40 be created. Even root cannot modify the files. He has to remove
41 the immutable attribute first.
42 - Append-only files: can only be written in append-mode when writing.
43 They cannot be removed, renamed and new links cannot be created.
44 Note: files may only be added to an append-only directory.
45 - No-dump files: the attribute is not used by the kernel. My port
46 of dump uses it to avoid backing up files which are not important.
47 - New check in ext2_check_dir_entry: the inode number is checked.
48 - Support for big file systems: the copy of the FS descriptor is now
49 dynamically allocated (previous versions used a fixed size array).
50 This allows to mount 2GB+ FS.
51 - Reorganization of the ext2_inode structure to allow other operating
52 systems to create specific fields if they use ext2fs as their native
53 file system. Currently, ext2fs is only implemented in Linux but
54 will soon be part of Gnu Hurd and of Masix.
55
56Changes from version 0.4b to version 0.5
57========================================
58 - New superblock fields: s_lastcheck and s_checkinterval added
59 by Uwe Ohse <uwe@tirka.gun.de> to implement timedependent checks
60 of the file system
61 - Real random numbers for secure rm added by Pierre del Perugia
62 <delperug@gla.ecoledoc.ibp.fr>
63 - The mount warnings related to the state of a fs are not printed
64 if the fs is mounted read-only, idea by Nick Holloway
65 <alfie@dcs.warwick.ac.uk>
66
67Changes from version 0.4a to version 0.4b
68=========================================
69 - Copyrights changed to include the name of my laboratory.
70 - Clean up of balloc.c and ialloc.c.
71 - More consistency checks.
72 - Block preallocation added by Stephen Tweedie.
73 - Direct reads of directories disallowed.
74 - Readahead implemented in readdir by Stephen Tweedie.
75 - Bugs in block and inodes allocation fixed.
76 - Readahead implemented in ext2_find_entry by Chip Salzenberg.
77 - New mount options:
78 `check=none|normal|strict'
79 `debug'
80 `errors=continue|remount-ro|panic'
81 `grpid', `bsdgroups'
82 `nocheck'
83 `nogrpid', `sysvgroups'
84 - truncate() now tries to deallocate contiguous blocks in a single call
85 to ext2_free_blocks().
86 - lots of cosmetic changes.
87
88Changes from version 0.4 to version 0.4a
89========================================
90 - the `sync' option support is now complete. Version 0.4 was not
91 supporting it when truncating a file. I have tested the synchronous
92 writes and they work but they make the system very slow :-( I have
93 to work again on this to make it faster.
94 - when detecting an error on a mounted filesystem, version 0.4 used
95 to try to write a flag in the super block even if the filesystem had
96 been mounted read-only. This is fixed.
97 - the `sb=#' option now causes the kernel code to use the filesystem
98 descriptors located at block #+1. Version 0.4 used the superblock
99 backup located at block # but used the main copy of the descriptors.
100 - a new file attribute `S' is supported. This attribute causes
101 synchronous writes but is applied to a file not to the entire file
102 system (thanks to Michael Kraehe <kraehe@bakunin.north.de> for
103 suggesting it).
104 - the directory cache is inhibited by default. The cache management
105 code seems to be buggy and I have to look at it carefully before
106 using it again.
107 - deleting a file with the `s' attribute (secure deletion) causes its
108 blocks to be overwritten with random values not with zeros (thanks to
109 Michael A. Griffith <grif@cs.ucr.edu> for suggesting it).
110 - lots of cosmetic changes have been made.
111
112Changes from version 0.3 to version 0.4
113=======================================
114 - Three new mount options are supported: `check', `sync' and `sb=#'.
115 `check' tells the kernel code to make more consistency checks
116 when the file system is mounted. Currently, the kernel code checks
117 that the blocks and inodes bitmaps are consistent with the free
118 blocks and inodes counts. More checks will be added in future
119 releases.
120 `sync' tells the kernel code to use synchronous writes when updating
121 an inode, a bitmap, a directory entry or an indirect block. This
122 can make the file system much slower but can be a big win for files
123 recovery in case of a crash (and we can now say to the BSD folks
124 that Linux also supports synchronous updates :-).
125 `sb=#' tells the kernel code to use an alternate super block instead
126 of its master copy. `#' is the number of the block (counted in
127 1024 bytes blocks) which contains the alternate super block.
128 An ext2 file system typically contains backups of the super block
129 at blocks 8193, 16385, and so on.
130 - I have change the meaning of the valid flag used by e2fsck. it
131 now contains the state of the file system. If the kernel code
132 detects an inconsistency while the file system is mounted, it flags
133 it as erroneous and e2fsck will detect that on next run.
134 - The super block now contains a mount counter. This counter is
135 incremented each time the file system is mounted read/write. When
136 this counter becomes bigger than a maximal mount counts (also stored
137 in the super block), e2fsck checks the file system, even if it had
138 been unmounted cleanly, and resets this counter to 0.
139 - File attributes are now supported. One can associate a set of
140 attributes to a file. Three attributes are defined:
141 `c': the file is marked for automatic compression,
142 `s': the file is marked for secure deletion: when the file is
143 deleted, its blocks are zeroed and written back to the disk,
144 `u': the file is marked for undeletion: when the file is deleted,
145 its contents are saved to allow a future undeletion.
146 Currently, only the `s' attribute is implemented in the kernel
147 code. Support for the other attributes will be added in a future
148 release.
149 - a few bugs related to times updates have been fixed by Bruce
150 Evans and me.
151 - a bug related to the links count of deleted inodes has been fixed.
152 Previous versions used to keep the links count set to 1 when a file
153 was deleted. The new version now sets links_count to 0 when deleting
154 the last link.
155 - a race condition when deallocating an inode has been fixed by
156 Stephen Tweedie.
157
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index 6591abef64d0..bb6908066494 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -624,76 +624,3 @@ unsigned long ext2_bg_num_gdb(struct super_block *sb, int group)
624 return EXT2_SB(sb)->s_gdb_count; 624 return EXT2_SB(sb)->s_gdb_count;
625} 625}
626 626
627#ifdef CONFIG_EXT2_CHECK
628/* Called at mount-time, super-block is locked */
629void ext2_check_blocks_bitmap (struct super_block * sb)
630{
631 struct buffer_head *bitmap_bh = NULL;
632 struct ext2_super_block * es;
633 unsigned long desc_count, bitmap_count, x, j;
634 unsigned long desc_blocks;
635 struct ext2_group_desc * desc;
636 int i;
637
638 es = EXT2_SB(sb)->s_es;
639 desc_count = 0;
640 bitmap_count = 0;
641 desc = NULL;
642 for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
643 desc = ext2_get_group_desc (sb, i, NULL);
644 if (!desc)
645 continue;
646 desc_count += le16_to_cpu(desc->bg_free_blocks_count);
647 brelse(bitmap_bh);
648 bitmap_bh = read_block_bitmap(sb, i);
649 if (!bitmap_bh)
650 continue;
651
652 if (ext2_bg_has_super(sb, i) &&
653 !ext2_test_bit(0, bitmap_bh->b_data))
654 ext2_error(sb, __FUNCTION__,
655 "Superblock in group %d is marked free", i);
656
657 desc_blocks = ext2_bg_num_gdb(sb, i);
658 for (j = 0; j < desc_blocks; j++)
659 if (!ext2_test_bit(j + 1, bitmap_bh->b_data))
660 ext2_error(sb, __FUNCTION__,
661 "Descriptor block #%ld in group "
662 "%d is marked free", j, i);
663
664 if (!block_in_use(le32_to_cpu(desc->bg_block_bitmap),
665 sb, bitmap_bh->b_data))
666 ext2_error(sb, "ext2_check_blocks_bitmap",
667 "Block bitmap for group %d is marked free",
668 i);
669
670 if (!block_in_use(le32_to_cpu(desc->bg_inode_bitmap),
671 sb, bitmap_bh->b_data))
672 ext2_error(sb, "ext2_check_blocks_bitmap",
673 "Inode bitmap for group %d is marked free",
674 i);
675
676 for (j = 0; j < EXT2_SB(sb)->s_itb_per_group; j++)
677 if (!block_in_use(le32_to_cpu(desc->bg_inode_table) + j,
678 sb, bitmap_bh->b_data))
679 ext2_error (sb, "ext2_check_blocks_bitmap",
680 "Block #%ld of the inode table in "
681 "group %d is marked free", j, i);
682
683 x = ext2_count_free(bitmap_bh, sb->s_blocksize);
684 if (le16_to_cpu(desc->bg_free_blocks_count) != x)
685 ext2_error (sb, "ext2_check_blocks_bitmap",
686 "Wrong free blocks count for group %d, "
687 "stored = %d, counted = %lu", i,
688 le16_to_cpu(desc->bg_free_blocks_count), x);
689 bitmap_count += x;
690 }
691 if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count)
692 ext2_error (sb, "ext2_check_blocks_bitmap",
693 "Wrong free blocks count in super block, "
694 "stored = %lu, counted = %lu",
695 (unsigned long)le32_to_cpu(es->s_free_blocks_count),
696 bitmap_count);
697 brelse(bitmap_bh);
698}
699#endif
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index e2d6208633a7..74714af4ae69 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -700,43 +700,3 @@ unsigned long ext2_count_dirs (struct super_block * sb)
700 return count; 700 return count;
701} 701}
702 702
703#ifdef CONFIG_EXT2_CHECK
704/* Called at mount-time, super-block is locked */
705void ext2_check_inodes_bitmap (struct super_block * sb)
706{
707 struct ext2_super_block * es = EXT2_SB(sb)->s_es;
708 unsigned long desc_count = 0, bitmap_count = 0;
709 struct buffer_head *bitmap_bh = NULL;
710 int i;
711
712 for (i = 0; i < EXT2_SB(sb)->s_groups_count; i++) {
713 struct ext2_group_desc *desc;
714 unsigned x;
715
716 desc = ext2_get_group_desc(sb, i, NULL);
717 if (!desc)
718 continue;
719 desc_count += le16_to_cpu(desc->bg_free_inodes_count);
720 brelse(bitmap_bh);
721 bitmap_bh = read_inode_bitmap(sb, i);
722 if (!bitmap_bh)
723 continue;
724
725 x = ext2_count_free(bitmap_bh, EXT2_INODES_PER_GROUP(sb) / 8);
726 if (le16_to_cpu(desc->bg_free_inodes_count) != x)
727 ext2_error (sb, "ext2_check_inodes_bitmap",
728 "Wrong free inodes count in group %d, "
729 "stored = %d, counted = %lu", i,
730 le16_to_cpu(desc->bg_free_inodes_count), x);
731 bitmap_count += x;
732 }
733 brelse(bitmap_bh);
734 if (percpu_counter_read(&EXT2_SB(sb)->s_freeinodes_counter) !=
735 bitmap_count)
736 ext2_error(sb, "ext2_check_inodes_bitmap",
737 "Wrong free inodes count in super block, "
738 "stored = %lu, counted = %lu",
739 (unsigned long)le32_to_cpu(es->s_free_inodes_count),
740 bitmap_count);
741}
742#endif
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 3c0c7c6a5b44..e4ed4b31a433 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -281,7 +281,7 @@ static unsigned long get_sb_block(void **data)
281enum { 281enum {
282 Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, 282 Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
283 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, 283 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic,
284 Opt_err_ro, Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, 284 Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
285 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr, 285 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
286 Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota, 286 Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
287 Opt_usrquota, Opt_grpquota 287 Opt_usrquota, Opt_grpquota
@@ -303,7 +303,6 @@ static match_table_t tokens = {
303 {Opt_nouid32, "nouid32"}, 303 {Opt_nouid32, "nouid32"},
304 {Opt_nocheck, "check=none"}, 304 {Opt_nocheck, "check=none"},
305 {Opt_nocheck, "nocheck"}, 305 {Opt_nocheck, "nocheck"},
306 {Opt_check, "check"},
307 {Opt_debug, "debug"}, 306 {Opt_debug, "debug"},
308 {Opt_oldalloc, "oldalloc"}, 307 {Opt_oldalloc, "oldalloc"},
309 {Opt_orlov, "orlov"}, 308 {Opt_orlov, "orlov"},
@@ -376,13 +375,6 @@ static int parse_options (char * options,
376 case Opt_nouid32: 375 case Opt_nouid32:
377 set_opt (sbi->s_mount_opt, NO_UID32); 376 set_opt (sbi->s_mount_opt, NO_UID32);
378 break; 377 break;
379 case Opt_check:
380#ifdef CONFIG_EXT2_CHECK
381 set_opt (sbi->s_mount_opt, CHECK);
382#else
383 printk("EXT2 Check option not supported\n");
384#endif
385 break;
386 case Opt_nocheck: 378 case Opt_nocheck:
387 clear_opt (sbi->s_mount_opt, CHECK); 379 clear_opt (sbi->s_mount_opt, CHECK);
388 break; 380 break;
@@ -503,12 +495,6 @@ static int ext2_setup_super (struct super_block * sb,
503 EXT2_BLOCKS_PER_GROUP(sb), 495 EXT2_BLOCKS_PER_GROUP(sb),
504 EXT2_INODES_PER_GROUP(sb), 496 EXT2_INODES_PER_GROUP(sb),
505 sbi->s_mount_opt); 497 sbi->s_mount_opt);
506#ifdef CONFIG_EXT2_CHECK
507 if (test_opt (sb, CHECK)) {
508 ext2_check_blocks_bitmap (sb);
509 ext2_check_inodes_bitmap (sb);
510 }
511#endif
512 return res; 498 return res;
513} 499}
514 500
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 7992d21e0e09..ae1148c24c53 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -1517,76 +1517,3 @@ unsigned long ext3_bg_num_gdb(struct super_block *sb, int group)
1517 return EXT3_SB(sb)->s_gdb_count; 1517 return EXT3_SB(sb)->s_gdb_count;
1518} 1518}
1519 1519
1520#ifdef CONFIG_EXT3_CHECK
1521/* Called at mount-time, super-block is locked */
1522void ext3_check_blocks_bitmap (struct super_block * sb)
1523{
1524 struct ext3_super_block *es;
1525 unsigned long desc_count, bitmap_count, x, j;
1526 unsigned long desc_blocks;
1527 struct buffer_head *bitmap_bh = NULL;
1528 struct ext3_group_desc *gdp;
1529 int i;
1530
1531 es = EXT3_SB(sb)->s_es;
1532 desc_count = 0;
1533 bitmap_count = 0;
1534 gdp = NULL;
1535 for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
1536 gdp = ext3_get_group_desc (sb, i, NULL);
1537 if (!gdp)
1538 continue;
1539 desc_count += le16_to_cpu(gdp->bg_free_blocks_count);
1540 brelse(bitmap_bh);
1541 bitmap_bh = read_block_bitmap(sb, i);
1542 if (bitmap_bh == NULL)
1543 continue;
1544
1545 if (ext3_bg_has_super(sb, i) &&
1546 !ext3_test_bit(0, bitmap_bh->b_data))
1547 ext3_error(sb, __FUNCTION__,
1548 "Superblock in group %d is marked free", i);
1549
1550 desc_blocks = ext3_bg_num_gdb(sb, i);
1551 for (j = 0; j < desc_blocks; j++)
1552 if (!ext3_test_bit(j + 1, bitmap_bh->b_data))
1553 ext3_error(sb, __FUNCTION__,
1554 "Descriptor block #%ld in group "
1555 "%d is marked free", j, i);
1556
1557 if (!block_in_use (le32_to_cpu(gdp->bg_block_bitmap),
1558 sb, bitmap_bh->b_data))
1559 ext3_error (sb, "ext3_check_blocks_bitmap",
1560 "Block bitmap for group %d is marked free",
1561 i);
1562
1563 if (!block_in_use (le32_to_cpu(gdp->bg_inode_bitmap),
1564 sb, bitmap_bh->b_data))
1565 ext3_error (sb, "ext3_check_blocks_bitmap",
1566 "Inode bitmap for group %d is marked free",
1567 i);
1568
1569 for (j = 0; j < EXT3_SB(sb)->s_itb_per_group; j++)
1570 if (!block_in_use (le32_to_cpu(gdp->bg_inode_table) + j,
1571 sb, bitmap_bh->b_data))
1572 ext3_error (sb, "ext3_check_blocks_bitmap",
1573 "Block #%d of the inode table in "
1574 "group %d is marked free", j, i);
1575
1576 x = ext3_count_free(bitmap_bh, sb->s_blocksize);
1577 if (le16_to_cpu(gdp->bg_free_blocks_count) != x)
1578 ext3_error (sb, "ext3_check_blocks_bitmap",
1579 "Wrong free blocks count for group %d, "
1580 "stored = %d, counted = %lu", i,
1581 le16_to_cpu(gdp->bg_free_blocks_count), x);
1582 bitmap_count += x;
1583 }
1584 brelse(bitmap_bh);
1585 if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count)
1586 ext3_error (sb, "ext3_check_blocks_bitmap",
1587 "Wrong free blocks count in super block, "
1588 "stored = %lu, counted = %lu",
1589 (unsigned long)le32_to_cpu(es->s_free_blocks_count),
1590 bitmap_count);
1591}
1592#endif
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index df3f517c54ac..9e4a24376210 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -756,44 +756,3 @@ unsigned long ext3_count_dirs (struct super_block * sb)
756 return count; 756 return count;
757} 757}
758 758
759#ifdef CONFIG_EXT3_CHECK
760/* Called at mount-time, super-block is locked */
761void ext3_check_inodes_bitmap (struct super_block * sb)
762{
763 struct ext3_super_block * es;
764 unsigned long desc_count, bitmap_count, x;
765 struct buffer_head *bitmap_bh = NULL;
766 struct ext3_group_desc * gdp;
767 int i;
768
769 es = EXT3_SB(sb)->s_es;
770 desc_count = 0;
771 bitmap_count = 0;
772 gdp = NULL;
773 for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
774 gdp = ext3_get_group_desc (sb, i, NULL);
775 if (!gdp)
776 continue;
777 desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
778 brelse(bitmap_bh);
779 bitmap_bh = read_inode_bitmap(sb, i);
780 if (!bitmap_bh)
781 continue;
782
783 x = ext3_count_free(bitmap_bh, EXT3_INODES_PER_GROUP(sb) / 8);
784 if (le16_to_cpu(gdp->bg_free_inodes_count) != x)
785 ext3_error (sb, "ext3_check_inodes_bitmap",
786 "Wrong free inodes count in group %d, "
787 "stored = %d, counted = %lu", i,
788 le16_to_cpu(gdp->bg_free_inodes_count), x);
789 bitmap_count += x;
790 }
791 brelse(bitmap_bh);
792 if (le32_to_cpu(es->s_free_inodes_count) != bitmap_count)
793 ext3_error (sb, "ext3_check_inodes_bitmap",
794 "Wrong free inodes count in super block, "
795 "stored = %lu, counted = %lu",
796 (unsigned long)le32_to_cpu(es->s_free_inodes_count),
797 bitmap_count);
798}
799#endif
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index f594989ccb7a..4e6730622d90 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -625,7 +625,7 @@ static struct export_operations ext3_export_ops = {
625enum { 625enum {
626 Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, 626 Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
627 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, 627 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
628 Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, 628 Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
629 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, 629 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
630 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, 630 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh,
631 Opt_commit, Opt_journal_update, Opt_journal_inum, 631 Opt_commit, Opt_journal_update, Opt_journal_inum,
@@ -652,7 +652,6 @@ static match_table_t tokens = {
652 {Opt_nouid32, "nouid32"}, 652 {Opt_nouid32, "nouid32"},
653 {Opt_nocheck, "nocheck"}, 653 {Opt_nocheck, "nocheck"},
654 {Opt_nocheck, "check=none"}, 654 {Opt_nocheck, "check=none"},
655 {Opt_check, "check"},
656 {Opt_debug, "debug"}, 655 {Opt_debug, "debug"},
657 {Opt_oldalloc, "oldalloc"}, 656 {Opt_oldalloc, "oldalloc"},
658 {Opt_orlov, "orlov"}, 657 {Opt_orlov, "orlov"},
@@ -773,14 +772,6 @@ static int parse_options (char * options, struct super_block *sb,
773 case Opt_nouid32: 772 case Opt_nouid32:
774 set_opt (sbi->s_mount_opt, NO_UID32); 773 set_opt (sbi->s_mount_opt, NO_UID32);
775 break; 774 break;
776 case Opt_check:
777#ifdef CONFIG_EXT3_CHECK
778 set_opt (sbi->s_mount_opt, CHECK);
779#else
780 printk(KERN_ERR
781 "EXT3 Check option not supported\n");
782#endif
783 break;
784 case Opt_nocheck: 775 case Opt_nocheck:
785 clear_opt (sbi->s_mount_opt, CHECK); 776 clear_opt (sbi->s_mount_opt, CHECK);
786 break; 777 break;
@@ -1115,12 +1106,6 @@ static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es,
1115 } else { 1106 } else {
1116 printk("internal journal\n"); 1107 printk("internal journal\n");
1117 } 1108 }
1118#ifdef CONFIG_EXT3_CHECK
1119 if (test_opt (sb, CHECK)) {
1120 ext3_check_blocks_bitmap (sb);
1121 ext3_check_inodes_bitmap (sb);
1122 }
1123#endif
1124 return res; 1109 return res;
1125} 1110}
1126 1111
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index e2effe2dc9b2..a0f9b9fe1307 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -846,7 +846,7 @@ static match_table_t vfat_tokens = {
846 {Opt_err, NULL} 846 {Opt_err, NULL}
847}; 847};
848 848
849static int parse_options(char *options, int is_vfat, int *debug, 849static int parse_options(char *options, int is_vfat, int silent, int *debug,
850 struct fat_mount_options *opts) 850 struct fat_mount_options *opts)
851{ 851{
852 char *p; 852 char *p;
@@ -1008,8 +1008,11 @@ static int parse_options(char *options, int is_vfat, int *debug,
1008 break; 1008 break;
1009 /* unknown option */ 1009 /* unknown option */
1010 default: 1010 default:
1011 printk(KERN_ERR "FAT: Unrecognized mount option \"%s\" " 1011 if (!silent) {
1012 "or missing value\n", p); 1012 printk(KERN_ERR
1013 "FAT: Unrecognized mount option \"%s\" "
1014 "or missing value\n", p);
1015 }
1013 return -EINVAL; 1016 return -EINVAL;
1014 } 1017 }
1015 } 1018 }
@@ -1091,7 +1094,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
1091 sb->s_export_op = &fat_export_ops; 1094 sb->s_export_op = &fat_export_ops;
1092 sbi->dir_ops = fs_dir_inode_ops; 1095 sbi->dir_ops = fs_dir_inode_ops;
1093 1096
1094 error = parse_options(data, isvfat, &debug, &sbi->options); 1097 error = parse_options(data, isvfat, silent, &debug, &sbi->options);
1095 if (error) 1098 if (error)
1096 goto out_fail; 1099 goto out_fail;
1097 1100
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index aae019aadf88..cc5dcd52e23d 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -9,7 +9,6 @@
9#ifndef _LINUX_HFS_FS_H 9#ifndef _LINUX_HFS_FS_H
10#define _LINUX_HFS_FS_H 10#define _LINUX_HFS_FS_H
11 11
12#include <linux/version.h>
13#include <linux/slab.h> 12#include <linux/slab.h>
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 3f680c5675bf..d499393a8ae7 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14#include <linux/pagemap.h> 14#include <linux/pagemap.h>
15#include <linux/version.h>
16#include <linux/mpage.h> 15#include <linux/mpage.h>
17 16
18#include "hfs_fs.h" 17#include "hfs_fs.h"
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index b85abc6e6f83..930cd9212de8 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -13,7 +13,6 @@
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/fs.h> 14#include <linux/fs.h>
15#include <linux/swap.h> 15#include <linux/swap.h>
16#include <linux/version.h>
17 16
18#include "hfsplus_fs.h" 17#include "hfsplus_fs.h"
19#include "hfsplus_raw.h" 18#include "hfsplus_raw.h"
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 7bda76667a4a..50c8f44b6c66 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -13,7 +13,6 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/random.h> 15#include <linux/random.h>
16#include <linux/version.h>
17 16
18#include "hfsplus_fs.h" 17#include "hfsplus_fs.h"
19#include "hfsplus_raw.h" 18#include "hfsplus_raw.h"
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
index e7235ca79a95..e3ff56a03011 100644
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -11,7 +11,6 @@
11#include <linux/errno.h> 11#include <linux/errno.h>
12#include <linux/fs.h> 12#include <linux/fs.h>
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/version.h>
15 14
16#include "hfsplus_fs.h" 15#include "hfsplus_fs.h"
17#include "hfsplus_raw.h" 16#include "hfsplus_raw.h"
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 2bc0cdd30e56..c60e5635498d 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -11,7 +11,6 @@
11#define _LINUX_HFSPLUS_FS_H 11#define _LINUX_HFSPLUS_FS_H
12 12
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/version.h>
15#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
16#include "hfsplus_raw.h" 15#include "hfsplus_raw.h"
17 16
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index f205773ddfbe..fc98583cf045 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -11,7 +11,6 @@
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/fs.h> 12#include <linux/fs.h>
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/version.h>
15#include <linux/mpage.h> 14#include <linux/mpage.h>
16 15
17#include "hfsplus_fs.h" 16#include "hfsplus_fs.h"
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 452fc1fdbd32..0ce1c455ae55 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -14,7 +14,6 @@
14#include <linux/fs.h> 14#include <linux/fs.h>
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/version.h>
18#include <linux/vfs.h> 17#include <linux/vfs.h>
19#include <linux/nls.h> 18#include <linux/nls.h>
20 19
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
index 0c51d6338b0b..95455e839231 100644
--- a/fs/hfsplus/wrapper.c
+++ b/fs/hfsplus/wrapper.c
@@ -12,7 +12,6 @@
12#include <linux/blkdev.h> 12#include <linux/blkdev.h>
13#include <linux/cdrom.h> 13#include <linux/cdrom.h>
14#include <linux/genhd.h> 14#include <linux/genhd.h>
15#include <linux/version.h>
16#include <asm/unaligned.h> 15#include <asm/unaligned.h>
17 16
18#include "hfsplus_fs.h" 17#include "hfsplus_fs.h"
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index a33fb1d91373..4684eb7d48c6 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -8,7 +8,6 @@
8 8
9#include <linux/stddef.h> 9#include <linux/stddef.h>
10#include <linux/fs.h> 10#include <linux/fs.h>
11#include <linux/version.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/slab.h> 13#include <linux/slab.h>
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index ab144dabd870..7c995ac4081b 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -114,11 +114,8 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf,
114 ssize_t retval; 114 ssize_t retval;
115 115
116 retval = generic_file_write(file, buf, count, ppos); 116 retval = generic_file_write(file, buf, count, ppos);
117 if (retval > 0) { 117 if (retval > 0)
118 struct inode *inode = file->f_dentry->d_inode; 118 hpfs_i(file->f_dentry->d_inode)->i_dirty = 1;
119 inode->i_mtime = CURRENT_TIME_SEC;
120 hpfs_i(inode)->i_dirty = 1;
121 }
122 return retval; 119 return retval;
123} 120}
124 121
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index e026c807e6b3..64983ab55586 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -63,7 +63,7 @@ static void huge_pagevec_release(struct pagevec *pvec)
63 * 63 *
64 * Result is in bytes to be compatible with is_hugepage_mem_enough() 64 * Result is in bytes to be compatible with is_hugepage_mem_enough()
65 */ 65 */
66unsigned long 66static unsigned long
67huge_pages_needed(struct address_space *mapping, struct vm_area_struct *vma) 67huge_pages_needed(struct address_space *mapping, struct vm_area_struct *vma)
68{ 68{
69 int i; 69 int i;
diff --git a/fs/inotify.c b/fs/inotify.c
index 9fbaebfdf40b..bf7ce1d2412b 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -372,7 +372,7 @@ static int find_inode(const char __user *dirname, struct nameidata *nd)
372 if (error) 372 if (error)
373 return error; 373 return error;
374 /* you can only watch an inode if you have read permissions on it */ 374 /* you can only watch an inode if you have read permissions on it */
375 error = permission(nd->dentry->d_inode, MAY_READ, NULL); 375 error = vfs_permission(nd, MAY_READ);
376 if (error) 376 if (error)
377 path_release(nd); 377 path_release(nd);
378 return error; 378 return error;
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 1abe7343f920..4abbe8604302 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -827,6 +827,7 @@ static int jfs_link(struct dentry *old_dentry,
827 /* update object inode */ 827 /* update object inode */
828 ip->i_nlink++; /* for new link */ 828 ip->i_nlink++; /* for new link */
829 ip->i_ctime = CURRENT_TIME; 829 ip->i_ctime = CURRENT_TIME;
830 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
830 mark_inode_dirty(dir); 831 mark_inode_dirty(dir);
831 atomic_inc(&ip->i_count); 832 atomic_inc(&ip->i_count);
832 833
@@ -1024,6 +1025,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
1024 insert_inode_hash(ip); 1025 insert_inode_hash(ip);
1025 mark_inode_dirty(ip); 1026 mark_inode_dirty(ip);
1026 1027
1028 dip->i_ctime = dip->i_mtime = CURRENT_TIME;
1029 mark_inode_dirty(dip);
1027 /* 1030 /*
1028 * commit update of parent directory and link object 1031 * commit update of parent directory and link object
1029 */ 1032 */
diff --git a/fs/namei.c b/fs/namei.c
index b3f8a1966c9c..6dbbd42d8b95 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -256,6 +256,38 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
256 return security_inode_permission(inode, mask, nd); 256 return security_inode_permission(inode, mask, nd);
257} 257}
258 258
259/**
260 * vfs_permission - check for access rights to a given path
261 * @nd: lookup result that describes the path
262 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
263 *
264 * Used to check for read/write/execute permissions on a path.
265 * We use "fsuid" for this, letting us set arbitrary permissions
266 * for filesystem access without changing the "normal" uids which
267 * are used for other things.
268 */
269int vfs_permission(struct nameidata *nd, int mask)
270{
271 return permission(nd->dentry->d_inode, mask, nd);
272}
273
274/**
275 * file_permission - check for additional access rights to a given file
276 * @file: file to check access rights for
277 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
278 *
279 * Used to check for read/write/execute permissions on an already opened
280 * file.
281 *
282 * Note:
283 * Do not use this function in new code. All access checks should
284 * be done using vfs_permission().
285 */
286int file_permission(struct file *file, int mask)
287{
288 return permission(file->f_dentry->d_inode, mask, NULL);
289}
290
259/* 291/*
260 * get_write_access() gets write permission for a file. 292 * get_write_access() gets write permission for a file.
261 * put_write_access() releases this write permission. 293 * put_write_access() releases this write permission.
@@ -765,9 +797,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
765 797
766 nd->flags |= LOOKUP_CONTINUE; 798 nd->flags |= LOOKUP_CONTINUE;
767 err = exec_permission_lite(inode, nd); 799 err = exec_permission_lite(inode, nd);
768 if (err == -EAGAIN) { 800 if (err == -EAGAIN)
769 err = permission(inode, MAY_EXEC, nd); 801 err = vfs_permission(nd, MAY_EXEC);
770 }
771 if (err) 802 if (err)
772 break; 803 break;
773 804
@@ -1109,8 +1140,9 @@ int path_lookup_open(const char *name, unsigned int lookup_flags,
1109 * @open_flags: open intent flags 1140 * @open_flags: open intent flags
1110 * @create_mode: create intent flags 1141 * @create_mode: create intent flags
1111 */ 1142 */
1112int path_lookup_create(const char *name, unsigned int lookup_flags, 1143static int path_lookup_create(const char *name, unsigned int lookup_flags,
1113 struct nameidata *nd, int open_flags, int create_mode) 1144 struct nameidata *nd, int open_flags,
1145 int create_mode)
1114{ 1146{
1115 return __path_lookup_intent_open(name, lookup_flags|LOOKUP_CREATE, nd, 1147 return __path_lookup_intent_open(name, lookup_flags|LOOKUP_CREATE, nd,
1116 open_flags, create_mode); 1148 open_flags, create_mode);
@@ -1173,9 +1205,9 @@ out:
1173 return dentry; 1205 return dentry;
1174} 1206}
1175 1207
1176struct dentry * lookup_hash(struct qstr *name, struct dentry * base) 1208struct dentry * lookup_hash(struct nameidata *nd)
1177{ 1209{
1178 return __lookup_hash(name, base, NULL); 1210 return __lookup_hash(&nd->last, nd->dentry, nd);
1179} 1211}
1180 1212
1181/* SMP-safe */ 1213/* SMP-safe */
@@ -1199,7 +1231,7 @@ struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
1199 } 1231 }
1200 this.hash = end_name_hash(hash); 1232 this.hash = end_name_hash(hash);
1201 1233
1202 return lookup_hash(&this, base); 1234 return __lookup_hash(&this, base, NULL);
1203access: 1235access:
1204 return ERR_PTR(-EACCES); 1236 return ERR_PTR(-EACCES);
1205} 1237}
@@ -1407,7 +1439,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1407 if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE)) 1439 if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
1408 return -EISDIR; 1440 return -EISDIR;
1409 1441
1410 error = permission(inode, acc_mode, nd); 1442 error = vfs_permission(nd, acc_mode);
1411 if (error) 1443 if (error)
1412 return error; 1444 return error;
1413 1445
@@ -1532,7 +1564,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
1532 dir = nd->dentry; 1564 dir = nd->dentry;
1533 nd->flags &= ~LOOKUP_PARENT; 1565 nd->flags &= ~LOOKUP_PARENT;
1534 down(&dir->d_inode->i_sem); 1566 down(&dir->d_inode->i_sem);
1535 path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); 1567 path.dentry = lookup_hash(nd);
1536 path.mnt = nd->mnt; 1568 path.mnt = nd->mnt;
1537 1569
1538do_last: 1570do_last:
@@ -1634,7 +1666,7 @@ do_link:
1634 } 1666 }
1635 dir = nd->dentry; 1667 dir = nd->dentry;
1636 down(&dir->d_inode->i_sem); 1668 down(&dir->d_inode->i_sem);
1637 path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); 1669 path.dentry = lookup_hash(nd);
1638 path.mnt = nd->mnt; 1670 path.mnt = nd->mnt;
1639 __putname(nd->last.name); 1671 __putname(nd->last.name);
1640 goto do_last; 1672 goto do_last;
@@ -1666,7 +1698,7 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
1666 /* 1698 /*
1667 * Do the final lookup. 1699 * Do the final lookup.
1668 */ 1700 */
1669 dentry = lookup_hash(&nd->last, nd->dentry); 1701 dentry = lookup_hash(nd);
1670 if (IS_ERR(dentry)) 1702 if (IS_ERR(dentry))
1671 goto fail; 1703 goto fail;
1672 1704
@@ -1901,7 +1933,7 @@ asmlinkage long sys_rmdir(const char __user * pathname)
1901 goto exit1; 1933 goto exit1;
1902 } 1934 }
1903 down(&nd.dentry->d_inode->i_sem); 1935 down(&nd.dentry->d_inode->i_sem);
1904 dentry = lookup_hash(&nd.last, nd.dentry); 1936 dentry = lookup_hash(&nd);
1905 error = PTR_ERR(dentry); 1937 error = PTR_ERR(dentry);
1906 if (!IS_ERR(dentry)) { 1938 if (!IS_ERR(dentry)) {
1907 error = vfs_rmdir(nd.dentry->d_inode, dentry); 1939 error = vfs_rmdir(nd.dentry->d_inode, dentry);
@@ -1970,7 +2002,7 @@ asmlinkage long sys_unlink(const char __user * pathname)
1970 if (nd.last_type != LAST_NORM) 2002 if (nd.last_type != LAST_NORM)
1971 goto exit1; 2003 goto exit1;
1972 down(&nd.dentry->d_inode->i_sem); 2004 down(&nd.dentry->d_inode->i_sem);
1973 dentry = lookup_hash(&nd.last, nd.dentry); 2005 dentry = lookup_hash(&nd);
1974 error = PTR_ERR(dentry); 2006 error = PTR_ERR(dentry);
1975 if (!IS_ERR(dentry)) { 2007 if (!IS_ERR(dentry)) {
1976 /* Why not before? Because we want correct error value */ 2008 /* Why not before? Because we want correct error value */
@@ -2313,7 +2345,7 @@ static inline int do_rename(const char * oldname, const char * newname)
2313 2345
2314 trap = lock_rename(new_dir, old_dir); 2346 trap = lock_rename(new_dir, old_dir);
2315 2347
2316 old_dentry = lookup_hash(&oldnd.last, old_dir); 2348 old_dentry = lookup_hash(&oldnd);
2317 error = PTR_ERR(old_dentry); 2349 error = PTR_ERR(old_dentry);
2318 if (IS_ERR(old_dentry)) 2350 if (IS_ERR(old_dentry))
2319 goto exit3; 2351 goto exit3;
@@ -2333,7 +2365,7 @@ static inline int do_rename(const char * oldname, const char * newname)
2333 error = -EINVAL; 2365 error = -EINVAL;
2334 if (old_dentry == trap) 2366 if (old_dentry == trap)
2335 goto exit4; 2367 goto exit4;
2336 new_dentry = lookup_hash(&newnd.last, new_dir); 2368 new_dentry = lookup_hash(&newnd);
2337 error = PTR_ERR(new_dentry); 2369 error = PTR_ERR(new_dentry);
2338 if (IS_ERR(new_dentry)) 2370 if (IS_ERR(new_dentry))
2339 goto exit4; 2371 goto exit4;
@@ -2536,6 +2568,8 @@ EXPORT_SYMBOL(path_lookup);
2536EXPORT_SYMBOL(path_release); 2568EXPORT_SYMBOL(path_release);
2537EXPORT_SYMBOL(path_walk); 2569EXPORT_SYMBOL(path_walk);
2538EXPORT_SYMBOL(permission); 2570EXPORT_SYMBOL(permission);
2571EXPORT_SYMBOL(vfs_permission);
2572EXPORT_SYMBOL(file_permission);
2539EXPORT_SYMBOL(unlock_rename); 2573EXPORT_SYMBOL(unlock_rename);
2540EXPORT_SYMBOL(vfs_create); 2574EXPORT_SYMBOL(vfs_create);
2541EXPORT_SYMBOL(vfs_follow_link); 2575EXPORT_SYMBOL(vfs_follow_link);
diff --git a/fs/namespace.c b/fs/namespace.c
index caa9187f67e5..2019899f2ab8 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -637,7 +637,7 @@ static int mount_is_safe(struct nameidata *nd)
637 if (current->uid != nd->dentry->d_inode->i_uid) 637 if (current->uid != nd->dentry->d_inode->i_uid)
638 return -EPERM; 638 return -EPERM;
639 } 639 }
640 if (permission(nd->dentry->d_inode, MAY_WRITE, nd)) 640 if (vfs_permission(nd, MAY_WRITE))
641 return -EPERM; 641 return -EPERM;
642 return 0; 642 return 0;
643#endif 643#endif
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 88df79356a1f..fd3efdca5ae3 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -30,11 +30,13 @@
30#define NCP_PACKET_SIZE_INTERNAL 65536 30#define NCP_PACKET_SIZE_INTERNAL 65536
31 31
32static int 32static int
33ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_info __user *arg) 33ncp_get_fs_info(struct ncp_server * server, struct file *file,
34 struct ncp_fs_info __user *arg)
34{ 35{
36 struct inode *inode = file->f_dentry->d_inode;
35 struct ncp_fs_info info; 37 struct ncp_fs_info info;
36 38
37 if ((permission(inode, MAY_WRITE, NULL) != 0) 39 if ((file_permission(file, MAY_WRITE) != 0)
38 && (current->uid != server->m.mounted_uid)) { 40 && (current->uid != server->m.mounted_uid)) {
39 return -EACCES; 41 return -EACCES;
40 } 42 }
@@ -58,11 +60,13 @@ ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_in
58} 60}
59 61
60static int 62static int
61ncp_get_fs_info_v2(struct ncp_server* server, struct inode* inode, struct ncp_fs_info_v2 __user * arg) 63ncp_get_fs_info_v2(struct ncp_server * server, struct file *file,
64 struct ncp_fs_info_v2 __user * arg)
62{ 65{
66 struct inode *inode = file->f_dentry->d_inode;
63 struct ncp_fs_info_v2 info2; 67 struct ncp_fs_info_v2 info2;
64 68
65 if ((permission(inode, MAY_WRITE, NULL) != 0) 69 if ((file_permission(file, MAY_WRITE) != 0)
66 && (current->uid != server->m.mounted_uid)) { 70 && (current->uid != server->m.mounted_uid)) {
67 return -EACCES; 71 return -EACCES;
68 } 72 }
@@ -190,7 +194,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
190 switch (cmd) { 194 switch (cmd) {
191 case NCP_IOC_NCPREQUEST: 195 case NCP_IOC_NCPREQUEST:
192 196
193 if ((permission(inode, MAY_WRITE, NULL) != 0) 197 if ((file_permission(filp, MAY_WRITE) != 0)
194 && (current->uid != server->m.mounted_uid)) { 198 && (current->uid != server->m.mounted_uid)) {
195 return -EACCES; 199 return -EACCES;
196 } 200 }
@@ -245,16 +249,16 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
245 return ncp_conn_logged_in(inode->i_sb); 249 return ncp_conn_logged_in(inode->i_sb);
246 250
247 case NCP_IOC_GET_FS_INFO: 251 case NCP_IOC_GET_FS_INFO:
248 return ncp_get_fs_info(server, inode, argp); 252 return ncp_get_fs_info(server, filp, argp);
249 253
250 case NCP_IOC_GET_FS_INFO_V2: 254 case NCP_IOC_GET_FS_INFO_V2:
251 return ncp_get_fs_info_v2(server, inode, argp); 255 return ncp_get_fs_info_v2(server, filp, argp);
252 256
253 case NCP_IOC_GETMOUNTUID2: 257 case NCP_IOC_GETMOUNTUID2:
254 { 258 {
255 unsigned long tmp = server->m.mounted_uid; 259 unsigned long tmp = server->m.mounted_uid;
256 260
257 if ( (permission(inode, MAY_READ, NULL) != 0) 261 if ((file_permission(filp, MAY_READ) != 0)
258 && (current->uid != server->m.mounted_uid)) 262 && (current->uid != server->m.mounted_uid))
259 { 263 {
260 return -EACCES; 264 return -EACCES;
@@ -268,7 +272,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
268 { 272 {
269 struct ncp_setroot_ioctl sr; 273 struct ncp_setroot_ioctl sr;
270 274
271 if ( (permission(inode, MAY_READ, NULL) != 0) 275 if ((file_permission(filp, MAY_READ) != 0)
272 && (current->uid != server->m.mounted_uid)) 276 && (current->uid != server->m.mounted_uid))
273 { 277 {
274 return -EACCES; 278 return -EACCES;
@@ -343,7 +347,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
343 347
344#ifdef CONFIG_NCPFS_PACKET_SIGNING 348#ifdef CONFIG_NCPFS_PACKET_SIGNING
345 case NCP_IOC_SIGN_INIT: 349 case NCP_IOC_SIGN_INIT:
346 if ((permission(inode, MAY_WRITE, NULL) != 0) 350 if ((file_permission(filp, MAY_WRITE) != 0)
347 && (current->uid != server->m.mounted_uid)) 351 && (current->uid != server->m.mounted_uid))
348 { 352 {
349 return -EACCES; 353 return -EACCES;
@@ -366,7 +370,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
366 return 0; 370 return 0;
367 371
368 case NCP_IOC_SIGN_WANTED: 372 case NCP_IOC_SIGN_WANTED:
369 if ( (permission(inode, MAY_READ, NULL) != 0) 373 if ((file_permission(filp, MAY_READ) != 0)
370 && (current->uid != server->m.mounted_uid)) 374 && (current->uid != server->m.mounted_uid))
371 { 375 {
372 return -EACCES; 376 return -EACCES;
@@ -379,7 +383,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
379 { 383 {
380 int newstate; 384 int newstate;
381 385
382 if ( (permission(inode, MAY_WRITE, NULL) != 0) 386 if ((file_permission(filp, MAY_WRITE) != 0)
383 && (current->uid != server->m.mounted_uid)) 387 && (current->uid != server->m.mounted_uid))
384 { 388 {
385 return -EACCES; 389 return -EACCES;
@@ -400,7 +404,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
400 404
401#ifdef CONFIG_NCPFS_IOCTL_LOCKING 405#ifdef CONFIG_NCPFS_IOCTL_LOCKING
402 case NCP_IOC_LOCKUNLOCK: 406 case NCP_IOC_LOCKUNLOCK:
403 if ( (permission(inode, MAY_WRITE, NULL) != 0) 407 if ((file_permission(filp, MAY_WRITE) != 0)
404 && (current->uid != server->m.mounted_uid)) 408 && (current->uid != server->m.mounted_uid))
405 { 409 {
406 return -EACCES; 410 return -EACCES;
@@ -605,7 +609,7 @@ outrel:
605#endif /* CONFIG_NCPFS_NLS */ 609#endif /* CONFIG_NCPFS_NLS */
606 610
607 case NCP_IOC_SETDENTRYTTL: 611 case NCP_IOC_SETDENTRYTTL:
608 if ((permission(inode, MAY_WRITE, NULL) != 0) && 612 if ((file_permission(filp, MAY_WRITE) != 0) &&
609 (current->uid != server->m.mounted_uid)) 613 (current->uid != server->m.mounted_uid))
610 return -EACCES; 614 return -EACCES;
611 { 615 {
@@ -635,7 +639,7 @@ outrel:
635 so we have this out of switch */ 639 so we have this out of switch */
636 if (cmd == NCP_IOC_GETMOUNTUID) { 640 if (cmd == NCP_IOC_GETMOUNTUID) {
637 __kernel_uid_t uid = 0; 641 __kernel_uid_t uid = 0;
638 if ((permission(inode, MAY_READ, NULL) != 0) 642 if ((file_permission(filp, MAY_READ) != 0)
639 && (current->uid != server->m.mounted_uid)) { 643 && (current->uid != server->m.mounted_uid)) {
640 return -EACCES; 644 return -EACCES;
641 } 645 }
diff --git a/fs/open.c b/fs/open.c
index 6e8136751e9a..f53a5b9ffb7d 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -240,7 +240,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length)
240 if (!S_ISREG(inode->i_mode)) 240 if (!S_ISREG(inode->i_mode))
241 goto dput_and_out; 241 goto dput_and_out;
242 242
243 error = permission(inode,MAY_WRITE,&nd); 243 error = vfs_permission(&nd, MAY_WRITE);
244 if (error) 244 if (error)
245 goto dput_and_out; 245 goto dput_and_out;
246 246
@@ -394,7 +394,7 @@ asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
394 goto dput_and_out; 394 goto dput_and_out;
395 395
396 if (current->fsuid != inode->i_uid && 396 if (current->fsuid != inode->i_uid &&
397 (error = permission(inode,MAY_WRITE,&nd)) != 0) 397 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
398 goto dput_and_out; 398 goto dput_and_out;
399 } 399 }
400 down(&inode->i_sem); 400 down(&inode->i_sem);
@@ -447,7 +447,7 @@ long do_utimes(char __user * filename, struct timeval * times)
447 goto dput_and_out; 447 goto dput_and_out;
448 448
449 if (current->fsuid != inode->i_uid && 449 if (current->fsuid != inode->i_uid &&
450 (error = permission(inode,MAY_WRITE,&nd)) != 0) 450 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
451 goto dput_and_out; 451 goto dput_and_out;
452 } 452 }
453 down(&inode->i_sem); 453 down(&inode->i_sem);
@@ -506,7 +506,7 @@ asmlinkage long sys_access(const char __user * filename, int mode)
506 506
507 res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); 507 res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
508 if (!res) { 508 if (!res) {
509 res = permission(nd.dentry->d_inode, mode, &nd); 509 res = vfs_permission(&nd, mode);
510 /* SuS v2 requires we report a read only fs too */ 510 /* SuS v2 requires we report a read only fs too */
511 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) 511 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
512 && !special_file(nd.dentry->d_inode->i_mode)) 512 && !special_file(nd.dentry->d_inode->i_mode))
@@ -530,7 +530,7 @@ asmlinkage long sys_chdir(const char __user * filename)
530 if (error) 530 if (error)
531 goto out; 531 goto out;
532 532
533 error = permission(nd.dentry->d_inode,MAY_EXEC,&nd); 533 error = vfs_permission(&nd, MAY_EXEC);
534 if (error) 534 if (error)
535 goto dput_and_out; 535 goto dput_and_out;
536 536
@@ -563,7 +563,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
563 if (!S_ISDIR(inode->i_mode)) 563 if (!S_ISDIR(inode->i_mode))
564 goto out_putf; 564 goto out_putf;
565 565
566 error = permission(inode, MAY_EXEC, NULL); 566 error = file_permission(file, MAY_EXEC);
567 if (!error) 567 if (!error)
568 set_fs_pwd(current->fs, mnt, dentry); 568 set_fs_pwd(current->fs, mnt, dentry);
569out_putf: 569out_putf:
@@ -581,7 +581,7 @@ asmlinkage long sys_chroot(const char __user * filename)
581 if (error) 581 if (error)
582 goto out; 582 goto out;
583 583
584 error = permission(nd.dentry->d_inode,MAY_EXEC,&nd); 584 error = vfs_permission(&nd, MAY_EXEC);
585 if (error) 585 if (error)
586 goto dput_and_out; 586 goto dput_and_out;
587 587
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index c20babd6216d..7892a865b58a 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -251,12 +251,12 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl
251 blocks_to_allocate, 251 blocks_to_allocate,
252 blocks_to_allocate); 252 blocks_to_allocate);
253 if (res != CARRY_ON) { 253 if (res != CARRY_ON) {
254 res = -ENOSPC; 254 res = res == QUOTA_EXCEEDED ? -EDQUOT : -ENOSPC;
255 pathrelse(&path); 255 pathrelse(&path);
256 goto error_exit; 256 goto error_exit;
257 } 257 }
258 } else { 258 } else {
259 res = -ENOSPC; 259 res = res == QUOTA_EXCEEDED ? -EDQUOT : -ENOSPC;
260 pathrelse(&path); 260 pathrelse(&path);
261 goto error_exit; 261 goto error_exit;
262 } 262 }
diff --git a/fs/udf/file.c b/fs/udf/file.c
index bb40d63f328f..01f520c71dc1 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -186,7 +186,7 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
186{ 186{
187 int result = -EINVAL; 187 int result = -EINVAL;
188 188
189 if ( permission(inode, MAY_READ, NULL) != 0 ) 189 if ( file_permission(filp, MAY_READ) != 0 )
190 { 190 {
191 udf_debug("no permission to access inode %lu\n", 191 udf_debug("no permission to access inode %lu\n",
192 inode->i_ino); 192 inode->i_ino);
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 44fed10af0dd..d8e21ba0cccc 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -72,7 +72,6 @@
72#include <linux/init.h> 72#include <linux/init.h>
73#include <linux/list.h> 73#include <linux/list.h>
74#include <linux/proc_fs.h> 74#include <linux/proc_fs.h>
75#include <linux/version.h>
76#include <linux/sort.h> 75#include <linux/sort.h>
77 76
78#include <asm/page.h> 77#include <asm/page.h>
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h
index 99b50d2bda9b..1a48dbb902a7 100644
--- a/fs/xfs/xfs.h
+++ b/fs/xfs/xfs.h
@@ -17,12 +17,5 @@
17 */ 17 */
18#ifndef __XFS_H__ 18#ifndef __XFS_H__
19#define __XFS_H__ 19#define __XFS_H__
20
21#include <linux/version.h>
22#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
23#include <linux-2.6/xfs_linux.h> 20#include <linux-2.6/xfs_linux.h>
24#else
25#include <linux-2.4/xfs_linux.h>
26#endif
27
28#endif /* __XFS_H__ */ 21#endif /* __XFS_H__ */
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 5a5c7a63e80b..864bf6955689 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -18,6 +18,7 @@
18#ifndef __XFS_DMAPI_H__ 18#ifndef __XFS_DMAPI_H__
19#define __XFS_DMAPI_H__ 19#define __XFS_DMAPI_H__
20 20
21#include <linux/version.h>
21/* Values used to define the on-disk version of dm_attrname_t. All 22/* Values used to define the on-disk version of dm_attrname_t. All
22 * on-disk attribute names start with the 8-byte string "SGI_DMI_". 23 * on-disk attribute names start with the 8-byte string "SGI_DMI_".
23 * 24 *
diff --git a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h
index 68934a25931f..6126afe27380 100644
--- a/include/asm-alpha/ide.h
+++ b/include/asm-alpha/ide.h
@@ -15,10 +15,6 @@
15 15
16#include <linux/config.h> 16#include <linux/config.h>
17 17
18#ifndef MAX_HWIFS
19#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
20#endif
21
22#define IDE_ARCH_OBSOLETE_DEFAULTS 18#define IDE_ARCH_OBSOLETE_DEFAULTS
23 19
24static inline int ide_default_irq(unsigned long base) 20static inline int ide_default_irq(unsigned long base)
diff --git a/include/asm-arm/arch-realview/entry-macro.S b/include/asm-arm/arch-realview/entry-macro.S
index 4df469bf42e2..6288fad0dc41 100644
--- a/include/asm-arm/arch-realview/entry-macro.S
+++ b/include/asm-arm/arch-realview/entry-macro.S
@@ -61,3 +61,14 @@
61 strcc \irqstat, [\base, #GIC_CPU_EOI] 61 strcc \irqstat, [\base, #GIC_CPU_EOI]
62 cmpcs \irqnr, \irqnr 62 cmpcs \irqnr, \irqnr
63 .endm 63 .endm
64
65 /* As above, this assumes that irqstat and base are preserved.. */
66
67 .macro test_for_ltirq, irqnr, irqstat, base, tmp
68 bic \irqnr, \irqstat, #0x1c00
69 mov \tmp, #0
70 cmp \irqnr, #29
71 moveq \tmp, #1
72 streq \irqstat, [\base, #GIC_CPU_EOI]
73 cmp \tmp, #0
74 .endm
diff --git a/include/asm-arm/arch-realview/irqs.h b/include/asm-arm/arch-realview/irqs.h
index ff376494e5b1..c16223c9588d 100644
--- a/include/asm-arm/arch-realview/irqs.h
+++ b/include/asm-arm/arch-realview/irqs.h
@@ -21,6 +21,9 @@
21 21
22#include <asm/arch/platform.h> 22#include <asm/arch/platform.h>
23 23
24#define IRQ_LOCALTIMER 29
25#define IRQ_LOCALWDOG 30
26
24/* 27/*
25 * IRQ interrupts definitions are the same the INT definitions 28 * IRQ interrupts definitions are the same the INT definitions
26 * held within platform.h 29 * held within platform.h
diff --git a/include/asm-arm/arch-realview/platform.h b/include/asm-arm/arch-realview/platform.h
index aef9b36b3c37..18d7c18b738c 100644
--- a/include/asm-arm/arch-realview/platform.h
+++ b/include/asm-arm/arch-realview/platform.h
@@ -209,6 +209,8 @@
209#else 209#else
210#define REALVIEW_MPCORE_SCU_BASE 0x10100000 /* SCU registers */ 210#define REALVIEW_MPCORE_SCU_BASE 0x10100000 /* SCU registers */
211#define REALVIEW_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */ 211#define REALVIEW_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */
212#define REALVIEW_TWD_BASE 0x10100700
213#define REALVIEW_TWD_SIZE 0x00000100
212#define REALVIEW_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */ 214#define REALVIEW_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */
213#endif 215#endif
214#define REALVIEW_SMC_BASE 0x10080000 /* SMC */ 216#define REALVIEW_SMC_BASE 0x10080000 /* SMC */
@@ -305,9 +307,6 @@
305#define INT_TSPENINT 30 /* Touchscreen pen */ 307#define INT_TSPENINT 30 /* Touchscreen pen */
306#define INT_TSKPADINT 31 /* Touchscreen keypad */ 308#define INT_TSKPADINT 31 /* Touchscreen keypad */
307#else 309#else
308#define INT_LOCALTIMER 29
309#define INT_LOCALWDOG 30
310
311#define INT_AACI 0 310#define INT_AACI 0
312#define INT_TIMERINT0_1 1 311#define INT_TIMERINT0_1 1
313#define INT_TIMERINT2_3 2 312#define INT_TIMERINT2_3 2
diff --git a/include/asm-arm/arch-s3c2410/uncompress.h b/include/asm-arm/arch-s3c2410/uncompress.h
index d7a4a8354fa9..ddd1578a7ee0 100644
--- a/include/asm-arm/arch-s3c2410/uncompress.h
+++ b/include/asm-arm/arch-s3c2410/uncompress.h
@@ -116,6 +116,8 @@ putstr(const char *ptr)
116 } 116 }
117} 117}
118 118
119#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0)
120
119/* CONFIG_S3C2410_BOOT_WATCHDOG 121/* CONFIG_S3C2410_BOOT_WATCHDOG
120 * 122 *
121 * Simple boot-time watchdog setup, to reboot the system if there is 123 * Simple boot-time watchdog setup, to reboot the system if there is
@@ -126,8 +128,6 @@ putstr(const char *ptr)
126 128
127#define WDOG_COUNT (0xff00) 129#define WDOG_COUNT (0xff00)
128 130
129#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0)
130
131static inline void arch_decomp_wdog(void) 131static inline void arch_decomp_wdog(void)
132{ 132{
133 __raw_writel(WDOG_COUNT, S3C2410_WTCNT); 133 __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
@@ -145,6 +145,24 @@ static void arch_decomp_wdog_start(void)
145#define arch_decomp_wdog() 145#define arch_decomp_wdog()
146#endif 146#endif
147 147
148#ifdef CONFIG_S3C2410_BOOT_ERROR_RESET
149
150static void arch_decomp_error(const char *x)
151{
152 putstr("\n\n");
153 putstr(x);
154 putstr("\n\n -- System resetting\n");
155
156 __raw_writel(0x4000, S3C2410_WTDAT);
157 __raw_writel(0x4000, S3C2410_WTCNT);
158 __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
159
160 while(1);
161}
162
163#define arch_error arch_decomp_error
164#endif
165
148static void error(char *err); 166static void error(char *err);
149 167
150static void 168static void
diff --git a/include/asm-arm/assembler.h b/include/asm-arm/assembler.h
index 69a28f96bee2..f31ac92b6c7f 100644
--- a/include/asm-arm/assembler.h
+++ b/include/asm-arm/assembler.h
@@ -83,10 +83,13 @@
83 * Save the current IRQ state and disable IRQs. Note that this macro 83 * Save the current IRQ state and disable IRQs. Note that this macro
84 * assumes FIQs are enabled, and that the processor is in SVC mode. 84 * assumes FIQs are enabled, and that the processor is in SVC mode.
85 */ 85 */
86 .macro save_and_disable_irqs, oldcpsr, temp 86 .macro save_and_disable_irqs, oldcpsr
87 mrs \oldcpsr, cpsr 87 mrs \oldcpsr, cpsr
88 mov \temp, #PSR_I_BIT | MODE_SVC 88#if __LINUX_ARM_ARCH__ >= 6
89 msr cpsr_c, \temp 89 cpsid i
90#else
91 msr cpsr_c, #PSR_I_BIT | MODE_SVC
92#endif
90 .endm 93 .endm
91 94
92/* 95/*
diff --git a/include/asm-arm/hardirq.h b/include/asm-arm/hardirq.h
index e5ccb6b8ff83..1cbb173bf5b1 100644
--- a/include/asm-arm/hardirq.h
+++ b/include/asm-arm/hardirq.h
@@ -8,6 +8,7 @@
8 8
9typedef struct { 9typedef struct {
10 unsigned int __softirq_pending; 10 unsigned int __softirq_pending;
11 unsigned int local_timer_irqs;
11} ____cacheline_aligned irq_cpustat_t; 12} ____cacheline_aligned irq_cpustat_t;
12 13
13#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ 14#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
diff --git a/include/asm-arm/hardware/scoop.h b/include/asm-arm/hardware/scoop.h
index a8f1013930e3..d37bf7443264 100644
--- a/include/asm-arm/hardware/scoop.h
+++ b/include/asm-arm/hardware/scoop.h
@@ -52,8 +52,14 @@ struct scoop_pcmcia_dev {
52 unsigned char keep_rd; 52 unsigned char keep_rd;
53}; 53};
54 54
55extern int scoop_num; 55struct scoop_pcmcia_config {
56extern struct scoop_pcmcia_dev *scoop_devs; 56 struct scoop_pcmcia_dev *devs;
57 int num_devs;
58 void (*pcmcia_init)(void);
59 void (*power_ctrl)(struct device *scoop, unsigned short cpr, int nr);
60};
61
62extern struct scoop_pcmcia_config *platform_scoop_config;
57 63
58void reset_scoop(struct device *dev); 64void reset_scoop(struct device *dev);
59unsigned short set_scoop_gpio(struct device *dev, unsigned short bit); 65unsigned short set_scoop_gpio(struct device *dev, unsigned short bit);
diff --git a/include/asm-arm/mach/flash.h b/include/asm-arm/mach/flash.h
index cd57436d9874..05b029ef6371 100644
--- a/include/asm-arm/mach/flash.h
+++ b/include/asm-arm/mach/flash.h
@@ -11,6 +11,7 @@
11#define ASMARM_MACH_FLASH_H 11#define ASMARM_MACH_FLASH_H
12 12
13struct mtd_partition; 13struct mtd_partition;
14struct mtd_info;
14 15
15/* 16/*
16 * map_name: the map probe function name 17 * map_name: the map probe function name
@@ -19,6 +20,7 @@ struct mtd_partition;
19 * init: method called at driver/device initialisation 20 * init: method called at driver/device initialisation
20 * exit: method called at driver/device removal 21 * exit: method called at driver/device removal
21 * set_vpp: method called to enable or disable VPP 22 * set_vpp: method called to enable or disable VPP
23 * mmcontrol: method called to enable or disable Sync. Burst Read in OneNAND
22 * parts: optional array of mtd_partitions for static partitioning 24 * parts: optional array of mtd_partitions for static partitioning
23 * nr_parts: number of mtd_partitions for static partitoning 25 * nr_parts: number of mtd_partitions for static partitoning
24 */ 26 */
@@ -29,6 +31,7 @@ struct flash_platform_data {
29 int (*init)(void); 31 int (*init)(void);
30 void (*exit)(void); 32 void (*exit)(void);
31 void (*set_vpp)(int on); 33 void (*set_vpp)(int on);
34 void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
32 struct mtd_partition *parts; 35 struct mtd_partition *parts;
33 unsigned int nr_parts; 36 unsigned int nr_parts;
34}; 37};
diff --git a/include/asm-arm/smp.h b/include/asm-arm/smp.h
index 551cd3c3093c..5a72e50ca9fc 100644
--- a/include/asm-arm/smp.h
+++ b/include/asm-arm/smp.h
@@ -37,6 +37,11 @@ struct seq_file;
37extern void show_ipi_list(struct seq_file *p); 37extern void show_ipi_list(struct seq_file *p);
38 38
39/* 39/*
40 * Called from assembly code, this handles an IPI.
41 */
42asmlinkage void do_IPI(struct pt_regs *regs);
43
44/*
40 * Move global data into per-processor storage. 45 * Move global data into per-processor storage.
41 */ 46 */
42extern void smp_store_cpu_info(unsigned int cpuid); 47extern void smp_store_cpu_info(unsigned int cpuid);
@@ -47,12 +52,23 @@ extern void smp_store_cpu_info(unsigned int cpuid);
47extern void smp_cross_call(cpumask_t callmap); 52extern void smp_cross_call(cpumask_t callmap);
48 53
49/* 54/*
55 * Broadcast a timer interrupt to the other CPUs.
56 */
57extern void smp_send_timer(void);
58
59/*
50 * Boot a secondary CPU, and assign it the specified idle task. 60 * Boot a secondary CPU, and assign it the specified idle task.
51 * This also gives us the initial stack to use for this CPU. 61 * This also gives us the initial stack to use for this CPU.
52 */ 62 */
53extern int boot_secondary(unsigned int cpu, struct task_struct *); 63extern int boot_secondary(unsigned int cpu, struct task_struct *);
54 64
55/* 65/*
66 * Called from platform specific assembly code, this is the
67 * secondary CPU entry point.
68 */
69asmlinkage void secondary_start_kernel(void);
70
71/*
56 * Perform platform specific initialisation of the specified CPU. 72 * Perform platform specific initialisation of the specified CPU.
57 */ 73 */
58extern void platform_secondary_init(unsigned int cpu); 74extern void platform_secondary_init(unsigned int cpu);
@@ -76,4 +92,42 @@ extern void platform_cpu_die(unsigned int cpu);
76extern int platform_cpu_kill(unsigned int cpu); 92extern int platform_cpu_kill(unsigned int cpu);
77extern void platform_cpu_enable(unsigned int cpu); 93extern void platform_cpu_enable(unsigned int cpu);
78 94
95#ifdef CONFIG_LOCAL_TIMERS
96/*
97 * Setup a local timer interrupt for a CPU.
98 */
99extern void local_timer_setup(unsigned int cpu);
100
101/*
102 * Stop a local timer interrupt.
103 */
104extern void local_timer_stop(unsigned int cpu);
105
106/*
107 * Platform provides this to acknowledge a local timer IRQ
108 */
109extern int local_timer_ack(void);
110
111#else
112
113static inline void local_timer_setup(unsigned int cpu)
114{
115}
116
117static inline void local_timer_stop(unsigned int cpu)
118{
119}
120
121#endif
122
123/*
124 * show local interrupt info
125 */
126extern void show_local_irqs(struct seq_file *);
127
128/*
129 * Called from assembly, this is the local timer IRQ handler
130 */
131asmlinkage void do_local_timer(struct pt_regs *);
132
79#endif /* ifndef __ASM_ARM_SMP_H */ 133#endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/include/asm-i386/ide.h b/include/asm-i386/ide.h
index 79dfab87135d..454440193eac 100644
--- a/include/asm-i386/ide.h
+++ b/include/asm-i386/ide.h
@@ -41,6 +41,12 @@ static __inline__ int ide_default_irq(unsigned long base)
41 41
42static __inline__ unsigned long ide_default_io_base(int index) 42static __inline__ unsigned long ide_default_io_base(int index)
43{ 43{
44 /*
45 * If PCI is present then it is not safe to poke around
46 * the other legacy IDE ports. Only 0x1f0 and 0x170 are
47 * defined compatibility mode ports for PCI. A user can
48 * override this using ide= but we must default safe.
49 */
44 if (pci_find_device(PCI_ANY_ID, PCI_ANY_ID, NULL) == NULL) { 50 if (pci_find_device(PCI_ANY_ID, PCI_ANY_ID, NULL) == NULL) {
45 switch(index) { 51 switch(index) {
46 case 2: return 0x1e8; 52 case 2: return 0x1e8;
diff --git a/include/asm-powerpc/pmc.h b/include/asm-powerpc/pmc.h
index 2f3c3fc2b796..5f41f3a2b293 100644
--- a/include/asm-powerpc/pmc.h
+++ b/include/asm-powerpc/pmc.h
@@ -22,6 +22,7 @@
22#include <asm/ptrace.h> 22#include <asm/ptrace.h>
23 23
24typedef void (*perf_irq_t)(struct pt_regs *); 24typedef void (*perf_irq_t)(struct pt_regs *);
25extern perf_irq_t perf_irq;
25 26
26int reserve_pmc_hardware(perf_irq_t new_perf_irq); 27int reserve_pmc_hardware(perf_irq_t new_perf_irq);
27void release_pmc_hardware(void); 28void release_pmc_hardware(void);
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index bb1b0576c947..ce212201db2a 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -107,6 +107,7 @@ enum ppc_sys_devices {
107 MPC83xx_SEC2, 107 MPC83xx_SEC2,
108 MPC83xx_USB2_DR, 108 MPC83xx_USB2_DR,
109 MPC83xx_USB2_MPH, 109 MPC83xx_USB2_MPH,
110 MPC83xx_MDIO,
110}; 111};
111 112
112#endif /* CONFIG_83xx */ 113#endif /* CONFIG_83xx */
diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h
index 7127030ae162..23450ed4b571 100644
--- a/include/asm-s390/debug.h
+++ b/include/asm-s390/debug.h
@@ -129,7 +129,7 @@ void debug_set_level(debug_info_t* id, int new_level);
129 129
130void debug_stop_all(void); 130void debug_stop_all(void);
131 131
132extern inline debug_entry_t* 132static inline debug_entry_t*
133debug_event(debug_info_t* id, int level, void* data, int length) 133debug_event(debug_info_t* id, int level, void* data, int length)
134{ 134{
135 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 135 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
@@ -137,7 +137,7 @@ debug_event(debug_info_t* id, int level, void* data, int length)
137 return debug_event_common(id,level,data,length); 137 return debug_event_common(id,level,data,length);
138} 138}
139 139
140extern inline debug_entry_t* 140static inline debug_entry_t*
141debug_int_event(debug_info_t* id, int level, unsigned int tag) 141debug_int_event(debug_info_t* id, int level, unsigned int tag)
142{ 142{
143 unsigned int t=tag; 143 unsigned int t=tag;
@@ -146,7 +146,7 @@ debug_int_event(debug_info_t* id, int level, unsigned int tag)
146 return debug_event_common(id,level,&t,sizeof(unsigned int)); 146 return debug_event_common(id,level,&t,sizeof(unsigned int));
147} 147}
148 148
149extern inline debug_entry_t * 149static inline debug_entry_t *
150debug_long_event (debug_info_t* id, int level, unsigned long tag) 150debug_long_event (debug_info_t* id, int level, unsigned long tag)
151{ 151{
152 unsigned long t=tag; 152 unsigned long t=tag;
@@ -155,7 +155,7 @@ debug_long_event (debug_info_t* id, int level, unsigned long tag)
155 return debug_event_common(id,level,&t,sizeof(unsigned long)); 155 return debug_event_common(id,level,&t,sizeof(unsigned long));
156} 156}
157 157
158extern inline debug_entry_t* 158static inline debug_entry_t*
159debug_text_event(debug_info_t* id, int level, const char* txt) 159debug_text_event(debug_info_t* id, int level, const char* txt)
160{ 160{
161 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 161 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
@@ -168,7 +168,7 @@ debug_sprintf_event(debug_info_t* id,int level,char *string,...)
168 __attribute__ ((format(printf, 3, 4))); 168 __attribute__ ((format(printf, 3, 4)));
169 169
170 170
171extern inline debug_entry_t* 171static inline debug_entry_t*
172debug_exception(debug_info_t* id, int level, void* data, int length) 172debug_exception(debug_info_t* id, int level, void* data, int length)
173{ 173{
174 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 174 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
@@ -176,7 +176,7 @@ debug_exception(debug_info_t* id, int level, void* data, int length)
176 return debug_exception_common(id,level,data,length); 176 return debug_exception_common(id,level,data,length);
177} 177}
178 178
179extern inline debug_entry_t* 179static inline debug_entry_t*
180debug_int_exception(debug_info_t* id, int level, unsigned int tag) 180debug_int_exception(debug_info_t* id, int level, unsigned int tag)
181{ 181{
182 unsigned int t=tag; 182 unsigned int t=tag;
@@ -185,7 +185,7 @@ debug_int_exception(debug_info_t* id, int level, unsigned int tag)
185 return debug_exception_common(id,level,&t,sizeof(unsigned int)); 185 return debug_exception_common(id,level,&t,sizeof(unsigned int));
186} 186}
187 187
188extern inline debug_entry_t * 188static inline debug_entry_t *
189debug_long_exception (debug_info_t* id, int level, unsigned long tag) 189debug_long_exception (debug_info_t* id, int level, unsigned long tag)
190{ 190{
191 unsigned long t=tag; 191 unsigned long t=tag;
@@ -194,7 +194,7 @@ debug_long_exception (debug_info_t* id, int level, unsigned long tag)
194 return debug_exception_common(id,level,&t,sizeof(unsigned long)); 194 return debug_exception_common(id,level,&t,sizeof(unsigned long));
195} 195}
196 196
197extern inline debug_entry_t* 197static inline debug_entry_t*
198debug_text_exception(debug_info_t* id, int level, const char* txt) 198debug_text_exception(debug_info_t* id, int level, const char* txt)
199{ 199{
200 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 200 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
diff --git a/include/asm-s390/ebcdic.h b/include/asm-s390/ebcdic.h
index 20e81e885821..4cbc336e4d60 100644
--- a/include/asm-s390/ebcdic.h
+++ b/include/asm-s390/ebcdic.h
@@ -21,7 +21,7 @@ extern __u8 _ebcasc[]; /* EBCDIC -> ASCII conversion table */
21extern __u8 _ebc_tolower[]; /* EBCDIC -> lowercase */ 21extern __u8 _ebc_tolower[]; /* EBCDIC -> lowercase */
22extern __u8 _ebc_toupper[]; /* EBCDIC -> uppercase */ 22extern __u8 _ebc_toupper[]; /* EBCDIC -> uppercase */
23 23
24extern __inline__ void 24static inline void
25codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr) 25codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr)
26{ 26{
27 if (nr-- <= 0) 27 if (nr-- <= 0)
diff --git a/include/asm-s390/io.h b/include/asm-s390/io.h
index 8188fdc9884f..71f55eb2350a 100644
--- a/include/asm-s390/io.h
+++ b/include/asm-s390/io.h
@@ -24,7 +24,7 @@
24 * Change virtual addresses to physical addresses and vv. 24 * Change virtual addresses to physical addresses and vv.
25 * These are pretty trivial 25 * These are pretty trivial
26 */ 26 */
27extern inline unsigned long virt_to_phys(volatile void * address) 27static inline unsigned long virt_to_phys(volatile void * address)
28{ 28{
29 unsigned long real_address; 29 unsigned long real_address;
30 __asm__ ( 30 __asm__ (
@@ -42,7 +42,7 @@ extern inline unsigned long virt_to_phys(volatile void * address)
42 return real_address; 42 return real_address;
43} 43}
44 44
45extern inline void * phys_to_virt(unsigned long address) 45static inline void * phys_to_virt(unsigned long address)
46{ 46{
47 return __io_virt(address); 47 return __io_virt(address);
48} 48}
@@ -54,7 +54,7 @@ extern inline void * phys_to_virt(unsigned long address)
54 54
55extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); 55extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
56 56
57extern inline void * ioremap (unsigned long offset, unsigned long size) 57static inline void * ioremap (unsigned long offset, unsigned long size)
58{ 58{
59 return __ioremap(offset, size, 0); 59 return __ioremap(offset, size, 0);
60} 60}
@@ -64,7 +64,7 @@ extern inline void * ioremap (unsigned long offset, unsigned long size)
64 * it's useful if some control registers are in such an area and write combining 64 * it's useful if some control registers are in such an area and write combining
65 * or read caching is not desirable: 65 * or read caching is not desirable:
66 */ 66 */
67extern inline void * ioremap_nocache (unsigned long offset, unsigned long size) 67static inline void * ioremap_nocache (unsigned long offset, unsigned long size)
68{ 68{
69 return __ioremap(offset, size, 0); 69 return __ioremap(offset, size, 0);
70} 70}
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index c6f51c9ce3ff..db0606c1abd4 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -346,7 +346,7 @@ struct _lowcore
346#define S390_lowcore (*((struct _lowcore *) 0)) 346#define S390_lowcore (*((struct _lowcore *) 0))
347extern struct _lowcore *lowcore_ptr[]; 347extern struct _lowcore *lowcore_ptr[];
348 348
349extern __inline__ void set_prefix(__u32 address) 349static inline void set_prefix(__u32 address)
350{ 350{
351 __asm__ __volatile__ ("spx %0" : : "m" (address) : "memory" ); 351 __asm__ __volatile__ ("spx %0" : : "m" (address) : "memory" );
352} 352}
diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h
index 3a3bb3f2dad5..bcf24a873874 100644
--- a/include/asm-s390/mmu_context.h
+++ b/include/asm-s390/mmu_context.h
@@ -44,7 +44,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
44 44
45#define deactivate_mm(tsk,mm) do { } while (0) 45#define deactivate_mm(tsk,mm) do { } while (0)
46 46
47extern inline void activate_mm(struct mm_struct *prev, 47static inline void activate_mm(struct mm_struct *prev,
48 struct mm_struct *next) 48 struct mm_struct *next)
49{ 49{
50 switch_mm(prev, next, current); 50 switch_mm(prev, next, current);
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index 9be741bb1496..859b5e969826 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -319,7 +319,7 @@ extern char empty_zero_page[PAGE_SIZE];
319 * within a page table are directly modified. Thus, the following 319 * within a page table are directly modified. Thus, the following
320 * hook is made available. 320 * hook is made available.
321 */ 321 */
322extern inline void set_pte(pte_t *pteptr, pte_t pteval) 322static inline void set_pte(pte_t *pteptr, pte_t pteval)
323{ 323{
324 *pteptr = pteval; 324 *pteptr = pteval;
325} 325}
@@ -330,63 +330,63 @@ extern inline void set_pte(pte_t *pteptr, pte_t pteval)
330 */ 330 */
331#ifndef __s390x__ 331#ifndef __s390x__
332 332
333extern inline int pgd_present(pgd_t pgd) { return 1; } 333static inline int pgd_present(pgd_t pgd) { return 1; }
334extern inline int pgd_none(pgd_t pgd) { return 0; } 334static inline int pgd_none(pgd_t pgd) { return 0; }
335extern inline int pgd_bad(pgd_t pgd) { return 0; } 335static inline int pgd_bad(pgd_t pgd) { return 0; }
336 336
337extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; } 337static inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; }
338extern inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) & _PAGE_TABLE_INV; } 338static inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) & _PAGE_TABLE_INV; }
339extern inline int pmd_bad(pmd_t pmd) 339static inline int pmd_bad(pmd_t pmd)
340{ 340{
341 return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE; 341 return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE;
342} 342}
343 343
344#else /* __s390x__ */ 344#else /* __s390x__ */
345 345
346extern inline int pgd_present(pgd_t pgd) 346static inline int pgd_present(pgd_t pgd)
347{ 347{
348 return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY; 348 return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY;
349} 349}
350 350
351extern inline int pgd_none(pgd_t pgd) 351static inline int pgd_none(pgd_t pgd)
352{ 352{
353 return pgd_val(pgd) & _PGD_ENTRY_INV; 353 return pgd_val(pgd) & _PGD_ENTRY_INV;
354} 354}
355 355
356extern inline int pgd_bad(pgd_t pgd) 356static inline int pgd_bad(pgd_t pgd)
357{ 357{
358 return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY; 358 return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY;
359} 359}
360 360
361extern inline int pmd_present(pmd_t pmd) 361static inline int pmd_present(pmd_t pmd)
362{ 362{
363 return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY; 363 return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY;
364} 364}
365 365
366extern inline int pmd_none(pmd_t pmd) 366static inline int pmd_none(pmd_t pmd)
367{ 367{
368 return pmd_val(pmd) & _PMD_ENTRY_INV; 368 return pmd_val(pmd) & _PMD_ENTRY_INV;
369} 369}
370 370
371extern inline int pmd_bad(pmd_t pmd) 371static inline int pmd_bad(pmd_t pmd)
372{ 372{
373 return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY; 373 return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY;
374} 374}
375 375
376#endif /* __s390x__ */ 376#endif /* __s390x__ */
377 377
378extern inline int pte_none(pte_t pte) 378static inline int pte_none(pte_t pte)
379{ 379{
380 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_EMPTY; 380 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_EMPTY;
381} 381}
382 382
383extern inline int pte_present(pte_t pte) 383static inline int pte_present(pte_t pte)
384{ 384{
385 return !(pte_val(pte) & _PAGE_INVALID) || 385 return !(pte_val(pte) & _PAGE_INVALID) ||
386 (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_NONE; 386 (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_NONE;
387} 387}
388 388
389extern inline int pte_file(pte_t pte) 389static inline int pte_file(pte_t pte)
390{ 390{
391 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_FILE; 391 return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_FILE;
392} 392}
@@ -397,12 +397,12 @@ extern inline int pte_file(pte_t pte)
397 * query functions pte_write/pte_dirty/pte_young only work if 397 * query functions pte_write/pte_dirty/pte_young only work if
398 * pte_present() is true. Undefined behaviour if not.. 398 * pte_present() is true. Undefined behaviour if not..
399 */ 399 */
400extern inline int pte_write(pte_t pte) 400static inline int pte_write(pte_t pte)
401{ 401{
402 return (pte_val(pte) & _PAGE_RO) == 0; 402 return (pte_val(pte) & _PAGE_RO) == 0;
403} 403}
404 404
405extern inline int pte_dirty(pte_t pte) 405static inline int pte_dirty(pte_t pte)
406{ 406{
407 /* A pte is neither clean nor dirty on s/390. The dirty bit 407 /* A pte is neither clean nor dirty on s/390. The dirty bit
408 * is in the storage key. See page_test_and_clear_dirty for 408 * is in the storage key. See page_test_and_clear_dirty for
@@ -411,7 +411,7 @@ extern inline int pte_dirty(pte_t pte)
411 return 0; 411 return 0;
412} 412}
413 413
414extern inline int pte_young(pte_t pte) 414static inline int pte_young(pte_t pte)
415{ 415{
416 /* A pte is neither young nor old on s/390. The young bit 416 /* A pte is neither young nor old on s/390. The young bit
417 * is in the storage key. See page_test_and_clear_young for 417 * is in the storage key. See page_test_and_clear_young for
@@ -420,7 +420,7 @@ extern inline int pte_young(pte_t pte)
420 return 0; 420 return 0;
421} 421}
422 422
423extern inline int pte_read(pte_t pte) 423static inline int pte_read(pte_t pte)
424{ 424{
425 /* All pages are readable since we don't use the fetch 425 /* All pages are readable since we don't use the fetch
426 * protection bit in the storage key. 426 * protection bit in the storage key.
@@ -434,9 +434,9 @@ extern inline int pte_read(pte_t pte)
434 434
435#ifndef __s390x__ 435#ifndef __s390x__
436 436
437extern inline void pgd_clear(pgd_t * pgdp) { } 437static inline void pgd_clear(pgd_t * pgdp) { }
438 438
439extern inline void pmd_clear(pmd_t * pmdp) 439static inline void pmd_clear(pmd_t * pmdp)
440{ 440{
441 pmd_val(pmdp[0]) = _PAGE_TABLE_INV; 441 pmd_val(pmdp[0]) = _PAGE_TABLE_INV;
442 pmd_val(pmdp[1]) = _PAGE_TABLE_INV; 442 pmd_val(pmdp[1]) = _PAGE_TABLE_INV;
@@ -446,12 +446,12 @@ extern inline void pmd_clear(pmd_t * pmdp)
446 446
447#else /* __s390x__ */ 447#else /* __s390x__ */
448 448
449extern inline void pgd_clear(pgd_t * pgdp) 449static inline void pgd_clear(pgd_t * pgdp)
450{ 450{
451 pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY; 451 pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY;
452} 452}
453 453
454extern inline void pmd_clear(pmd_t * pmdp) 454static inline void pmd_clear(pmd_t * pmdp)
455{ 455{
456 pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY; 456 pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
457 pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY; 457 pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
@@ -459,7 +459,7 @@ extern inline void pmd_clear(pmd_t * pmdp)
459 459
460#endif /* __s390x__ */ 460#endif /* __s390x__ */
461 461
462extern inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 462static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
463{ 463{
464 pte_val(*ptep) = _PAGE_INVALID_EMPTY; 464 pte_val(*ptep) = _PAGE_INVALID_EMPTY;
465} 465}
@@ -468,14 +468,14 @@ extern inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
468 * The following pte modification functions only work if 468 * The following pte modification functions only work if
469 * pte_present() is true. Undefined behaviour if not.. 469 * pte_present() is true. Undefined behaviour if not..
470 */ 470 */
471extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 471static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
472{ 472{
473 pte_val(pte) &= PAGE_MASK; 473 pte_val(pte) &= PAGE_MASK;
474 pte_val(pte) |= pgprot_val(newprot); 474 pte_val(pte) |= pgprot_val(newprot);
475 return pte; 475 return pte;
476} 476}
477 477
478extern inline pte_t pte_wrprotect(pte_t pte) 478static inline pte_t pte_wrprotect(pte_t pte)
479{ 479{
480 /* Do not clobber _PAGE_INVALID_NONE pages! */ 480 /* Do not clobber _PAGE_INVALID_NONE pages! */
481 if (!(pte_val(pte) & _PAGE_INVALID)) 481 if (!(pte_val(pte) & _PAGE_INVALID))
@@ -483,13 +483,13 @@ extern inline pte_t pte_wrprotect(pte_t pte)
483 return pte; 483 return pte;
484} 484}
485 485
486extern inline pte_t pte_mkwrite(pte_t pte) 486static inline pte_t pte_mkwrite(pte_t pte)
487{ 487{
488 pte_val(pte) &= ~_PAGE_RO; 488 pte_val(pte) &= ~_PAGE_RO;
489 return pte; 489 return pte;
490} 490}
491 491
492extern inline pte_t pte_mkclean(pte_t pte) 492static inline pte_t pte_mkclean(pte_t pte)
493{ 493{
494 /* The only user of pte_mkclean is the fork() code. 494 /* The only user of pte_mkclean is the fork() code.
495 We must *not* clear the *physical* page dirty bit 495 We must *not* clear the *physical* page dirty bit
@@ -498,7 +498,7 @@ extern inline pte_t pte_mkclean(pte_t pte)
498 return pte; 498 return pte;
499} 499}
500 500
501extern inline pte_t pte_mkdirty(pte_t pte) 501static inline pte_t pte_mkdirty(pte_t pte)
502{ 502{
503 /* We do not explicitly set the dirty bit because the 503 /* We do not explicitly set the dirty bit because the
504 * sske instruction is slow. It is faster to let the 504 * sske instruction is slow. It is faster to let the
@@ -507,7 +507,7 @@ extern inline pte_t pte_mkdirty(pte_t pte)
507 return pte; 507 return pte;
508} 508}
509 509
510extern inline pte_t pte_mkold(pte_t pte) 510static inline pte_t pte_mkold(pte_t pte)
511{ 511{
512 /* S/390 doesn't keep its dirty/referenced bit in the pte. 512 /* S/390 doesn't keep its dirty/referenced bit in the pte.
513 * There is no point in clearing the real referenced bit. 513 * There is no point in clearing the real referenced bit.
@@ -515,7 +515,7 @@ extern inline pte_t pte_mkold(pte_t pte)
515 return pte; 515 return pte;
516} 516}
517 517
518extern inline pte_t pte_mkyoung(pte_t pte) 518static inline pte_t pte_mkyoung(pte_t pte)
519{ 519{
520 /* S/390 doesn't keep its dirty/referenced bit in the pte. 520 /* S/390 doesn't keep its dirty/referenced bit in the pte.
521 * There is no point in setting the real referenced bit. 521 * There is no point in setting the real referenced bit.
@@ -695,7 +695,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
695#ifndef __s390x__ 695#ifndef __s390x__
696 696
697/* Find an entry in the second-level page table.. */ 697/* Find an entry in the second-level page table.. */
698extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) 698static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
699{ 699{
700 return (pmd_t *) dir; 700 return (pmd_t *) dir;
701} 701}
@@ -758,7 +758,7 @@ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
758#else 758#else
759#define __SWP_OFFSET_MASK (~0UL >> 11) 759#define __SWP_OFFSET_MASK (~0UL >> 11)
760#endif 760#endif
761extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) 761static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
762{ 762{
763 pte_t pte; 763 pte_t pte;
764 offset &= __SWP_OFFSET_MASK; 764 offset &= __SWP_OFFSET_MASK;
diff --git a/include/asm-s390/sigp.h b/include/asm-s390/sigp.h
index 3979bc3858e2..fc56458aff66 100644
--- a/include/asm-s390/sigp.h
+++ b/include/asm-s390/sigp.h
@@ -67,7 +67,7 @@ typedef enum
67/* 67/*
68 * Signal processor 68 * Signal processor
69 */ 69 */
70extern __inline__ sigp_ccode 70static inline sigp_ccode
71signal_processor(__u16 cpu_addr, sigp_order_code order_code) 71signal_processor(__u16 cpu_addr, sigp_order_code order_code)
72{ 72{
73 sigp_ccode ccode; 73 sigp_ccode ccode;
@@ -86,7 +86,7 @@ signal_processor(__u16 cpu_addr, sigp_order_code order_code)
86/* 86/*
87 * Signal processor with parameter 87 * Signal processor with parameter
88 */ 88 */
89extern __inline__ sigp_ccode 89static inline sigp_ccode
90signal_processor_p(__u32 parameter, __u16 cpu_addr, 90signal_processor_p(__u32 parameter, __u16 cpu_addr,
91 sigp_order_code order_code) 91 sigp_order_code order_code)
92{ 92{
@@ -107,7 +107,7 @@ signal_processor_p(__u32 parameter, __u16 cpu_addr,
107/* 107/*
108 * Signal processor with parameter and return status 108 * Signal processor with parameter and return status
109 */ 109 */
110extern __inline__ sigp_ccode 110static inline sigp_ccode
111signal_processor_ps(__u32 *statusptr, __u32 parameter, 111signal_processor_ps(__u32 *statusptr, __u32 parameter,
112 __u16 cpu_addr, sigp_order_code order_code) 112 __u16 cpu_addr, sigp_order_code order_code)
113{ 113{
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h
index dd50e57a928f..a2ae7628bbaa 100644
--- a/include/asm-s390/smp.h
+++ b/include/asm-s390/smp.h
@@ -52,7 +52,7 @@ extern int smp_call_function_on(void (*func) (void *info), void *info,
52extern int smp_get_cpu(cpumask_t cpu_map); 52extern int smp_get_cpu(cpumask_t cpu_map);
53extern void smp_put_cpu(int cpu); 53extern void smp_put_cpu(int cpu);
54 54
55extern __inline__ __u16 hard_smp_processor_id(void) 55static inline __u16 hard_smp_processor_id(void)
56{ 56{
57 __u16 cpu_address; 57 __u16 cpu_address;
58 58
diff --git a/include/asm-sh/ide.h b/include/asm-sh/ide.h
index f42cf3977a57..711dad4cb48b 100644
--- a/include/asm-sh/ide.h
+++ b/include/asm-sh/ide.h
@@ -16,10 +16,6 @@
16 16
17#include <linux/config.h> 17#include <linux/config.h>
18 18
19#ifndef MAX_HWIFS
20#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
21#endif
22
23#define ide_default_io_ctl(base) (0) 19#define ide_default_io_ctl(base) (0)
24 20
25#include <asm-generic/ide_iops.h> 21#include <asm-generic/ide_iops.h>
diff --git a/include/asm-sh64/ide.h b/include/asm-sh64/ide.h
index 6fd514daa1ba..852f50afe39c 100644
--- a/include/asm-sh64/ide.h
+++ b/include/asm-sh64/ide.h
@@ -17,10 +17,6 @@
17 17
18#include <linux/config.h> 18#include <linux/config.h>
19 19
20#ifndef MAX_HWIFS
21#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
22#endif
23
24/* Without this, the initialisation of PCI IDE cards end up calling 20/* Without this, the initialisation of PCI IDE cards end up calling
25 * ide_init_hwif_ports, which won't work. */ 21 * ide_init_hwif_ports, which won't work. */
26#ifdef CONFIG_BLK_DEV_IDEPCI 22#ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index ecb0d39c0798..2209ad3499a3 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -10,6 +10,10 @@
10#define ULONG_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl) 10#define ULONG_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl)
11#endif 11#endif
12 12
13
14COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */
15COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */
16
13/* Big T */ 17/* Big T */
14COMPATIBLE_IOCTL(TCGETA) 18COMPATIBLE_IOCTL(TCGETA)
15COMPATIBLE_IOCTL(TCSETA) 19COMPATIBLE_IOCTL(TCSETA)
@@ -52,13 +56,6 @@ ULONG_IOCTL(TIOCSCTTY)
52COMPATIBLE_IOCTL(TIOCGPTN) 56COMPATIBLE_IOCTL(TIOCGPTN)
53COMPATIBLE_IOCTL(TIOCSPTLCK) 57COMPATIBLE_IOCTL(TIOCSPTLCK)
54COMPATIBLE_IOCTL(TIOCSERGETLSR) 58COMPATIBLE_IOCTL(TIOCSERGETLSR)
55/* Big F */
56COMPATIBLE_IOCTL(FBIOBLANK)
57COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
58COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
59COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
60COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP)
61COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)
62/* Little f */ 59/* Little f */
63COMPATIBLE_IOCTL(FIOCLEX) 60COMPATIBLE_IOCTL(FIOCLEX)
64COMPATIBLE_IOCTL(FIONCLEX) 61COMPATIBLE_IOCTL(FIONCLEX)
@@ -81,6 +78,8 @@ COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
81COMPATIBLE_IOCTL(HDIO_DRIVE_TASK) 78COMPATIBLE_IOCTL(HDIO_DRIVE_TASK)
82COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE) 79COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE)
83COMPATIBLE_IOCTL(HDIO_SET_NICE) 80COMPATIBLE_IOCTL(HDIO_SET_NICE)
81COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS)
82COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
84/* 0x02 -- Floppy ioctls */ 83/* 0x02 -- Floppy ioctls */
85COMPATIBLE_IOCTL(FDMSGON) 84COMPATIBLE_IOCTL(FDMSGON)
86COMPATIBLE_IOCTL(FDMSGOFF) 85COMPATIBLE_IOCTL(FDMSGOFF)
@@ -99,6 +98,7 @@ COMPATIBLE_IOCTL(FDTWADDLE)
99COMPATIBLE_IOCTL(FDFMTTRK) 98COMPATIBLE_IOCTL(FDFMTTRK)
100COMPATIBLE_IOCTL(FDRAWCMD) 99COMPATIBLE_IOCTL(FDRAWCMD)
101/* 0x12 */ 100/* 0x12 */
101COMPATIBLE_IOCTL(BLKRASET)
102COMPATIBLE_IOCTL(BLKROSET) 102COMPATIBLE_IOCTL(BLKROSET)
103COMPATIBLE_IOCTL(BLKROGET) 103COMPATIBLE_IOCTL(BLKROGET)
104COMPATIBLE_IOCTL(BLKRRPART) 104COMPATIBLE_IOCTL(BLKRRPART)
@@ -262,6 +262,7 @@ COMPATIBLE_IOCTL(RTC_WKALM_RD)
262/* Little m */ 262/* Little m */
263COMPATIBLE_IOCTL(MTIOCTOP) 263COMPATIBLE_IOCTL(MTIOCTOP)
264/* Socket level stuff */ 264/* Socket level stuff */
265COMPATIBLE_IOCTL(FIOQSIZE)
265COMPATIBLE_IOCTL(FIOSETOWN) 266COMPATIBLE_IOCTL(FIOSETOWN)
266COMPATIBLE_IOCTL(SIOCSPGRP) 267COMPATIBLE_IOCTL(SIOCSPGRP)
267COMPATIBLE_IOCTL(FIOGETOWN) 268COMPATIBLE_IOCTL(FIOGETOWN)
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 1f7b2c097503..43c44530ef9d 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -42,6 +42,7 @@ struct notifier_block;
42/* Need to know about CPUs going up/down? */ 42/* Need to know about CPUs going up/down? */
43extern int register_cpu_notifier(struct notifier_block *nb); 43extern int register_cpu_notifier(struct notifier_block *nb);
44extern void unregister_cpu_notifier(struct notifier_block *nb); 44extern void unregister_cpu_notifier(struct notifier_block *nb);
45extern int current_in_cpu_hotplug(void);
45 46
46int cpu_up(unsigned int cpu); 47int cpu_up(unsigned int cpu);
47 48
@@ -54,6 +55,10 @@ static inline int register_cpu_notifier(struct notifier_block *nb)
54static inline void unregister_cpu_notifier(struct notifier_block *nb) 55static inline void unregister_cpu_notifier(struct notifier_block *nb)
55{ 56{
56} 57}
58static inline int current_in_cpu_hotplug(void)
59{
60 return 0;
61}
57 62
58#endif /* CONFIG_SMP */ 63#endif /* CONFIG_SMP */
59extern struct sysdev_class cpu_sysdev_class; 64extern struct sysdev_class cpu_sysdev_class;
diff --git a/include/linux/eeprom.h b/include/linux/eeprom.h
deleted file mode 100644
index 38afd9da1dfe..000000000000
--- a/include/linux/eeprom.h
+++ /dev/null
@@ -1,136 +0,0 @@
1/* credit winbond-840.c
2 */
3#include <asm/io.h>
4struct eeprom_ops {
5 void (*set_cs)(void *ee);
6 void (*clear_cs)(void *ee);
7};
8
9#define EEPOL_EEDI 0x01
10#define EEPOL_EEDO 0x02
11#define EEPOL_EECLK 0x04
12#define EEPOL_EESEL 0x08
13
14struct eeprom {
15 void *dev;
16 struct eeprom_ops *ops;
17
18 void __iomem * addr;
19
20 unsigned ee_addr_bits;
21
22 unsigned eesel;
23 unsigned eeclk;
24 unsigned eedo;
25 unsigned eedi;
26 unsigned polarity;
27 unsigned ee_state;
28
29 spinlock_t *lock;
30 u32 *cache;
31};
32
33
34u8 eeprom_readb(struct eeprom *ee, unsigned address);
35void eeprom_read(struct eeprom *ee, unsigned address, u8 *bytes,
36 unsigned count);
37void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data);
38void eeprom_write(struct eeprom *ee, unsigned address, u8 *bytes,
39 unsigned count);
40
41/* The EEPROM commands include the alway-set leading bit. */
42enum EEPROM_Cmds {
43 EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
44};
45
46void setup_ee_mem_bitbanger(struct eeprom *ee, void __iomem *memaddr, int eesel_bit, int eeclk_bit, int eedo_bit, int eedi_bit, unsigned polarity)
47{
48 ee->addr = memaddr;
49 ee->eesel = 1 << eesel_bit;
50 ee->eeclk = 1 << eeclk_bit;
51 ee->eedo = 1 << eedo_bit;
52 ee->eedi = 1 << eedi_bit;
53
54 ee->polarity = polarity;
55
56 *ee->cache = readl(ee->addr);
57}
58
59/* foo. put this in a .c file */
60static inline void eeprom_update(struct eeprom *ee, u32 mask, int pol)
61{
62 unsigned long flags;
63 u32 data;
64
65 spin_lock_irqsave(ee->lock, flags);
66 data = *ee->cache;
67
68 data &= ~mask;
69 if (pol)
70 data |= mask;
71
72 *ee->cache = data;
73//printk("update: %08x\n", data);
74 writel(data, ee->addr);
75 spin_unlock_irqrestore(ee->lock, flags);
76}
77
78void eeprom_clk_lo(struct eeprom *ee)
79{
80 int pol = !!(ee->polarity & EEPOL_EECLK);
81
82 eeprom_update(ee, ee->eeclk, pol);
83 udelay(2);
84}
85
86void eeprom_clk_hi(struct eeprom *ee)
87{
88 int pol = !!(ee->polarity & EEPOL_EECLK);
89
90 eeprom_update(ee, ee->eeclk, !pol);
91 udelay(2);
92}
93
94void eeprom_send_addr(struct eeprom *ee, unsigned address)
95{
96 int pol = !!(ee->polarity & EEPOL_EEDI);
97 unsigned i;
98 address |= 6 << 6;
99
100 /* Shift the read command bits out. */
101 for (i=0; i<11; i++) {
102 eeprom_update(ee, ee->eedi, ((address >> 10) & 1) ^ pol);
103 address <<= 1;
104 eeprom_clk_hi(ee);
105 eeprom_clk_lo(ee);
106 }
107 eeprom_update(ee, ee->eedi, pol);
108}
109
110u16 eeprom_readw(struct eeprom *ee, unsigned address)
111{
112 unsigned i;
113 u16 res = 0;
114
115 eeprom_clk_lo(ee);
116 eeprom_update(ee, ee->eesel, 1 ^ !!(ee->polarity & EEPOL_EESEL));
117 eeprom_send_addr(ee, address);
118
119 for (i=0; i<16; i++) {
120 u32 data;
121 eeprom_clk_hi(ee);
122 res <<= 1;
123 data = readl(ee->addr);
124//printk("eeprom_readw: %08x\n", data);
125 res |= !!(data & ee->eedo) ^ !!(ee->polarity & EEPOL_EEDO);
126 eeprom_clk_lo(ee);
127 }
128 eeprom_update(ee, ee->eesel, 0 ^ !!(ee->polarity & EEPOL_EESEL));
129
130 return res;
131}
132
133
134void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data)
135{
136}
diff --git a/include/linux/fb.h b/include/linux/fb.h
index e7ff98e395f6..04a58f33ec53 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -201,6 +201,14 @@ struct fb_bitfield {
201#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */ 201#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
202#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */ 202#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
203 203
204/*
205 * Display rotation support
206 */
207#define FB_ROTATE_UR 0
208#define FB_ROTATE_CW 1
209#define FB_ROTATE_UD 2
210#define FB_ROTATE_CCW 3
211
204#define PICOS2KHZ(a) (1000000000UL/(a)) 212#define PICOS2KHZ(a) (1000000000UL/(a))
205#define KHZ2PICOS(a) (1000000000UL/(a)) 213#define KHZ2PICOS(a) (1000000000UL/(a))
206 214
@@ -489,9 +497,9 @@ struct fb_cursor_user {
489#define FB_EVENT_MODE_DELETE 0x04 497#define FB_EVENT_MODE_DELETE 0x04
490/* A driver registered itself */ 498/* A driver registered itself */
491#define FB_EVENT_FB_REGISTERED 0x05 499#define FB_EVENT_FB_REGISTERED 0x05
492/* get console to framebuffer mapping */ 500/* CONSOLE-SPECIFIC: get console to framebuffer mapping */
493#define FB_EVENT_GET_CONSOLE_MAP 0x06 501#define FB_EVENT_GET_CONSOLE_MAP 0x06
494/* set console to framebuffer mapping */ 502/* CONSOLE-SPECIFIC: set console to framebuffer mapping */
495#define FB_EVENT_SET_CONSOLE_MAP 0x07 503#define FB_EVENT_SET_CONSOLE_MAP 0x07
496/* A display blank is requested */ 504/* A display blank is requested */
497#define FB_EVENT_BLANK 0x08 505#define FB_EVENT_BLANK 0x08
@@ -500,6 +508,12 @@ struct fb_cursor_user {
500/* The resolution of the passed in fb_info about to change and 508/* The resolution of the passed in fb_info about to change and
501 all vc's should be changed */ 509 all vc's should be changed */
502#define FB_EVENT_MODE_CHANGE_ALL 0x0A 510#define FB_EVENT_MODE_CHANGE_ALL 0x0A
511/* CONSOLE-SPECIFIC: set console rotation */
512#define FB_EVENT_SET_CON_ROTATE 0x0B
513/* CONSOLE-SPECIFIC: get console rotation */
514#define FB_EVENT_GET_CON_ROTATE 0x0C
515/* CONSOLE-SPECIFIC: rotate all consoles */
516#define FB_EVENT_SET_CON_ROTATE_ALL 0x0D
503 517
504struct fb_event { 518struct fb_event {
505 struct fb_info *info; 519 struct fb_info *info;
@@ -817,8 +831,8 @@ extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
817/* drivers/video/fbmem.c */ 831/* drivers/video/fbmem.c */
818extern int register_framebuffer(struct fb_info *fb_info); 832extern int register_framebuffer(struct fb_info *fb_info);
819extern int unregister_framebuffer(struct fb_info *fb_info); 833extern int unregister_framebuffer(struct fb_info *fb_info);
820extern int fb_prepare_logo(struct fb_info *fb_info); 834extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
821extern int fb_show_logo(struct fb_info *fb_info); 835extern int fb_show_logo(struct fb_info *fb_info, int rotate);
822extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size); 836extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
823extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx, 837extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx,
824 u32 height, u32 shift_high, u32 shift_low, u32 mod); 838 u32 height, u32 shift_high, u32 shift_low, u32 mod);
@@ -828,6 +842,7 @@ extern int fb_get_color_depth(struct fb_var_screeninfo *var,
828 struct fb_fix_screeninfo *fix); 842 struct fb_fix_screeninfo *fix);
829extern int fb_get_options(char *name, char **option); 843extern int fb_get_options(char *name, char **option);
830extern int fb_new_modelist(struct fb_info *info); 844extern int fb_new_modelist(struct fb_info *info);
845extern int fb_con_duit(struct fb_info *info, int event, void *data);
831 846
832extern struct fb_info *registered_fb[FB_MAX]; 847extern struct fb_info *registered_fb[FB_MAX];
833extern int num_registered_fb; 848extern int num_registered_fb;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1b5f502a4b8f..cc35b6ac778d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -874,6 +874,7 @@ static inline void unlock_super(struct super_block * sb)
874/* 874/*
875 * VFS helper functions.. 875 * VFS helper functions..
876 */ 876 */
877extern int vfs_permission(struct nameidata *, int);
877extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); 878extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
878extern int vfs_mkdir(struct inode *, struct dentry *, int); 879extern int vfs_mkdir(struct inode *, struct dentry *, int);
879extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t); 880extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
@@ -889,6 +890,11 @@ extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct de
889extern void dentry_unhash(struct dentry *dentry); 890extern void dentry_unhash(struct dentry *dentry);
890 891
891/* 892/*
893 * VFS file helper functions.
894 */
895extern int file_permission(struct file *, int);
896
897/*
892 * File types 898 * File types
893 * 899 *
894 * NOTE! These match bits 12..15 of stat.st_mode 900 * NOTE! These match bits 12..15 of stat.st_mode
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
index bef23bbf8690..783c476b8674 100644
--- a/include/linux/fs_enet_pd.h
+++ b/include/linux/fs_enet_pd.h
@@ -16,7 +16,6 @@
16#ifndef FS_ENET_PD_H 16#ifndef FS_ENET_PD_H
17#define FS_ENET_PD_H 17#define FS_ENET_PD_H
18 18
19#include <linux/version.h>
20#include <asm/types.h> 19#include <asm/types.h>
21 20
22#define FS_ENET_NAME "fs_enet" 21#define FS_ENET_NAME "fs_enet"
diff --git a/include/linux/genetlink.h b/include/linux/genetlink.h
new file mode 100644
index 000000000000..84f12a41dc01
--- /dev/null
+++ b/include/linux/genetlink.h
@@ -0,0 +1,51 @@
1#ifndef __LINUX_GENERIC_NETLINK_H
2#define __LINUX_GENERIC_NETLINK_H
3
4#include <linux/netlink.h>
5
6#define GENL_NAMSIZ 16 /* length of family name */
7
8#define GENL_MIN_ID NLMSG_MIN_TYPE
9#define GENL_MAX_ID 1023
10
11struct genlmsghdr {
12 __u8 cmd;
13 __u8 version;
14 __u16 reserved;
15};
16
17#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))
18
19/*
20 * List of reserved static generic netlink identifiers:
21 */
22#define GENL_ID_GENERATE 0
23#define GENL_ID_CTRL NLMSG_MIN_TYPE
24
25/**************************************************************************
26 * Controller
27 **************************************************************************/
28
29enum {
30 CTRL_CMD_UNSPEC,
31 CTRL_CMD_NEWFAMILY,
32 CTRL_CMD_DELFAMILY,
33 CTRL_CMD_GETFAMILY,
34 CTRL_CMD_NEWOPS,
35 CTRL_CMD_DELOPS,
36 CTRL_CMD_GETOPS,
37 __CTRL_CMD_MAX,
38};
39
40#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1)
41
42enum {
43 CTRL_ATTR_UNSPEC,
44 CTRL_ATTR_FAMILY_ID,
45 CTRL_ATTR_FAMILY_NAME,
46 __CTRL_ATTR_MAX,
47};
48
49#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1)
50
51#endif /* __LINUX_GENERIC_NETLINK_H */
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 1ce4b54caa21..74abaecdb572 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -27,10 +27,10 @@
27 * ---- Driver types ----------------------------------------------------- 27 * ---- Driver types -----------------------------------------------------
28 * device id name + number function description, i2c address(es) 28 * device id name + number function description, i2c address(es)
29 * 29 *
30 * Range 1000-1999 range is defined in sensors/sensors.h 30 * Range 1000-1999 range is defined in sensors/sensors.h
31 * Range 0x100 - 0x1ff is for V4L2 Common Components 31 * Range 0x100 - 0x1ff is for V4L2 Common Components
32 * Range 0xf000 - 0xffff is reserved for local experimentation, and should 32 * Range 0xf000 - 0xffff is reserved for local experimentation, and should
33 * never be used in official drivers 33 * never be used in official drivers
34 */ 34 */
35 35
36#define I2C_DRIVERID_MSP3400 1 36#define I2C_DRIVERID_MSP3400 1
@@ -99,7 +99,14 @@
99#define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */ 99#define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */
100#define I2C_DRIVERID_SAA7114H 64 /* video decoder */ 100#define I2C_DRIVERID_SAA7114H 64 /* video decoder */
101#define I2C_DRIVERID_DS1374 65 /* DS1374 real time clock */ 101#define I2C_DRIVERID_DS1374 65 /* DS1374 real time clock */
102 102#define I2C_DRIVERID_TDA9874 66 /* TV sound decoder */
103#define I2C_DRIVERID_SAA6752HS 67 /* MPEG2 encoder */
104#define I2C_DRIVERID_TVEEPROM 68 /* TV EEPROM */
105#define I2C_DRIVERID_WM8775 69 /* wm8775 audio processor */
106#define I2C_DRIVERID_CS53L32A 70 /* cs53l32a audio processor */
107#define I2C_DRIVERID_CX25840 71 /* cx2584x video encoder */
108#define I2C_DRIVERID_SAA7127 72 /* saa7124 video encoder */
109#define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */
103 110
104#define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */ 111#define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
105#define I2C_DRIVERID_EXP1 0xF1 112#define I2C_DRIVERID_EXP1 0xF1
@@ -111,7 +118,7 @@
111#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ 118#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
112#define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */ 119#define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */
113 120
114/* IDs -- Use DRIVERIDs 1000-1999 for sensors. 121/* IDs -- Use DRIVERIDs 1000-1999 for sensors.
115 These were originally in sensors.h in the lm_sensors package */ 122 These were originally in sensors.h in the lm_sensors package */
116#define I2C_DRIVERID_LM78 1002 123#define I2C_DRIVERID_LM78 1002
117#define I2C_DRIVERID_LM75 1003 124#define I2C_DRIVERID_LM75 1003
@@ -190,6 +197,7 @@
190#define I2C_HW_B_NVIDIA 0x01001c /* nvidia framebuffer driver */ 197#define I2C_HW_B_NVIDIA 0x01001c /* nvidia framebuffer driver */
191#define I2C_HW_B_SAVAGE 0x01001d /* savage framebuffer driver */ 198#define I2C_HW_B_SAVAGE 0x01001d /* savage framebuffer driver */
192#define I2C_HW_B_RADEON 0x01001e /* radeon framebuffer driver */ 199#define I2C_HW_B_RADEON 0x01001e /* radeon framebuffer driver */
200#define I2C_HW_B_EM28XX 0x01001f /* em28xx video capture cards */
193 201
194/* --- PCF 8584 based algorithms */ 202/* --- PCF 8584 based algorithms */
195#define I2C_HW_P_LP 0x020000 /* Parallel port interface */ 203#define I2C_HW_P_LP 0x020000 /* Parallel port interface */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 3461abc1e854..77ae55d4c13c 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -230,6 +230,7 @@ typedef struct hw_regs_s {
230 int dma; /* our dma entry */ 230 int dma; /* our dma entry */
231 ide_ack_intr_t *ack_intr; /* acknowledge interrupt */ 231 ide_ack_intr_t *ack_intr; /* acknowledge interrupt */
232 hwif_chipset_t chipset; 232 hwif_chipset_t chipset;
233 struct device *dev;
233} hw_regs_t; 234} hw_regs_t;
234 235
235/* 236/*
@@ -266,6 +267,10 @@ static inline void ide_std_init_ports(hw_regs_t *hw,
266 267
267#include <asm/ide.h> 268#include <asm/ide.h>
268 269
270#ifndef MAX_HWIFS
271#define MAX_HWIFS CONFIG_IDE_MAX_HWIFS
272#endif
273
269/* needed on alpha, x86/x86_64, ia64, mips, ppc32 and sh */ 274/* needed on alpha, x86/x86_64, ia64, mips, ppc32 and sh */
270#ifndef IDE_ARCH_OBSOLETE_DEFAULTS 275#ifndef IDE_ARCH_OBSOLETE_DEFAULTS
271# define ide_default_io_base(index) (0) 276# define ide_default_io_base(index) (0)
diff --git a/include/linux/if_ppp.h b/include/linux/if_ppp.h
index 572aff7daa21..768372f07caa 100644
--- a/include/linux/if_ppp.h
+++ b/include/linux/if_ppp.h
@@ -21,7 +21,7 @@
21 */ 21 */
22 22
23/* 23/*
24 * ==FILEVERSION 20000724== 24 * ==FILEVERSION 20050812==
25 * 25 *
26 * NOTE TO MAINTAINERS: 26 * NOTE TO MAINTAINERS:
27 * If you modify this file at all, please set the above date. 27 * If you modify this file at all, please set the above date.
@@ -35,6 +35,8 @@
35#ifndef _IF_PPP_H_ 35#ifndef _IF_PPP_H_
36#define _IF_PPP_H_ 36#define _IF_PPP_H_
37 37
38#include <linux/compiler.h>
39
38/* 40/*
39 * Packet sizes 41 * Packet sizes
40 */ 42 */
@@ -70,7 +72,8 @@
70#define SC_LOG_RAWIN 0x00080000 /* log all chars received */ 72#define SC_LOG_RAWIN 0x00080000 /* log all chars received */
71#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */ 73#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */
72#define SC_SYNC 0x00200000 /* synchronous serial mode */ 74#define SC_SYNC 0x00200000 /* synchronous serial mode */
73#define SC_MASK 0x0f200fff /* bits that user can change */ 75#define SC_MUST_COMP 0x00400000 /* no uncompressed packets may be sent or received */
76#define SC_MASK 0x0f600fff /* bits that user can change */
74 77
75/* state bits */ 78/* state bits */
76#define SC_XMIT_BUSY 0x10000000 /* (used by isdn_ppp?) */ 79#define SC_XMIT_BUSY 0x10000000 /* (used by isdn_ppp?) */
diff --git a/include/linux/if_wanpipe_common.h b/include/linux/if_wanpipe_common.h
index f25fec8ee2ca..6e5461d69fdd 100644
--- a/include/linux/if_wanpipe_common.h
+++ b/include/linux/if_wanpipe_common.h
@@ -17,8 +17,6 @@
17#ifndef _WANPIPE_SOCK_DRIVER_COMMON_H 17#ifndef _WANPIPE_SOCK_DRIVER_COMMON_H
18#define _WANPIPE_SOCK_DRIVER_COMMON_H 18#define _WANPIPE_SOCK_DRIVER_COMMON_H
19 19
20#include <linux/version.h>
21
22typedef struct { 20typedef struct {
23 struct net_device *slave; 21 struct net_device *slave;
24 atomic_t packet_sent; 22 atomic_t packet_sent;
diff --git a/include/linux/istallion.h b/include/linux/istallion.h
index 5f4ee646c119..1f996621bc9c 100644
--- a/include/linux/istallion.h
+++ b/include/linux/istallion.h
@@ -21,8 +21,6 @@
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */ 22 */
23 23
24#include <linux/version.h>
25
26/*****************************************************************************/ 24/*****************************************************************************/
27#ifndef _ISTALLION_H 25#ifndef _ISTALLION_H
28#define _ISTALLION_H 26#define _ISTALLION_H
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index 39f1430bd6d5..3c9ea4b7adda 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -8,7 +8,6 @@
8#define __MTD_CFI_H__ 8#define __MTD_CFI_H__
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/version.h>
12#include <linux/delay.h> 11#include <linux/delay.h>
13#include <linux/types.h> 12#include <linux/types.h>
14#include <linux/interrupt.h> 13#include <linux/interrupt.h>
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index e95d0463a3e5..b6f2fdae65c6 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -14,7 +14,6 @@
14#endif 14#endif
15 15
16#include <linux/config.h> 16#include <linux/config.h>
17#include <linux/version.h>
18#include <linux/types.h> 17#include <linux/types.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/uio.h> 19#include <linux/uio.h>
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 1c975d0d9e94..455660eafba9 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -74,7 +74,7 @@ extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
74extern void release_open_intent(struct nameidata *); 74extern void release_open_intent(struct nameidata *);
75 75
76extern struct dentry * lookup_one_len(const char *, struct dentry *, int); 76extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
77extern struct dentry * lookup_hash(struct qstr *, struct dentry *); 77extern struct dentry * lookup_hash(struct nameidata *);
78 78
79extern int follow_down(struct vfsmount **, struct dentry **); 79extern int follow_down(struct vfsmount **, struct dentry **);
80extern int follow_up(struct vfsmount **, struct dentry **); 80extern int follow_up(struct vfsmount **, struct dentry **);
diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h
new file mode 100644
index 000000000000..6d39b518486b
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_common.h
@@ -0,0 +1,159 @@
1#ifndef _NF_CONNTRACK_COMMON_H
2#define _NF_CONNTRACK_COMMON_H
3/* Connection state tracking for netfilter. This is separated from,
4 but required by, the NAT layer; it can also be used by an iptables
5 extension. */
6enum ip_conntrack_info
7{
8 /* Part of an established connection (either direction). */
9 IP_CT_ESTABLISHED,
10
11 /* Like NEW, but related to an existing connection, or ICMP error
12 (in either direction). */
13 IP_CT_RELATED,
14
15 /* Started a new connection to track (only
16 IP_CT_DIR_ORIGINAL); may be a retransmission. */
17 IP_CT_NEW,
18
19 /* >= this indicates reply direction */
20 IP_CT_IS_REPLY,
21
22 /* Number of distinct IP_CT types (no NEW in reply dirn). */
23 IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
24};
25
26/* Bitset representing status of connection. */
27enum ip_conntrack_status {
28 /* It's an expected connection: bit 0 set. This bit never changed */
29 IPS_EXPECTED_BIT = 0,
30 IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
31
32 /* We've seen packets both ways: bit 1 set. Can be set, not unset. */
33 IPS_SEEN_REPLY_BIT = 1,
34 IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
35
36 /* Conntrack should never be early-expired. */
37 IPS_ASSURED_BIT = 2,
38 IPS_ASSURED = (1 << IPS_ASSURED_BIT),
39
40 /* Connection is confirmed: originating packet has left box */
41 IPS_CONFIRMED_BIT = 3,
42 IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
43
44 /* Connection needs src nat in orig dir. This bit never changed. */
45 IPS_SRC_NAT_BIT = 4,
46 IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
47
48 /* Connection needs dst nat in orig dir. This bit never changed. */
49 IPS_DST_NAT_BIT = 5,
50 IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
51
52 /* Both together. */
53 IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
54
55 /* Connection needs TCP sequence adjusted. */
56 IPS_SEQ_ADJUST_BIT = 6,
57 IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
58
59 /* NAT initialization bits. */
60 IPS_SRC_NAT_DONE_BIT = 7,
61 IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
62
63 IPS_DST_NAT_DONE_BIT = 8,
64 IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
65
66 /* Both together */
67 IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
68
69 /* Connection is dying (removed from lists), can not be unset. */
70 IPS_DYING_BIT = 9,
71 IPS_DYING = (1 << IPS_DYING_BIT),
72};
73
74/* Connection tracking event bits */
75enum ip_conntrack_events
76{
77 /* New conntrack */
78 IPCT_NEW_BIT = 0,
79 IPCT_NEW = (1 << IPCT_NEW_BIT),
80
81 /* Expected connection */
82 IPCT_RELATED_BIT = 1,
83 IPCT_RELATED = (1 << IPCT_RELATED_BIT),
84
85 /* Destroyed conntrack */
86 IPCT_DESTROY_BIT = 2,
87 IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
88
89 /* Timer has been refreshed */
90 IPCT_REFRESH_BIT = 3,
91 IPCT_REFRESH = (1 << IPCT_REFRESH_BIT),
92
93 /* Status has changed */
94 IPCT_STATUS_BIT = 4,
95 IPCT_STATUS = (1 << IPCT_STATUS_BIT),
96
97 /* Update of protocol info */
98 IPCT_PROTOINFO_BIT = 5,
99 IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
100
101 /* Volatile protocol info */
102 IPCT_PROTOINFO_VOLATILE_BIT = 6,
103 IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT),
104
105 /* New helper for conntrack */
106 IPCT_HELPER_BIT = 7,
107 IPCT_HELPER = (1 << IPCT_HELPER_BIT),
108
109 /* Update of helper info */
110 IPCT_HELPINFO_BIT = 8,
111 IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT),
112
113 /* Volatile helper info */
114 IPCT_HELPINFO_VOLATILE_BIT = 9,
115 IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT),
116
117 /* NAT info */
118 IPCT_NATINFO_BIT = 10,
119 IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
120
121 /* Counter highest bit has been set */
122 IPCT_COUNTER_FILLING_BIT = 11,
123 IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
124};
125
126enum ip_conntrack_expect_events {
127 IPEXP_NEW_BIT = 0,
128 IPEXP_NEW = (1 << IPEXP_NEW_BIT),
129};
130
131#ifdef __KERNEL__
132struct ip_conntrack_counter
133{
134 u_int32_t packets;
135 u_int32_t bytes;
136};
137
138struct ip_conntrack_stat
139{
140 unsigned int searched;
141 unsigned int found;
142 unsigned int new;
143 unsigned int invalid;
144 unsigned int ignore;
145 unsigned int delete;
146 unsigned int delete_list;
147 unsigned int insert;
148 unsigned int insert_failed;
149 unsigned int drop;
150 unsigned int early_drop;
151 unsigned int error;
152 unsigned int expect_new;
153 unsigned int expect_create;
154 unsigned int expect_delete;
155};
156
157#endif /* __KERNEL__ */
158
159#endif /* _NF_CONNTRACK_COMMON_H */
diff --git a/include/linux/netfilter/nf_conntrack_ftp.h b/include/linux/netfilter/nf_conntrack_ftp.h
new file mode 100644
index 000000000000..ad4a41c9ce93
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_ftp.h
@@ -0,0 +1,44 @@
1#ifndef _NF_CONNTRACK_FTP_H
2#define _NF_CONNTRACK_FTP_H
3/* FTP tracking. */
4
5/* This enum is exposed to userspace */
6enum ip_ct_ftp_type
7{
8 /* PORT command from client */
9 IP_CT_FTP_PORT,
10 /* PASV response from server */
11 IP_CT_FTP_PASV,
12 /* EPRT command from client */
13 IP_CT_FTP_EPRT,
14 /* EPSV response from server */
15 IP_CT_FTP_EPSV,
16};
17
18#ifdef __KERNEL__
19
20#define FTP_PORT 21
21
22#define NUM_SEQ_TO_REMEMBER 2
23/* This structure exists only once per master */
24struct ip_ct_ftp_master {
25 /* Valid seq positions for cmd matching after newline */
26 u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
27 /* 0 means seq_match_aft_nl not set */
28 int seq_aft_nl_num[IP_CT_DIR_MAX];
29};
30
31struct ip_conntrack_expect;
32
33/* For NAT to hook in when we find a packet which describes what other
34 * connection we should expect. */
35extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
36 enum ip_conntrack_info ctinfo,
37 enum ip_ct_ftp_type type,
38 unsigned int matchoff,
39 unsigned int matchlen,
40 struct ip_conntrack_expect *exp,
41 u32 *seq);
42#endif /* __KERNEL__ */
43
44#endif /* _NF_CONNTRACK_FTP_H */
diff --git a/include/linux/netfilter/nf_conntrack_sctp.h b/include/linux/netfilter/nf_conntrack_sctp.h
new file mode 100644
index 000000000000..b8994d9fd1a9
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_sctp.h
@@ -0,0 +1,27 @@
1#ifndef _NF_CONNTRACK_SCTP_H
2#define _NF_CONNTRACK_SCTP_H
3/* SCTP tracking. */
4
5#include <linux/netfilter/nf_conntrack_tuple_common.h>
6
7enum sctp_conntrack {
8 SCTP_CONNTRACK_NONE,
9 SCTP_CONNTRACK_CLOSED,
10 SCTP_CONNTRACK_COOKIE_WAIT,
11 SCTP_CONNTRACK_COOKIE_ECHOED,
12 SCTP_CONNTRACK_ESTABLISHED,
13 SCTP_CONNTRACK_SHUTDOWN_SENT,
14 SCTP_CONNTRACK_SHUTDOWN_RECD,
15 SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
16 SCTP_CONNTRACK_MAX
17};
18
19struct ip_ct_sctp
20{
21 enum sctp_conntrack state;
22
23 u_int32_t vtag[IP_CT_DIR_MAX];
24 u_int32_t ttag[IP_CT_DIR_MAX];
25};
26
27#endif /* _NF_CONNTRACK_SCTP_H */
diff --git a/include/linux/netfilter/nf_conntrack_tcp.h b/include/linux/netfilter/nf_conntrack_tcp.h
new file mode 100644
index 000000000000..b2feeffde384
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_tcp.h
@@ -0,0 +1,56 @@
1#ifndef _NF_CONNTRACK_TCP_H
2#define _NF_CONNTRACK_TCP_H
3/* TCP tracking. */
4
5/* This is exposed to userspace (ctnetlink) */
6enum tcp_conntrack {
7 TCP_CONNTRACK_NONE,
8 TCP_CONNTRACK_SYN_SENT,
9 TCP_CONNTRACK_SYN_RECV,
10 TCP_CONNTRACK_ESTABLISHED,
11 TCP_CONNTRACK_FIN_WAIT,
12 TCP_CONNTRACK_CLOSE_WAIT,
13 TCP_CONNTRACK_LAST_ACK,
14 TCP_CONNTRACK_TIME_WAIT,
15 TCP_CONNTRACK_CLOSE,
16 TCP_CONNTRACK_LISTEN,
17 TCP_CONNTRACK_MAX,
18 TCP_CONNTRACK_IGNORE
19};
20
21/* Window scaling is advertised by the sender */
22#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01
23
24/* SACK is permitted by the sender */
25#define IP_CT_TCP_FLAG_SACK_PERM 0x02
26
27/* This sender sent FIN first */
28#define IP_CT_TCP_FLAG_CLOSE_INIT 0x03
29
30#ifdef __KERNEL__
31
32struct ip_ct_tcp_state {
33 u_int32_t td_end; /* max of seq + len */
34 u_int32_t td_maxend; /* max of ack + max(win, 1) */
35 u_int32_t td_maxwin; /* max(win) */
36 u_int8_t td_scale; /* window scale factor */
37 u_int8_t loose; /* used when connection picked up from the middle */
38 u_int8_t flags; /* per direction options */
39};
40
41struct ip_ct_tcp
42{
43 struct ip_ct_tcp_state seen[2]; /* connection parameters per direction */
44 u_int8_t state; /* state of the connection (enum tcp_conntrack) */
45 /* For detecting stale connections */
46 u_int8_t last_dir; /* Direction of the last packet (enum ip_conntrack_dir) */
47 u_int8_t retrans; /* Number of retransmitted packets */
48 u_int8_t last_index; /* Index of the last packet */
49 u_int32_t last_seq; /* Last sequence number seen in dir */
50 u_int32_t last_ack; /* Last sequence number seen in opposite dir */
51 u_int32_t last_end; /* Last seq + len */
52};
53
54#endif /* __KERNEL__ */
55
56#endif /* _NF_CONNTRACK_TCP_H */
diff --git a/include/linux/netfilter/nf_conntrack_tuple_common.h b/include/linux/netfilter/nf_conntrack_tuple_common.h
new file mode 100644
index 000000000000..8e145f0d61cb
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_tuple_common.h
@@ -0,0 +1,13 @@
1#ifndef _NF_CONNTRACK_TUPLE_COMMON_H
2#define _NF_CONNTRACK_TUPLE_COMMON_H
3
4enum ip_conntrack_dir
5{
6 IP_CT_DIR_ORIGINAL,
7 IP_CT_DIR_REPLY,
8 IP_CT_DIR_MAX
9};
10
11#define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
12
13#endif /* _NF_CONNTRACK_TUPLE_COMMON_H */
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index f08e870100f4..72975fa8795d 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -146,7 +146,7 @@ extern void nfnl_unlock(void);
146extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n); 146extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n);
147extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n); 147extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n);
148 148
149extern int nfattr_parse(struct nfattr *tb[], int maxattr, 149extern void nfattr_parse(struct nfattr *tb[], int maxattr,
150 struct nfattr *nfa, int len); 150 struct nfattr *nfa, int len);
151 151
152#define nfattr_parse_nested(tb, max, nfa) \ 152#define nfattr_parse_nested(tb, max, nfa) \
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index d078bb91d9e5..b3432ab59a17 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -1,132 +1,7 @@
1#ifndef _IP_CONNTRACK_H 1#ifndef _IP_CONNTRACK_H
2#define _IP_CONNTRACK_H 2#define _IP_CONNTRACK_H
3/* Connection state tracking for netfilter. This is separated from,
4 but required by, the NAT layer; it can also be used by an iptables
5 extension. */
6enum ip_conntrack_info
7{
8 /* Part of an established connection (either direction). */
9 IP_CT_ESTABLISHED,
10
11 /* Like NEW, but related to an existing connection, or ICMP error
12 (in either direction). */
13 IP_CT_RELATED,
14
15 /* Started a new connection to track (only
16 IP_CT_DIR_ORIGINAL); may be a retransmission. */
17 IP_CT_NEW,
18
19 /* >= this indicates reply direction */
20 IP_CT_IS_REPLY,
21
22 /* Number of distinct IP_CT types (no NEW in reply dirn). */
23 IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
24};
25
26/* Bitset representing status of connection. */
27enum ip_conntrack_status {
28 /* It's an expected connection: bit 0 set. This bit never changed */
29 IPS_EXPECTED_BIT = 0,
30 IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
31
32 /* We've seen packets both ways: bit 1 set. Can be set, not unset. */
33 IPS_SEEN_REPLY_BIT = 1,
34 IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
35
36 /* Conntrack should never be early-expired. */
37 IPS_ASSURED_BIT = 2,
38 IPS_ASSURED = (1 << IPS_ASSURED_BIT),
39
40 /* Connection is confirmed: originating packet has left box */
41 IPS_CONFIRMED_BIT = 3,
42 IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
43
44 /* Connection needs src nat in orig dir. This bit never changed. */
45 IPS_SRC_NAT_BIT = 4,
46 IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
47
48 /* Connection needs dst nat in orig dir. This bit never changed. */
49 IPS_DST_NAT_BIT = 5,
50 IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
51
52 /* Both together. */
53 IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
54
55 /* Connection needs TCP sequence adjusted. */
56 IPS_SEQ_ADJUST_BIT = 6,
57 IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
58
59 /* NAT initialization bits. */
60 IPS_SRC_NAT_DONE_BIT = 7,
61 IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
62
63 IPS_DST_NAT_DONE_BIT = 8,
64 IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
65
66 /* Both together */
67 IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
68
69 /* Connection is dying (removed from lists), can not be unset. */
70 IPS_DYING_BIT = 9,
71 IPS_DYING = (1 << IPS_DYING_BIT),
72};
73
74/* Connection tracking event bits */
75enum ip_conntrack_events
76{
77 /* New conntrack */
78 IPCT_NEW_BIT = 0,
79 IPCT_NEW = (1 << IPCT_NEW_BIT),
80
81 /* Expected connection */
82 IPCT_RELATED_BIT = 1,
83 IPCT_RELATED = (1 << IPCT_RELATED_BIT),
84
85 /* Destroyed conntrack */
86 IPCT_DESTROY_BIT = 2,
87 IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
88
89 /* Timer has been refreshed */
90 IPCT_REFRESH_BIT = 3,
91 IPCT_REFRESH = (1 << IPCT_REFRESH_BIT),
92
93 /* Status has changed */
94 IPCT_STATUS_BIT = 4,
95 IPCT_STATUS = (1 << IPCT_STATUS_BIT),
96
97 /* Update of protocol info */
98 IPCT_PROTOINFO_BIT = 5,
99 IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
100
101 /* Volatile protocol info */
102 IPCT_PROTOINFO_VOLATILE_BIT = 6,
103 IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT),
104
105 /* New helper for conntrack */
106 IPCT_HELPER_BIT = 7,
107 IPCT_HELPER = (1 << IPCT_HELPER_BIT),
108
109 /* Update of helper info */
110 IPCT_HELPINFO_BIT = 8,
111 IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT),
112
113 /* Volatile helper info */
114 IPCT_HELPINFO_VOLATILE_BIT = 9,
115 IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT),
116 3
117 /* NAT info */ 4#include <linux/netfilter/nf_conntrack_common.h>
118 IPCT_NATINFO_BIT = 10,
119 IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
120
121 /* Counter highest bit has been set */
122 IPCT_COUNTER_FILLING_BIT = 11,
123 IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
124};
125
126enum ip_conntrack_expect_events {
127 IPEXP_NEW_BIT = 0,
128 IPEXP_NEW = (1 << IPEXP_NEW_BIT),
129};
130 5
131#ifdef __KERNEL__ 6#ifdef __KERNEL__
132#include <linux/config.h> 7#include <linux/config.h>
@@ -194,12 +69,6 @@ do { \
194#define IP_NF_ASSERT(x) 69#define IP_NF_ASSERT(x)
195#endif 70#endif
196 71
197struct ip_conntrack_counter
198{
199 u_int32_t packets;
200 u_int32_t bytes;
201};
202
203struct ip_conntrack_helper; 72struct ip_conntrack_helper;
204 73
205struct ip_conntrack 74struct ip_conntrack
@@ -426,25 +295,6 @@ static inline int is_dying(struct ip_conntrack *ct)
426 295
427extern unsigned int ip_conntrack_htable_size; 296extern unsigned int ip_conntrack_htable_size;
428 297
429struct ip_conntrack_stat
430{
431 unsigned int searched;
432 unsigned int found;
433 unsigned int new;
434 unsigned int invalid;
435 unsigned int ignore;
436 unsigned int delete;
437 unsigned int delete_list;
438 unsigned int insert;
439 unsigned int insert_failed;
440 unsigned int drop;
441 unsigned int early_drop;
442 unsigned int error;
443 unsigned int expect_new;
444 unsigned int expect_create;
445 unsigned int expect_delete;
446};
447
448#define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++) 298#define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++)
449 299
450#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS 300#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_ftp.h b/include/linux/netfilter_ipv4/ip_conntrack_ftp.h
index 5f06429b9047..63811934de4d 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_ftp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_ftp.h
@@ -1,43 +1,6 @@
1#ifndef _IP_CONNTRACK_FTP_H 1#ifndef _IP_CONNTRACK_FTP_H
2#define _IP_CONNTRACK_FTP_H 2#define _IP_CONNTRACK_FTP_H
3/* FTP tracking. */
4 3
5#ifdef __KERNEL__ 4#include <linux/netfilter/nf_conntrack_ftp.h>
6 5
7#define FTP_PORT 21
8
9#endif /* __KERNEL__ */
10
11enum ip_ct_ftp_type
12{
13 /* PORT command from client */
14 IP_CT_FTP_PORT,
15 /* PASV response from server */
16 IP_CT_FTP_PASV,
17 /* EPRT command from client */
18 IP_CT_FTP_EPRT,
19 /* EPSV response from server */
20 IP_CT_FTP_EPSV,
21};
22
23#define NUM_SEQ_TO_REMEMBER 2
24/* This structure exists only once per master */
25struct ip_ct_ftp_master {
26 /* Valid seq positions for cmd matching after newline */
27 u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
28 /* 0 means seq_match_aft_nl not set */
29 int seq_aft_nl_num[IP_CT_DIR_MAX];
30};
31
32struct ip_conntrack_expect;
33
34/* For NAT to hook in when we find a packet which describes what other
35 * connection we should expect. */
36extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
37 enum ip_conntrack_info ctinfo,
38 enum ip_ct_ftp_type type,
39 unsigned int matchoff,
40 unsigned int matchlen,
41 struct ip_conntrack_expect *exp,
42 u32 *seq);
43#endif /* _IP_CONNTRACK_FTP_H */ 6#endif /* _IP_CONNTRACK_FTP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_icmp.h b/include/linux/netfilter_ipv4/ip_conntrack_icmp.h
index f1664abbe392..eed5ee3e4744 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_icmp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_icmp.h
@@ -1,11 +1,6 @@
1#ifndef _IP_CONNTRACK_ICMP_H 1#ifndef _IP_CONNTRACK_ICMP_H
2#define _IP_CONNTRACK_ICMP_H 2#define _IP_CONNTRACK_ICMP_H
3/* ICMP tracking. */
4#include <asm/atomic.h>
5 3
6struct ip_ct_icmp 4#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
7{ 5
8 /* Optimization: when number in == number out, forget immediately. */
9 atomic_t count;
10};
11#endif /* _IP_CONNTRACK_ICMP_H */ 6#endif /* _IP_CONNTRACK_ICMP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_sctp.h b/include/linux/netfilter_ipv4/ip_conntrack_sctp.h
index 7a8d869321f7..4099a041a32a 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_sctp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_sctp.h
@@ -1,25 +1,6 @@
1#ifndef _IP_CONNTRACK_SCTP_H 1#ifndef _IP_CONNTRACK_SCTP_H
2#define _IP_CONNTRACK_SCTP_H 2#define _IP_CONNTRACK_SCTP_H
3/* SCTP tracking. */
4 3
5enum sctp_conntrack { 4#include <linux/netfilter/nf_conntrack_sctp.h>
6 SCTP_CONNTRACK_NONE,
7 SCTP_CONNTRACK_CLOSED,
8 SCTP_CONNTRACK_COOKIE_WAIT,
9 SCTP_CONNTRACK_COOKIE_ECHOED,
10 SCTP_CONNTRACK_ESTABLISHED,
11 SCTP_CONNTRACK_SHUTDOWN_SENT,
12 SCTP_CONNTRACK_SHUTDOWN_RECD,
13 SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
14 SCTP_CONNTRACK_MAX
15};
16
17struct ip_ct_sctp
18{
19 enum sctp_conntrack state;
20
21 u_int32_t vtag[IP_CT_DIR_MAX];
22 u_int32_t ttag[IP_CT_DIR_MAX];
23};
24 5
25#endif /* _IP_CONNTRACK_SCTP_H */ 6#endif /* _IP_CONNTRACK_SCTP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tcp.h b/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
index 16da044d97a7..876b8fb17e68 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tcp.h
@@ -1,51 +1,6 @@
1#ifndef _IP_CONNTRACK_TCP_H 1#ifndef _IP_CONNTRACK_TCP_H
2#define _IP_CONNTRACK_TCP_H 2#define _IP_CONNTRACK_TCP_H
3/* TCP tracking. */
4 3
5enum tcp_conntrack { 4#include <linux/netfilter/nf_conntrack_tcp.h>
6 TCP_CONNTRACK_NONE,
7 TCP_CONNTRACK_SYN_SENT,
8 TCP_CONNTRACK_SYN_RECV,
9 TCP_CONNTRACK_ESTABLISHED,
10 TCP_CONNTRACK_FIN_WAIT,
11 TCP_CONNTRACK_CLOSE_WAIT,
12 TCP_CONNTRACK_LAST_ACK,
13 TCP_CONNTRACK_TIME_WAIT,
14 TCP_CONNTRACK_CLOSE,
15 TCP_CONNTRACK_LISTEN,
16 TCP_CONNTRACK_MAX,
17 TCP_CONNTRACK_IGNORE
18};
19
20/* Window scaling is advertised by the sender */
21#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01
22
23/* SACK is permitted by the sender */
24#define IP_CT_TCP_FLAG_SACK_PERM 0x02
25
26/* This sender sent FIN first */
27#define IP_CT_TCP_FLAG_CLOSE_INIT 0x03
28
29struct ip_ct_tcp_state {
30 u_int32_t td_end; /* max of seq + len */
31 u_int32_t td_maxend; /* max of ack + max(win, 1) */
32 u_int32_t td_maxwin; /* max(win) */
33 u_int8_t td_scale; /* window scale factor */
34 u_int8_t loose; /* used when connection picked up from the middle */
35 u_int8_t flags; /* per direction options */
36};
37
38struct ip_ct_tcp
39{
40 struct ip_ct_tcp_state seen[2]; /* connection parameters per direction */
41 u_int8_t state; /* state of the connection (enum tcp_conntrack) */
42 /* For detecting stale connections */
43 u_int8_t last_dir; /* Direction of the last packet (enum ip_conntrack_dir) */
44 u_int8_t retrans; /* Number of retransmitted packets */
45 u_int8_t last_index; /* Index of the last packet */
46 u_int32_t last_seq; /* Last sequence number seen in dir */
47 u_int32_t last_ack; /* Last sequence number seen in opposite dir */
48 u_int32_t last_end; /* Last seq + len */
49};
50 5
51#endif /* _IP_CONNTRACK_TCP_H */ 6#endif /* _IP_CONNTRACK_TCP_H */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
index 3232db11a4e5..2fdabdb4c0ef 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
@@ -2,6 +2,7 @@
2#define _IP_CONNTRACK_TUPLE_H 2#define _IP_CONNTRACK_TUPLE_H
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/netfilter/nf_conntrack_tuple_common.h>
5 6
6/* A `tuple' is a structure containing the information to uniquely 7/* A `tuple' is a structure containing the information to uniquely
7 identify a connection. ie. if two packets have the same tuple, they 8 identify a connection. ie. if two packets have the same tuple, they
@@ -88,13 +89,6 @@ struct ip_conntrack_tuple
88 (tuple)->dst.u.all = 0; \ 89 (tuple)->dst.u.all = 0; \
89 } while (0) 90 } while (0)
90 91
91enum ip_conntrack_dir
92{
93 IP_CT_DIR_ORIGINAL,
94 IP_CT_DIR_REPLY,
95 IP_CT_DIR_MAX
96};
97
98#ifdef __KERNEL__ 92#ifdef __KERNEL__
99 93
100#define DUMP_TUPLE(tp) \ 94#define DUMP_TUPLE(tp) \
@@ -103,8 +97,6 @@ DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n", \
103 NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \ 97 NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \
104 NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all)) 98 NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all))
105 99
106#define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
107
108/* If we're the first tuple, it's the original dir. */ 100/* If we're the first tuple, it's the original dir. */
109#define DIRECTION(h) ((enum ip_conntrack_dir)(h)->tuple.dst.dir) 101#define DIRECTION(h) ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
110 102
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h
index edcc2c6eb5c7..53b2983f6278 100644
--- a/include/linux/netfilter_ipv6.h
+++ b/include/linux/netfilter_ipv6.h
@@ -59,6 +59,7 @@
59 59
60enum nf_ip6_hook_priorities { 60enum nf_ip6_hook_priorities {
61 NF_IP6_PRI_FIRST = INT_MIN, 61 NF_IP6_PRI_FIRST = INT_MIN,
62 NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
62 NF_IP6_PRI_SELINUX_FIRST = -225, 63 NF_IP6_PRI_SELINUX_FIRST = -225,
63 NF_IP6_PRI_CONNTRACK = -200, 64 NF_IP6_PRI_CONNTRACK = -200,
64 NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175, 65 NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index ba25ca874c20..6a2ccf78a356 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -71,7 +71,8 @@ struct nlmsghdr
71 71
72#define NLMSG_ALIGNTO 4 72#define NLMSG_ALIGNTO 4
73#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) 73#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
74#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(sizeof(struct nlmsghdr))) 74#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
75#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))
75#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) 76#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
76#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0))) 77#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
77#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \ 78#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
@@ -86,6 +87,8 @@ struct nlmsghdr
86#define NLMSG_DONE 0x3 /* End of a dump */ 87#define NLMSG_DONE 0x3 /* End of a dump */
87#define NLMSG_OVERRUN 0x4 /* Data lost */ 88#define NLMSG_OVERRUN 0x4 /* Data lost */
88 89
90#define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */
91
89struct nlmsgerr 92struct nlmsgerr
90{ 93{
91 int error; 94 int error;
@@ -108,6 +111,25 @@ enum {
108 NETLINK_CONNECTED, 111 NETLINK_CONNECTED,
109}; 112};
110 113
114/*
115 * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
116 * +---------------------+- - -+- - - - - - - - - -+- - -+
117 * | Header | Pad | Payload | Pad |
118 * | (struct nlattr) | ing | | ing |
119 * +---------------------+- - -+- - - - - - - - - -+- - -+
120 * <-------------- nlattr->nla_len -------------->
121 */
122
123struct nlattr
124{
125 __u16 nla_len;
126 __u16 nla_type;
127};
128
129#define NLA_ALIGNTO 4
130#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
131#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
132
111#ifdef __KERNEL__ 133#ifdef __KERNEL__
112 134
113#include <linux/capability.h> 135#include <linux/capability.h>
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 914b55f4abbb..d00f8ba7f22b 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -387,6 +387,7 @@
387#define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511 387#define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511
388#define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515 388#define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515
389#define PCI_DEVICE_ID_NS_87410 0xd001 389#define PCI_DEVICE_ID_NS_87410 0xd001
390#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d
390 391
391#define PCI_VENDOR_ID_TSENG 0x100c 392#define PCI_VENDOR_ID_TSENG 0x100c
392#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 393#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202
@@ -488,6 +489,8 @@
488#define PCI_DEVICE_ID_AMD_8151_0 0x7454 489#define PCI_DEVICE_ID_AMD_8151_0 0x7454
489#define PCI_DEVICE_ID_AMD_8131_APIC 0x7450 490#define PCI_DEVICE_ID_AMD_8131_APIC 0x7450
490 491
492#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A
493
491#define PCI_VENDOR_ID_TRIDENT 0x1023 494#define PCI_VENDOR_ID_TRIDENT 0x1023
492#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000 495#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
493#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001 496#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001
diff --git a/include/linux/phonedev.h b/include/linux/phonedev.h
index d54049eed0c3..a0e31adf3abe 100644
--- a/include/linux/phonedev.h
+++ b/include/linux/phonedev.h
@@ -2,7 +2,6 @@
2#define __LINUX_PHONEDEV_H 2#define __LINUX_PHONEDEV_H
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/version.h>
6 5
7#ifdef __KERNEL__ 6#ifdef __KERNEL__
8 7
diff --git a/include/linux/ppp-comp.h b/include/linux/ppp-comp.h
index 7227e653b3be..e86a7a5cf355 100644
--- a/include/linux/ppp-comp.h
+++ b/include/linux/ppp-comp.h
@@ -111,6 +111,8 @@ struct compressor {
111 111
112 /* Used in locking compressor modules */ 112 /* Used in locking compressor modules */
113 struct module *owner; 113 struct module *owner;
114 /* Extra skb space needed by the compressor algorithm */
115 unsigned int comp_extra;
114}; 116};
115 117
116/* 118/*
@@ -191,6 +193,13 @@ struct compressor {
191#define DEFLATE_CHK_SEQUENCE 0 193#define DEFLATE_CHK_SEQUENCE 0
192 194
193/* 195/*
196 * Definitions for MPPE.
197 */
198
199#define CI_MPPE 18 /* config option for MPPE */
200#define CILEN_MPPE 6 /* length of config option */
201
202/*
194 * Definitions for other, as yet unsupported, compression methods. 203 * Definitions for other, as yet unsupported, compression methods.
195 */ 204 */
196 205
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 65ceeaa30652..74488e49166d 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -66,6 +66,7 @@ struct proc_dir_entry {
66 write_proc_t *write_proc; 66 write_proc_t *write_proc;
67 atomic_t count; /* use count */ 67 atomic_t count; /* use count */
68 int deleted; /* delete flag */ 68 int deleted; /* delete flag */
69 void *set;
69}; 70};
70 71
71struct kcore_list { 72struct kcore_list {
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index 9de99198caf1..899437802aea 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -6,7 +6,13 @@
6#ifndef BITMAP_H 6#ifndef BITMAP_H
7#define BITMAP_H 1 7#define BITMAP_H 1
8 8
9#define BITMAP_MAJOR 3 9#define BITMAP_MAJOR_LO 3
10/* version 4 insists the bitmap is in little-endian order
11 * with version 3, it is host-endian which is non-portable
12 */
13#define BITMAP_MAJOR_HI 4
14#define BITMAP_MAJOR_HOSTENDIAN 3
15
10#define BITMAP_MINOR 39 16#define BITMAP_MINOR 39
11 17
12/* 18/*
@@ -133,7 +139,8 @@ typedef __u16 bitmap_counter_t;
133/* use these for bitmap->flags and bitmap->sb->state bit-fields */ 139/* use these for bitmap->flags and bitmap->sb->state bit-fields */
134enum bitmap_state { 140enum bitmap_state {
135 BITMAP_ACTIVE = 0x001, /* the bitmap is in use */ 141 BITMAP_ACTIVE = 0x001, /* the bitmap is in use */
136 BITMAP_STALE = 0x002 /* the bitmap file is out of date or had -EIO */ 142 BITMAP_STALE = 0x002, /* the bitmap file is out of date or had -EIO */
143 BITMAP_HOSTENDIAN = 0x8000,
137}; 144};
138 145
139/* the superblock at the front of the bitmap file -- little endian */ 146/* the superblock at the front of the bitmap file -- little endian */
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index ffa316ce4dc8..13e7c4b62367 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -66,8 +66,10 @@
66 * and major_version/minor_version accordingly 66 * and major_version/minor_version accordingly
67 * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT 67 * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT
68 * in the super status byte 68 * in the super status byte
69 * >=3 means that bitmap superblock version 4 is supported, which uses
70 * little-ending representation rather than host-endian
69 */ 71 */
70#define MD_PATCHLEVEL_VERSION 2 72#define MD_PATCHLEVEL_VERSION 3
71 73
72extern int register_md_personality (int p_num, mdk_personality_t *p); 74extern int register_md_personality (int p_num, mdk_personality_t *p);
73extern int unregister_md_personality (int p_num); 75extern int unregister_md_personality (int p_num);
@@ -87,6 +89,7 @@ extern void md_print_devices (void);
87 89
88extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, 90extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
89 sector_t sector, int size, struct page *page); 91 sector_t sector, int size, struct page *page);
92extern void md_super_wait(mddev_t *mddev);
90extern int sync_page_io(struct block_device *bdev, sector_t sector, int size, 93extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
91 struct page *page, int rw); 94 struct page *page, int rw);
92 95
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index ebce949b1443..46629a275ba9 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -105,6 +105,8 @@ struct mdk_rdev_s
105 int sb_size; /* bytes in the superblock */ 105 int sb_size; /* bytes in the superblock */
106 int preferred_minor; /* autorun support */ 106 int preferred_minor; /* autorun support */
107 107
108 struct kobject kobj;
109
108 /* A device can be in one of three states based on two flags: 110 /* A device can be in one of three states based on two flags:
109 * Not working: faulty==1 in_sync==0 111 * Not working: faulty==1 in_sync==0
110 * Fully working: faulty==0 in_sync==1 112 * Fully working: faulty==0 in_sync==1
@@ -115,11 +117,12 @@ struct mdk_rdev_s
115 * It can never have faulty==1, in_sync==1 117 * It can never have faulty==1, in_sync==1
116 * This reduces the burden of testing multiple flags in many cases 118 * This reduces the burden of testing multiple flags in many cases
117 */ 119 */
118 int faulty; /* if faulty do not issue IO requests */
119 int in_sync; /* device is a full member of the array */
120 120
121 unsigned long flags; /* Should include faulty and in_sync here. */ 121 unsigned long flags;
122#define Faulty 1 /* device is known to have a fault */
123#define In_sync 2 /* device is in_sync with rest of array */
122#define WriteMostly 4 /* Avoid reading if at all possible */ 124#define WriteMostly 4 /* Avoid reading if at all possible */
125#define BarriersNotsupp 5 /* BIO_RW_BARRIER is not supported */
123 126
124 int desc_nr; /* descriptor index in the superblock */ 127 int desc_nr; /* descriptor index in the superblock */
125 int raid_disk; /* role of device in array */ 128 int raid_disk; /* role of device in array */
@@ -132,6 +135,9 @@ struct mdk_rdev_s
132 * only maintained for arrays that 135 * only maintained for arrays that
133 * support hot removal 136 * support hot removal
134 */ 137 */
138 atomic_t read_errors; /* number of consecutive read errors that
139 * we have tried to ignore.
140 */
135}; 141};
136 142
137typedef struct mdk_personality_s mdk_personality_t; 143typedef struct mdk_personality_s mdk_personality_t;
@@ -148,6 +154,8 @@ struct mddev_s
148 154
149 struct gendisk *gendisk; 155 struct gendisk *gendisk;
150 156
157 struct kobject kobj;
158
151 /* Superblock information */ 159 /* Superblock information */
152 int major_version, 160 int major_version,
153 minor_version, 161 minor_version,
@@ -171,6 +179,10 @@ struct mddev_s
171 sector_t resync_mark_cnt;/* blocks written at resync_mark */ 179 sector_t resync_mark_cnt;/* blocks written at resync_mark */
172 180
173 sector_t resync_max_sectors; /* may be set by personality */ 181 sector_t resync_max_sectors; /* may be set by personality */
182
183 sector_t resync_mismatches; /* count of sectors where
184 * parity/replica mismatch found
185 */
174 /* recovery/resync flags 186 /* recovery/resync flags
175 * NEEDED: we might need to start a resync/recover 187 * NEEDED: we might need to start a resync/recover
176 * RUNNING: a thread is running, or about to be started 188 * RUNNING: a thread is running, or about to be started
@@ -178,6 +190,8 @@ struct mddev_s
178 * ERR: and IO error was detected - abort the resync/recovery 190 * ERR: and IO error was detected - abort the resync/recovery
179 * INTR: someone requested a (clean) early abort. 191 * INTR: someone requested a (clean) early abort.
180 * DONE: thread is done and is waiting to be reaped 192 * DONE: thread is done and is waiting to be reaped
193 * REQUEST: user-space has requested a sync (used with SYNC)
194 * CHECK: user-space request for for check-only, no repair
181 */ 195 */
182#define MD_RECOVERY_RUNNING 0 196#define MD_RECOVERY_RUNNING 0
183#define MD_RECOVERY_SYNC 1 197#define MD_RECOVERY_SYNC 1
@@ -185,6 +199,8 @@ struct mddev_s
185#define MD_RECOVERY_INTR 3 199#define MD_RECOVERY_INTR 3
186#define MD_RECOVERY_DONE 4 200#define MD_RECOVERY_DONE 4
187#define MD_RECOVERY_NEEDED 5 201#define MD_RECOVERY_NEEDED 5
202#define MD_RECOVERY_REQUESTED 6
203#define MD_RECOVERY_CHECK 7
188 unsigned long recovery; 204 unsigned long recovery;
189 205
190 int in_sync; /* know to not need resync */ 206 int in_sync; /* know to not need resync */
@@ -195,6 +211,13 @@ struct mddev_s
195 int degraded; /* whether md should consider 211 int degraded; /* whether md should consider
196 * adding a spare 212 * adding a spare
197 */ 213 */
214 int barriers_work; /* initialised to true, cleared as soon
215 * as a barrier request to slave
216 * fails. Only supported
217 */
218 struct bio *biolist; /* bios that need to be retried
219 * because BIO_RW_BARRIER is not supported
220 */
198 221
199 atomic_t recovery_active; /* blocks scheduled, but not written */ 222 atomic_t recovery_active; /* blocks scheduled, but not written */
200 wait_queue_head_t recovery_wait; 223 wait_queue_head_t recovery_wait;
@@ -232,7 +255,7 @@ struct mddev_s
232 255
233static inline void rdev_dec_pending(mdk_rdev_t *rdev, mddev_t *mddev) 256static inline void rdev_dec_pending(mdk_rdev_t *rdev, mddev_t *mddev)
234{ 257{
235 int faulty = rdev->faulty; 258 int faulty = test_bit(Faulty, &rdev->flags);
236 if (atomic_dec_and_test(&rdev->nr_pending) && faulty) 259 if (atomic_dec_and_test(&rdev->nr_pending) && faulty)
237 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 260 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
238} 261}
@@ -270,6 +293,13 @@ struct mdk_personality_s
270}; 293};
271 294
272 295
296struct md_sysfs_entry {
297 struct attribute attr;
298 ssize_t (*show)(mddev_t *, char *);
299 ssize_t (*store)(mddev_t *, const char *, size_t);
300};
301
302
273static inline char * mdname (mddev_t * mddev) 303static inline char * mdname (mddev_t * mddev)
274{ 304{
275 return mddev->gendisk ? mddev->gendisk->disk_name : "mdX"; 305 return mddev->gendisk ? mddev->gendisk->disk_name : "mdX";
@@ -304,10 +334,8 @@ typedef struct mdk_thread_s {
304 mddev_t *mddev; 334 mddev_t *mddev;
305 wait_queue_head_t wqueue; 335 wait_queue_head_t wqueue;
306 unsigned long flags; 336 unsigned long flags;
307 struct completion *event;
308 struct task_struct *tsk; 337 struct task_struct *tsk;
309 unsigned long timeout; 338 unsigned long timeout;
310 const char *name;
311} mdk_thread_t; 339} mdk_thread_t;
312 340
313#define THREAD_WAKEUP 0 341#define THREAD_WAKEUP 0
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
index 60e19b667548..292b98f2b408 100644
--- a/include/linux/raid/raid1.h
+++ b/include/linux/raid/raid1.h
@@ -110,7 +110,9 @@ struct r1bio_s {
110#define R1BIO_Uptodate 0 110#define R1BIO_Uptodate 0
111#define R1BIO_IsSync 1 111#define R1BIO_IsSync 1
112#define R1BIO_Degraded 2 112#define R1BIO_Degraded 2
113#define R1BIO_BehindIO 3 113#define R1BIO_BehindIO 3
114#define R1BIO_Barrier 4
115#define R1BIO_BarrierRetry 5
114/* For write-behind requests, we call bi_end_io when 116/* For write-behind requests, we call bi_end_io when
115 * the last non-write-behind device completes, providing 117 * the last non-write-behind device completes, providing
116 * any write was successful. Otherwise we call when 118 * any write was successful. Otherwise we call when
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
index 176fc653c284..f025ba6fb14c 100644
--- a/include/linux/raid/raid5.h
+++ b/include/linux/raid/raid5.h
@@ -154,6 +154,8 @@ struct stripe_head {
154#define R5_Wantwrite 5 154#define R5_Wantwrite 5
155#define R5_Syncio 6 /* this io need to be accounted as resync io */ 155#define R5_Syncio 6 /* this io need to be accounted as resync io */
156#define R5_Overlap 7 /* There is a pending overlapping request on this block */ 156#define R5_Overlap 7 /* There is a pending overlapping request on this block */
157#define R5_ReadError 8 /* seen a read error here recently */
158#define R5_ReWrite 9 /* have tried to over-write the readerror */
157 159
158/* 160/*
159 * Write method 161 * Write method
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 03b68a7b4b82..2bbf968b23d9 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -909,6 +909,7 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
909#define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */ 909#define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */
910#define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */ 910#define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */
911#define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */ 911#define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */
912#define PF_HOTPLUG_CPU 0x01000000 /* Currently performing CPU hotplug */
912 913
913/* 914/*
914 * Only the _current_ task can read/write to tsk->flags, but other 915 * Only the _current_ task can read/write to tsk->flags, but other
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index fdfb8fe8c38c..83010231db99 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -274,6 +274,9 @@ struct sk_buff {
274#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 274#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
275 __u8 ipvs_property:1; 275 __u8 ipvs_property:1;
276#endif 276#endif
277#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
278 struct sk_buff *nfct_reasm;
279#endif
277#ifdef CONFIG_BRIDGE_NETFILTER 280#ifdef CONFIG_BRIDGE_NETFILTER
278 struct nf_bridge_info *nf_bridge; 281 struct nf_bridge_info *nf_bridge;
279#endif 282#endif
@@ -1313,10 +1316,26 @@ static inline void nf_conntrack_get(struct nf_conntrack *nfct)
1313 if (nfct) 1316 if (nfct)
1314 atomic_inc(&nfct->use); 1317 atomic_inc(&nfct->use);
1315} 1318}
1319#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
1320static inline void nf_conntrack_get_reasm(struct sk_buff *skb)
1321{
1322 if (skb)
1323 atomic_inc(&skb->users);
1324}
1325static inline void nf_conntrack_put_reasm(struct sk_buff *skb)
1326{
1327 if (skb)
1328 kfree_skb(skb);
1329}
1330#endif
1316static inline void nf_reset(struct sk_buff *skb) 1331static inline void nf_reset(struct sk_buff *skb)
1317{ 1332{
1318 nf_conntrack_put(skb->nfct); 1333 nf_conntrack_put(skb->nfct);
1319 skb->nfct = NULL; 1334 skb->nfct = NULL;
1335#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
1336 nf_conntrack_put_reasm(skb->nfct_reasm);
1337 skb->nfct_reasm = NULL;
1338#endif
1320} 1339}
1321 1340
1322#ifdef CONFIG_BRIDGE_NETFILTER 1341#ifdef CONFIG_BRIDGE_NETFILTER
diff --git a/include/linux/stallion.h b/include/linux/stallion.h
index e89b77b6505a..13a37f137ea2 100644
--- a/include/linux/stallion.h
+++ b/include/linux/stallion.h
@@ -21,8 +21,6 @@
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */ 22 */
23 23
24#include <linux/version.h>
25
26/*****************************************************************************/ 24/*****************************************************************************/
27#ifndef _STALLION_H 25#ifndef _STALLION_H
28#define _STALLION_H 26#define _STALLION_H
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index fc8e367f671e..22cf5e1ac987 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -24,6 +24,7 @@
24#include <linux/compiler.h> 24#include <linux/compiler.h>
25 25
26struct file; 26struct file;
27struct completion;
27 28
28#define CTL_MAXNAME 10 /* how many path components do we allow in a 29#define CTL_MAXNAME 10 /* how many path components do we allow in a
29 call to sysctl? In other words, what is 30 call to sysctl? In other words, what is
@@ -204,6 +205,7 @@ enum
204 NET_ECONET=16, 205 NET_ECONET=16,
205 NET_SCTP=17, 206 NET_SCTP=17,
206 NET_LLC=18, 207 NET_LLC=18,
208 NET_NETFILTER=19,
207}; 209};
208 210
209/* /proc/sys/kernel/random */ 211/* /proc/sys/kernel/random */
@@ -269,6 +271,42 @@ enum
269 NET_UNIX_MAX_DGRAM_QLEN=3, 271 NET_UNIX_MAX_DGRAM_QLEN=3,
270}; 272};
271 273
274/* /proc/sys/net/netfilter */
275enum
276{
277 NET_NF_CONNTRACK_MAX=1,
278 NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
279 NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
280 NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
281 NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
282 NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
283 NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
284 NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
285 NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
286 NET_NF_CONNTRACK_UDP_TIMEOUT=10,
287 NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
288 NET_NF_CONNTRACK_ICMP_TIMEOUT=12,
289 NET_NF_CONNTRACK_GENERIC_TIMEOUT=13,
290 NET_NF_CONNTRACK_BUCKETS=14,
291 NET_NF_CONNTRACK_LOG_INVALID=15,
292 NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
293 NET_NF_CONNTRACK_TCP_LOOSE=17,
294 NET_NF_CONNTRACK_TCP_BE_LIBERAL=18,
295 NET_NF_CONNTRACK_TCP_MAX_RETRANS=19,
296 NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
297 NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
298 NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
299 NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
300 NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
301 NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
302 NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
303 NET_NF_CONNTRACK_COUNT=27,
304 NET_NF_CONNTRACK_ICMPV6_TIMEOUT=28,
305 NET_NF_CONNTRACK_FRAG6_TIMEOUT=29,
306 NET_NF_CONNTRACK_FRAG6_LOW_THRESH=30,
307 NET_NF_CONNTRACK_FRAG6_HIGH_THRESH=31,
308};
309
272/* /proc/sys/net/ipv4 */ 310/* /proc/sys/net/ipv4 */
273enum 311enum
274{ 312{
@@ -925,6 +963,8 @@ struct ctl_table_header
925{ 963{
926 ctl_table *ctl_table; 964 ctl_table *ctl_table;
927 struct list_head ctl_entry; 965 struct list_head ctl_entry;
966 int used;
967 struct completion *unregistering;
928}; 968};
929 969
930struct ctl_table_header * register_sysctl_table(ctl_table * table, 970struct ctl_table_header * register_sysctl_table(ctl_table * table,
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 1cc8c31b7988..91140091ced2 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -1,57 +1,16 @@
1#ifndef __LINUX_VIDEODEV_H 1#ifndef __LINUX_VIDEODEV_H
2#define __LINUX_VIDEODEV_H 2#define __LINUX_VIDEODEV_H
3 3
4#include <linux/compiler.h>
5#include <linux/types.h> 4#include <linux/types.h>
6 5
7#define HAVE_V4L2 1 6#define HAVE_V4L1 1
7
8#include <linux/videodev2.h> 8#include <linux/videodev2.h>
9 9
10#ifdef __KERNEL__ 10#ifdef __KERNEL__
11 11
12#include <linux/poll.h>
13#include <linux/mm.h> 12#include <linux/mm.h>
14#include <linux/device.h>
15
16struct video_device
17{
18 /* device info */
19 struct device *dev;
20 char name[32];
21 int type; /* v4l1 */
22 int type2; /* v4l2 */
23 int hardware;
24 int minor;
25
26 /* device ops + callbacks */
27 struct file_operations *fops;
28 void (*release)(struct video_device *vfd);
29
30
31 /* obsolete -- fops->owner is used instead */
32 struct module *owner;
33 /* dev->driver_data will be used instead some day.
34 * Use the video_{get|set}_drvdata() helper functions,
35 * so the switch over will be transparent for you.
36 * Or use {pci|usb}_{get|set}_drvdata() directly. */
37 void *priv;
38
39 /* for videodev.c intenal usage -- please don't touch */
40 int users; /* video_exclusive_{open|close} ... */
41 struct semaphore lock; /* ... helper function uses these */
42 char devfs_name[64]; /* devfs */
43 struct class_device class_dev; /* sysfs */
44};
45
46#define VIDEO_MAJOR 81
47
48#define VFL_TYPE_GRABBER 0
49#define VFL_TYPE_VBI 1
50#define VFL_TYPE_RADIO 2
51#define VFL_TYPE_VTX 3
52 13
53extern int video_register_device(struct video_device *, int type, int nr);
54extern void video_unregister_device(struct video_device *);
55extern struct video_device* video_devdata(struct file*); 14extern struct video_device* video_devdata(struct file*);
56 15
57#define to_video_device(cd) container_of(cd, struct video_device, class_dev) 16#define to_video_device(cd) container_of(cd, struct video_device, class_dev)
@@ -68,11 +27,7 @@ video_device_remove_file(struct video_device *vfd,
68 class_device_remove_file(&vfd->class_dev, attr); 27 class_device_remove_file(&vfd->class_dev, attr);
69} 28}
70 29
71/* helper functions to alloc / release struct video_device, the 30#if OBSOLETE_OWNER /* to be removed in 2.6.15 */
72 later can be used for video_device->release() */
73struct video_device *video_device_alloc(void);
74void video_device_release(struct video_device *vfd);
75
76/* helper functions to access driver private data. */ 31/* helper functions to access driver private data. */
77static inline void *video_get_drvdata(struct video_device *dev) 32static inline void *video_get_drvdata(struct video_device *dev)
78{ 33{
@@ -83,30 +38,12 @@ static inline void video_set_drvdata(struct video_device *dev, void *data)
83{ 38{
84 dev->priv = data; 39 dev->priv = data;
85} 40}
41#endif
86 42
87extern int video_exclusive_open(struct inode *inode, struct file *file); 43extern int video_exclusive_open(struct inode *inode, struct file *file);
88extern int video_exclusive_release(struct inode *inode, struct file *file); 44extern int video_exclusive_release(struct inode *inode, struct file *file);
89extern int video_usercopy(struct inode *inode, struct file *file,
90 unsigned int cmd, unsigned long arg,
91 int (*func)(struct inode *inode, struct file *file,
92 unsigned int cmd, void *arg));
93#endif /* __KERNEL__ */ 45#endif /* __KERNEL__ */
94 46
95#define VID_TYPE_CAPTURE 1 /* Can capture */
96#define VID_TYPE_TUNER 2 /* Can tune */
97#define VID_TYPE_TELETEXT 4 /* Does teletext */
98#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
99#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
100#define VID_TYPE_CLIPPING 32 /* Can clip */
101#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
102#define VID_TYPE_SCALES 128 /* Scalable */
103#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
104#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
105#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
106#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
107#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
108#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
109
110struct video_capability 47struct video_capability
111{ 48{
112 char name[32]; 49 char name[32];
@@ -202,9 +139,9 @@ struct video_audio
202#define VIDEO_SOUND_STEREO 2 139#define VIDEO_SOUND_STEREO 2
203#define VIDEO_SOUND_LANG1 4 140#define VIDEO_SOUND_LANG1 4
204#define VIDEO_SOUND_LANG2 8 141#define VIDEO_SOUND_LANG2 8
205 __u16 mode; 142 __u16 mode;
206 __u16 balance; /* Stereo balance */ 143 __u16 balance; /* Stereo balance */
207 __u16 step; /* Step actual volume uses */ 144 __u16 step; /* Step actual volume uses */
208}; 145};
209 146
210struct video_clip 147struct video_clip
@@ -260,9 +197,6 @@ struct video_key
260 __u32 flags; 197 __u32 flags;
261}; 198};
262 199
263
264#define VIDEO_MAX_FRAME 32
265
266struct video_mbuf 200struct video_mbuf
267{ 201{
268 int size; /* Total memory to map */ 202 int size; /* Total memory to map */
@@ -270,10 +204,8 @@ struct video_mbuf
270 int offsets[VIDEO_MAX_FRAME]; 204 int offsets[VIDEO_MAX_FRAME];
271}; 205};
272 206
273
274#define VIDEO_NO_UNIT (-1) 207#define VIDEO_NO_UNIT (-1)
275 208
276
277struct video_unit 209struct video_unit
278{ 210{
279 int video; /* Video minor */ 211 int video; /* Video minor */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 89a055761bed..a114fff6568b 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -15,16 +15,99 @@
15 */ 15 */
16#ifdef __KERNEL__ 16#ifdef __KERNEL__
17#include <linux/time.h> /* need struct timeval */ 17#include <linux/time.h> /* need struct timeval */
18#include <linux/poll.h>
19#include <linux/device.h>
18#endif 20#endif
19#include <linux/compiler.h> /* need __user */ 21#include <linux/compiler.h> /* need __user */
20 22
23
24#define OBSOLETE_OWNER 1 /* It will be removed for 2.6.15 */
25#define HAVE_V4L2 1
26
27/*
28 * Common stuff for both V4L1 and V4L2
29 * Moved from videodev.h
30 */
31
32#define VIDEO_MAX_FRAME 32
33
34#define VID_TYPE_CAPTURE 1 /* Can capture */
35#define VID_TYPE_TUNER 2 /* Can tune */
36#define VID_TYPE_TELETEXT 4 /* Does teletext */
37#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
38#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
39#define VID_TYPE_CLIPPING 32 /* Can clip */
40#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
41#define VID_TYPE_SCALES 128 /* Scalable */
42#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
43#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
44#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
45#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
46#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
47#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
48
49#ifdef __KERNEL__
50
51#define VFL_TYPE_GRABBER 0
52#define VFL_TYPE_VBI 1
53#define VFL_TYPE_RADIO 2
54#define VFL_TYPE_VTX 3
55
56struct video_device
57{
58 /* device info */
59 struct device *dev;
60 char name[32];
61 int type; /* v4l1 */
62 int type2; /* v4l2 */
63 int hardware;
64 int minor;
65
66 /* device ops + callbacks */
67 struct file_operations *fops;
68 void (*release)(struct video_device *vfd);
69
70
71#if OBSOLETE_OWNER /* to be removed in 2.6.15 */
72 /* obsolete -- fops->owner is used instead */
73 struct module *owner;
74 /* dev->driver_data will be used instead some day.
75 * Use the video_{get|set}_drvdata() helper functions,
76 * so the switch over will be transparent for you.
77 * Or use {pci|usb}_{get|set}_drvdata() directly. */
78 void *priv;
79#endif
80
81 /* for videodev.c intenal usage -- please don't touch */
82 int users; /* video_exclusive_{open|close} ... */
83 struct semaphore lock; /* ... helper function uses these */
84 char devfs_name[64]; /* devfs */
85 struct class_device class_dev; /* sysfs */
86};
87
88#define VIDEO_MAJOR 81
89
90extern int video_register_device(struct video_device *, int type, int nr);
91extern void video_unregister_device(struct video_device *);
92extern int video_usercopy(struct inode *inode, struct file *file,
93 unsigned int cmd, unsigned long arg,
94 int (*func)(struct inode *inode, struct file *file,
95 unsigned int cmd, void *arg));
96
97/* helper functions to alloc / release struct video_device, the
98 later can be used for video_device->release() */
99struct video_device *video_device_alloc(void);
100void video_device_release(struct video_device *vfd);
101
102#endif
103
21/* 104/*
22 * M I S C E L L A N E O U S 105 * M I S C E L L A N E O U S
23 */ 106 */
24 107
25/* Four-character-code (FOURCC) */ 108/* Four-character-code (FOURCC) */
26#define v4l2_fourcc(a,b,c,d)\ 109#define v4l2_fourcc(a,b,c,d)\
27 (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24)) 110 (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
28 111
29/* 112/*
30 * E N U M S 113 * E N U M S
@@ -154,20 +237,20 @@ struct v4l2_capability
154}; 237};
155 238
156/* Values for 'capabilities' field */ 239/* Values for 'capabilities' field */
157#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ 240#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
158#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ 241#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
159#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ 242#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
160#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ 243#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */
161#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ 244#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */
162#if 1 245#if 1
163#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ 246#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
164#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ 247#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
165#endif 248#endif
166#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ 249#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
167 250
168#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ 251#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
169#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ 252#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
170#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ 253#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
171 254
172#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ 255#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
173#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ 256#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
@@ -179,13 +262,13 @@ struct v4l2_capability
179 262
180struct v4l2_pix_format 263struct v4l2_pix_format
181{ 264{
182 __u32 width; 265 __u32 width;
183 __u32 height; 266 __u32 height;
184 __u32 pixelformat; 267 __u32 pixelformat;
185 enum v4l2_field field; 268 enum v4l2_field field;
186 __u32 bytesperline; /* for padding, zero if unused */ 269 __u32 bytesperline; /* for padding, zero if unused */
187 __u32 sizeimage; 270 __u32 sizeimage;
188 enum v4l2_colorspace colorspace; 271 enum v4l2_colorspace colorspace;
189 __u32 priv; /* private data, depends on pixelformat */ 272 __u32 priv; /* private data, depends on pixelformat */
190}; 273};
191 274
@@ -238,12 +321,12 @@ struct v4l2_pix_format
238 */ 321 */
239struct v4l2_fmtdesc 322struct v4l2_fmtdesc
240{ 323{
241 __u32 index; /* Format number */ 324 __u32 index; /* Format number */
242 enum v4l2_buf_type type; /* buffer type */ 325 enum v4l2_buf_type type; /* buffer type */
243 __u32 flags; 326 __u32 flags;
244 __u8 description[32]; /* Description string */ 327 __u8 description[32]; /* Description string */
245 __u32 pixelformat; /* Format fourcc */ 328 __u32 pixelformat; /* Format fourcc */
246 __u32 reserved[4]; 329 __u32 reserved[4];
247}; 330};
248 331
249#define V4L2_FMT_FLAG_COMPRESSED 0x0001 332#define V4L2_FMT_FLAG_COMPRESSED 0x0001
@@ -393,7 +476,7 @@ struct v4l2_jpegcompression
393#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ 476#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
394#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ 477#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */
395#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will 478#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will
396 * allways use APP0 */ 479 * allways use APP0 */
397}; 480};
398 481
399 482
@@ -402,10 +485,10 @@ struct v4l2_jpegcompression
402 */ 485 */
403struct v4l2_requestbuffers 486struct v4l2_requestbuffers
404{ 487{
405 __u32 count; 488 __u32 count;
406 enum v4l2_buf_type type; 489 enum v4l2_buf_type type;
407 enum v4l2_memory memory; 490 enum v4l2_memory memory;
408 __u32 reserved[2]; 491 __u32 reserved[2];
409}; 492};
410 493
411struct v4l2_buffer 494struct v4l2_buffer
@@ -511,9 +594,9 @@ struct v4l2_outputparm
511 594
512struct v4l2_cropcap { 595struct v4l2_cropcap {
513 enum v4l2_buf_type type; 596 enum v4l2_buf_type type;
514 struct v4l2_rect bounds; 597 struct v4l2_rect bounds;
515 struct v4l2_rect defrect; 598 struct v4l2_rect defrect;
516 struct v4l2_fract pixelaspect; 599 struct v4l2_fract pixelaspect;
517}; 600};
518 601
519struct v4l2_crop { 602struct v4l2_crop {
@@ -544,6 +627,7 @@ typedef __u64 v4l2_std_id;
544 627
545#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) 628#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
546#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) 629#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
630#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000)
547 631
548#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) 632#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
549#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) 633#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
@@ -581,13 +665,14 @@ typedef __u64 v4l2_std_id;
581 665
582#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ 666#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
583 V4L2_STD_PAL_60 |\ 667 V4L2_STD_PAL_60 |\
584 V4L2_STD_NTSC) 668 V4L2_STD_NTSC |\
669 V4L2_STD_NTSC_443)
585#define V4L2_STD_625_50 (V4L2_STD_PAL |\ 670#define V4L2_STD_625_50 (V4L2_STD_PAL |\
586 V4L2_STD_PAL_N |\ 671 V4L2_STD_PAL_N |\
587 V4L2_STD_PAL_Nc |\ 672 V4L2_STD_PAL_Nc |\
588 V4L2_STD_SECAM) 673 V4L2_STD_SECAM)
589#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\ 674#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\
590 V4L2_STD_ATSC_16_VSB) 675 V4L2_STD_ATSC_16_VSB)
591 676
592#define V4L2_STD_UNKNOWN 0 677#define V4L2_STD_UNKNOWN 0
593#define V4L2_STD_ALL (V4L2_STD_525_60 |\ 678#define V4L2_STD_ALL (V4L2_STD_525_60 |\
@@ -595,7 +680,7 @@ typedef __u64 v4l2_std_id;
595 680
596struct v4l2_standard 681struct v4l2_standard
597{ 682{
598 __u32 index; 683 __u32 index;
599 v4l2_std_id id; 684 v4l2_std_id id;
600 __u8 name[24]; 685 __u8 name[24];
601 struct v4l2_fract frameperiod; /* Frames, not fields */ 686 struct v4l2_fract frameperiod; /* Frames, not fields */
@@ -610,9 +695,9 @@ struct v4l2_standard
610struct v4l2_input 695struct v4l2_input
611{ 696{
612 __u32 index; /* Which input */ 697 __u32 index; /* Which input */
613 __u8 name[32]; /* Label */ 698 __u8 name[32]; /* Label */
614 __u32 type; /* Type of input */ 699 __u32 type; /* Type of input */
615 __u32 audioset; /* Associated audios (bitfield) */ 700 __u32 audioset; /* Associated audios (bitfield) */
616 __u32 tuner; /* Associated tuner */ 701 __u32 tuner; /* Associated tuner */
617 v4l2_std_id std; 702 v4l2_std_id std;
618 __u32 status; 703 __u32 status;
@@ -647,9 +732,9 @@ struct v4l2_input
647struct v4l2_output 732struct v4l2_output
648{ 733{
649 __u32 index; /* Which output */ 734 __u32 index; /* Which output */
650 __u8 name[32]; /* Label */ 735 __u8 name[32]; /* Label */
651 __u32 type; /* Type of output */ 736 __u32 type; /* Type of output */
652 __u32 audioset; /* Associated audios (bitfield) */ 737 __u32 audioset; /* Associated audios (bitfield) */
653 __u32 modulator; /* Associated modulator */ 738 __u32 modulator; /* Associated modulator */
654 v4l2_std_id std; 739 v4l2_std_id std;
655 __u32 reserved[4]; 740 __u32 reserved[4];
@@ -671,12 +756,12 @@ struct v4l2_control
671/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ 756/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
672struct v4l2_queryctrl 757struct v4l2_queryctrl
673{ 758{
674 __u32 id; 759 __u32 id;
675 enum v4l2_ctrl_type type; 760 enum v4l2_ctrl_type type;
676 __u8 name[32]; /* Whatever */ 761 __u8 name[32]; /* Whatever */
677 __s32 minimum; /* Note signedness */ 762 __s32 minimum; /* Note signedness */
678 __s32 maximum; 763 __s32 maximum;
679 __s32 step; 764 __s32 step;
680 __s32 default_value; 765 __s32 default_value;
681 __u32 flags; 766 __u32 flags;
682 __u32 reserved[2]; 767 __u32 reserved[2];
@@ -779,10 +864,10 @@ struct v4l2_modulator
779 864
780struct v4l2_frequency 865struct v4l2_frequency
781{ 866{
782 __u32 tuner; 867 __u32 tuner;
783 enum v4l2_tuner_type type; 868 enum v4l2_tuner_type type;
784 __u32 frequency; 869 __u32 frequency;
785 __u32 reserved[8]; 870 __u32 reserved[8];
786}; 871};
787 872
788/* 873/*
@@ -802,6 +887,7 @@ struct v4l2_audio
802 887
803/* Flags for the 'mode' field */ 888/* Flags for the 'mode' field */
804#define V4L2_AUDMODE_AVL 0x00001 889#define V4L2_AUDMODE_AVL 0x00001
890#define V4L2_AUDMODE_32BITS 0x00002
805 891
806struct v4l2_audioout 892struct v4l2_audioout
807{ 893{
@@ -846,14 +932,14 @@ struct v4l2_vbi_format
846 932
847struct v4l2_sliced_vbi_format 933struct v4l2_sliced_vbi_format
848{ 934{
849 __u16 service_set; 935 __u16 service_set;
850 /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field 936 /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
851 service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field 937 service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
852 (equals frame lines 313-336 for 625 line video 938 (equals frame lines 313-336 for 625 line video
853 standards, 263-286 for 525 line standards) */ 939 standards, 263-286 for 525 line standards) */
854 __u16 service_lines[2][24]; 940 __u16 service_lines[2][24];
855 __u32 io_size; 941 __u32 io_size;
856 __u32 reserved[2]; /* must be zero */ 942 __u32 reserved[2]; /* must be zero */
857}; 943};
858 944
859#define V4L2_SLICED_TELETEXT_B (0x0001) 945#define V4L2_SLICED_TELETEXT_B (0x0001)
@@ -866,22 +952,22 @@ struct v4l2_sliced_vbi_format
866 952
867struct v4l2_sliced_vbi_cap 953struct v4l2_sliced_vbi_cap
868{ 954{
869 __u16 service_set; 955 __u16 service_set;
870 /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field 956 /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
871 service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field 957 service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
872 (equals frame lines 313-336 for 625 line video 958 (equals frame lines 313-336 for 625 line video
873 standards, 263-286 for 525 line standards) */ 959 standards, 263-286 for 525 line standards) */
874 __u16 service_lines[2][24]; 960 __u16 service_lines[2][24];
875 __u32 reserved[4]; /* must be 0 */ 961 __u32 reserved[4]; /* must be 0 */
876}; 962};
877 963
878struct v4l2_sliced_vbi_data 964struct v4l2_sliced_vbi_data
879{ 965{
880 __u32 id; 966 __u32 id;
881 __u32 field; /* 0: first field, 1: second field */ 967 __u32 field; /* 0: first field, 1: second field */
882 __u32 line; /* 1-23 */ 968 __u32 line; /* 1-23 */
883 __u32 reserved; /* must be 0 */ 969 __u32 reserved; /* must be 0 */
884 __u8 data[48]; 970 __u8 data[48];
885}; 971};
886#endif 972#endif
887 973
@@ -896,9 +982,9 @@ struct v4l2_format
896 enum v4l2_buf_type type; 982 enum v4l2_buf_type type;
897 union 983 union
898 { 984 {
899 struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE 985 struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
900 struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY 986 struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
901 struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE 987 struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
902#if 1 988#if 1
903 struct v4l2_sliced_vbi_format sliced; // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE 989 struct v4l2_sliced_vbi_format sliced; // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
904#endif 990#endif
@@ -981,6 +1067,7 @@ struct v4l2_streamparm
981#if 1 1067#if 1
982#define VIDIOC_G_SLICED_VBI_CAP _IOR ('V', 69, struct v4l2_sliced_vbi_cap) 1068#define VIDIOC_G_SLICED_VBI_CAP _IOR ('V', 69, struct v4l2_sliced_vbi_cap)
983#endif 1069#endif
1070#define VIDIOC_LOG_STATUS _IO ('V', 70)
984 1071
985/* for compatibility, will go away some day */ 1072/* for compatibility, will go away some day */
986#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int) 1073#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
index a7ceee9fc5e9..b7d4b0930408 100644
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -4,6 +4,23 @@
4#ifndef AUDIOCHIP_H 4#ifndef AUDIOCHIP_H
5#define AUDIOCHIP_H 5#define AUDIOCHIP_H
6 6
7enum audiochip {
8 AUDIO_CHIP_NONE,
9 AUDIO_CHIP_UNKNOWN,
10 /* Provided by video chip */
11 AUDIO_CHIP_INTERNAL,
12 /* Provided by tvaudio.c */
13 AUDIO_CHIP_TDA8425,
14 AUDIO_CHIP_TEA6300,
15 AUDIO_CHIP_TEA6420,
16 AUDIO_CHIP_TDA9840,
17 AUDIO_CHIP_TDA985X,
18 AUDIO_CHIP_TDA9874,
19 AUDIO_CHIP_PIC16C54,
20 /* Provided by msp3400.c */
21 AUDIO_CHIP_MSP34XX
22};
23
7/* ---------------------------------------------------------------------- */ 24/* ---------------------------------------------------------------------- */
8 25
9/* v4l device was opened in Radio mode */ 26/* v4l device was opened in Radio mode */
diff --git a/include/media/id.h b/include/media/id.h
deleted file mode 100644
index 6d02c94cdc0d..000000000000
--- a/include/media/id.h
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 */
3
4/* FIXME: this temporarely, until these are included in linux/i2c-id.h */
5
6/* drivers */
7#ifndef I2C_DRIVERID_TVMIXER
8# define I2C_DRIVERID_TVMIXER I2C_DRIVERID_EXP0
9#endif
10#ifndef I2C_DRIVERID_TVAUDIO
11# define I2C_DRIVERID_TVAUDIO I2C_DRIVERID_EXP1
12#endif
13
14/* chips */
15#ifndef I2C_DRIVERID_DPL3518
16# define I2C_DRIVERID_DPL3518 I2C_DRIVERID_EXP2
17#endif
18#ifndef I2C_DRIVERID_TDA9873
19# define I2C_DRIVERID_TDA9873 I2C_DRIVERID_EXP3
20#endif
21#ifndef I2C_DRIVERID_TDA9875
22# define I2C_DRIVERID_TDA9875 I2C_DRIVERID_EXP0+4
23#endif
24#ifndef I2C_DRIVERID_PIC16C54_PV951
25# define I2C_DRIVERID_PIC16C54_PV951 I2C_DRIVERID_EXP0+5
26#endif
27#ifndef I2C_DRIVERID_TDA7432
28# define I2C_DRIVERID_TDA7432 I2C_DRIVERID_EXP0+6
29#endif
30#ifndef I2C_DRIVERID_TDA9874
31# define I2C_DRIVERID_TDA9874 I2C_DRIVERID_EXP0+7
32#endif
33#ifndef I2C_DRIVERID_SAA6752HS
34# define I2C_DRIVERID_SAA6752HS I2C_DRIVERID_EXP0+8
35#endif
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 01b56822df4d..0f1ba95ec8d6 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -20,8 +20,10 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23#include <linux/input.h> 23#ifndef _IR_COMMON
24#define _IR_COMMON
24 25
26#include <linux/input.h>
25 27
26#define IR_TYPE_RC5 1 28#define IR_TYPE_RC5 1
27#define IR_TYPE_PD 2 /* Pulse distance encoded IR */ 29#define IR_TYPE_PD 2 /* Pulse distance encoded IR */
@@ -61,6 +63,8 @@ int ir_dump_samples(u32 *samples, int count);
61int ir_decode_biphase(u32 *samples, int count, int low, int high); 63int ir_decode_biphase(u32 *samples, int count, int low, int high);
62int ir_decode_pulsedistance(u32 *samples, int count, int low, int high); 64int ir_decode_pulsedistance(u32 *samples, int count, int low, int high);
63 65
66#endif
67
64/* 68/*
65 * Local variables: 69 * Local variables:
66 * c-basic-offset: 8 70 * c-basic-offset: 8
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
new file mode 100644
index 000000000000..00fa57eb9fde
--- /dev/null
+++ b/include/media/ir-kbd-i2c.h
@@ -0,0 +1,22 @@
1#ifndef _IR_I2C
2#define _IR_I2C
3
4#include <media/ir-common.h>
5
6struct IR_i2c;
7
8struct IR_i2c {
9 IR_KEYTAB_TYPE *ir_codes;
10 struct i2c_client c;
11 struct input_dev *input;
12 struct ir_input_state ir;
13
14 /* Used to avoid fast repeating */
15 unsigned char old;
16
17 struct work_struct work;
18 struct timer_list timer;
19 char phys[32];
20 int (*get_key)(struct IR_i2c*, u32*, u32*);
21};
22#endif
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index f3aa24f8131c..64691753721e 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -1,7 +1,7 @@
1#ifndef __SAA7146_VV__ 1#ifndef __SAA7146_VV__
2#define __SAA7146_VV__ 2#define __SAA7146_VV__
3 3
4#include <linux/videodev2.h> 4#include <linux/videodev.h>
5 5
6#include <media/saa7146.h> 6#include <media/saa7146.h>
7#include <media/video-buf.h> 7#include <media/video-buf.h>
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 4ad08e24a1aa..9184e534b7ef 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -95,7 +95,7 @@
95#define TUNER_THOMSON_DTT7610 52 95#define TUNER_THOMSON_DTT7610 52
96#define TUNER_PHILIPS_FQ1286 53 96#define TUNER_PHILIPS_FQ1286 53
97#define TUNER_PHILIPS_TDA8290 54 97#define TUNER_PHILIPS_TDA8290 54
98#define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */ 98#define TUNER_TCL_2002MB 55 /* Hauppauge PVR-150 PAL */
99 99
100#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */ 100#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */
101#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */ 101#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */
@@ -110,6 +110,9 @@
110#define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */ 110#define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */
111#define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */ 111#define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */
112#define TUNER_LG_NTSC_TALN_MINI 66 112#define TUNER_LG_NTSC_TALN_MINI 66
113#define TUNER_PHILIPS_TD1316 67
114
115#define TUNER_PHILIPS_TUV1236D 68 /* ATI HDTV Wonder */
113 116
114#define NOTUNER 0 117#define NOTUNER 0
115#define PAL 1 /* PAL_BG */ 118#define PAL 1 /* PAL_BG */
@@ -145,6 +148,7 @@
145# define TDA9887_INTERCARRIER (1<<4) 148# define TDA9887_INTERCARRIER (1<<4)
146# define TDA9887_PORT1_ACTIVE (1<<5) 149# define TDA9887_PORT1_ACTIVE (1<<5)
147# define TDA9887_PORT2_ACTIVE (1<<6) 150# define TDA9887_PORT2_ACTIVE (1<<6)
151# define TDA9887_INTERCARRIER_NTSC (1<<7)
148/* config options */ 152/* config options */
149# define TDA9887_DEEMPHASIS_MASK (3<<16) 153# define TDA9887_DEEMPHASIS_MASK (3<<16)
150# define TDA9887_DEEMPHASIS_NONE (1<<16) 154# define TDA9887_DEEMPHASIS_NONE (1<<16)
@@ -188,8 +192,11 @@ struct tuner {
188 unsigned int radio_if2; 192 unsigned int radio_if2;
189 193
190 /* used by tda8290 */ 194 /* used by tda8290 */
191 unsigned char i2c_easy_mode[2]; 195 unsigned char tda8290_easy_mode;
192 unsigned char i2c_set_freq[8]; 196 unsigned char tda827x_lpsel;
197 unsigned char tda827x_addr;
198 unsigned char tda827x_ver;
199 unsigned int sgIF;
193 200
194 /* function ptrs */ 201 /* function ptrs */
195 void (*tv_freq)(struct i2c_client *c, unsigned int freq); 202 void (*tv_freq)(struct i2c_client *c, unsigned int freq);
@@ -204,20 +211,21 @@ extern unsigned const int tuner_count;
204 211
205extern int microtune_init(struct i2c_client *c); 212extern int microtune_init(struct i2c_client *c);
206extern int tda8290_init(struct i2c_client *c); 213extern int tda8290_init(struct i2c_client *c);
214extern int tda8290_probe(struct i2c_client *c);
207extern int tea5767_tuner_init(struct i2c_client *c); 215extern int tea5767_tuner_init(struct i2c_client *c);
208extern int default_tuner_init(struct i2c_client *c); 216extern int default_tuner_init(struct i2c_client *c);
209extern int tea5767_autodetection(struct i2c_client *c); 217extern int tea5767_autodetection(struct i2c_client *c);
210 218
211#define tuner_warn(fmt, arg...) do {\ 219#define tuner_warn(fmt, arg...) do {\
212 printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->name, \ 220 printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->name, \
213 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) 221 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
214#define tuner_info(fmt, arg...) do {\ 222#define tuner_info(fmt, arg...) do {\
215 printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->name, \ 223 printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->name, \
216 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) 224 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
217#define tuner_dbg(fmt, arg...) do {\ 225#define tuner_dbg(fmt, arg...) do {\
218 if (tuner_debug) \ 226 if (tuner_debug) \
219 printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->name, \ 227 printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->name, \
220 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) 228 t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
221 229
222#endif /* __KERNEL__ */ 230#endif /* __KERNEL__ */
223 231
diff --git a/include/media/video-buf.h b/include/media/video-buf.h
index ae8d7a000440..8ecfd78e0027 100644
--- a/include/media/video-buf.h
+++ b/include/media/video-buf.h
@@ -17,7 +17,7 @@
17 * (at your option) any later version. 17 * (at your option) any later version.
18 */ 18 */
19 19
20#include <linux/videodev.h> 20#include <linux/videodev2.h>
21 21
22#define UNSET (-1U) 22#define UNSET (-1U)
23 23
@@ -177,7 +177,7 @@ struct videobuf_queue_ops {
177}; 177};
178 178
179struct videobuf_queue { 179struct videobuf_queue {
180 struct semaphore lock; 180 struct semaphore lock;
181 spinlock_t *irqlock; 181 spinlock_t *irqlock;
182 struct pci_dev *pci; 182 struct pci_dev *pci;
183 183
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index e42d728b1620..911ceb5cd263 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -57,8 +57,6 @@
57#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg) 57#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg)
58#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg) 58#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg)
59 59
60extern struct proc_dir_entry *proc_bt;
61
62/* Connection and socket states */ 60/* Connection and socket states */
63enum { 61enum {
64 BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */ 62 BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */
@@ -177,4 +175,6 @@ extern int hci_sock_cleanup(void);
177extern int bt_sysfs_init(void); 175extern int bt_sysfs_init(void);
178extern void bt_sysfs_cleanup(void); 176extern void bt_sysfs_cleanup(void);
179 177
178extern struct class bt_class;
179
180#endif /* __BLUETOOTH_H */ 180#endif /* __BLUETOOTH_H */
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index fa2d12b0579b..b06a2d2f63d2 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -184,10 +184,10 @@ enum {
184struct hci_rp_read_loc_version { 184struct hci_rp_read_loc_version {
185 __u8 status; 185 __u8 status;
186 __u8 hci_ver; 186 __u8 hci_ver;
187 __u16 hci_rev; 187 __le16 hci_rev;
188 __u8 lmp_ver; 188 __u8 lmp_ver;
189 __u16 manufacturer; 189 __le16 manufacturer;
190 __u16 lmp_subver; 190 __le16 lmp_subver;
191} __attribute__ ((packed)); 191} __attribute__ ((packed));
192 192
193#define OCF_READ_LOCAL_FEATURES 0x0003 193#define OCF_READ_LOCAL_FEATURES 0x0003
@@ -199,10 +199,10 @@ struct hci_rp_read_loc_features {
199#define OCF_READ_BUFFER_SIZE 0x0005 199#define OCF_READ_BUFFER_SIZE 0x0005
200struct hci_rp_read_buffer_size { 200struct hci_rp_read_buffer_size {
201 __u8 status; 201 __u8 status;
202 __u16 acl_mtu; 202 __le16 acl_mtu;
203 __u8 sco_mtu; 203 __u8 sco_mtu;
204 __u16 acl_max_pkt; 204 __le16 acl_max_pkt;
205 __u16 sco_max_pkt; 205 __le16 sco_max_pkt;
206} __attribute__ ((packed)); 206} __attribute__ ((packed));
207 207
208#define OCF_READ_BD_ADDR 0x0009 208#define OCF_READ_BD_ADDR 0x0009
@@ -267,21 +267,21 @@ struct hci_cp_write_dev_class {
267 267
268#define OCF_READ_VOICE_SETTING 0x0025 268#define OCF_READ_VOICE_SETTING 0x0025
269struct hci_rp_read_voice_setting { 269struct hci_rp_read_voice_setting {
270 __u8 status; 270 __u8 status;
271 __u16 voice_setting; 271 __le16 voice_setting;
272} __attribute__ ((packed)); 272} __attribute__ ((packed));
273 273
274#define OCF_WRITE_VOICE_SETTING 0x0026 274#define OCF_WRITE_VOICE_SETTING 0x0026
275struct hci_cp_write_voice_setting { 275struct hci_cp_write_voice_setting {
276 __u16 voice_setting; 276 __le16 voice_setting;
277} __attribute__ ((packed)); 277} __attribute__ ((packed));
278 278
279#define OCF_HOST_BUFFER_SIZE 0x0033 279#define OCF_HOST_BUFFER_SIZE 0x0033
280struct hci_cp_host_buffer_size { 280struct hci_cp_host_buffer_size {
281 __u16 acl_mtu; 281 __le16 acl_mtu;
282 __u8 sco_mtu; 282 __u8 sco_mtu;
283 __u16 acl_max_pkt; 283 __le16 acl_max_pkt;
284 __u16 sco_max_pkt; 284 __le16 sco_max_pkt;
285} __attribute__ ((packed)); 285} __attribute__ ((packed));
286 286
287/* Link Control */ 287/* Link Control */
@@ -289,10 +289,10 @@ struct hci_cp_host_buffer_size {
289#define OCF_CREATE_CONN 0x0005 289#define OCF_CREATE_CONN 0x0005
290struct hci_cp_create_conn { 290struct hci_cp_create_conn {
291 bdaddr_t bdaddr; 291 bdaddr_t bdaddr;
292 __u16 pkt_type; 292 __le16 pkt_type;
293 __u8 pscan_rep_mode; 293 __u8 pscan_rep_mode;
294 __u8 pscan_mode; 294 __u8 pscan_mode;
295 __u16 clock_offset; 295 __le16 clock_offset;
296 __u8 role_switch; 296 __u8 role_switch;
297} __attribute__ ((packed)); 297} __attribute__ ((packed));
298 298
@@ -310,14 +310,14 @@ struct hci_cp_reject_conn_req {
310 310
311#define OCF_DISCONNECT 0x0006 311#define OCF_DISCONNECT 0x0006
312struct hci_cp_disconnect { 312struct hci_cp_disconnect {
313 __u16 handle; 313 __le16 handle;
314 __u8 reason; 314 __u8 reason;
315} __attribute__ ((packed)); 315} __attribute__ ((packed));
316 316
317#define OCF_ADD_SCO 0x0007 317#define OCF_ADD_SCO 0x0007
318struct hci_cp_add_sco { 318struct hci_cp_add_sco {
319 __u16 handle; 319 __le16 handle;
320 __u16 pkt_type; 320 __le16 pkt_type;
321} __attribute__ ((packed)); 321} __attribute__ ((packed));
322 322
323#define OCF_INQUIRY 0x0001 323#define OCF_INQUIRY 0x0001
@@ -354,56 +354,56 @@ struct hci_cp_pin_code_neg_reply {
354 354
355#define OCF_CHANGE_CONN_PTYPE 0x000F 355#define OCF_CHANGE_CONN_PTYPE 0x000F
356struct hci_cp_change_conn_ptype { 356struct hci_cp_change_conn_ptype {
357 __u16 handle; 357 __le16 handle;
358 __u16 pkt_type; 358 __le16 pkt_type;
359} __attribute__ ((packed)); 359} __attribute__ ((packed));
360 360
361#define OCF_AUTH_REQUESTED 0x0011 361#define OCF_AUTH_REQUESTED 0x0011
362struct hci_cp_auth_requested { 362struct hci_cp_auth_requested {
363 __u16 handle; 363 __le16 handle;
364} __attribute__ ((packed)); 364} __attribute__ ((packed));
365 365
366#define OCF_SET_CONN_ENCRYPT 0x0013 366#define OCF_SET_CONN_ENCRYPT 0x0013
367struct hci_cp_set_conn_encrypt { 367struct hci_cp_set_conn_encrypt {
368 __u16 handle; 368 __le16 handle;
369 __u8 encrypt; 369 __u8 encrypt;
370} __attribute__ ((packed)); 370} __attribute__ ((packed));
371 371
372#define OCF_CHANGE_CONN_LINK_KEY 0x0015 372#define OCF_CHANGE_CONN_LINK_KEY 0x0015
373struct hci_cp_change_conn_link_key { 373struct hci_cp_change_conn_link_key {
374 __u16 handle; 374 __le16 handle;
375} __attribute__ ((packed)); 375} __attribute__ ((packed));
376 376
377#define OCF_READ_REMOTE_FEATURES 0x001B 377#define OCF_READ_REMOTE_FEATURES 0x001B
378struct hci_cp_read_rmt_features { 378struct hci_cp_read_rmt_features {
379 __u16 handle; 379 __le16 handle;
380} __attribute__ ((packed)); 380} __attribute__ ((packed));
381 381
382#define OCF_READ_REMOTE_VERSION 0x001D 382#define OCF_READ_REMOTE_VERSION 0x001D
383struct hci_cp_read_rmt_version { 383struct hci_cp_read_rmt_version {
384 __u16 handle; 384 __le16 handle;
385} __attribute__ ((packed)); 385} __attribute__ ((packed));
386 386
387/* Link Policy */ 387/* Link Policy */
388#define OGF_LINK_POLICY 0x02 388#define OGF_LINK_POLICY 0x02
389#define OCF_ROLE_DISCOVERY 0x0009 389#define OCF_ROLE_DISCOVERY 0x0009
390struct hci_cp_role_discovery { 390struct hci_cp_role_discovery {
391 __u16 handle; 391 __le16 handle;
392} __attribute__ ((packed)); 392} __attribute__ ((packed));
393struct hci_rp_role_discovery { 393struct hci_rp_role_discovery {
394 __u8 status; 394 __u8 status;
395 __u16 handle; 395 __le16 handle;
396 __u8 role; 396 __u8 role;
397} __attribute__ ((packed)); 397} __attribute__ ((packed));
398 398
399#define OCF_READ_LINK_POLICY 0x000C 399#define OCF_READ_LINK_POLICY 0x000C
400struct hci_cp_read_link_policy { 400struct hci_cp_read_link_policy {
401 __u16 handle; 401 __le16 handle;
402} __attribute__ ((packed)); 402} __attribute__ ((packed));
403struct hci_rp_read_link_policy { 403struct hci_rp_read_link_policy {
404 __u8 status; 404 __u8 status;
405 __u16 handle; 405 __le16 handle;
406 __u16 policy; 406 __le16 policy;
407} __attribute__ ((packed)); 407} __attribute__ ((packed));
408 408
409#define OCF_SWITCH_ROLE 0x000B 409#define OCF_SWITCH_ROLE 0x000B
@@ -414,12 +414,12 @@ struct hci_cp_switch_role {
414 414
415#define OCF_WRITE_LINK_POLICY 0x000D 415#define OCF_WRITE_LINK_POLICY 0x000D
416struct hci_cp_write_link_policy { 416struct hci_cp_write_link_policy {
417 __u16 handle; 417 __le16 handle;
418 __u16 policy; 418 __le16 policy;
419} __attribute__ ((packed)); 419} __attribute__ ((packed));
420struct hci_rp_write_link_policy { 420struct hci_rp_write_link_policy {
421 __u8 status; 421 __u8 status;
422 __u16 handle; 422 __le16 handle;
423} __attribute__ ((packed)); 423} __attribute__ ((packed));
424 424
425/* Status params */ 425/* Status params */
@@ -441,7 +441,7 @@ struct inquiry_info {
441 __u8 pscan_period_mode; 441 __u8 pscan_period_mode;
442 __u8 pscan_mode; 442 __u8 pscan_mode;
443 __u8 dev_class[3]; 443 __u8 dev_class[3];
444 __u16 clock_offset; 444 __le16 clock_offset;
445} __attribute__ ((packed)); 445} __attribute__ ((packed));
446 446
447#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22 447#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22
@@ -450,7 +450,7 @@ struct inquiry_info_with_rssi {
450 __u8 pscan_rep_mode; 450 __u8 pscan_rep_mode;
451 __u8 pscan_period_mode; 451 __u8 pscan_period_mode;
452 __u8 dev_class[3]; 452 __u8 dev_class[3];
453 __u16 clock_offset; 453 __le16 clock_offset;
454 __s8 rssi; 454 __s8 rssi;
455} __attribute__ ((packed)); 455} __attribute__ ((packed));
456struct inquiry_info_with_rssi_and_pscan_mode { 456struct inquiry_info_with_rssi_and_pscan_mode {
@@ -459,7 +459,7 @@ struct inquiry_info_with_rssi_and_pscan_mode {
459 __u8 pscan_period_mode; 459 __u8 pscan_period_mode;
460 __u8 pscan_mode; 460 __u8 pscan_mode;
461 __u8 dev_class[3]; 461 __u8 dev_class[3];
462 __u16 clock_offset; 462 __le16 clock_offset;
463 __s8 rssi; 463 __s8 rssi;
464} __attribute__ ((packed)); 464} __attribute__ ((packed));
465 465
@@ -469,7 +469,7 @@ struct extended_inquiry_info {
469 __u8 pscan_rep_mode; 469 __u8 pscan_rep_mode;
470 __u8 pscan_period_mode; 470 __u8 pscan_period_mode;
471 __u8 dev_class[3]; 471 __u8 dev_class[3];
472 __u16 clock_offset; 472 __le16 clock_offset;
473 __s8 rssi; 473 __s8 rssi;
474 __u8 data[240]; 474 __u8 data[240];
475} __attribute__ ((packed)); 475} __attribute__ ((packed));
@@ -477,7 +477,7 @@ struct extended_inquiry_info {
477#define HCI_EV_CONN_COMPLETE 0x03 477#define HCI_EV_CONN_COMPLETE 0x03
478struct hci_ev_conn_complete { 478struct hci_ev_conn_complete {
479 __u8 status; 479 __u8 status;
480 __u16 handle; 480 __le16 handle;
481 bdaddr_t bdaddr; 481 bdaddr_t bdaddr;
482 __u8 link_type; 482 __u8 link_type;
483 __u8 encr_mode; 483 __u8 encr_mode;
@@ -493,27 +493,27 @@ struct hci_ev_conn_request {
493#define HCI_EV_DISCONN_COMPLETE 0x05 493#define HCI_EV_DISCONN_COMPLETE 0x05
494struct hci_ev_disconn_complete { 494struct hci_ev_disconn_complete {
495 __u8 status; 495 __u8 status;
496 __u16 handle; 496 __le16 handle;
497 __u8 reason; 497 __u8 reason;
498} __attribute__ ((packed)); 498} __attribute__ ((packed));
499 499
500#define HCI_EV_AUTH_COMPLETE 0x06 500#define HCI_EV_AUTH_COMPLETE 0x06
501struct hci_ev_auth_complete { 501struct hci_ev_auth_complete {
502 __u8 status; 502 __u8 status;
503 __u16 handle; 503 __le16 handle;
504} __attribute__ ((packed)); 504} __attribute__ ((packed));
505 505
506#define HCI_EV_ENCRYPT_CHANGE 0x08 506#define HCI_EV_ENCRYPT_CHANGE 0x08
507struct hci_ev_encrypt_change { 507struct hci_ev_encrypt_change {
508 __u8 status; 508 __u8 status;
509 __u16 handle; 509 __le16 handle;
510 __u8 encrypt; 510 __u8 encrypt;
511} __attribute__ ((packed)); 511} __attribute__ ((packed));
512 512
513#define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE 0x09 513#define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE 0x09
514struct hci_ev_change_conn_link_key_complete { 514struct hci_ev_change_conn_link_key_complete {
515 __u8 status; 515 __u8 status;
516 __u16 handle; 516 __le16 handle;
517} __attribute__ ((packed)); 517} __attribute__ ((packed));
518 518
519#define HCI_EV_QOS_SETUP_COMPLETE 0x0D 519#define HCI_EV_QOS_SETUP_COMPLETE 0x0D
@@ -526,21 +526,21 @@ struct hci_qos {
526} __attribute__ ((packed)); 526} __attribute__ ((packed));
527struct hci_ev_qos_setup_complete { 527struct hci_ev_qos_setup_complete {
528 __u8 status; 528 __u8 status;
529 __u16 handle; 529 __le16 handle;
530 struct hci_qos qos; 530 struct hci_qos qos;
531} __attribute__ ((packed)); 531} __attribute__ ((packed));
532 532
533#define HCI_EV_CMD_COMPLETE 0x0E 533#define HCI_EV_CMD_COMPLETE 0x0E
534struct hci_ev_cmd_complete { 534struct hci_ev_cmd_complete {
535 __u8 ncmd; 535 __u8 ncmd;
536 __u16 opcode; 536 __le16 opcode;
537} __attribute__ ((packed)); 537} __attribute__ ((packed));
538 538
539#define HCI_EV_CMD_STATUS 0x0F 539#define HCI_EV_CMD_STATUS 0x0F
540struct hci_ev_cmd_status { 540struct hci_ev_cmd_status {
541 __u8 status; 541 __u8 status;
542 __u8 ncmd; 542 __u8 ncmd;
543 __u16 opcode; 543 __le16 opcode;
544} __attribute__ ((packed)); 544} __attribute__ ((packed));
545 545
546#define HCI_EV_NUM_COMP_PKTS 0x13 546#define HCI_EV_NUM_COMP_PKTS 0x13
@@ -559,9 +559,9 @@ struct hci_ev_role_change {
559#define HCI_EV_MODE_CHANGE 0x14 559#define HCI_EV_MODE_CHANGE 0x14
560struct hci_ev_mode_change { 560struct hci_ev_mode_change {
561 __u8 status; 561 __u8 status;
562 __u16 handle; 562 __le16 handle;
563 __u8 mode; 563 __u8 mode;
564 __u16 interval; 564 __le16 interval;
565} __attribute__ ((packed)); 565} __attribute__ ((packed));
566 566
567#define HCI_EV_PIN_CODE_REQ 0x16 567#define HCI_EV_PIN_CODE_REQ 0x16
@@ -584,24 +584,24 @@ struct hci_ev_link_key_notify {
584#define HCI_EV_RMT_FEATURES 0x0B 584#define HCI_EV_RMT_FEATURES 0x0B
585struct hci_ev_rmt_features { 585struct hci_ev_rmt_features {
586 __u8 status; 586 __u8 status;
587 __u16 handle; 587 __le16 handle;
588 __u8 features[8]; 588 __u8 features[8];
589} __attribute__ ((packed)); 589} __attribute__ ((packed));
590 590
591#define HCI_EV_RMT_VERSION 0x0C 591#define HCI_EV_RMT_VERSION 0x0C
592struct hci_ev_rmt_version { 592struct hci_ev_rmt_version {
593 __u8 status; 593 __u8 status;
594 __u16 handle; 594 __le16 handle;
595 __u8 lmp_ver; 595 __u8 lmp_ver;
596 __u16 manufacturer; 596 __le16 manufacturer;
597 __u16 lmp_subver; 597 __le16 lmp_subver;
598} __attribute__ ((packed)); 598} __attribute__ ((packed));
599 599
600#define HCI_EV_CLOCK_OFFSET 0x01C 600#define HCI_EV_CLOCK_OFFSET 0x01C
601struct hci_ev_clock_offset { 601struct hci_ev_clock_offset {
602 __u8 status; 602 __u8 status;
603 __u16 handle; 603 __le16 handle;
604 __u16 clock_offset; 604 __le16 clock_offset;
605} __attribute__ ((packed)); 605} __attribute__ ((packed));
606 606
607#define HCI_EV_PSCAN_REP_MODE 0x20 607#define HCI_EV_PSCAN_REP_MODE 0x20
@@ -638,7 +638,7 @@ struct hci_ev_si_security {
638#define HCI_SCO_HDR_SIZE 3 638#define HCI_SCO_HDR_SIZE 3
639 639
640struct hci_command_hdr { 640struct hci_command_hdr {
641 __u16 opcode; /* OCF & OGF */ 641 __le16 opcode; /* OCF & OGF */
642 __u8 plen; 642 __u8 plen;
643} __attribute__ ((packed)); 643} __attribute__ ((packed));
644 644
@@ -648,22 +648,22 @@ struct hci_event_hdr {
648} __attribute__ ((packed)); 648} __attribute__ ((packed));
649 649
650struct hci_acl_hdr { 650struct hci_acl_hdr {
651 __u16 handle; /* Handle & Flags(PB, BC) */ 651 __le16 handle; /* Handle & Flags(PB, BC) */
652 __u16 dlen; 652 __le16 dlen;
653} __attribute__ ((packed)); 653} __attribute__ ((packed));
654 654
655struct hci_sco_hdr { 655struct hci_sco_hdr {
656 __u16 handle; 656 __le16 handle;
657 __u8 dlen; 657 __u8 dlen;
658} __attribute__ ((packed)); 658} __attribute__ ((packed));
659 659
660/* Command opcode pack/unpack */ 660/* Command opcode pack/unpack */
661#define hci_opcode_pack(ogf, ocf) (__u16)((ocf & 0x03ff)|(ogf << 10)) 661#define hci_opcode_pack(ogf, ocf) (__u16) ((ocf & 0x03ff)|(ogf << 10))
662#define hci_opcode_ogf(op) (op >> 10) 662#define hci_opcode_ogf(op) (op >> 10)
663#define hci_opcode_ocf(op) (op & 0x03ff) 663#define hci_opcode_ocf(op) (op & 0x03ff)
664 664
665/* ACL handle and flags pack/unpack */ 665/* ACL handle and flags pack/unpack */
666#define hci_handle_pack(h, f) (__u16)((h & 0x0fff)|(f << 12)) 666#define hci_handle_pack(h, f) (__u16) ((h & 0x0fff)|(f << 12))
667#define hci_handle(h) (h & 0x0fff) 667#define hci_handle(h) (h & 0x0fff)
668#define hci_flags(h) (h >> 12) 668#define hci_flags(h) (h >> 12)
669 669
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 7f933f302078..bb9f81dc8723 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -25,7 +25,6 @@
25#ifndef __HCI_CORE_H 25#ifndef __HCI_CORE_H
26#define __HCI_CORE_H 26#define __HCI_CORE_H
27 27
28#include <linux/proc_fs.h>
29#include <net/bluetooth/hci.h> 28#include <net/bluetooth/hci.h>
30 29
31/* HCI upper protocols */ 30/* HCI upper protocols */
@@ -34,8 +33,6 @@
34 33
35#define HCI_INIT_TIMEOUT (HZ * 10) 34#define HCI_INIT_TIMEOUT (HZ * 10)
36 35
37extern struct proc_dir_entry *proc_bt_hci;
38
39/* HCI Core structures */ 36/* HCI Core structures */
40 37
41struct inquiry_data { 38struct inquiry_data {
@@ -44,7 +41,7 @@ struct inquiry_data {
44 __u8 pscan_period_mode; 41 __u8 pscan_period_mode;
45 __u8 pscan_mode; 42 __u8 pscan_mode;
46 __u8 dev_class[3]; 43 __u8 dev_class[3];
47 __u16 clock_offset; 44 __le16 clock_offset;
48 __s8 rssi; 45 __s8 rssi;
49}; 46};
50 47
@@ -126,10 +123,6 @@ struct hci_dev {
126 123
127 atomic_t promisc; 124 atomic_t promisc;
128 125
129#ifdef CONFIG_PROC_FS
130 struct proc_dir_entry *proc;
131#endif
132
133 struct class_device class_dev; 126 struct class_device class_dev;
134 127
135 struct module *owner; 128 struct module *owner;
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index e656be7c001a..bbfac86734ec 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -351,6 +351,4 @@ int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
351int rfcomm_init_ttys(void); 351int rfcomm_init_ttys(void);
352void rfcomm_cleanup_ttys(void); 352void rfcomm_cleanup_ttys(void);
353 353
354extern struct proc_dir_entry *proc_bt_rfcomm;
355
356#endif /* __RFCOMM_H */ 354#endif /* __RFCOMM_H */
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
new file mode 100644
index 000000000000..52d8b1a73d52
--- /dev/null
+++ b/include/net/genetlink.h
@@ -0,0 +1,154 @@
1#ifndef __NET_GENERIC_NETLINK_H
2#define __NET_GENERIC_NETLINK_H
3
4#include <linux/genetlink.h>
5#include <net/netlink.h>
6
7/**
8 * struct genl_family - generic netlink family
9 * @id: protocol family idenfitier
10 * @hdrsize: length of user specific header in bytes
11 * @name: name of family
12 * @version: protocol version
13 * @maxattr: maximum number of attributes supported
14 * @attrbuf: buffer to store parsed attributes
15 * @ops_list: list of all assigned operations
16 * @family_list: family list
17 */
18struct genl_family
19{
20 unsigned int id;
21 unsigned int hdrsize;
22 char name[GENL_NAMSIZ];
23 unsigned int version;
24 unsigned int maxattr;
25 struct module * owner;
26 struct nlattr ** attrbuf; /* private */
27 struct list_head ops_list; /* private */
28 struct list_head family_list; /* private */
29};
30
31#define GENL_ADMIN_PERM 0x01
32
33/**
34 * struct genl_info - receiving information
35 * @snd_seq: sending sequence number
36 * @snd_pid: netlink pid of sender
37 * @nlhdr: netlink message header
38 * @genlhdr: generic netlink message header
39 * @userhdr: user specific header
40 * @attrs: netlink attributes
41 */
42struct genl_info
43{
44 u32 snd_seq;
45 u32 snd_pid;
46 struct nlmsghdr * nlhdr;
47 struct genlmsghdr * genlhdr;
48 void * userhdr;
49 struct nlattr ** attrs;
50};
51
52/**
53 * struct genl_ops - generic netlink operations
54 * @cmd: command identifier
55 * @flags: flags
56 * @policy: attribute validation policy
57 * @doit: standard command callback
58 * @dumpit: callback for dumpers
59 * @ops_list: operations list
60 */
61struct genl_ops
62{
63 unsigned int cmd;
64 unsigned int flags;
65 struct nla_policy *policy;
66 int (*doit)(struct sk_buff *skb,
67 struct genl_info *info);
68 int (*dumpit)(struct sk_buff *skb,
69 struct netlink_callback *cb);
70 struct list_head ops_list;
71};
72
73extern int genl_register_family(struct genl_family *family);
74extern int genl_unregister_family(struct genl_family *family);
75extern int genl_register_ops(struct genl_family *, struct genl_ops *ops);
76extern int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
77
78extern struct sock *genl_sock;
79
80/**
81 * genlmsg_put - Add generic netlink header to netlink message
82 * @skb: socket buffer holding the message
83 * @pid: netlink pid the message is addressed to
84 * @seq: sequence number (usually the one of the sender)
85 * @type: netlink message type
86 * @hdrlen: length of the user specific header
87 * @flags netlink message flags
88 * @cmd: generic netlink command
89 * @version: version
90 *
91 * Returns pointer to user specific header
92 */
93static inline void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
94 int type, int hdrlen, int flags,
95 u8 cmd, u8 version)
96{
97 struct nlmsghdr *nlh;
98 struct genlmsghdr *hdr;
99
100 nlh = nlmsg_put(skb, pid, seq, type, GENL_HDRLEN + hdrlen, flags);
101 if (nlh == NULL)
102 return NULL;
103
104 hdr = nlmsg_data(nlh);
105 hdr->cmd = cmd;
106 hdr->version = version;
107 hdr->reserved = 0;
108
109 return (char *) hdr + GENL_HDRLEN;
110}
111
112/**
113 * genlmsg_end - Finalize a generic netlink message
114 * @skb: socket buffer the message is stored in
115 * @hdr: user specific header
116 */
117static inline int genlmsg_end(struct sk_buff *skb, void *hdr)
118{
119 return nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
120}
121
122/**
123 * genlmsg_cancel - Cancel construction of a generic netlink message
124 * @skb: socket buffer the message is stored in
125 * @hdr: generic netlink message header
126 */
127static inline int genlmsg_cancel(struct sk_buff *skb, void *hdr)
128{
129 return nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
130}
131
132/**
133 * genlmsg_multicast - multicast a netlink message
134 * @skb: netlink message as socket buffer
135 * @pid: own netlink pid to avoid sending to yourself
136 * @group: multicast group id
137 */
138static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid,
139 unsigned int group)
140{
141 return nlmsg_multicast(genl_sock, skb, pid, group);
142}
143
144/**
145 * genlmsg_unicast - unicast a netlink message
146 * @skb: netlink message as socket buffer
147 * @pid: netlink pid of the destination socket
148 */
149static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid)
150{
151 return nlmsg_unicast(genl_sock, skb, pid);
152}
153
154#endif /* __NET_GENERIC_NETLINK_H */
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index 5e38dca1d082..b93fd8c1d884 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -29,7 +29,7 @@
29#include <linux/kernel.h> /* ARRAY_SIZE */ 29#include <linux/kernel.h> /* ARRAY_SIZE */
30#include <linux/wireless.h> 30#include <linux/wireless.h>
31 31
32#define IEEE80211_VERSION "git-1.1.6" 32#define IEEE80211_VERSION "git-1.1.7"
33 33
34#define IEEE80211_DATA_LEN 2304 34#define IEEE80211_DATA_LEN 2304
35/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section 35/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h
index 0a1c2d82ca4b..225fc751d464 100644
--- a/include/net/ieee80211_crypt.h
+++ b/include/net/ieee80211_crypt.h
@@ -31,6 +31,7 @@ enum {
31 31
32struct ieee80211_crypto_ops { 32struct ieee80211_crypto_ops {
33 const char *name; 33 const char *name;
34 struct list_head list;
34 35
35 /* init new crypto context (e.g., allocate private data space, 36 /* init new crypto context (e.g., allocate private data space,
36 * select IV, etc.); returns NULL on failure or pointer to allocated 37 * select IV, etc.); returns NULL on failure or pointer to allocated
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 65ec86678a08..6addb4d464d6 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -252,12 +252,25 @@ typedef int (*inet_getfrag_t) (const void *data,
252 char *, 252 char *,
253 unsigned int, unsigned int); 253 unsigned int, unsigned int);
254 254
255 255extern int __ipv6_addr_type(const struct in6_addr *addr);
256extern int ipv6_addr_type(const struct in6_addr *addr); 256static inline int ipv6_addr_type(const struct in6_addr *addr)
257{
258 return __ipv6_addr_type(addr) & 0xffff;
259}
257 260
258static inline int ipv6_addr_scope(const struct in6_addr *addr) 261static inline int ipv6_addr_scope(const struct in6_addr *addr)
259{ 262{
260 return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK; 263 return __ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
264}
265
266static inline int __ipv6_addr_src_scope(int type)
267{
268 return (type == IPV6_ADDR_ANY ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16));
269}
270
271static inline int ipv6_addr_src_scope(const struct in6_addr *addr)
272{
273 return __ipv6_addr_src_scope(__ipv6_addr_type(addr));
261} 274}
262 275
263static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2) 276static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
@@ -341,6 +354,54 @@ static inline int ipv6_addr_any(const struct in6_addr *a)
341} 354}
342 355
343/* 356/*
357 * find the first different bit between two addresses
358 * length of address must be a multiple of 32bits
359 */
360static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen)
361{
362 const __u32 *a1 = token1, *a2 = token2;
363 int i;
364
365 addrlen >>= 2;
366
367 for (i = 0; i < addrlen; i++) {
368 __u32 xb = a1[i] ^ a2[i];
369 if (xb) {
370 int j = 31;
371
372 xb = ntohl(xb);
373 while ((xb & (1 << j)) == 0)
374 j--;
375
376 return (i * 32 + 31 - j);
377 }
378 }
379
380 /*
381 * we should *never* get to this point since that
382 * would mean the addrs are equal
383 *
384 * However, we do get to it 8) And exacly, when
385 * addresses are equal 8)
386 *
387 * ip route add 1111::/128 via ...
388 * ip route add 1111::/64 via ...
389 * and we are here.
390 *
391 * Ideally, this function should stop comparison
392 * at prefix length. It does not, but it is still OK,
393 * if returned value is greater than prefix length.
394 * --ANK (980803)
395 */
396 return (addrlen << 5);
397}
398
399static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2)
400{
401 return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
402}
403
404/*
344 * Prototypes exported by ipv6 405 * Prototypes exported by ipv6
345 */ 406 */
346 407
diff --git a/include/net/netfilter/ipv4/nf_conntrack_icmp.h b/include/net/netfilter/ipv4/nf_conntrack_icmp.h
new file mode 100644
index 000000000000..3dd22cff23ec
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_conntrack_icmp.h
@@ -0,0 +1,11 @@
1#ifndef _NF_CONNTRACK_ICMP_H
2#define _NF_CONNTRACK_ICMP_H
3/* ICMP tracking. */
4#include <asm/atomic.h>
5
6struct ip_ct_icmp
7{
8 /* Optimization: when number in == number out, forget immediately. */
9 atomic_t count;
10};
11#endif /* _NF_CONNTRACK_ICMP_H */
diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
new file mode 100644
index 000000000000..25b081a730e6
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
@@ -0,0 +1,43 @@
1/*
2 * IPv4 support for nf_conntrack.
3 *
4 * 23 Mar 2004: Yasuyuki Kozakai @ USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - move L3 protocol dependent part from include/linux/netfilter_ipv4/
6 * ip_conntarck.h
7 */
8
9#ifndef _NF_CONNTRACK_IPV4_H
10#define _NF_CONNTRACK_IPV4_H
11
12#ifdef CONFIG_IP_NF_NAT_NEEDED
13#include <linux/netfilter_ipv4/ip_nat.h>
14
15/* per conntrack: nat application helper private data */
16union ip_conntrack_nat_help {
17 /* insert nat helper private data here */
18};
19
20struct nf_conntrack_ipv4_nat {
21 struct ip_nat_info info;
22 union ip_conntrack_nat_help help;
23#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
24 defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
25 int masq_index;
26#endif
27};
28#endif /* CONFIG_IP_NF_NAT_NEEDED */
29
30struct nf_conntrack_ipv4 {
31#ifdef CONFIG_IP_NF_NAT_NEEDED
32 struct nf_conntrack_ipv4_nat *nat;
33#endif
34};
35
36/* Returns new sk_buff, or NULL */
37struct sk_buff *
38nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb);
39
40/* call to create an explicit dependency on nf_conntrack_l3proto_ipv4. */
41extern void need_ip_conntrack(void);
42
43#endif /*_NF_CONNTRACK_IPV4_H*/
diff --git a/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
new file mode 100644
index 000000000000..86591afda29c
--- /dev/null
+++ b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
@@ -0,0 +1,27 @@
1/*
2 * ICMPv6 tracking.
3 *
4 * 21 Apl 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - separated from nf_conntrack_icmp.h
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_icmp.h
8 */
9
10#ifndef _NF_CONNTRACK_ICMPV6_H
11#define _NF_CONNTRACK_ICMPV6_H
12#include <asm/atomic.h>
13
14#ifndef ICMPV6_NI_QUERY
15#define ICMPV6_NI_QUERY 139
16#endif
17#ifndef ICMPV6_NI_REPLY
18#define ICMPV6_NI_REPLY 140
19#endif
20
21struct nf_ct_icmpv6
22{
23 /* Optimization: when number in == number out, forget immediately. */
24 atomic_t count;
25};
26
27#endif /* _NF_CONNTRACK_ICMPV6_H */
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
new file mode 100644
index 000000000000..cc4825610795
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack.h
@@ -0,0 +1,354 @@
1/*
2 * Connection state tracking for netfilter. This is separated from,
3 * but required by, the (future) NAT layer; it can also be used by an iptables
4 * extension.
5 *
6 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
7 * - generalize L3 protocol dependent part.
8 *
9 * Derived from include/linux/netfiter_ipv4/ip_conntrack.h
10 */
11
12#ifndef _NF_CONNTRACK_H
13#define _NF_CONNTRACK_H
14
15#include <linux/netfilter/nf_conntrack_common.h>
16
17#ifdef __KERNEL__
18#include <linux/config.h>
19#include <linux/bitops.h>
20#include <linux/compiler.h>
21#include <asm/atomic.h>
22
23#include <linux/netfilter/nf_conntrack_tcp.h>
24#include <linux/netfilter/nf_conntrack_sctp.h>
25#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
26#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
27
28#include <net/netfilter/nf_conntrack_tuple.h>
29
30/* per conntrack: protocol private data */
31union nf_conntrack_proto {
32 /* insert conntrack proto private data here */
33 struct ip_ct_sctp sctp;
34 struct ip_ct_tcp tcp;
35 struct ip_ct_icmp icmp;
36 struct nf_ct_icmpv6 icmpv6;
37};
38
39union nf_conntrack_expect_proto {
40 /* insert expect proto private data here */
41};
42
43/* Add protocol helper include file here */
44#include <linux/netfilter/nf_conntrack_ftp.h>
45
46/* per conntrack: application helper private data */
47union nf_conntrack_help {
48 /* insert conntrack helper private data (master) here */
49 struct ip_ct_ftp_master ct_ftp_info;
50};
51
52#include <linux/types.h>
53#include <linux/skbuff.h>
54
55#ifdef CONFIG_NETFILTER_DEBUG
56#define NF_CT_ASSERT(x) \
57do { \
58 if (!(x)) \
59 /* Wooah! I'm tripping my conntrack in a frenzy of \
60 netplay... */ \
61 printk("NF_CT_ASSERT: %s:%i(%s)\n", \
62 __FILE__, __LINE__, __FUNCTION__); \
63} while(0)
64#else
65#define NF_CT_ASSERT(x)
66#endif
67
68struct nf_conntrack_helper;
69
70#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
71struct nf_conn
72{
73 /* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
74 plus 1 for any connection(s) we are `master' for */
75 struct nf_conntrack ct_general;
76
77 /* XXX should I move this to the tail ? - Y.K */
78 /* These are my tuples; original and reply */
79 struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
80
81 /* Have we seen traffic both ways yet? (bitset) */
82 unsigned long status;
83
84 /* Timer function; drops refcnt when it goes off. */
85 struct timer_list timeout;
86
87#ifdef CONFIG_NF_CT_ACCT
88 /* Accounting Information (same cache line as other written members) */
89 struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
90#endif
91 /* If we were expected by an expectation, this will be it */
92 struct nf_conn *master;
93
94 /* Current number of expected connections */
95 unsigned int expecting;
96
97 /* Helper. if any */
98 struct nf_conntrack_helper *helper;
99
100 /* features - nat, helper, ... used by allocating system */
101 u_int32_t features;
102
103 /* Storage reserved for other modules: */
104
105 union nf_conntrack_proto proto;
106
107#if defined(CONFIG_NF_CONNTRACK_MARK)
108 u_int32_t mark;
109#endif
110
111 /* These members are dynamically allocated. */
112
113 union nf_conntrack_help *help;
114
115 /* Layer 3 dependent members. (ex: NAT) */
116 union {
117 struct nf_conntrack_ipv4 *ipv4;
118 } l3proto;
119 void *data[0];
120};
121
122struct nf_conntrack_expect
123{
124 /* Internal linked list (global expectation list) */
125 struct list_head list;
126
127 /* We expect this tuple, with the following mask */
128 struct nf_conntrack_tuple tuple, mask;
129
130 /* Function to call after setup and insertion */
131 void (*expectfn)(struct nf_conn *new,
132 struct nf_conntrack_expect *this);
133
134 /* The conntrack of the master connection */
135 struct nf_conn *master;
136
137 /* Timer function; deletes the expectation. */
138 struct timer_list timeout;
139
140 /* Usage count. */
141 atomic_t use;
142
143 /* Flags */
144 unsigned int flags;
145
146#ifdef CONFIG_NF_NAT_NEEDED
147 /* This is the original per-proto part, used to map the
148 * expected connection the way the recipient expects. */
149 union nf_conntrack_manip_proto saved_proto;
150 /* Direction relative to the master connection. */
151 enum ip_conntrack_dir dir;
152#endif
153};
154
155#define NF_CT_EXPECT_PERMANENT 0x1
156
157static inline struct nf_conn *
158nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
159{
160 return container_of(hash, struct nf_conn,
161 tuplehash[hash->tuple.dst.dir]);
162}
163
164/* get master conntrack via master expectation */
165#define master_ct(conntr) (conntr->master)
166
167/* Alter reply tuple (maybe alter helper). */
168extern void
169nf_conntrack_alter_reply(struct nf_conn *conntrack,
170 const struct nf_conntrack_tuple *newreply);
171
172/* Is this tuple taken? (ignoring any belonging to the given
173 conntrack). */
174extern int
175nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
176 const struct nf_conn *ignored_conntrack);
177
178/* Return conntrack_info and tuple hash for given skb. */
179static inline struct nf_conn *
180nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
181{
182 *ctinfo = skb->nfctinfo;
183 return (struct nf_conn *)skb->nfct;
184}
185
186/* decrement reference count on a conntrack */
187static inline void nf_ct_put(struct nf_conn *ct)
188{
189 NF_CT_ASSERT(ct);
190 nf_conntrack_put(&ct->ct_general);
191}
192
193/* call to create an explicit dependency on nf_conntrack. */
194extern void need_nf_conntrack(void);
195
196extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
197 const struct nf_conntrack_tuple *orig);
198
199extern void __nf_ct_refresh_acct(struct nf_conn *ct,
200 enum ip_conntrack_info ctinfo,
201 const struct sk_buff *skb,
202 unsigned long extra_jiffies,
203 int do_acct);
204
205/* Refresh conntrack for this many jiffies and do accounting */
206static inline void nf_ct_refresh_acct(struct nf_conn *ct,
207 enum ip_conntrack_info ctinfo,
208 const struct sk_buff *skb,
209 unsigned long extra_jiffies)
210{
211 __nf_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1);
212}
213
214/* Refresh conntrack for this many jiffies */
215static inline void nf_ct_refresh(struct nf_conn *ct,
216 const struct sk_buff *skb,
217 unsigned long extra_jiffies)
218{
219 __nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0);
220}
221
222/* These are for NAT. Icky. */
223/* Update TCP window tracking data when NAT mangles the packet */
224extern void nf_conntrack_tcp_update(struct sk_buff *skb,
225 unsigned int dataoff,
226 struct nf_conn *conntrack,
227 int dir);
228
229/* Call me when a conntrack is destroyed. */
230extern void (*nf_conntrack_destroyed)(struct nf_conn *conntrack);
231
232/* Fake conntrack entry for untracked connections */
233extern struct nf_conn nf_conntrack_untracked;
234
235extern int nf_ct_no_defrag;
236
237/* Iterate over all conntracks: if iter returns true, it's deleted. */
238extern void
239nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data);
240extern void nf_conntrack_free(struct nf_conn *ct);
241extern struct nf_conn *
242nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
243 const struct nf_conntrack_tuple *repl);
244
245/* It's confirmed if it is, or has been in the hash table. */
246static inline int nf_ct_is_confirmed(struct nf_conn *ct)
247{
248 return test_bit(IPS_CONFIRMED_BIT, &ct->status);
249}
250
251static inline int nf_ct_is_dying(struct nf_conn *ct)
252{
253 return test_bit(IPS_DYING_BIT, &ct->status);
254}
255
256extern unsigned int nf_conntrack_htable_size;
257
258#define NF_CT_STAT_INC(count) (__get_cpu_var(nf_conntrack_stat).count++)
259
260#ifdef CONFIG_NF_CONNTRACK_EVENTS
261#include <linux/notifier.h>
262#include <linux/interrupt.h>
263
264struct nf_conntrack_ecache {
265 struct nf_conn *ct;
266 unsigned int events;
267};
268DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
269
270#define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x)
271
272extern struct notifier_block *nf_conntrack_chain;
273extern struct notifier_block *nf_conntrack_expect_chain;
274
275static inline int nf_conntrack_register_notifier(struct notifier_block *nb)
276{
277 return notifier_chain_register(&nf_conntrack_chain, nb);
278}
279
280static inline int nf_conntrack_unregister_notifier(struct notifier_block *nb)
281{
282 return notifier_chain_unregister(&nf_conntrack_chain, nb);
283}
284
285static inline int
286nf_conntrack_expect_register_notifier(struct notifier_block *nb)
287{
288 return notifier_chain_register(&nf_conntrack_expect_chain, nb);
289}
290
291static inline int
292nf_conntrack_expect_unregister_notifier(struct notifier_block *nb)
293{
294 return notifier_chain_unregister(&nf_conntrack_expect_chain, nb);
295}
296
297extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
298extern void __nf_ct_event_cache_init(struct nf_conn *ct);
299
300static inline void
301nf_conntrack_event_cache(enum ip_conntrack_events event,
302 const struct sk_buff *skb)
303{
304 struct nf_conn *ct = (struct nf_conn *)skb->nfct;
305 struct nf_conntrack_ecache *ecache;
306
307 local_bh_disable();
308 ecache = &__get_cpu_var(nf_conntrack_ecache);
309 if (ct != ecache->ct)
310 __nf_ct_event_cache_init(ct);
311 ecache->events |= event;
312 local_bh_enable();
313}
314
315static inline void nf_conntrack_event(enum ip_conntrack_events event,
316 struct nf_conn *ct)
317{
318 if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
319 notifier_call_chain(&nf_conntrack_chain, event, ct);
320}
321
322static inline void
323nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
324 struct nf_conntrack_expect *exp)
325{
326 notifier_call_chain(&nf_conntrack_expect_chain, event, exp);
327}
328#else /* CONFIG_NF_CONNTRACK_EVENTS */
329static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
330 const struct sk_buff *skb) {}
331static inline void nf_conntrack_event(enum ip_conntrack_events event,
332 struct nf_conn *ct) {}
333static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
334static inline void
335nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
336 struct nf_conntrack_expect *exp) {}
337#endif /* CONFIG_NF_CONNTRACK_EVENTS */
338
339/* no helper, no nat */
340#define NF_CT_F_BASIC 0
341/* for helper */
342#define NF_CT_F_HELP 1
343/* for nat. */
344#define NF_CT_F_NAT 2
345#define NF_CT_F_NUM 4
346
347extern int
348nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size,
349 int (*init_conntrack)(struct nf_conn *, u_int32_t));
350extern void
351nf_conntrack_unregister_cache(u_int32_t features);
352
353#endif /* __KERNEL__ */
354#endif /* _NF_CONNTRACK_H */
diff --git a/include/net/netfilter/nf_conntrack_compat.h b/include/net/netfilter/nf_conntrack_compat.h
new file mode 100644
index 000000000000..3cac19fb3648
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_compat.h
@@ -0,0 +1,108 @@
1#ifndef _NF_CONNTRACK_COMPAT_H
2#define _NF_CONNTRACK_COMPAT_H
3
4#ifdef __KERNEL__
5
6#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
7
8#include <linux/netfilter_ipv4/ip_conntrack.h>
9
10#ifdef CONFIG_IP_NF_CONNTRACK_MARK
11static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb,
12 u_int32_t *ctinfo)
13{
14 struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo);
15
16 if (ct)
17 return &ct->mark;
18 else
19 return NULL;
20}
21#endif /* CONFIG_IP_NF_CONNTRACK_MARK */
22
23#ifdef CONFIG_IP_NF_CT_ACCT
24static inline struct ip_conntrack_counter *
25nf_ct_get_counters(const struct sk_buff *skb)
26{
27 enum ip_conntrack_info ctinfo;
28 struct ip_conntrack *ct = ip_conntrack_get(skb, &ctinfo);
29
30 if (ct)
31 return ct->counters;
32 else
33 return NULL;
34}
35#endif /* CONFIG_IP_NF_CT_ACCT */
36
37static inline int nf_ct_is_untracked(const struct sk_buff *skb)
38{
39 return (skb->nfct == &ip_conntrack_untracked.ct_general);
40}
41
42static inline void nf_ct_untrack(struct sk_buff *skb)
43{
44 skb->nfct = &ip_conntrack_untracked.ct_general;
45}
46
47static inline int nf_ct_get_ctinfo(const struct sk_buff *skb,
48 enum ip_conntrack_info *ctinfo)
49{
50 struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo);
51 return (ct != NULL);
52}
53
54#else /* CONFIG_IP_NF_CONNTRACK */
55
56#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
57#include <net/netfilter/nf_conntrack.h>
58
59#ifdef CONFIG_NF_CONNTRACK_MARK
60
61static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb,
62 u_int32_t *ctinfo)
63{
64 struct nf_conn *ct = nf_ct_get(skb, ctinfo);
65
66 if (ct)
67 return &ct->mark;
68 else
69 return NULL;
70}
71#endif /* CONFIG_NF_CONNTRACK_MARK */
72
73#ifdef CONFIG_NF_CT_ACCT
74static inline struct ip_conntrack_counter *
75nf_ct_get_counters(const struct sk_buff *skb)
76{
77 enum ip_conntrack_info ctinfo;
78 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
79
80 if (ct)
81 return ct->counters;
82 else
83 return NULL;
84}
85#endif /* CONFIG_NF_CT_ACCT */
86
87static inline int nf_ct_is_untracked(const struct sk_buff *skb)
88{
89 return (skb->nfct == &nf_conntrack_untracked.ct_general);
90}
91
92static inline void nf_ct_untrack(struct sk_buff *skb)
93{
94 skb->nfct = &nf_conntrack_untracked.ct_general;
95}
96
97static inline int nf_ct_get_ctinfo(const struct sk_buff *skb,
98 enum ip_conntrack_info *ctinfo)
99{
100 struct nf_conn *ct = nf_ct_get(skb, ctinfo);
101 return (ct != NULL);
102}
103
104#endif /* CONFIG_IP_NF_CONNTRACK */
105
106#endif /* __KERNEL__ */
107
108#endif /* _NF_CONNTRACK_COMPAT_H */
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
new file mode 100644
index 000000000000..da254525a4ce
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -0,0 +1,76 @@
1/*
2 * This header is used to share core functionality between the
3 * standalone connection tracking module, and the compatibility layer's use
4 * of connection tracking.
5 *
6 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
7 * - generalize L3 protocol dependent part.
8 *
9 * Derived from include/linux/netfiter_ipv4/ip_conntrack_core.h
10 */
11
12#ifndef _NF_CONNTRACK_CORE_H
13#define _NF_CONNTRACK_CORE_H
14
15#include <linux/netfilter.h>
16
17/* This header is used to share core functionality between the
18 standalone connection tracking module, and the compatibility layer's use
19 of connection tracking. */
20extern unsigned int nf_conntrack_in(int pf,
21 unsigned int hooknum,
22 struct sk_buff **pskb);
23
24extern int nf_conntrack_init(void);
25extern void nf_conntrack_cleanup(void);
26
27struct nf_conntrack_l3proto;
28extern struct nf_conntrack_l3proto *nf_ct_find_l3proto(u_int16_t pf);
29/* Like above, but you already have conntrack read lock. */
30extern struct nf_conntrack_l3proto *__nf_ct_find_l3proto(u_int16_t l3proto);
31
32struct nf_conntrack_protocol;
33
34extern int
35nf_ct_get_tuple(const struct sk_buff *skb,
36 unsigned int nhoff,
37 unsigned int dataoff,
38 u_int16_t l3num,
39 u_int8_t protonum,
40 struct nf_conntrack_tuple *tuple,
41 const struct nf_conntrack_l3proto *l3proto,
42 const struct nf_conntrack_protocol *protocol);
43
44extern int
45nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
46 const struct nf_conntrack_tuple *orig,
47 const struct nf_conntrack_l3proto *l3proto,
48 const struct nf_conntrack_protocol *protocol);
49
50/* Find a connection corresponding to a tuple. */
51extern struct nf_conntrack_tuple_hash *
52nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
53 const struct nf_conn *ignored_conntrack);
54
55extern int __nf_conntrack_confirm(struct sk_buff **pskb);
56
57/* Confirm a connection: returns NF_DROP if packet must be dropped. */
58static inline int nf_conntrack_confirm(struct sk_buff **pskb)
59{
60 struct nf_conn *ct = (struct nf_conn *)(*pskb)->nfct;
61 int ret = NF_ACCEPT;
62
63 if (ct) {
64 if (!nf_ct_is_confirmed(ct))
65 ret = __nf_conntrack_confirm(pskb);
66 nf_ct_deliver_cached_events(ct);
67 }
68 return ret;
69}
70
71extern void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb);
72
73extern struct list_head *nf_conntrack_hash;
74extern struct list_head nf_conntrack_expect_list;
75extern rwlock_t nf_conntrack_lock ;
76#endif /* _NF_CONNTRACK_CORE_H */
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
new file mode 100644
index 000000000000..5a66b2a3a623
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -0,0 +1,51 @@
1/*
2 * connection tracking helpers.
3 *
4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - generalize L3 protocol dependent part.
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_helper.h
8 */
9
10#ifndef _NF_CONNTRACK_HELPER_H
11#define _NF_CONNTRACK_HELPER_H
12#include <net/netfilter/nf_conntrack.h>
13
14struct module;
15
16struct nf_conntrack_helper
17{
18 struct list_head list; /* Internal use. */
19
20 const char *name; /* name of the module */
21 struct module *me; /* pointer to self */
22 unsigned int max_expected; /* Maximum number of concurrent
23 * expected connections */
24 unsigned int timeout; /* timeout for expecteds */
25
26 /* Mask of things we will help (compared against server response) */
27 struct nf_conntrack_tuple tuple;
28 struct nf_conntrack_tuple mask;
29
30 /* Function to call when data passes; return verdict, or -1 to
31 invalidate. */
32 int (*help)(struct sk_buff **pskb,
33 unsigned int protoff,
34 struct nf_conn *ct,
35 enum ip_conntrack_info conntrackinfo);
36};
37
38extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
39extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
40
41/* Allocate space for an expectation: this is mandatory before calling
42 nf_conntrack_expect_related. You will have to call put afterwards. */
43extern struct nf_conntrack_expect *
44nf_conntrack_expect_alloc(struct nf_conn *master);
45extern void nf_conntrack_expect_put(struct nf_conntrack_expect *exp);
46
47/* Add an expected connection: can have more than one per connection */
48extern int nf_conntrack_expect_related(struct nf_conntrack_expect *exp);
49extern void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp);
50
51#endif /*_NF_CONNTRACK_HELPER_H*/
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
new file mode 100644
index 000000000000..01663e5b33df
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -0,0 +1,93 @@
1/*
2 * Copyright (C)2003,2004 USAGI/WIDE Project
3 *
4 * Header for use in defining a given L3 protocol for connection tracking.
5 *
6 * Author:
7 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
8 *
9 * Derived from include/netfilter_ipv4/ip_conntrack_protocol.h
10 */
11
12#ifndef _NF_CONNTRACK_L3PROTO_H
13#define _NF_CONNTRACK_L3PROTO_H
14#include <linux/seq_file.h>
15#include <net/netfilter/nf_conntrack.h>
16
17struct nf_conntrack_l3proto
18{
19 /* Next pointer. */
20 struct list_head list;
21
22 /* L3 Protocol Family number. ex) PF_INET */
23 u_int16_t l3proto;
24
25 /* Protocol name */
26 const char *name;
27
28 /*
29 * Try to fill in the third arg: nhoff is offset of l3 proto
30 * hdr. Return true if possible.
31 */
32 int (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int nhoff,
33 struct nf_conntrack_tuple *tuple);
34
35 /*
36 * Invert the per-proto part of the tuple: ie. turn xmit into reply.
37 * Some packets can't be inverted: return 0 in that case.
38 */
39 int (*invert_tuple)(struct nf_conntrack_tuple *inverse,
40 const struct nf_conntrack_tuple *orig);
41
42 /* Print out the per-protocol part of the tuple. */
43 int (*print_tuple)(struct seq_file *s,
44 const struct nf_conntrack_tuple *);
45
46 /* Print out the private part of the conntrack. */
47 int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
48
49 /* Returns verdict for packet, or -1 for invalid. */
50 int (*packet)(struct nf_conn *conntrack,
51 const struct sk_buff *skb,
52 enum ip_conntrack_info ctinfo);
53
54 /*
55 * Called when a new connection for this protocol found;
56 * returns TRUE if it's OK. If so, packet() called next.
57 */
58 int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb);
59
60 /* Called when a conntrack entry is destroyed */
61 void (*destroy)(struct nf_conn *conntrack);
62
63 /*
64 * Called before tracking.
65 * *dataoff: offset of protocol header (TCP, UDP,...) in *pskb
66 * *protonum: protocol number
67 */
68 int (*prepare)(struct sk_buff **pskb, unsigned int hooknum,
69 unsigned int *dataoff, u_int8_t *protonum);
70
71 u_int32_t (*get_features)(const struct nf_conntrack_tuple *tuple);
72
73 /* Module (if any) which this is connected to. */
74 struct module *me;
75};
76
77extern struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX];
78
79/* Protocol registration. */
80extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
81extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
82
83static inline struct nf_conntrack_l3proto *
84nf_ct_find_l3proto(u_int16_t l3proto)
85{
86 return nf_ct_l3protos[l3proto];
87}
88
89/* Existing built-in protocols */
90extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
91extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
92extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto;
93#endif /*_NF_CONNTRACK_L3PROTO_H*/
diff --git a/include/net/netfilter/nf_conntrack_protocol.h b/include/net/netfilter/nf_conntrack_protocol.h
new file mode 100644
index 000000000000..b3afda35397a
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_protocol.h
@@ -0,0 +1,105 @@
1/*
2 * Header for use in defining a given protocol for connection tracking.
3 *
4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - generalized L3 protocol dependent part.
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_protcol.h
8 */
9
10#ifndef _NF_CONNTRACK_PROTOCOL_H
11#define _NF_CONNTRACK_PROTOCOL_H
12#include <net/netfilter/nf_conntrack.h>
13
14struct seq_file;
15
16struct nf_conntrack_protocol
17{
18 /* Next pointer. */
19 struct list_head list;
20
21 /* L3 Protocol number. */
22 u_int16_t l3proto;
23
24 /* Protocol number. */
25 u_int8_t proto;
26
27 /* Protocol name */
28 const char *name;
29
30 /* Try to fill in the third arg: dataoff is offset past network protocol
31 hdr. Return true if possible. */
32 int (*pkt_to_tuple)(const struct sk_buff *skb,
33 unsigned int dataoff,
34 struct nf_conntrack_tuple *tuple);
35
36 /* Invert the per-proto part of the tuple: ie. turn xmit into reply.
37 * Some packets can't be inverted: return 0 in that case.
38 */
39 int (*invert_tuple)(struct nf_conntrack_tuple *inverse,
40 const struct nf_conntrack_tuple *orig);
41
42 /* Print out the per-protocol part of the tuple. Return like seq_* */
43 int (*print_tuple)(struct seq_file *s,
44 const struct nf_conntrack_tuple *);
45
46 /* Print out the private part of the conntrack. */
47 int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
48
49 /* Returns verdict for packet, or -1 for invalid. */
50 int (*packet)(struct nf_conn *conntrack,
51 const struct sk_buff *skb,
52 unsigned int dataoff,
53 enum ip_conntrack_info ctinfo,
54 int pf,
55 unsigned int hooknum);
56
57 /* Called when a new connection for this protocol found;
58 * returns TRUE if it's OK. If so, packet() called next. */
59 int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb,
60 unsigned int dataoff);
61
62 /* Called when a conntrack entry is destroyed */
63 void (*destroy)(struct nf_conn *conntrack);
64
65 int (*error)(struct sk_buff *skb, unsigned int dataoff,
66 enum ip_conntrack_info *ctinfo,
67 int pf, unsigned int hooknum);
68
69 /* Module (if any) which this is connected to. */
70 struct module *me;
71};
72
73/* Existing built-in protocols */
74extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp6;
75extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4;
76extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6;
77extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
78
79#define MAX_NF_CT_PROTO 256
80extern struct nf_conntrack_protocol **nf_ct_protos[PF_MAX];
81
82extern struct nf_conntrack_protocol *
83nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol);
84
85/* Protocol registration. */
86extern int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto);
87extern void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto);
88
89/* Log invalid packets */
90extern unsigned int nf_ct_log_invalid;
91
92#ifdef CONFIG_SYSCTL
93#ifdef DEBUG_INVALID_PACKETS
94#define LOG_INVALID(proto) \
95 (nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW)
96#else
97#define LOG_INVALID(proto) \
98 ((nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW) \
99 && net_ratelimit())
100#endif
101#else
102#define LOG_INVALID(proto) 0
103#endif /* CONFIG_SYSCTL */
104
105#endif /*_NF_CONNTRACK_PROTOCOL_H*/
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
new file mode 100644
index 000000000000..14ce790e5c65
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_tuple.h
@@ -0,0 +1,190 @@
1/*
2 * Definitions and Declarations for tuple.
3 *
4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - generalize L3 protocol dependent part.
6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_tuple.h
8 */
9
10#ifndef _NF_CONNTRACK_TUPLE_H
11#define _NF_CONNTRACK_TUPLE_H
12
13#include <linux/netfilter/nf_conntrack_tuple_common.h>
14
15/* A `tuple' is a structure containing the information to uniquely
16 identify a connection. ie. if two packets have the same tuple, they
17 are in the same connection; if not, they are not.
18
19 We divide the structure along "manipulatable" and
20 "non-manipulatable" lines, for the benefit of the NAT code.
21*/
22
23#define NF_CT_TUPLE_L3SIZE 4
24
25/* The l3 protocol-specific manipulable parts of the tuple: always in
26 network order! */
27union nf_conntrack_man_l3proto {
28 u_int32_t all[NF_CT_TUPLE_L3SIZE];
29 u_int32_t ip;
30 u_int32_t ip6[4];
31};
32
33/* The protocol-specific manipulable parts of the tuple: always in
34 network order! */
35union nf_conntrack_man_proto
36{
37 /* Add other protocols here. */
38 u_int16_t all;
39
40 struct {
41 u_int16_t port;
42 } tcp;
43 struct {
44 u_int16_t port;
45 } udp;
46 struct {
47 u_int16_t id;
48 } icmp;
49 struct {
50 u_int16_t port;
51 } sctp;
52};
53
54/* The manipulable part of the tuple. */
55struct nf_conntrack_man
56{
57 union nf_conntrack_man_l3proto u3;
58 union nf_conntrack_man_proto u;
59 /* Layer 3 protocol */
60 u_int16_t l3num;
61};
62
63/* This contains the information to distinguish a connection. */
64struct nf_conntrack_tuple
65{
66 struct nf_conntrack_man src;
67
68 /* These are the parts of the tuple which are fixed. */
69 struct {
70 union {
71 u_int32_t all[NF_CT_TUPLE_L3SIZE];
72 u_int32_t ip;
73 u_int32_t ip6[4];
74 } u3;
75 union {
76 /* Add other protocols here. */
77 u_int16_t all;
78
79 struct {
80 u_int16_t port;
81 } tcp;
82 struct {
83 u_int16_t port;
84 } udp;
85 struct {
86 u_int8_t type, code;
87 } icmp;
88 struct {
89 u_int16_t port;
90 } sctp;
91 } u;
92
93 /* The protocol. */
94 u_int8_t protonum;
95
96 /* The direction (for tuplehash) */
97 u_int8_t dir;
98 } dst;
99};
100
101/* This is optimized opposed to a memset of the whole structure. Everything we
102 * really care about is the source/destination unions */
103#define NF_CT_TUPLE_U_BLANK(tuple) \
104 do { \
105 (tuple)->src.u.all = 0; \
106 (tuple)->dst.u.all = 0; \
107 memset(&(tuple)->src.u3, 0, sizeof((tuple)->src.u3)); \
108 memset(&(tuple)->dst.u3, 0, sizeof((tuple)->dst.u3)); \
109 } while (0)
110
111#ifdef __KERNEL__
112
113#define NF_CT_DUMP_TUPLE(tp) \
114DEBUGP("tuple %p: %u %u %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu -> %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu\n", \
115 (tp), (tp)->src.l3num, (tp)->dst.protonum, \
116 NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \
117 NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all))
118
119/* If we're the first tuple, it's the original dir. */
120#define NF_CT_DIRECTION(h) \
121 ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
122
123/* Connections have two entries in the hash table: one for each way */
124struct nf_conntrack_tuple_hash
125{
126 struct list_head list;
127
128 struct nf_conntrack_tuple tuple;
129};
130
131#endif /* __KERNEL__ */
132
133static inline int nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
134 const struct nf_conntrack_tuple *t2)
135{
136 return (t1->src.u3.all[0] == t2->src.u3.all[0] &&
137 t1->src.u3.all[1] == t2->src.u3.all[1] &&
138 t1->src.u3.all[2] == t2->src.u3.all[2] &&
139 t1->src.u3.all[3] == t2->src.u3.all[3] &&
140 t1->src.u.all == t2->src.u.all &&
141 t1->src.l3num == t2->src.l3num &&
142 t1->dst.protonum == t2->dst.protonum);
143}
144
145static inline int nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1,
146 const struct nf_conntrack_tuple *t2)
147{
148 return (t1->dst.u3.all[0] == t2->dst.u3.all[0] &&
149 t1->dst.u3.all[1] == t2->dst.u3.all[1] &&
150 t1->dst.u3.all[2] == t2->dst.u3.all[2] &&
151 t1->dst.u3.all[3] == t2->dst.u3.all[3] &&
152 t1->dst.u.all == t2->dst.u.all &&
153 t1->src.l3num == t2->src.l3num &&
154 t1->dst.protonum == t2->dst.protonum);
155}
156
157static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
158 const struct nf_conntrack_tuple *t2)
159{
160 return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2);
161}
162
163static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
164 const struct nf_conntrack_tuple *tuple,
165 const struct nf_conntrack_tuple *mask)
166{
167 int count = 0;
168
169 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
170 if ((t->src.u3.all[count] ^ tuple->src.u3.all[count]) &
171 mask->src.u3.all[count])
172 return 0;
173 }
174
175 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
176 if ((t->dst.u3.all[count] ^ tuple->dst.u3.all[count]) &
177 mask->dst.u3.all[count])
178 return 0;
179 }
180
181 if ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all ||
182 (t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all ||
183 (t->src.l3num ^ tuple->src.l3num) & mask->src.l3num ||
184 (t->dst.protonum ^ tuple->dst.protonum) & mask->dst.protonum)
185 return 0;
186
187 return 1;
188}
189
190#endif /* _NF_CONNTRACK_TUPLE_H */
diff --git a/include/net/netlink.h b/include/net/netlink.h
new file mode 100644
index 000000000000..640c26a90cf1
--- /dev/null
+++ b/include/net/netlink.h
@@ -0,0 +1,883 @@
1#ifndef __NET_NETLINK_H
2#define __NET_NETLINK_H
3
4#include <linux/types.h>
5#include <linux/netlink.h>
6
7/* ========================================================================
8 * Netlink Messages and Attributes Interface (As Seen On TV)
9 * ------------------------------------------------------------------------
10 * Messages Interface
11 * ------------------------------------------------------------------------
12 *
13 * Message Format:
14 * <--- nlmsg_total_size(payload) --->
15 * <-- nlmsg_msg_size(payload) ->
16 * +----------+- - -+-------------+- - -+-------- - -
17 * | nlmsghdr | Pad | Payload | Pad | nlmsghdr
18 * +----------+- - -+-------------+- - -+-------- - -
19 * nlmsg_data(nlh)---^ ^
20 * nlmsg_next(nlh)-----------------------+
21 *
22 * Payload Format:
23 * <---------------------- nlmsg_len(nlh) --------------------->
24 * <------ hdrlen ------> <- nlmsg_attrlen(nlh, hdrlen) ->
25 * +----------------------+- - -+--------------------------------+
26 * | Family Header | Pad | Attributes |
27 * +----------------------+- - -+--------------------------------+
28 * nlmsg_attrdata(nlh, hdrlen)---^
29 *
30 * Data Structures:
31 * struct nlmsghdr netlink message header
32 *
33 * Message Construction:
34 * nlmsg_new() create a new netlink message
35 * nlmsg_put() add a netlink message to an skb
36 * nlmsg_put_answer() callback based nlmsg_put()
37 * nlmsg_end() finanlize netlink message
38 * nlmsg_cancel() cancel message construction
39 * nlmsg_free() free a netlink message
40 *
41 * Message Sending:
42 * nlmsg_multicast() multicast message to several groups
43 * nlmsg_unicast() unicast a message to a single socket
44 *
45 * Message Length Calculations:
46 * nlmsg_msg_size(payload) length of message w/o padding
47 * nlmsg_total_size(payload) length of message w/ padding
48 * nlmsg_padlen(payload) length of padding at tail
49 *
50 * Message Payload Access:
51 * nlmsg_data(nlh) head of message payload
52 * nlmsg_len(nlh) length of message payload
53 * nlmsg_attrdata(nlh, hdrlen) head of attributes data
54 * nlmsg_attrlen(nlh, hdrlen) length of attributes data
55 *
56 * Message Parsing:
57 * nlmsg_ok(nlh, remaining) does nlh fit into remaining bytes?
58 * nlmsg_next(nlh, remaining) get next netlink message
59 * nlmsg_parse() parse attributes of a message
60 * nlmsg_find_attr() find an attribute in a message
61 * nlmsg_for_each_msg() loop over all messages
62 * nlmsg_validate() validate netlink message incl. attrs
63 * nlmsg_for_each_attr() loop over all attributes
64 *
65 * ------------------------------------------------------------------------
66 * Attributes Interface
67 * ------------------------------------------------------------------------
68 *
69 * Attribute Format:
70 * <------- nla_total_size(payload) ------->
71 * <---- nla_attr_size(payload) ----->
72 * +----------+- - -+- - - - - - - - - +- - -+-------- - -
73 * | Header | Pad | Payload | Pad | Header
74 * +----------+- - -+- - - - - - - - - +- - -+-------- - -
75 * <- nla_len(nla) -> ^
76 * nla_data(nla)----^ |
77 * nla_next(nla)-----------------------------'
78 *
79 * Data Structures:
80 * struct nlattr netlink attribtue header
81 *
82 * Attribute Construction:
83 * nla_reserve(skb, type, len) reserve skb tailroom for an attribute
84 * nla_put(skb, type, len, data) add attribute to skb
85 *
86 * Attribute Construction for Basic Types:
87 * nla_put_u8(skb, type, value) add u8 attribute to skb
88 * nla_put_u16(skb, type, value) add u16 attribute to skb
89 * nla_put_u32(skb, type, value) add u32 attribute to skb
90 * nla_put_u64(skb, type, value) add u64 attribute to skb
91 * nla_put_string(skb, type, str) add string attribute to skb
92 * nla_put_flag(skb, type) add flag attribute to skb
93 * nla_put_msecs(skb, type, jiffies) add msecs attribute to skb
94 *
95 * Exceptions Based Attribute Construction:
96 * NLA_PUT(skb, type, len, data) add attribute to skb
97 * NLA_PUT_U8(skb, type, value) add u8 attribute to skb
98 * NLA_PUT_U16(skb, type, value) add u16 attribute to skb
99 * NLA_PUT_U32(skb, type, value) add u32 attribute to skb
100 * NLA_PUT_U64(skb, type, value) add u64 attribute to skb
101 * NLA_PUT_STRING(skb, type, str) add string attribute to skb
102 * NLA_PUT_FLAG(skb, type) add flag attribute to skb
103 * NLA_PUT_MSECS(skb, type, jiffies) add msecs attribute to skb
104 *
105 * The meaning of these functions is equal to their lower case
106 * variants but they jump to the label nla_put_failure in case
107 * of a failure.
108 *
109 * Nested Attributes Construction:
110 * nla_nest_start(skb, type) start a nested attribute
111 * nla_nest_end(skb, nla) finalize a nested attribute
112 * nla_nest_cancel(skb, nla) cancel nested attribute construction
113 *
114 * Attribute Length Calculations:
115 * nla_attr_size(payload) length of attribute w/o padding
116 * nla_total_size(payload) length of attribute w/ padding
117 * nla_padlen(payload) length of padding
118 *
119 * Attribute Payload Access:
120 * nla_data(nla) head of attribute payload
121 * nla_len(nla) length of attribute payload
122 *
123 * Attribute Payload Access for Basic Types:
124 * nla_get_u8(nla) get payload for a u8 attribute
125 * nla_get_u16(nla) get payload for a u16 attribute
126 * nla_get_u32(nla) get payload for a u32 attribute
127 * nla_get_u64(nla) get payload for a u64 attribute
128 * nla_get_flag(nla) return 1 if flag is true
129 * nla_get_msecs(nla) get payload for a msecs attribute
130 *
131 * Attribute Misc:
132 * nla_memcpy(dest, nla, count) copy attribute into memory
133 * nla_memcmp(nla, data, size) compare attribute with memory area
134 * nla_strlcpy(dst, nla, size) copy attribute to a sized string
135 * nla_strcmp(nla, str) compare attribute with string
136 *
137 * Attribute Parsing:
138 * nla_ok(nla, remaining) does nla fit into remaining bytes?
139 * nla_next(nla, remaining) get next netlink attribute
140 * nla_validate() validate a stream of attributes
141 * nla_find() find attribute in stream of attributes
142 * nla_parse() parse and validate stream of attrs
143 * nla_parse_nested() parse nested attribuets
144 * nla_for_each_attr() loop over all attributes
145 *=========================================================================
146 */
147
148 /**
149 * Standard attribute types to specify validation policy
150 */
151enum {
152 NLA_UNSPEC,
153 NLA_U8,
154 NLA_U16,
155 NLA_U32,
156 NLA_U64,
157 NLA_STRING,
158 NLA_FLAG,
159 NLA_MSECS,
160 NLA_NESTED,
161 __NLA_TYPE_MAX,
162};
163
164#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
165
166/**
167 * struct nla_policy - attribute validation policy
168 * @type: Type of attribute or NLA_UNSPEC
169 * @minlen: Minimal length of payload required to be available
170 *
171 * Policies are defined as arrays of this struct, the array must be
172 * accessible by attribute type up to the highest identifier to be expected.
173 *
174 * Example:
175 * static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = {
176 * [ATTR_FOO] = { .type = NLA_U16 },
177 * [ATTR_BAR] = { .type = NLA_STRING },
178 * [ATTR_BAZ] = { .minlen = sizeof(struct mystruct) },
179 * };
180 */
181struct nla_policy {
182 u16 type;
183 u16 minlen;
184};
185
186extern void netlink_run_queue(struct sock *sk, unsigned int *qlen,
187 int (*cb)(struct sk_buff *,
188 struct nlmsghdr *, int *));
189extern void netlink_queue_skip(struct nlmsghdr *nlh,
190 struct sk_buff *skb);
191
192extern int nla_validate(struct nlattr *head, int len, int maxtype,
193 struct nla_policy *policy);
194extern int nla_parse(struct nlattr *tb[], int maxtype,
195 struct nlattr *head, int len,
196 struct nla_policy *policy);
197extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
198extern size_t nla_strlcpy(char *dst, const struct nlattr *nla,
199 size_t dstsize);
200extern int nla_memcpy(void *dest, struct nlattr *src, int count);
201extern int nla_memcmp(const struct nlattr *nla, const void *data,
202 size_t size);
203extern int nla_strcmp(const struct nlattr *nla, const char *str);
204extern struct nlattr * __nla_reserve(struct sk_buff *skb, int attrtype,
205 int attrlen);
206extern struct nlattr * nla_reserve(struct sk_buff *skb, int attrtype,
207 int attrlen);
208extern void __nla_put(struct sk_buff *skb, int attrtype,
209 int attrlen, const void *data);
210extern int nla_put(struct sk_buff *skb, int attrtype,
211 int attrlen, const void *data);
212
213/**************************************************************************
214 * Netlink Messages
215 **************************************************************************/
216
217/**
218 * nlmsg_msg_size - length of netlink message not including padding
219 * @payload: length of message payload
220 */
221static inline int nlmsg_msg_size(int payload)
222{
223 return NLMSG_HDRLEN + payload;
224}
225
226/**
227 * nlmsg_total_size - length of netlink message including padding
228 * @payload: length of message payload
229 */
230static inline int nlmsg_total_size(int payload)
231{
232 return NLMSG_ALIGN(nlmsg_msg_size(payload));
233}
234
235/**
236 * nlmsg_padlen - length of padding at the message's tail
237 * @payload: length of message payload
238 */
239static inline int nlmsg_padlen(int payload)
240{
241 return nlmsg_total_size(payload) - nlmsg_msg_size(payload);
242}
243
244/**
245 * nlmsg_data - head of message payload
246 * @nlh: netlink messsage header
247 */
248static inline void *nlmsg_data(const struct nlmsghdr *nlh)
249{
250 return (unsigned char *) nlh + NLMSG_HDRLEN;
251}
252
253/**
254 * nlmsg_len - length of message payload
255 * @nlh: netlink message header
256 */
257static inline int nlmsg_len(const struct nlmsghdr *nlh)
258{
259 return nlh->nlmsg_len - NLMSG_HDRLEN;
260}
261
262/**
263 * nlmsg_attrdata - head of attributes data
264 * @nlh: netlink message header
265 * @hdrlen: length of family specific header
266 */
267static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh,
268 int hdrlen)
269{
270 unsigned char *data = nlmsg_data(nlh);
271 return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen));
272}
273
274/**
275 * nlmsg_attrlen - length of attributes data
276 * @nlh: netlink message header
277 * @hdrlen: length of family specific header
278 */
279static inline int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen)
280{
281 return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen);
282}
283
284/**
285 * nlmsg_ok - check if the netlink message fits into the remaining bytes
286 * @nlh: netlink message header
287 * @remaining: number of bytes remaining in message stream
288 */
289static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
290{
291 return (remaining >= sizeof(struct nlmsghdr) &&
292 nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
293 nlh->nlmsg_len <= remaining);
294}
295
296/**
297 * nlmsg_next - next netlink message in message stream
298 * @nlh: netlink message header
299 * @remaining: number of bytes remaining in message stream
300 *
301 * Returns the next netlink message in the message stream and
302 * decrements remaining by the size of the current message.
303 */
304static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining)
305{
306 int totlen = NLMSG_ALIGN(nlh->nlmsg_len);
307
308 *remaining -= totlen;
309
310 return (struct nlmsghdr *) ((unsigned char *) nlh + totlen);
311}
312
313/**
314 * nlmsg_parse - parse attributes of a netlink message
315 * @nlh: netlink message header
316 * @hdrlen: length of family specific header
317 * @tb: destination array with maxtype+1 elements
318 * @maxtype: maximum attribute type to be expected
319 * @policy: validation policy
320 *
321 * See nla_parse()
322 */
323static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen,
324 struct nlattr *tb[], int maxtype,
325 struct nla_policy *policy)
326{
327 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
328 return -EINVAL;
329
330 return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
331 nlmsg_attrlen(nlh, hdrlen), policy);
332}
333
334/**
335 * nlmsg_find_attr - find a specific attribute in a netlink message
336 * @nlh: netlink message header
337 * @hdrlen: length of familiy specific header
338 * @attrtype: type of attribute to look for
339 *
340 * Returns the first attribute which matches the specified type.
341 */
342static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh,
343 int hdrlen, int attrtype)
344{
345 return nla_find(nlmsg_attrdata(nlh, hdrlen),
346 nlmsg_attrlen(nlh, hdrlen), attrtype);
347}
348
349/**
350 * nlmsg_validate - validate a netlink message including attributes
351 * @nlh: netlinket message header
352 * @hdrlen: length of familiy specific header
353 * @maxtype: maximum attribute type to be expected
354 * @policy: validation policy
355 */
356static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
357 struct nla_policy *policy)
358{
359 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
360 return -EINVAL;
361
362 return nla_validate(nlmsg_attrdata(nlh, hdrlen),
363 nlmsg_attrlen(nlh, hdrlen), maxtype, policy);
364}
365
366/**
367 * nlmsg_for_each_attr - iterate over a stream of attributes
368 * @pos: loop counter, set to current attribute
369 * @nlh: netlink message header
370 * @hdrlen: length of familiy specific header
371 * @rem: initialized to len, holds bytes currently remaining in stream
372 */
373#define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \
374 nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \
375 nlmsg_attrlen(nlh, hdrlen), rem)
376
377#if 0
378/* FIXME: Enable once all users have been converted */
379
380/**
381 * __nlmsg_put - Add a new netlink message to an skb
382 * @skb: socket buffer to store message in
383 * @pid: netlink process id
384 * @seq: sequence number of message
385 * @type: message type
386 * @payload: length of message payload
387 * @flags: message flags
388 *
389 * The caller is responsible to ensure that the skb provides enough
390 * tailroom for both the netlink header and payload.
391 */
392static inline struct nlmsghdr *__nlmsg_put(struct sk_buff *skb, u32 pid,
393 u32 seq, int type, int payload,
394 int flags)
395{
396 struct nlmsghdr *nlh;
397
398 nlh = (struct nlmsghdr *) skb_put(skb, nlmsg_total_size(payload));
399 nlh->nlmsg_type = type;
400 nlh->nlmsg_len = nlmsg_msg_size(payload);
401 nlh->nlmsg_flags = flags;
402 nlh->nlmsg_pid = pid;
403 nlh->nlmsg_seq = seq;
404
405 memset((unsigned char *) nlmsg_data(nlh) + payload, 0,
406 nlmsg_padlen(payload));
407
408 return nlh;
409}
410#endif
411
412/**
413 * nlmsg_put - Add a new netlink message to an skb
414 * @skb: socket buffer to store message in
415 * @pid: netlink process id
416 * @seq: sequence number of message
417 * @type: message type
418 * @payload: length of message payload
419 * @flags: message flags
420 *
421 * Returns NULL if the tailroom of the skb is insufficient to store
422 * the message header and payload.
423 */
424static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
425 int type, int payload, int flags)
426{
427 if (unlikely(skb_tailroom(skb) < nlmsg_total_size(payload)))
428 return NULL;
429
430 return __nlmsg_put(skb, pid, seq, type, payload, flags);
431}
432
433/**
434 * nlmsg_put_answer - Add a new callback based netlink message to an skb
435 * @skb: socket buffer to store message in
436 * @cb: netlink callback
437 * @type: message type
438 * @payload: length of message payload
439 * @flags: message flags
440 *
441 * Returns NULL if the tailroom of the skb is insufficient to store
442 * the message header and payload.
443 */
444static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb,
445 struct netlink_callback *cb,
446 int type, int payload,
447 int flags)
448{
449 return nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
450 type, payload, flags);
451}
452
453/**
454 * nlmsg_new - Allocate a new netlink message
455 * @size: maximum size of message
456 *
457 * Use NLMSG_GOODSIZE if size isn't know and you need a good default size.
458 */
459static inline struct sk_buff *nlmsg_new(int size)
460{
461 return alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
462}
463
464/**
465 * nlmsg_end - Finalize a netlink message
466 * @skb: socket buffer the message is stored in
467 * @nlh: netlink message header
468 *
469 * Corrects the netlink message header to include the appeneded
470 * attributes. Only necessary if attributes have been added to
471 * the message.
472 *
473 * Returns the total data length of the skb.
474 */
475static inline int nlmsg_end(struct sk_buff *skb, struct nlmsghdr *nlh)
476{
477 nlh->nlmsg_len = skb->tail - (unsigned char *) nlh;
478
479 return skb->len;
480}
481
482/**
483 * nlmsg_cancel - Cancel construction of a netlink message
484 * @skb: socket buffer the message is stored in
485 * @nlh: netlink message header
486 *
487 * Removes the complete netlink message including all
488 * attributes from the socket buffer again. Returns -1.
489 */
490static inline int nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh)
491{
492 skb_trim(skb, (unsigned char *) nlh - skb->data);
493
494 return -1;
495}
496
497/**
498 * nlmsg_free - free a netlink message
499 * @skb: socket buffer of netlink message
500 */
501static inline void nlmsg_free(struct sk_buff *skb)
502{
503 kfree_skb(skb);
504}
505
506/**
507 * nlmsg_multicast - multicast a netlink message
508 * @sk: netlink socket to spread messages to
509 * @skb: netlink message as socket buffer
510 * @pid: own netlink pid to avoid sending to yourself
511 * @group: multicast group id
512 */
513static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
514 u32 pid, unsigned int group)
515{
516 int err;
517
518 NETLINK_CB(skb).dst_group = group;
519
520 err = netlink_broadcast(sk, skb, pid, group, GFP_KERNEL);
521 if (err > 0)
522 err = 0;
523
524 return err;
525}
526
527/**
528 * nlmsg_unicast - unicast a netlink message
529 * @sk: netlink socket to spread message to
530 * @skb: netlink message as socket buffer
531 * @pid: netlink pid of the destination socket
532 */
533static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid)
534{
535 int err;
536
537 err = netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
538 if (err > 0)
539 err = 0;
540
541 return err;
542}
543
544/**
545 * nlmsg_for_each_msg - iterate over a stream of messages
546 * @pos: loop counter, set to current message
547 * @head: head of message stream
548 * @len: length of message stream
549 * @rem: initialized to len, holds bytes currently remaining in stream
550 */
551#define nlmsg_for_each_msg(pos, head, len, rem) \
552 for (pos = head, rem = len; \
553 nlmsg_ok(pos, rem); \
554 pos = nlmsg_next(pos, &(rem)))
555
556/**************************************************************************
557 * Netlink Attributes
558 **************************************************************************/
559
560/**
561 * nla_attr_size - length of attribute not including padding
562 * @payload: length of payload
563 */
564static inline int nla_attr_size(int payload)
565{
566 return NLA_HDRLEN + payload;
567}
568
569/**
570 * nla_total_size - total length of attribute including padding
571 * @payload: length of payload
572 */
573static inline int nla_total_size(int payload)
574{
575 return NLA_ALIGN(nla_attr_size(payload));
576}
577
578/**
579 * nla_padlen - length of padding at the tail of attribute
580 * @payload: length of payload
581 */
582static inline int nla_padlen(int payload)
583{
584 return nla_total_size(payload) - nla_attr_size(payload);
585}
586
587/**
588 * nla_data - head of payload
589 * @nla: netlink attribute
590 */
591static inline void *nla_data(const struct nlattr *nla)
592{
593 return (char *) nla + NLA_HDRLEN;
594}
595
596/**
597 * nla_len - length of payload
598 * @nla: netlink attribute
599 */
600static inline int nla_len(const struct nlattr *nla)
601{
602 return nla->nla_len - NLA_HDRLEN;
603}
604
605/**
606 * nla_ok - check if the netlink attribute fits into the remaining bytes
607 * @nla: netlink attribute
608 * @remaining: number of bytes remaining in attribute stream
609 */
610static inline int nla_ok(const struct nlattr *nla, int remaining)
611{
612 return remaining >= sizeof(*nla) &&
613 nla->nla_len >= sizeof(*nla) &&
614 nla->nla_len <= remaining;
615}
616
617/**
618 * nla_next - next netlink attribte in attribute stream
619 * @nla: netlink attribute
620 * @remaining: number of bytes remaining in attribute stream
621 *
622 * Returns the next netlink attribute in the attribute stream and
623 * decrements remaining by the size of the current attribute.
624 */
625static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
626{
627 int totlen = NLA_ALIGN(nla->nla_len);
628
629 *remaining -= totlen;
630 return (struct nlattr *) ((char *) nla + totlen);
631}
632
633/**
634 * nla_parse_nested - parse nested attributes
635 * @tb: destination array with maxtype+1 elements
636 * @maxtype: maximum attribute type to be expected
637 * @nla: attribute containing the nested attributes
638 * @policy: validation policy
639 *
640 * See nla_parse()
641 */
642static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
643 struct nlattr *nla,
644 struct nla_policy *policy)
645{
646 return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
647}
648/**
649 * nla_put_u8 - Add a u16 netlink attribute to a socket buffer
650 * @skb: socket buffer to add attribute to
651 * @attrtype: attribute type
652 * @value: numeric value
653 */
654static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
655{
656 return nla_put(skb, attrtype, sizeof(u8), &value);
657}
658
659/**
660 * nla_put_u16 - Add a u16 netlink attribute to a socket buffer
661 * @skb: socket buffer to add attribute to
662 * @attrtype: attribute type
663 * @value: numeric value
664 */
665static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
666{
667 return nla_put(skb, attrtype, sizeof(u16), &value);
668}
669
670/**
671 * nla_put_u32 - Add a u32 netlink attribute to a socket buffer
672 * @skb: socket buffer to add attribute to
673 * @attrtype: attribute type
674 * @value: numeric value
675 */
676static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
677{
678 return nla_put(skb, attrtype, sizeof(u32), &value);
679}
680
681/**
682 * nla_put_64 - Add a u64 netlink attribute to a socket buffer
683 * @skb: socket buffer to add attribute to
684 * @attrtype: attribute type
685 * @value: numeric value
686 */
687static inline int nla_put_u64(struct sk_buff *skb, int attrtype, u64 value)
688{
689 return nla_put(skb, attrtype, sizeof(u64), &value);
690}
691
692/**
693 * nla_put_string - Add a string netlink attribute to a socket buffer
694 * @skb: socket buffer to add attribute to
695 * @attrtype: attribute type
696 * @str: NUL terminated string
697 */
698static inline int nla_put_string(struct sk_buff *skb, int attrtype,
699 const char *str)
700{
701 return nla_put(skb, attrtype, strlen(str) + 1, str);
702}
703
704/**
705 * nla_put_flag - Add a flag netlink attribute to a socket buffer
706 * @skb: socket buffer to add attribute to
707 * @attrtype: attribute type
708 */
709static inline int nla_put_flag(struct sk_buff *skb, int attrtype)
710{
711 return nla_put(skb, attrtype, 0, NULL);
712}
713
714/**
715 * nla_put_msecs - Add a msecs netlink attribute to a socket buffer
716 * @skb: socket buffer to add attribute to
717 * @attrtype: attribute type
718 * @jiffies: number of msecs in jiffies
719 */
720static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
721 unsigned long jiffies)
722{
723 u64 tmp = jiffies_to_msecs(jiffies);
724 return nla_put(skb, attrtype, sizeof(u64), &tmp);
725}
726
727#define NLA_PUT(skb, attrtype, attrlen, data) \
728 do { \
729 if (nla_put(skb, attrtype, attrlen, data) < 0) \
730 goto nla_put_failure; \
731 } while(0)
732
733#define NLA_PUT_TYPE(skb, type, attrtype, value) \
734 do { \
735 type __tmp = value; \
736 NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \
737 } while(0)
738
739#define NLA_PUT_U8(skb, attrtype, value) \
740 NLA_PUT_TYPE(skb, u8, attrtype, value)
741
742#define NLA_PUT_U16(skb, attrtype, value) \
743 NLA_PUT_TYPE(skb, u16, attrtype, value)
744
745#define NLA_PUT_U32(skb, attrtype, value) \
746 NLA_PUT_TYPE(skb, u32, attrtype, value)
747
748#define NLA_PUT_U64(skb, attrtype, value) \
749 NLA_PUT_TYPE(skb, u64, attrtype, value)
750
751#define NLA_PUT_STRING(skb, attrtype, value) \
752 NLA_PUT(skb, attrtype, strlen(value) + 1, value)
753
754#define NLA_PUT_FLAG(skb, attrtype, value) \
755 NLA_PUT(skb, attrtype, 0, NULL)
756
757#define NLA_PUT_MSECS(skb, attrtype, jiffies) \
758 NLA_PUT_U64(skb, attrtype, jiffies_to_msecs(jiffies))
759
760/**
761 * nla_get_u32 - return payload of u32 attribute
762 * @nla: u32 netlink attribute
763 */
764static inline u32 nla_get_u32(struct nlattr *nla)
765{
766 return *(u32 *) nla_data(nla);
767}
768
769/**
770 * nla_get_u16 - return payload of u16 attribute
771 * @nla: u16 netlink attribute
772 */
773static inline u16 nla_get_u16(struct nlattr *nla)
774{
775 return *(u16 *) nla_data(nla);
776}
777
778/**
779 * nla_get_u8 - return payload of u8 attribute
780 * @nla: u8 netlink attribute
781 */
782static inline u8 nla_get_u8(struct nlattr *nla)
783{
784 return *(u8 *) nla_data(nla);
785}
786
787/**
788 * nla_get_u64 - return payload of u64 attribute
789 * @nla: u64 netlink attribute
790 */
791static inline u64 nla_get_u64(struct nlattr *nla)
792{
793 u64 tmp;
794
795 nla_memcpy(&tmp, nla, sizeof(tmp));
796
797 return tmp;
798}
799
800/**
801 * nla_get_flag - return payload of flag attribute
802 * @nla: flag netlink attribute
803 */
804static inline int nla_get_flag(struct nlattr *nla)
805{
806 return !!nla;
807}
808
809/**
810 * nla_get_msecs - return payload of msecs attribute
811 * @nla: msecs netlink attribute
812 *
813 * Returns the number of milliseconds in jiffies.
814 */
815static inline unsigned long nla_get_msecs(struct nlattr *nla)
816{
817 u64 msecs = nla_get_u64(nla);
818
819 return msecs_to_jiffies((unsigned long) msecs);
820}
821
822/**
823 * nla_nest_start - Start a new level of nested attributes
824 * @skb: socket buffer to add attributes to
825 * @attrtype: attribute type of container
826 *
827 * Returns the container attribute
828 */
829static inline struct nlattr *nla_nest_start(struct sk_buff *skb, int attrtype)
830{
831 struct nlattr *start = (struct nlattr *) skb->tail;
832
833 if (nla_put(skb, attrtype, 0, NULL) < 0)
834 return NULL;
835
836 return start;
837}
838
839/**
840 * nla_nest_end - Finalize nesting of attributes
841 * @skb: socket buffer the attribtues are stored in
842 * @start: container attribute
843 *
844 * Corrects the container attribute header to include the all
845 * appeneded attributes.
846 *
847 * Returns the total data length of the skb.
848 */
849static inline int nla_nest_end(struct sk_buff *skb, struct nlattr *start)
850{
851 start->nla_len = skb->tail - (unsigned char *) start;
852 return skb->len;
853}
854
855/**
856 * nla_nest_cancel - Cancel nesting of attributes
857 * @skb: socket buffer the message is stored in
858 * @start: container attribute
859 *
860 * Removes the container attribute and including all nested
861 * attributes. Returns -1.
862 */
863static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
864{
865 if (start)
866 skb_trim(skb, (unsigned char *) start - skb->data);
867
868 return -1;
869}
870
871/**
872 * nla_for_each_attr - iterate over a stream of attributes
873 * @pos: loop counter, set to current attribute
874 * @head: head of attribute stream
875 * @len: length of attribute stream
876 * @rem: initialized to len, holds bytes currently remaining in stream
877 */
878#define nla_for_each_attr(pos, head, len, rem) \
879 for (pos = head, rem = len; \
880 nla_ok(pos, rem); \
881 pos = nla_next(pos, &(rem)))
882
883#endif
diff --git a/include/net/sock.h b/include/net/sock.h
index e0498bd36004..ff13c4cc287a 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -461,16 +461,16 @@ static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb)
461} 461}
462 462
463/* The per-socket spinlock must be held here. */ 463/* The per-socket spinlock must be held here. */
464#define sk_add_backlog(__sk, __skb) \ 464static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
465do { if (!(__sk)->sk_backlog.tail) { \ 465{
466 (__sk)->sk_backlog.head = \ 466 if (!sk->sk_backlog.tail) {
467 (__sk)->sk_backlog.tail = (__skb); \ 467 sk->sk_backlog.head = sk->sk_backlog.tail = skb;
468 } else { \ 468 } else {
469 ((__sk)->sk_backlog.tail)->next = (__skb); \ 469 sk->sk_backlog.tail->next = skb;
470 (__sk)->sk_backlog.tail = (__skb); \ 470 sk->sk_backlog.tail = skb;
471 } \ 471 }
472 (__skb)->next = NULL; \ 472 skb->next = NULL;
473} while(0) 473}
474 474
475#define sk_wait_event(__sk, __timeo, __condition) \ 475#define sk_wait_event(__sk, __timeo, __condition) \
476({ int rc; \ 476({ int rc; \
diff --git a/init/main.c b/init/main.c
index f142d4035341..27f97f9b4636 100644
--- a/init/main.c
+++ b/init/main.c
@@ -394,14 +394,16 @@ static void noinline rest_init(void)
394 kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND); 394 kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
395 numa_default_policy(); 395 numa_default_policy();
396 unlock_kernel(); 396 unlock_kernel();
397 preempt_enable_no_resched();
398 397
399 /* 398 /*
400 * The boot idle thread must execute schedule() 399 * The boot idle thread must execute schedule()
401 * at least one to get things moving: 400 * at least one to get things moving:
402 */ 401 */
402 preempt_enable_no_resched();
403 schedule(); 403 schedule();
404 preempt_disable();
404 405
406 /* Call into cpu_idle with preempt disabled */
405 cpu_idle(); 407 cpu_idle();
406} 408}
407 409
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 3619e939182e..d61ba88f34e5 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -21,6 +21,24 @@ EXPORT_SYMBOL_GPL(cpucontrol);
21 21
22static struct notifier_block *cpu_chain; 22static struct notifier_block *cpu_chain;
23 23
24/*
25 * Used to check by callers if they need to acquire the cpucontrol
26 * or not to protect a cpu from being removed. Its sometimes required to
27 * call these functions both for normal operations, and in response to
28 * a cpu being added/removed. If the context of the call is in the same
29 * thread context as a CPU hotplug thread, we dont need to take the lock
30 * since its already protected
31 * check drivers/cpufreq/cpufreq.c for its usage - Ashok Raj
32 */
33
34int current_in_cpu_hotplug(void)
35{
36 return (current->flags & PF_HOTPLUG_CPU);
37}
38
39EXPORT_SYMBOL_GPL(current_in_cpu_hotplug);
40
41
24/* Need to know about CPUs going up/down? */ 42/* Need to know about CPUs going up/down? */
25int register_cpu_notifier(struct notifier_block *nb) 43int register_cpu_notifier(struct notifier_block *nb)
26{ 44{
@@ -94,6 +112,13 @@ int cpu_down(unsigned int cpu)
94 goto out; 112 goto out;
95 } 113 }
96 114
115 /*
116 * Leave a trace in current->flags indicating we are already in
117 * process of performing CPU hotplug. Callers can check if cpucontrol
118 * is already acquired by current thread, and if so not cause
119 * a dead lock by not acquiring the lock
120 */
121 current->flags |= PF_HOTPLUG_CPU;
97 err = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, 122 err = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
98 (void *)(long)cpu); 123 (void *)(long)cpu);
99 if (err == NOTIFY_BAD) { 124 if (err == NOTIFY_BAD) {
@@ -146,6 +171,7 @@ out_thread:
146out_allowed: 171out_allowed:
147 set_cpus_allowed(current, old_allowed); 172 set_cpus_allowed(current, old_allowed);
148out: 173out:
174 current->flags &= ~PF_HOTPLUG_CPU;
149 unlock_cpu_hotplug(); 175 unlock_cpu_hotplug();
150 return err; 176 return err;
151} 177}
@@ -163,6 +189,12 @@ int __devinit cpu_up(unsigned int cpu)
163 ret = -EINVAL; 189 ret = -EINVAL;
164 goto out; 190 goto out;
165 } 191 }
192
193 /*
194 * Leave a trace in current->flags indicating we are already in
195 * process of performing CPU hotplug.
196 */
197 current->flags |= PF_HOTPLUG_CPU;
166 ret = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu); 198 ret = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);
167 if (ret == NOTIFY_BAD) { 199 if (ret == NOTIFY_BAD) {
168 printk("%s: attempt to bring up CPU %u failed\n", 200 printk("%s: attempt to bring up CPU %u failed\n",
@@ -185,6 +217,7 @@ out_notify:
185 if (ret != 0) 217 if (ret != 0)
186 notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu); 218 notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu);
187out: 219out:
220 current->flags &= ~PF_HOTPLUG_CPU;
188 up(&cpucontrol); 221 up(&cpucontrol);
189 return ret; 222 return ret;
190} 223}
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 18d7d693fbba..6ee2cad530e8 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -167,7 +167,7 @@ static int enter_state(suspend_state_t state)
167{ 167{
168 int error; 168 int error;
169 169
170 if (pm_ops->valid && !pm_ops->valid(state)) 170 if (pm_ops && pm_ops->valid && !pm_ops->valid(state))
171 return -ENODEV; 171 return -ENODEV;
172 if (down_trylock(&pm_sem)) 172 if (down_trylock(&pm_sem))
173 return -EBUSY; 173 return -EBUSY;
diff --git a/kernel/power/power.h b/kernel/power/power.h
index d4fd96a135ab..6c042b5ee14b 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -65,8 +65,8 @@ extern suspend_pagedir_t *pagedir_save;
65extern asmlinkage int swsusp_arch_suspend(void); 65extern asmlinkage int swsusp_arch_suspend(void);
66extern asmlinkage int swsusp_arch_resume(void); 66extern asmlinkage int swsusp_arch_resume(void);
67 67
68extern int restore_highmem(void); 68extern void free_pagedir(struct pbe *pblist);
69extern struct pbe * alloc_pagedir(unsigned nr_pages); 69extern struct pbe *alloc_pagedir(unsigned nr_pages, gfp_t gfp_mask, int safe_needed);
70extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages); 70extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages);
71extern void swsusp_free(void); 71extern void swsusp_free(void);
72extern int enough_swap(unsigned nr_pages); 72extern int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 723f5179883e..4a6dbcefd378 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -88,8 +88,7 @@ static int save_highmem_zone(struct zone *zone)
88 return 0; 88 return 0;
89} 89}
90 90
91 91int save_highmem(void)
92static int save_highmem(void)
93{ 92{
94 struct zone *zone; 93 struct zone *zone;
95 int res = 0; 94 int res = 0;
@@ -120,11 +119,7 @@ int restore_highmem(void)
120 } 119 }
121 return 0; 120 return 0;
122} 121}
123#else 122#endif
124static int save_highmem(void) { return 0; }
125int restore_highmem(void) { return 0; }
126#endif /* CONFIG_HIGHMEM */
127
128 123
129static int pfn_is_nosave(unsigned long pfn) 124static int pfn_is_nosave(unsigned long pfn)
130{ 125{
@@ -216,7 +211,7 @@ static void copy_data_pages(struct pbe *pblist)
216 * free_pagedir - free pages allocated with alloc_pagedir() 211 * free_pagedir - free pages allocated with alloc_pagedir()
217 */ 212 */
218 213
219static void free_pagedir(struct pbe *pblist) 214void free_pagedir(struct pbe *pblist)
220{ 215{
221 struct pbe *pbe; 216 struct pbe *pbe;
222 217
@@ -269,9 +264,30 @@ void create_pbe_list(struct pbe *pblist, unsigned int nr_pages)
269 pr_debug("create_pbe_list(): initialized %d PBEs\n", num); 264 pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
270} 265}
271 266
272static void *alloc_image_page(void) 267/**
268 * @safe_needed - on resume, for storing the PBE list and the image,
269 * we can only use memory pages that do not conflict with the pages
270 * which had been used before suspend.
271 *
272 * The unsafe pages are marked with the PG_nosave_free flag
273 *
274 * Allocated but unusable (ie eaten) memory pages should be marked
275 * so that swsusp_free() can release them
276 */
277
278static inline void *alloc_image_page(gfp_t gfp_mask, int safe_needed)
273{ 279{
274 void *res = (void *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD); 280 void *res;
281
282 if (safe_needed)
283 do {
284 res = (void *)get_zeroed_page(gfp_mask);
285 if (res && PageNosaveFree(virt_to_page(res)))
286 /* This is for swsusp_free() */
287 SetPageNosave(virt_to_page(res));
288 } while (res && PageNosaveFree(virt_to_page(res)));
289 else
290 res = (void *)get_zeroed_page(gfp_mask);
275 if (res) { 291 if (res) {
276 SetPageNosave(virt_to_page(res)); 292 SetPageNosave(virt_to_page(res));
277 SetPageNosaveFree(virt_to_page(res)); 293 SetPageNosaveFree(virt_to_page(res));
@@ -279,6 +295,11 @@ static void *alloc_image_page(void)
279 return res; 295 return res;
280} 296}
281 297
298unsigned long get_safe_page(gfp_t gfp_mask)
299{
300 return (unsigned long)alloc_image_page(gfp_mask, 1);
301}
302
282/** 303/**
283 * alloc_pagedir - Allocate the page directory. 304 * alloc_pagedir - Allocate the page directory.
284 * 305 *
@@ -292,7 +313,7 @@ static void *alloc_image_page(void)
292 * On each page we set up a list of struct_pbe elements. 313 * On each page we set up a list of struct_pbe elements.
293 */ 314 */
294 315
295struct pbe *alloc_pagedir(unsigned int nr_pages) 316struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask, int safe_needed)
296{ 317{
297 unsigned int num; 318 unsigned int num;
298 struct pbe *pblist, *pbe; 319 struct pbe *pblist, *pbe;
@@ -301,12 +322,12 @@ struct pbe *alloc_pagedir(unsigned int nr_pages)
301 return NULL; 322 return NULL;
302 323
303 pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages); 324 pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
304 pblist = alloc_image_page(); 325 pblist = alloc_image_page(gfp_mask, safe_needed);
305 /* FIXME: rewrite this ugly loop */ 326 /* FIXME: rewrite this ugly loop */
306 for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages; 327 for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
307 pbe = pbe->next, num += PBES_PER_PAGE) { 328 pbe = pbe->next, num += PBES_PER_PAGE) {
308 pbe += PB_PAGE_SKIP; 329 pbe += PB_PAGE_SKIP;
309 pbe->next = alloc_image_page(); 330 pbe->next = alloc_image_page(gfp_mask, safe_needed);
310 } 331 }
311 if (!pbe) { /* get_zeroed_page() failed */ 332 if (!pbe) { /* get_zeroed_page() failed */
312 free_pagedir(pblist); 333 free_pagedir(pblist);
@@ -354,24 +375,32 @@ static int enough_free_mem(unsigned int nr_pages)
354 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE); 375 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
355} 376}
356 377
378int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed)
379{
380 struct pbe *p;
381
382 for_each_pbe (p, pblist) {
383 p->address = (unsigned long)alloc_image_page(gfp_mask, safe_needed);
384 if (!p->address)
385 return -ENOMEM;
386 }
387 return 0;
388}
357 389
358static struct pbe *swsusp_alloc(unsigned int nr_pages) 390static struct pbe *swsusp_alloc(unsigned int nr_pages)
359{ 391{
360 struct pbe *pblist, *p; 392 struct pbe *pblist;
361 393
362 if (!(pblist = alloc_pagedir(nr_pages))) { 394 if (!(pblist = alloc_pagedir(nr_pages, GFP_ATOMIC | __GFP_COLD, 0))) {
363 printk(KERN_ERR "suspend: Allocating pagedir failed.\n"); 395 printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
364 return NULL; 396 return NULL;
365 } 397 }
366 create_pbe_list(pblist, nr_pages); 398 create_pbe_list(pblist, nr_pages);
367 399
368 for_each_pbe (p, pblist) { 400 if (alloc_data_pages(pblist, GFP_ATOMIC | __GFP_COLD, 0)) {
369 p->address = (unsigned long)alloc_image_page(); 401 printk(KERN_ERR "suspend: Allocating image pages failed.\n");
370 if (!p->address) { 402 swsusp_free();
371 printk(KERN_ERR "suspend: Allocating image pages failed.\n"); 403 return NULL;
372 swsusp_free();
373 return NULL;
374 }
375 } 404 }
376 405
377 return pblist; 406 return pblist;
@@ -382,11 +411,6 @@ asmlinkage int swsusp_save(void)
382 unsigned int nr_pages; 411 unsigned int nr_pages;
383 412
384 pr_debug("swsusp: critical section: \n"); 413 pr_debug("swsusp: critical section: \n");
385 if (save_highmem()) {
386 printk(KERN_CRIT "swsusp: Not enough free pages for highmem\n");
387 restore_highmem();
388 return -ENOMEM;
389 }
390 414
391 drain_local_pages(); 415 drain_local_pages();
392 nr_pages = count_data_pages(); 416 nr_pages = count_data_pages();
@@ -406,11 +430,6 @@ asmlinkage int swsusp_save(void)
406 return -ENOMEM; 430 return -ENOMEM;
407 } 431 }
408 432
409 if (!enough_swap(nr_pages)) {
410 printk(KERN_ERR "swsusp: Not enough free swap\n");
411 return -ENOSPC;
412 }
413
414 pagedir_nosave = swsusp_alloc(nr_pages); 433 pagedir_nosave = swsusp_alloc(nr_pages);
415 if (!pagedir_nosave) 434 if (!pagedir_nosave)
416 return -ENOMEM; 435 return -ENOMEM;
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index e1ab28b9b217..c05f46e7348f 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -73,6 +73,14 @@
73 73
74#include "power.h" 74#include "power.h"
75 75
76#ifdef CONFIG_HIGHMEM
77int save_highmem(void);
78int restore_highmem(void);
79#else
80static int save_highmem(void) { return 0; }
81static int restore_highmem(void) { return 0; }
82#endif
83
76#define CIPHER "aes" 84#define CIPHER "aes"
77#define MAXKEY 32 85#define MAXKEY 32
78#define MAXIV 32 86#define MAXIV 32
@@ -500,6 +508,26 @@ static int write_pagedir(void)
500} 508}
501 509
502/** 510/**
511 * enough_swap - Make sure we have enough swap to save the image.
512 *
513 * Returns TRUE or FALSE after checking the total amount of swap
514 * space avaiable.
515 *
516 * FIXME: si_swapinfo(&i) returns all swap devices information.
517 * We should only consider resume_device.
518 */
519
520static int enough_swap(unsigned int nr_pages)
521{
522 struct sysinfo i;
523
524 si_swapinfo(&i);
525 pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
526 return i.freeswap > (nr_pages + PAGES_FOR_IO +
527 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
528}
529
530/**
503 * write_suspend_image - Write entire image and metadata. 531 * write_suspend_image - Write entire image and metadata.
504 * 532 *
505 */ 533 */
@@ -507,6 +535,11 @@ static int write_suspend_image(void)
507{ 535{
508 int error; 536 int error;
509 537
538 if (!enough_swap(nr_copy_pages)) {
539 printk(KERN_ERR "swsusp: Not enough free swap\n");
540 return -ENOSPC;
541 }
542
510 init_header(); 543 init_header();
511 if ((error = data_write())) 544 if ((error = data_write()))
512 goto FreeData; 545 goto FreeData;
@@ -526,27 +559,6 @@ static int write_suspend_image(void)
526 goto Done; 559 goto Done;
527} 560}
528 561
529/**
530 * enough_swap - Make sure we have enough swap to save the image.
531 *
532 * Returns TRUE or FALSE after checking the total amount of swap
533 * space avaiable.
534 *
535 * FIXME: si_swapinfo(&i) returns all swap devices information.
536 * We should only consider resume_device.
537 */
538
539int enough_swap(unsigned int nr_pages)
540{
541 struct sysinfo i;
542
543 si_swapinfo(&i);
544 pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
545 return i.freeswap > (nr_pages + PAGES_FOR_IO +
546 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
547}
548
549
550/* It is important _NOT_ to umount filesystems at this point. We want 562/* It is important _NOT_ to umount filesystems at this point. We want
551 * them synced (in case something goes wrong) but we DO not want to mark 563 * them synced (in case something goes wrong) but we DO not want to mark
552 * filesystem clean: it is not. (And it does not matter, if we resume 564 * filesystem clean: it is not. (And it does not matter, if we resume
@@ -556,12 +568,15 @@ int swsusp_write(void)
556{ 568{
557 int error; 569 int error;
558 570
571 if ((error = swsusp_swap_check())) {
572 printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n");
573 return error;
574 }
559 lock_swapdevices(); 575 lock_swapdevices();
560 error = write_suspend_image(); 576 error = write_suspend_image();
561 /* This will unlock ignored swap devices since writing is finished */ 577 /* This will unlock ignored swap devices since writing is finished */
562 lock_swapdevices(); 578 lock_swapdevices();
563 return error; 579 return error;
564
565} 580}
566 581
567 582
@@ -569,6 +584,7 @@ int swsusp_write(void)
569int swsusp_suspend(void) 584int swsusp_suspend(void)
570{ 585{
571 int error; 586 int error;
587
572 if ((error = arch_prepare_suspend())) 588 if ((error = arch_prepare_suspend()))
573 return error; 589 return error;
574 local_irq_disable(); 590 local_irq_disable();
@@ -580,15 +596,12 @@ int swsusp_suspend(void)
580 */ 596 */
581 if ((error = device_power_down(PMSG_FREEZE))) { 597 if ((error = device_power_down(PMSG_FREEZE))) {
582 printk(KERN_ERR "Some devices failed to power down, aborting suspend\n"); 598 printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
583 local_irq_enable(); 599 goto Enable_irqs;
584 return error;
585 } 600 }
586 601
587 if ((error = swsusp_swap_check())) { 602 if ((error = save_highmem())) {
588 printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n"); 603 printk(KERN_ERR "swsusp: Not enough free pages for highmem\n");
589 device_power_up(); 604 goto Restore_highmem;
590 local_irq_enable();
591 return error;
592 } 605 }
593 606
594 save_processor_state(); 607 save_processor_state();
@@ -596,8 +609,10 @@ int swsusp_suspend(void)
596 printk(KERN_ERR "Error %d suspending\n", error); 609 printk(KERN_ERR "Error %d suspending\n", error);
597 /* Restore control flow magically appears here */ 610 /* Restore control flow magically appears here */
598 restore_processor_state(); 611 restore_processor_state();
612Restore_highmem:
599 restore_highmem(); 613 restore_highmem();
600 device_power_up(); 614 device_power_up();
615Enable_irqs:
601 local_irq_enable(); 616 local_irq_enable();
602 return error; 617 return error;
603} 618}
@@ -629,127 +644,43 @@ int swsusp_resume(void)
629} 644}
630 645
631/** 646/**
632 * On resume, for storing the PBE list and the image, 647 * mark_unsafe_pages - mark the pages that cannot be used for storing
633 * we can only use memory pages that do not conflict with the pages 648 * the image during resume, because they conflict with the pages that
634 * which had been used before suspend. 649 * had been used before suspend
635 *
636 * We don't know which pages are usable until we allocate them.
637 *
638 * Allocated but unusable (ie eaten) memory pages are marked so that
639 * swsusp_free() can release them
640 */
641
642unsigned long get_safe_page(gfp_t gfp_mask)
643{
644 unsigned long m;
645
646 do {
647 m = get_zeroed_page(gfp_mask);
648 if (m && PageNosaveFree(virt_to_page(m)))
649 /* This is for swsusp_free() */
650 SetPageNosave(virt_to_page(m));
651 } while (m && PageNosaveFree(virt_to_page(m)));
652 if (m) {
653 /* This is for swsusp_free() */
654 SetPageNosave(virt_to_page(m));
655 SetPageNosaveFree(virt_to_page(m));
656 }
657 return m;
658}
659
660/**
661 * check_pagedir - We ensure here that pages that the PBEs point to
662 * won't collide with pages where we're going to restore from the loaded
663 * pages later
664 */
665
666static int check_pagedir(struct pbe *pblist)
667{
668 struct pbe *p;
669
670 /* This is necessary, so that we can free allocated pages
671 * in case of failure
672 */
673 for_each_pbe (p, pblist)
674 p->address = 0UL;
675
676 for_each_pbe (p, pblist) {
677 p->address = get_safe_page(GFP_ATOMIC);
678 if (!p->address)
679 return -ENOMEM;
680 }
681 return 0;
682}
683
684/**
685 * swsusp_pagedir_relocate - It is possible, that some memory pages
686 * occupied by the list of PBEs collide with pages where we're going to
687 * restore from the loaded pages later. We relocate them here.
688 */ 650 */
689 651
690static struct pbe *swsusp_pagedir_relocate(struct pbe *pblist) 652static void mark_unsafe_pages(struct pbe *pblist)
691{ 653{
692 struct zone *zone; 654 struct zone *zone;
693 unsigned long zone_pfn; 655 unsigned long zone_pfn;
694 struct pbe *pbpage, *tail, *p; 656 struct pbe *p;
695 void *m;
696 int rel = 0;
697 657
698 if (!pblist) /* a sanity check */ 658 if (!pblist) /* a sanity check */
699 return NULL; 659 return;
700
701 pr_debug("swsusp: Relocating pagedir (%lu pages to check)\n",
702 swsusp_info.pagedir_pages);
703 660
704 /* Clear page flags */ 661 /* Clear page flags */
705
706 for_each_zone (zone) { 662 for_each_zone (zone) {
707 for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) 663 for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
708 if (pfn_valid(zone_pfn + zone->zone_start_pfn)) 664 if (pfn_valid(zone_pfn + zone->zone_start_pfn))
709 ClearPageNosaveFree(pfn_to_page(zone_pfn + 665 ClearPageNosaveFree(pfn_to_page(zone_pfn +
710 zone->zone_start_pfn)); 666 zone->zone_start_pfn));
711 } 667 }
712 668
713 /* Mark orig addresses */ 669 /* Mark orig addresses */
714
715 for_each_pbe (p, pblist) 670 for_each_pbe (p, pblist)
716 SetPageNosaveFree(virt_to_page(p->orig_address)); 671 SetPageNosaveFree(virt_to_page(p->orig_address));
717 672
718 tail = pblist + PB_PAGE_SKIP; 673}
719
720 /* Relocate colliding pages */
721
722 for_each_pb_page (pbpage, pblist) {
723 if (PageNosaveFree(virt_to_page((unsigned long)pbpage))) {
724 m = (void *)get_safe_page(GFP_ATOMIC | __GFP_COLD);
725 if (!m)
726 return NULL;
727 memcpy(m, (void *)pbpage, PAGE_SIZE);
728 if (pbpage == pblist)
729 pblist = (struct pbe *)m;
730 else
731 tail->next = (struct pbe *)m;
732 pbpage = (struct pbe *)m;
733
734 /* We have to link the PBEs again */
735 for (p = pbpage; p < pbpage + PB_PAGE_SKIP; p++)
736 if (p->next) /* needed to save the end */
737 p->next = p + 1;
738
739 rel++;
740 }
741 tail = pbpage + PB_PAGE_SKIP;
742 }
743 674
744 /* This is for swsusp_free() */ 675static void copy_page_backup_list(struct pbe *dst, struct pbe *src)
745 for_each_pb_page (pbpage, pblist) { 676{
746 SetPageNosave(virt_to_page(pbpage)); 677 /* We assume both lists contain the same number of elements */
747 SetPageNosaveFree(virt_to_page(pbpage)); 678 while (src) {
679 dst->orig_address = src->orig_address;
680 dst->swap_address = src->swap_address;
681 dst = dst->next;
682 src = src->next;
748 } 683 }
749
750 printk("swsusp: Relocated %d pages\n", rel);
751
752 return pblist;
753} 684}
754 685
755/* 686/*
@@ -888,7 +819,7 @@ static int check_sig(void)
888 * Reset swap signature now. 819 * Reset swap signature now.
889 */ 820 */
890 error = bio_write_page(0, &swsusp_header); 821 error = bio_write_page(0, &swsusp_header);
891 } else { 822 } else {
892 return -EINVAL; 823 return -EINVAL;
893 } 824 }
894 if (!error) 825 if (!error)
@@ -990,20 +921,25 @@ static int read_suspend_image(void)
990 int error = 0; 921 int error = 0;
991 struct pbe *p; 922 struct pbe *p;
992 923
993 if (!(p = alloc_pagedir(nr_copy_pages))) 924 if (!(p = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 0)))
994 return -ENOMEM; 925 return -ENOMEM;
995 926
996 if ((error = read_pagedir(p))) 927 if ((error = read_pagedir(p)))
997 return error; 928 return error;
998
999 create_pbe_list(p, nr_copy_pages); 929 create_pbe_list(p, nr_copy_pages);
1000 930 mark_unsafe_pages(p);
1001 if (!(pagedir_nosave = swsusp_pagedir_relocate(p))) 931 pagedir_nosave = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 1);
932 if (pagedir_nosave) {
933 create_pbe_list(pagedir_nosave, nr_copy_pages);
934 copy_page_backup_list(pagedir_nosave, p);
935 }
936 free_pagedir(p);
937 if (!pagedir_nosave)
1002 return -ENOMEM; 938 return -ENOMEM;
1003 939
1004 /* Allocate memory for the image and read the data from swap */ 940 /* Allocate memory for the image and read the data from swap */
1005 941
1006 error = check_pagedir(pagedir_nosave); 942 error = alloc_data_pages(pagedir_nosave, GFP_ATOMIC, 1);
1007 943
1008 if (!error) 944 if (!error)
1009 error = data_read(pagedir_nosave); 945 error = data_read(pagedir_nosave);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 5b8dd98a230e..b88d4186cd7a 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -155,7 +155,7 @@ int ptrace_attach(struct task_struct *task)
155 retval = -EPERM; 155 retval = -EPERM;
156 if (task->pid <= 1) 156 if (task->pid <= 1)
157 goto bad; 157 goto bad;
158 if (task == current) 158 if (task->tgid == current->tgid)
159 goto bad; 159 goto bad;
160 /* the same process cannot be attached many times */ 160 /* the same process cannot be attached many times */
161 if (task->ptrace & PT_PTRACED) 161 if (task->ptrace & PT_PTRACED)
diff --git a/kernel/sched.c b/kernel/sched.c
index 3ce26954be12..b6506671b2be 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -206,6 +206,7 @@ struct runqueue {
206 */ 206 */
207 unsigned long nr_running; 207 unsigned long nr_running;
208#ifdef CONFIG_SMP 208#ifdef CONFIG_SMP
209 unsigned long prio_bias;
209 unsigned long cpu_load[3]; 210 unsigned long cpu_load[3];
210#endif 211#endif
211 unsigned long long nr_switches; 212 unsigned long long nr_switches;
@@ -659,13 +660,68 @@ static int effective_prio(task_t *p)
659 return prio; 660 return prio;
660} 661}
661 662
663#ifdef CONFIG_SMP
664static inline void inc_prio_bias(runqueue_t *rq, int prio)
665{
666 rq->prio_bias += MAX_PRIO - prio;
667}
668
669static inline void dec_prio_bias(runqueue_t *rq, int prio)
670{
671 rq->prio_bias -= MAX_PRIO - prio;
672}
673
674static inline void inc_nr_running(task_t *p, runqueue_t *rq)
675{
676 rq->nr_running++;
677 if (rt_task(p)) {
678 if (p != rq->migration_thread)
679 /*
680 * The migration thread does the actual balancing. Do
681 * not bias by its priority as the ultra high priority
682 * will skew balancing adversely.
683 */
684 inc_prio_bias(rq, p->prio);
685 } else
686 inc_prio_bias(rq, p->static_prio);
687}
688
689static inline void dec_nr_running(task_t *p, runqueue_t *rq)
690{
691 rq->nr_running--;
692 if (rt_task(p)) {
693 if (p != rq->migration_thread)
694 dec_prio_bias(rq, p->prio);
695 } else
696 dec_prio_bias(rq, p->static_prio);
697}
698#else
699static inline void inc_prio_bias(runqueue_t *rq, int prio)
700{
701}
702
703static inline void dec_prio_bias(runqueue_t *rq, int prio)
704{
705}
706
707static inline void inc_nr_running(task_t *p, runqueue_t *rq)
708{
709 rq->nr_running++;
710}
711
712static inline void dec_nr_running(task_t *p, runqueue_t *rq)
713{
714 rq->nr_running--;
715}
716#endif
717
662/* 718/*
663 * __activate_task - move a task to the runqueue. 719 * __activate_task - move a task to the runqueue.
664 */ 720 */
665static inline void __activate_task(task_t *p, runqueue_t *rq) 721static inline void __activate_task(task_t *p, runqueue_t *rq)
666{ 722{
667 enqueue_task(p, rq->active); 723 enqueue_task(p, rq->active);
668 rq->nr_running++; 724 inc_nr_running(p, rq);
669} 725}
670 726
671/* 727/*
@@ -674,7 +730,7 @@ static inline void __activate_task(task_t *p, runqueue_t *rq)
674static inline void __activate_idle_task(task_t *p, runqueue_t *rq) 730static inline void __activate_idle_task(task_t *p, runqueue_t *rq)
675{ 731{
676 enqueue_task_head(p, rq->active); 732 enqueue_task_head(p, rq->active);
677 rq->nr_running++; 733 inc_nr_running(p, rq);
678} 734}
679 735
680static int recalc_task_prio(task_t *p, unsigned long long now) 736static int recalc_task_prio(task_t *p, unsigned long long now)
@@ -759,7 +815,8 @@ static void activate_task(task_t *p, runqueue_t *rq, int local)
759 } 815 }
760#endif 816#endif
761 817
762 p->prio = recalc_task_prio(p, now); 818 if (!rt_task(p))
819 p->prio = recalc_task_prio(p, now);
763 820
764 /* 821 /*
765 * This checks to make sure it's not an uninterruptible task 822 * This checks to make sure it's not an uninterruptible task
@@ -793,7 +850,7 @@ static void activate_task(task_t *p, runqueue_t *rq, int local)
793 */ 850 */
794static void deactivate_task(struct task_struct *p, runqueue_t *rq) 851static void deactivate_task(struct task_struct *p, runqueue_t *rq)
795{ 852{
796 rq->nr_running--; 853 dec_nr_running(p, rq);
797 dequeue_task(p, p->array); 854 dequeue_task(p, p->array);
798 p->array = NULL; 855 p->array = NULL;
799} 856}
@@ -808,21 +865,28 @@ static void deactivate_task(struct task_struct *p, runqueue_t *rq)
808#ifdef CONFIG_SMP 865#ifdef CONFIG_SMP
809static void resched_task(task_t *p) 866static void resched_task(task_t *p)
810{ 867{
811 int need_resched, nrpolling; 868 int cpu;
812 869
813 assert_spin_locked(&task_rq(p)->lock); 870 assert_spin_locked(&task_rq(p)->lock);
814 871
815 /* minimise the chance of sending an interrupt to poll_idle() */ 872 if (unlikely(test_tsk_thread_flag(p, TIF_NEED_RESCHED)))
816 nrpolling = test_tsk_thread_flag(p,TIF_POLLING_NRFLAG); 873 return;
817 need_resched = test_and_set_tsk_thread_flag(p,TIF_NEED_RESCHED); 874
818 nrpolling |= test_tsk_thread_flag(p,TIF_POLLING_NRFLAG); 875 set_tsk_thread_flag(p, TIF_NEED_RESCHED);
876
877 cpu = task_cpu(p);
878 if (cpu == smp_processor_id())
879 return;
819 880
820 if (!need_resched && !nrpolling && (task_cpu(p) != smp_processor_id())) 881 /* NEED_RESCHED must be visible before we test POLLING_NRFLAG */
821 smp_send_reschedule(task_cpu(p)); 882 smp_mb();
883 if (!test_tsk_thread_flag(p, TIF_POLLING_NRFLAG))
884 smp_send_reschedule(cpu);
822} 885}
823#else 886#else
824static inline void resched_task(task_t *p) 887static inline void resched_task(task_t *p)
825{ 888{
889 assert_spin_locked(&task_rq(p)->lock);
826 set_tsk_need_resched(p); 890 set_tsk_need_resched(p);
827} 891}
828#endif 892#endif
@@ -930,27 +994,61 @@ void kick_process(task_t *p)
930 * We want to under-estimate the load of migration sources, to 994 * We want to under-estimate the load of migration sources, to
931 * balance conservatively. 995 * balance conservatively.
932 */ 996 */
933static inline unsigned long source_load(int cpu, int type) 997static inline unsigned long __source_load(int cpu, int type, enum idle_type idle)
934{ 998{
935 runqueue_t *rq = cpu_rq(cpu); 999 runqueue_t *rq = cpu_rq(cpu);
936 unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE; 1000 unsigned long running = rq->nr_running;
1001 unsigned long source_load, cpu_load = rq->cpu_load[type-1],
1002 load_now = running * SCHED_LOAD_SCALE;
1003
937 if (type == 0) 1004 if (type == 0)
938 return load_now; 1005 source_load = load_now;
1006 else
1007 source_load = min(cpu_load, load_now);
939 1008
940 return min(rq->cpu_load[type-1], load_now); 1009 if (running > 1 || (idle == NOT_IDLE && running))
1010 /*
1011 * If we are busy rebalancing the load is biased by
1012 * priority to create 'nice' support across cpus. When
1013 * idle rebalancing we should only bias the source_load if
1014 * there is more than one task running on that queue to
1015 * prevent idle rebalance from trying to pull tasks from a
1016 * queue with only one running task.
1017 */
1018 source_load = source_load * rq->prio_bias / running;
1019
1020 return source_load;
1021}
1022
1023static inline unsigned long source_load(int cpu, int type)
1024{
1025 return __source_load(cpu, type, NOT_IDLE);
941} 1026}
942 1027
943/* 1028/*
944 * Return a high guess at the load of a migration-target cpu 1029 * Return a high guess at the load of a migration-target cpu
945 */ 1030 */
946static inline unsigned long target_load(int cpu, int type) 1031static inline unsigned long __target_load(int cpu, int type, enum idle_type idle)
947{ 1032{
948 runqueue_t *rq = cpu_rq(cpu); 1033 runqueue_t *rq = cpu_rq(cpu);
949 unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE; 1034 unsigned long running = rq->nr_running;
1035 unsigned long target_load, cpu_load = rq->cpu_load[type-1],
1036 load_now = running * SCHED_LOAD_SCALE;
1037
950 if (type == 0) 1038 if (type == 0)
951 return load_now; 1039 target_load = load_now;
1040 else
1041 target_load = max(cpu_load, load_now);
1042
1043 if (running > 1 || (idle == NOT_IDLE && running))
1044 target_load = target_load * rq->prio_bias / running;
952 1045
953 return max(rq->cpu_load[type-1], load_now); 1046 return target_load;
1047}
1048
1049static inline unsigned long target_load(int cpu, int type)
1050{
1051 return __target_load(cpu, type, NOT_IDLE);
954} 1052}
955 1053
956/* 1054/*
@@ -1411,7 +1509,7 @@ void fastcall wake_up_new_task(task_t *p, unsigned long clone_flags)
1411 list_add_tail(&p->run_list, &current->run_list); 1509 list_add_tail(&p->run_list, &current->run_list);
1412 p->array = current->array; 1510 p->array = current->array;
1413 p->array->nr_active++; 1511 p->array->nr_active++;
1414 rq->nr_running++; 1512 inc_nr_running(p, rq);
1415 } 1513 }
1416 set_need_resched(); 1514 set_need_resched();
1417 } else 1515 } else
@@ -1756,9 +1854,9 @@ void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t *p,
1756 runqueue_t *this_rq, prio_array_t *this_array, int this_cpu) 1854 runqueue_t *this_rq, prio_array_t *this_array, int this_cpu)
1757{ 1855{
1758 dequeue_task(p, src_array); 1856 dequeue_task(p, src_array);
1759 src_rq->nr_running--; 1857 dec_nr_running(p, src_rq);
1760 set_task_cpu(p, this_cpu); 1858 set_task_cpu(p, this_cpu);
1761 this_rq->nr_running++; 1859 inc_nr_running(p, this_rq);
1762 enqueue_task(p, this_array); 1860 enqueue_task(p, this_array);
1763 p->timestamp = (p->timestamp - src_rq->timestamp_last_tick) 1861 p->timestamp = (p->timestamp - src_rq->timestamp_last_tick)
1764 + this_rq->timestamp_last_tick; 1862 + this_rq->timestamp_last_tick;
@@ -1937,9 +2035,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
1937 2035
1938 /* Bias balancing toward cpus of our domain */ 2036 /* Bias balancing toward cpus of our domain */
1939 if (local_group) 2037 if (local_group)
1940 load = target_load(i, load_idx); 2038 load = __target_load(i, load_idx, idle);
1941 else 2039 else
1942 load = source_load(i, load_idx); 2040 load = __source_load(i, load_idx, idle);
1943 2041
1944 avg_load += load; 2042 avg_load += load;
1945 } 2043 }
@@ -2044,14 +2142,15 @@ out_balanced:
2044/* 2142/*
2045 * find_busiest_queue - find the busiest runqueue among the cpus in group. 2143 * find_busiest_queue - find the busiest runqueue among the cpus in group.
2046 */ 2144 */
2047static runqueue_t *find_busiest_queue(struct sched_group *group) 2145static runqueue_t *find_busiest_queue(struct sched_group *group,
2146 enum idle_type idle)
2048{ 2147{
2049 unsigned long load, max_load = 0; 2148 unsigned long load, max_load = 0;
2050 runqueue_t *busiest = NULL; 2149 runqueue_t *busiest = NULL;
2051 int i; 2150 int i;
2052 2151
2053 for_each_cpu_mask(i, group->cpumask) { 2152 for_each_cpu_mask(i, group->cpumask) {
2054 load = source_load(i, 0); 2153 load = __source_load(i, 0, idle);
2055 2154
2056 if (load > max_load) { 2155 if (load > max_load) {
2057 max_load = load; 2156 max_load = load;
@@ -2095,7 +2194,7 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
2095 goto out_balanced; 2194 goto out_balanced;
2096 } 2195 }
2097 2196
2098 busiest = find_busiest_queue(group); 2197 busiest = find_busiest_queue(group, idle);
2099 if (!busiest) { 2198 if (!busiest) {
2100 schedstat_inc(sd, lb_nobusyq[idle]); 2199 schedstat_inc(sd, lb_nobusyq[idle]);
2101 goto out_balanced; 2200 goto out_balanced;
@@ -2218,7 +2317,7 @@ static int load_balance_newidle(int this_cpu, runqueue_t *this_rq,
2218 goto out_balanced; 2317 goto out_balanced;
2219 } 2318 }
2220 2319
2221 busiest = find_busiest_queue(group); 2320 busiest = find_busiest_queue(group, NEWLY_IDLE);
2222 if (!busiest) { 2321 if (!busiest) {
2223 schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]); 2322 schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]);
2224 goto out_balanced; 2323 goto out_balanced;
@@ -3451,8 +3550,10 @@ void set_user_nice(task_t *p, long nice)
3451 goto out_unlock; 3550 goto out_unlock;
3452 } 3551 }
3453 array = p->array; 3552 array = p->array;
3454 if (array) 3553 if (array) {
3455 dequeue_task(p, array); 3554 dequeue_task(p, array);
3555 dec_prio_bias(rq, p->static_prio);
3556 }
3456 3557
3457 old_prio = p->prio; 3558 old_prio = p->prio;
3458 new_prio = NICE_TO_PRIO(nice); 3559 new_prio = NICE_TO_PRIO(nice);
@@ -3462,6 +3563,7 @@ void set_user_nice(task_t *p, long nice)
3462 3563
3463 if (array) { 3564 if (array) {
3464 enqueue_task(p, array); 3565 enqueue_task(p, array);
3566 inc_prio_bias(rq, p->static_prio);
3465 /* 3567 /*
3466 * If the task increased its priority or is running and 3568 * If the task increased its priority or is running and
3467 * lowered its priority, then reschedule its CPU: 3569 * lowered its priority, then reschedule its CPU:
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index a2dcceb9437d..c67189a25d52 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -73,9 +73,6 @@ void softlockup_tick(struct pt_regs *regs)
73static int watchdog(void * __bind_cpu) 73static int watchdog(void * __bind_cpu)
74{ 74{
75 struct sched_param param = { .sched_priority = 99 }; 75 struct sched_param param = { .sched_priority = 99 };
76 int this_cpu = (long) __bind_cpu;
77
78 printk("softlockup thread %d started up.\n", this_cpu);
79 76
80 sched_setscheduler(current, SCHED_FIFO, &param); 77 sched_setscheduler(current, SCHED_FIFO, &param);
81 current->flags |= PF_NOFREEZE; 78 current->flags |= PF_NOFREEZE;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c4f35f96884d..9990e10192e8 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -169,7 +169,7 @@ struct file_operations proc_sys_file_operations = {
169 169
170extern struct proc_dir_entry *proc_sys_root; 170extern struct proc_dir_entry *proc_sys_root;
171 171
172static void register_proc_table(ctl_table *, struct proc_dir_entry *); 172static void register_proc_table(ctl_table *, struct proc_dir_entry *, void *);
173static void unregister_proc_table(ctl_table *, struct proc_dir_entry *); 173static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
174#endif 174#endif
175 175
@@ -992,10 +992,51 @@ static ctl_table dev_table[] = {
992 992
993extern void init_irq_proc (void); 993extern void init_irq_proc (void);
994 994
995static DEFINE_SPINLOCK(sysctl_lock);
996
997/* called under sysctl_lock */
998static int use_table(struct ctl_table_header *p)
999{
1000 if (unlikely(p->unregistering))
1001 return 0;
1002 p->used++;
1003 return 1;
1004}
1005
1006/* called under sysctl_lock */
1007static void unuse_table(struct ctl_table_header *p)
1008{
1009 if (!--p->used)
1010 if (unlikely(p->unregistering))
1011 complete(p->unregistering);
1012}
1013
1014/* called under sysctl_lock, will reacquire if has to wait */
1015static void start_unregistering(struct ctl_table_header *p)
1016{
1017 /*
1018 * if p->used is 0, nobody will ever touch that entry again;
1019 * we'll eliminate all paths to it before dropping sysctl_lock
1020 */
1021 if (unlikely(p->used)) {
1022 struct completion wait;
1023 init_completion(&wait);
1024 p->unregistering = &wait;
1025 spin_unlock(&sysctl_lock);
1026 wait_for_completion(&wait);
1027 spin_lock(&sysctl_lock);
1028 }
1029 /*
1030 * do not remove from the list until nobody holds it; walking the
1031 * list in do_sysctl() relies on that.
1032 */
1033 list_del_init(&p->ctl_entry);
1034}
1035
995void __init sysctl_init(void) 1036void __init sysctl_init(void)
996{ 1037{
997#ifdef CONFIG_PROC_FS 1038#ifdef CONFIG_PROC_FS
998 register_proc_table(root_table, proc_sys_root); 1039 register_proc_table(root_table, proc_sys_root, &root_table_header);
999 init_irq_proc(); 1040 init_irq_proc();
1000#endif 1041#endif
1001} 1042}
@@ -1004,6 +1045,7 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol
1004 void __user *newval, size_t newlen) 1045 void __user *newval, size_t newlen)
1005{ 1046{
1006 struct list_head *tmp; 1047 struct list_head *tmp;
1048 int error = -ENOTDIR;
1007 1049
1008 if (nlen <= 0 || nlen >= CTL_MAXNAME) 1050 if (nlen <= 0 || nlen >= CTL_MAXNAME)
1009 return -ENOTDIR; 1051 return -ENOTDIR;
@@ -1012,20 +1054,30 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol
1012 if (!oldlenp || get_user(old_len, oldlenp)) 1054 if (!oldlenp || get_user(old_len, oldlenp))
1013 return -EFAULT; 1055 return -EFAULT;
1014 } 1056 }
1057 spin_lock(&sysctl_lock);
1015 tmp = &root_table_header.ctl_entry; 1058 tmp = &root_table_header.ctl_entry;
1016 do { 1059 do {
1017 struct ctl_table_header *head = 1060 struct ctl_table_header *head =
1018 list_entry(tmp, struct ctl_table_header, ctl_entry); 1061 list_entry(tmp, struct ctl_table_header, ctl_entry);
1019 void *context = NULL; 1062 void *context = NULL;
1020 int error = parse_table(name, nlen, oldval, oldlenp, 1063
1064 if (!use_table(head))
1065 continue;
1066
1067 spin_unlock(&sysctl_lock);
1068
1069 error = parse_table(name, nlen, oldval, oldlenp,
1021 newval, newlen, head->ctl_table, 1070 newval, newlen, head->ctl_table,
1022 &context); 1071 &context);
1023 kfree(context); 1072 kfree(context);
1073
1074 spin_lock(&sysctl_lock);
1075 unuse_table(head);
1024 if (error != -ENOTDIR) 1076 if (error != -ENOTDIR)
1025 return error; 1077 break;
1026 tmp = tmp->next; 1078 } while ((tmp = tmp->next) != &root_table_header.ctl_entry);
1027 } while (tmp != &root_table_header.ctl_entry); 1079 spin_unlock(&sysctl_lock);
1028 return -ENOTDIR; 1080 return error;
1029} 1081}
1030 1082
1031asmlinkage long sys_sysctl(struct __sysctl_args __user *args) 1083asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
@@ -1236,12 +1288,16 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table,
1236 return NULL; 1288 return NULL;
1237 tmp->ctl_table = table; 1289 tmp->ctl_table = table;
1238 INIT_LIST_HEAD(&tmp->ctl_entry); 1290 INIT_LIST_HEAD(&tmp->ctl_entry);
1291 tmp->used = 0;
1292 tmp->unregistering = NULL;
1293 spin_lock(&sysctl_lock);
1239 if (insert_at_head) 1294 if (insert_at_head)
1240 list_add(&tmp->ctl_entry, &root_table_header.ctl_entry); 1295 list_add(&tmp->ctl_entry, &root_table_header.ctl_entry);
1241 else 1296 else
1242 list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); 1297 list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
1298 spin_unlock(&sysctl_lock);
1243#ifdef CONFIG_PROC_FS 1299#ifdef CONFIG_PROC_FS
1244 register_proc_table(table, proc_sys_root); 1300 register_proc_table(table, proc_sys_root, tmp);
1245#endif 1301#endif
1246 return tmp; 1302 return tmp;
1247} 1303}
@@ -1255,10 +1311,13 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table,
1255 */ 1311 */
1256void unregister_sysctl_table(struct ctl_table_header * header) 1312void unregister_sysctl_table(struct ctl_table_header * header)
1257{ 1313{
1258 list_del(&header->ctl_entry); 1314 might_sleep();
1315 spin_lock(&sysctl_lock);
1316 start_unregistering(header);
1259#ifdef CONFIG_PROC_FS 1317#ifdef CONFIG_PROC_FS
1260 unregister_proc_table(header->ctl_table, proc_sys_root); 1318 unregister_proc_table(header->ctl_table, proc_sys_root);
1261#endif 1319#endif
1320 spin_unlock(&sysctl_lock);
1262 kfree(header); 1321 kfree(header);
1263} 1322}
1264 1323
@@ -1269,7 +1328,7 @@ void unregister_sysctl_table(struct ctl_table_header * header)
1269#ifdef CONFIG_PROC_FS 1328#ifdef CONFIG_PROC_FS
1270 1329
1271/* Scan the sysctl entries in table and add them all into /proc */ 1330/* Scan the sysctl entries in table and add them all into /proc */
1272static void register_proc_table(ctl_table * table, struct proc_dir_entry *root) 1331static void register_proc_table(ctl_table * table, struct proc_dir_entry *root, void *set)
1273{ 1332{
1274 struct proc_dir_entry *de; 1333 struct proc_dir_entry *de;
1275 int len; 1334 int len;
@@ -1305,13 +1364,14 @@ static void register_proc_table(ctl_table * table, struct proc_dir_entry *root)
1305 de = create_proc_entry(table->procname, mode, root); 1364 de = create_proc_entry(table->procname, mode, root);
1306 if (!de) 1365 if (!de)
1307 continue; 1366 continue;
1367 de->set = set;
1308 de->data = (void *) table; 1368 de->data = (void *) table;
1309 if (table->proc_handler) 1369 if (table->proc_handler)
1310 de->proc_fops = &proc_sys_file_operations; 1370 de->proc_fops = &proc_sys_file_operations;
1311 } 1371 }
1312 table->de = de; 1372 table->de = de;
1313 if (de->mode & S_IFDIR) 1373 if (de->mode & S_IFDIR)
1314 register_proc_table(table->child, de); 1374 register_proc_table(table->child, de, set);
1315 } 1375 }
1316} 1376}
1317 1377
@@ -1336,6 +1396,13 @@ static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root
1336 continue; 1396 continue;
1337 } 1397 }
1338 1398
1399 /*
1400 * In any case, mark the entry as goner; we'll keep it
1401 * around if it's busy, but we'll know to do nothing with
1402 * its fields. We are under sysctl_lock here.
1403 */
1404 de->data = NULL;
1405
1339 /* Don't unregister proc entries that are still being used.. */ 1406 /* Don't unregister proc entries that are still being used.. */
1340 if (atomic_read(&de->count)) 1407 if (atomic_read(&de->count))
1341 continue; 1408 continue;
@@ -1349,27 +1416,38 @@ static ssize_t do_rw_proc(int write, struct file * file, char __user * buf,
1349 size_t count, loff_t *ppos) 1416 size_t count, loff_t *ppos)
1350{ 1417{
1351 int op; 1418 int op;
1352 struct proc_dir_entry *de; 1419 struct proc_dir_entry *de = PDE(file->f_dentry->d_inode);
1353 struct ctl_table *table; 1420 struct ctl_table *table;
1354 size_t res; 1421 size_t res;
1355 ssize_t error; 1422 ssize_t error = -ENOTDIR;
1356
1357 de = PDE(file->f_dentry->d_inode);
1358 if (!de || !de->data)
1359 return -ENOTDIR;
1360 table = (struct ctl_table *) de->data;
1361 if (!table || !table->proc_handler)
1362 return -ENOTDIR;
1363 op = (write ? 002 : 004);
1364 if (ctl_perm(table, op))
1365 return -EPERM;
1366 1423
1367 res = count; 1424 spin_lock(&sysctl_lock);
1368 1425 if (de && de->data && use_table(de->set)) {
1369 error = (*table->proc_handler) (table, write, file, buf, &res, ppos); 1426 /*
1370 if (error) 1427 * at that point we know that sysctl was not unregistered
1371 return error; 1428 * and won't be until we finish
1372 return res; 1429 */
1430 spin_unlock(&sysctl_lock);
1431 table = (struct ctl_table *) de->data;
1432 if (!table || !table->proc_handler)
1433 goto out;
1434 error = -EPERM;
1435 op = (write ? 002 : 004);
1436 if (ctl_perm(table, op))
1437 goto out;
1438
1439 /* careful: calling conventions are nasty here */
1440 res = count;
1441 error = (*table->proc_handler)(table, write, file,
1442 buf, &res, ppos);
1443 if (!error)
1444 error = res;
1445 out:
1446 spin_lock(&sysctl_lock);
1447 unuse_table(de->set);
1448 }
1449 spin_unlock(&sysctl_lock);
1450 return error;
1373} 1451}
1374 1452
1375static int proc_opensys(struct inode *inode, struct file *file) 1453static int proc_opensys(struct inode *inode, struct file *file)
diff --git a/net/802/p8023.c b/net/802/p8023.c
index 6368d3dce444..d23e906456eb 100644
--- a/net/802/p8023.c
+++ b/net/802/p8023.c
@@ -54,8 +54,7 @@ struct datalink_proto *make_8023_client(void)
54 */ 54 */
55void destroy_8023_client(struct datalink_proto *dl) 55void destroy_8023_client(struct datalink_proto *dl)
56{ 56{
57 if (dl) 57 kfree(dl);
58 kfree(dl);
59} 58}
60 59
61EXPORT_SYMBOL(destroy_8023_client); 60EXPORT_SYMBOL(destroy_8023_client);
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 8e37e71e34ff..1b683f302657 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1138,10 +1138,8 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr,
1138 sk->sk_state = TCP_CLOSE; 1138 sk->sk_state = TCP_CLOSE;
1139 sock->state = SS_UNCONNECTED; 1139 sock->state = SS_UNCONNECTED;
1140 1140
1141 if (ax25->digipeat != NULL) { 1141 kfree(ax25->digipeat);
1142 kfree(ax25->digipeat); 1142 ax25->digipeat = NULL;
1143 ax25->digipeat = NULL;
1144 }
1145 1143
1146 /* 1144 /*
1147 * Handle digi-peaters to be used. 1145 * Handle digi-peaters to be used.
diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c
index 73cfc3411c46..4cf87540fb3a 100644
--- a/net/ax25/ax25_in.c
+++ b/net/ax25/ax25_in.c
@@ -401,10 +401,8 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
401 } 401 }
402 402
403 if (dp.ndigi == 0) { 403 if (dp.ndigi == 0) {
404 if (ax25->digipeat != NULL) { 404 kfree(ax25->digipeat);
405 kfree(ax25->digipeat); 405 ax25->digipeat = NULL;
406 ax25->digipeat = NULL;
407 }
408 } else { 406 } else {
409 /* Reverse the source SABM's path */ 407 /* Reverse the source SABM's path */
410 memcpy(ax25->digipeat, &reverse_dp, sizeof(ax25_digi)); 408 memcpy(ax25->digipeat, &reverse_dp, sizeof(ax25_digi));
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index 26b77d972220..b1e945bd6ed3 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -54,15 +54,13 @@ void ax25_rt_device_down(struct net_device *dev)
54 if (s->dev == dev) { 54 if (s->dev == dev) {
55 if (ax25_route_list == s) { 55 if (ax25_route_list == s) {
56 ax25_route_list = s->next; 56 ax25_route_list = s->next;
57 if (s->digipeat != NULL) 57 kfree(s->digipeat);
58 kfree(s->digipeat);
59 kfree(s); 58 kfree(s);
60 } else { 59 } else {
61 for (t = ax25_route_list; t != NULL; t = t->next) { 60 for (t = ax25_route_list; t != NULL; t = t->next) {
62 if (t->next == s) { 61 if (t->next == s) {
63 t->next = s->next; 62 t->next = s->next;
64 if (s->digipeat != NULL) 63 kfree(s->digipeat);
65 kfree(s->digipeat);
66 kfree(s); 64 kfree(s);
67 break; 65 break;
68 } 66 }
@@ -90,10 +88,8 @@ static int ax25_rt_add(struct ax25_routes_struct *route)
90 while (ax25_rt != NULL) { 88 while (ax25_rt != NULL) {
91 if (ax25cmp(&ax25_rt->callsign, &route->dest_addr) == 0 && 89 if (ax25cmp(&ax25_rt->callsign, &route->dest_addr) == 0 &&
92 ax25_rt->dev == ax25_dev->dev) { 90 ax25_rt->dev == ax25_dev->dev) {
93 if (ax25_rt->digipeat != NULL) { 91 kfree(ax25_rt->digipeat);
94 kfree(ax25_rt->digipeat); 92 ax25_rt->digipeat = NULL;
95 ax25_rt->digipeat = NULL;
96 }
97 if (route->digi_count != 0) { 93 if (route->digi_count != 0) {
98 if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { 94 if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
99 write_unlock(&ax25_route_lock); 95 write_unlock(&ax25_route_lock);
@@ -145,8 +141,7 @@ static int ax25_rt_add(struct ax25_routes_struct *route)
145static void ax25_rt_destroy(ax25_route *ax25_rt) 141static void ax25_rt_destroy(ax25_route *ax25_rt)
146{ 142{
147 if (atomic_read(&ax25_rt->ref) == 0) { 143 if (atomic_read(&ax25_rt->ref) == 0) {
148 if (ax25_rt->digipeat != NULL) 144 kfree(ax25_rt->digipeat);
149 kfree(ax25_rt->digipeat);
150 kfree(ax25_rt); 145 kfree(ax25_rt);
151 return; 146 return;
152 } 147 }
@@ -530,9 +525,7 @@ void __exit ax25_rt_free(void)
530 s = ax25_rt; 525 s = ax25_rt;
531 ax25_rt = ax25_rt->next; 526 ax25_rt = ax25_rt->next;
532 527
533 if (s->digipeat != NULL) 528 kfree(s->digipeat);
534 kfree(s->digipeat);
535
536 kfree(s); 529 kfree(s);
537 } 530 }
538 write_unlock(&ax25_route_lock); 531 write_unlock(&ax25_route_lock);
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 03532062a46a..ea616e3fc98e 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -36,7 +36,6 @@
36#include <linux/skbuff.h> 36#include <linux/skbuff.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/poll.h> 38#include <linux/poll.h>
39#include <linux/proc_fs.h>
40#include <net/sock.h> 39#include <net/sock.h>
41 40
42#if defined(CONFIG_KMOD) 41#if defined(CONFIG_KMOD)
@@ -50,10 +49,7 @@
50#define BT_DBG(D...) 49#define BT_DBG(D...)
51#endif 50#endif
52 51
53#define VERSION "2.7" 52#define VERSION "2.8"
54
55struct proc_dir_entry *proc_bt;
56EXPORT_SYMBOL(proc_bt);
57 53
58/* Bluetooth sockets */ 54/* Bluetooth sockets */
59#define BT_MAX_PROTO 8 55#define BT_MAX_PROTO 8
@@ -312,10 +308,6 @@ static int __init bt_init(void)
312{ 308{
313 BT_INFO("Core ver %s", VERSION); 309 BT_INFO("Core ver %s", VERSION);
314 310
315 proc_bt = proc_mkdir("bluetooth", NULL);
316 if (proc_bt)
317 proc_bt->owner = THIS_MODULE;
318
319 sock_register(&bt_sock_family_ops); 311 sock_register(&bt_sock_family_ops);
320 312
321 BT_INFO("HCI device and connection manager initialized"); 313 BT_INFO("HCI device and connection manager initialized");
@@ -334,8 +326,6 @@ static void __exit bt_exit(void)
334 bt_sysfs_cleanup(); 326 bt_sysfs_cleanup();
335 327
336 sock_unregister(PF_BLUETOOTH); 328 sock_unregister(PF_BLUETOOTH);
337
338 remove_proc_entry("bluetooth", NULL);
339} 329}
340 330
341subsys_initcall(bt_init); 331subsys_initcall(bt_init);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index cf0df1c8c933..9106354c781e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -183,7 +183,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
183static void hci_init_req(struct hci_dev *hdev, unsigned long opt) 183static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
184{ 184{
185 struct sk_buff *skb; 185 struct sk_buff *skb;
186 __u16 param; 186 __le16 param;
187 187
188 BT_DBG("%s %ld", hdev->name, opt); 188 BT_DBG("%s %ld", hdev->name, opt);
189 189
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index b61b4e8e36fd..eb64555d1fb3 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -242,7 +242,7 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
242 break; 242 break;
243 243
244 status = *((__u8 *) skb->data); 244 status = *((__u8 *) skb->data);
245 setting = __le16_to_cpu(get_unaligned((__u16 *) sent)); 245 setting = __le16_to_cpu(get_unaligned((__le16 *) sent));
246 246
247 if (!status && hdev->voice_setting != setting) { 247 if (!status && hdev->voice_setting != setting) {
248 hdev->voice_setting = setting; 248 hdev->voice_setting = setting;
@@ -728,7 +728,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
728static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) 728static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
729{ 729{
730 struct hci_ev_num_comp_pkts *ev = (struct hci_ev_num_comp_pkts *) skb->data; 730 struct hci_ev_num_comp_pkts *ev = (struct hci_ev_num_comp_pkts *) skb->data;
731 __u16 *ptr; 731 __le16 *ptr;
732 int i; 732 int i;
733 733
734 skb_pull(skb, sizeof(*ev)); 734 skb_pull(skb, sizeof(*ev));
@@ -742,7 +742,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
742 742
743 tasklet_disable(&hdev->tx_task); 743 tasklet_disable(&hdev->tx_task);
744 744
745 for (i = 0, ptr = (__u16 *) skb->data; i < ev->num_hndl; i++) { 745 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
746 struct hci_conn *conn; 746 struct hci_conn *conn;
747 __u16 handle, count; 747 __u16 handle, count;
748 748
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 799e448750ad..1d6d0a15c099 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -416,7 +416,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
416 skb->dev = (void *) hdev; 416 skb->dev = (void *) hdev;
417 417
418 if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { 418 if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
419 u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data)); 419 u16 opcode = __le16_to_cpu(get_unaligned((__le16 *) skb->data));
420 u16 ogf = hci_opcode_ogf(opcode); 420 u16 ogf = hci_opcode_ogf(opcode);
421 u16 ocf = hci_opcode_ocf(opcode); 421 u16 ocf = hci_opcode_ocf(opcode);
422 422
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 7856bc26accb..bd7568ac87fc 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -103,7 +103,7 @@ static void bt_release(struct class_device *cdev)
103 kfree(hdev); 103 kfree(hdev);
104} 104}
105 105
106static struct class bt_class = { 106struct class bt_class = {
107 .name = "bluetooth", 107 .name = "bluetooth",
108 .release = bt_release, 108 .release = bt_release,
109#ifdef CONFIG_HOTPLUG 109#ifdef CONFIG_HOTPLUG
@@ -111,6 +111,8 @@ static struct class bt_class = {
111#endif 111#endif
112}; 112};
113 113
114EXPORT_SYMBOL_GPL(bt_class);
115
114int hci_register_sysfs(struct hci_dev *hdev) 116int hci_register_sysfs(struct hci_dev *hdev)
115{ 117{
116 struct class_device *cdev = &hdev->class_dev; 118 struct class_device *cdev = &hdev->class_dev;
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 860444a7fc0f..cdb9cfafd960 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -660,9 +660,7 @@ unlink:
660failed: 660failed:
661 up_write(&hidp_session_sem); 661 up_write(&hidp_session_sem);
662 662
663 if (session->input) 663 kfree(session->input);
664 kfree(session->input);
665
666 kfree(session); 664 kfree(session);
667 return err; 665 return err;
668} 666}
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 59b2dd36baa7..e3bb11ca4235 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -38,9 +38,8 @@
38#include <linux/interrupt.h> 38#include <linux/interrupt.h>
39#include <linux/socket.h> 39#include <linux/socket.h>
40#include <linux/skbuff.h> 40#include <linux/skbuff.h>
41#include <linux/proc_fs.h>
42#include <linux/seq_file.h>
43#include <linux/list.h> 41#include <linux/list.h>
42#include <linux/device.h>
44#include <net/sock.h> 43#include <net/sock.h>
45 44
46#include <asm/system.h> 45#include <asm/system.h>
@@ -56,7 +55,7 @@
56#define BT_DBG(D...) 55#define BT_DBG(D...)
57#endif 56#endif
58 57
59#define VERSION "2.7" 58#define VERSION "2.8"
60 59
61static struct proto_ops l2cap_sock_ops; 60static struct proto_ops l2cap_sock_ops;
62 61
@@ -2137,94 +2136,29 @@ drop:
2137 return 0; 2136 return 0;
2138} 2137}
2139 2138
2140/* ---- Proc fs support ---- */ 2139static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
2141#ifdef CONFIG_PROC_FS
2142static void *l2cap_seq_start(struct seq_file *seq, loff_t *pos)
2143{ 2140{
2144 struct sock *sk; 2141 struct sock *sk;
2145 struct hlist_node *node; 2142 struct hlist_node *node;
2146 loff_t l = *pos; 2143 char *str = buf;
2147 2144
2148 read_lock_bh(&l2cap_sk_list.lock); 2145 read_lock_bh(&l2cap_sk_list.lock);
2149 2146
2150 sk_for_each(sk, node, &l2cap_sk_list.head) 2147 sk_for_each(sk, node, &l2cap_sk_list.head) {
2151 if (!l--) 2148 struct l2cap_pinfo *pi = l2cap_pi(sk);
2152 goto found;
2153 sk = NULL;
2154found:
2155 return sk;
2156}
2157 2149
2158static void *l2cap_seq_next(struct seq_file *seq, void *e, loff_t *pos) 2150 str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
2159{ 2151 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
2160 (*pos)++; 2152 sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu,
2161 return sk_next(e); 2153 pi->omtu, pi->link_mode);
2162} 2154 }
2163 2155
2164static void l2cap_seq_stop(struct seq_file *seq, void *e)
2165{
2166 read_unlock_bh(&l2cap_sk_list.lock); 2156 read_unlock_bh(&l2cap_sk_list.lock);
2167}
2168 2157
2169static int l2cap_seq_show(struct seq_file *seq, void *e) 2158 return (str - buf);
2170{
2171 struct sock *sk = e;
2172 struct l2cap_pinfo *pi = l2cap_pi(sk);
2173
2174 seq_printf(seq, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
2175 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
2176 sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu,
2177 pi->omtu, pi->link_mode);
2178 return 0;
2179} 2159}
2180 2160
2181static struct seq_operations l2cap_seq_ops = { 2161static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
2182 .start = l2cap_seq_start,
2183 .next = l2cap_seq_next,
2184 .stop = l2cap_seq_stop,
2185 .show = l2cap_seq_show
2186};
2187
2188static int l2cap_seq_open(struct inode *inode, struct file *file)
2189{
2190 return seq_open(file, &l2cap_seq_ops);
2191}
2192
2193static struct file_operations l2cap_seq_fops = {
2194 .owner = THIS_MODULE,
2195 .open = l2cap_seq_open,
2196 .read = seq_read,
2197 .llseek = seq_lseek,
2198 .release = seq_release,
2199};
2200
2201static int __init l2cap_proc_init(void)
2202{
2203 struct proc_dir_entry *p = create_proc_entry("l2cap", S_IRUGO, proc_bt);
2204 if (!p)
2205 return -ENOMEM;
2206 p->owner = THIS_MODULE;
2207 p->proc_fops = &l2cap_seq_fops;
2208 return 0;
2209}
2210
2211static void __exit l2cap_proc_cleanup(void)
2212{
2213 remove_proc_entry("l2cap", proc_bt);
2214}
2215
2216#else /* CONFIG_PROC_FS */
2217
2218static int __init l2cap_proc_init(void)
2219{
2220 return 0;
2221}
2222
2223static void __exit l2cap_proc_cleanup(void)
2224{
2225 return;
2226}
2227#endif /* CONFIG_PROC_FS */
2228 2162
2229static struct proto_ops l2cap_sock_ops = { 2163static struct proto_ops l2cap_sock_ops = {
2230 .family = PF_BLUETOOTH, 2164 .family = PF_BLUETOOTH,
@@ -2266,7 +2200,7 @@ static struct hci_proto l2cap_hci_proto = {
2266static int __init l2cap_init(void) 2200static int __init l2cap_init(void)
2267{ 2201{
2268 int err; 2202 int err;
2269 2203
2270 err = proto_register(&l2cap_proto, 0); 2204 err = proto_register(&l2cap_proto, 0);
2271 if (err < 0) 2205 if (err < 0)
2272 return err; 2206 return err;
@@ -2284,7 +2218,7 @@ static int __init l2cap_init(void)
2284 goto error; 2218 goto error;
2285 } 2219 }
2286 2220
2287 l2cap_proc_init(); 2221 class_create_file(&bt_class, &class_attr_l2cap);
2288 2222
2289 BT_INFO("L2CAP ver %s", VERSION); 2223 BT_INFO("L2CAP ver %s", VERSION);
2290 BT_INFO("L2CAP socket layer initialized"); 2224 BT_INFO("L2CAP socket layer initialized");
@@ -2298,7 +2232,7 @@ error:
2298 2232
2299static void __exit l2cap_exit(void) 2233static void __exit l2cap_exit(void)
2300{ 2234{
2301 l2cap_proc_cleanup(); 2235 class_remove_file(&bt_class, &class_attr_l2cap);
2302 2236
2303 if (bt_sock_unregister(BTPROTO_L2CAP) < 0) 2237 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
2304 BT_ERR("L2CAP socket unregistration failed"); 2238 BT_ERR("L2CAP socket unregistration failed");
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index c3d56ead840c..0d89d6434136 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -35,9 +35,8 @@
35#include <linux/signal.h> 35#include <linux/signal.h>
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/wait.h> 37#include <linux/wait.h>
38#include <linux/device.h>
38#include <linux/net.h> 39#include <linux/net.h>
39#include <linux/proc_fs.h>
40#include <linux/seq_file.h>
41#include <net/sock.h> 40#include <net/sock.h>
42#include <asm/uaccess.h> 41#include <asm/uaccess.h>
43#include <asm/unaligned.h> 42#include <asm/unaligned.h>
@@ -47,17 +46,13 @@
47#include <net/bluetooth/l2cap.h> 46#include <net/bluetooth/l2cap.h>
48#include <net/bluetooth/rfcomm.h> 47#include <net/bluetooth/rfcomm.h>
49 48
50#define VERSION "1.5" 49#define VERSION "1.6"
51 50
52#ifndef CONFIG_BT_RFCOMM_DEBUG 51#ifndef CONFIG_BT_RFCOMM_DEBUG
53#undef BT_DBG 52#undef BT_DBG
54#define BT_DBG(D...) 53#define BT_DBG(D...)
55#endif 54#endif
56 55
57#ifdef CONFIG_PROC_FS
58struct proc_dir_entry *proc_bt_rfcomm;
59#endif
60
61static struct task_struct *rfcomm_thread; 56static struct task_struct *rfcomm_thread;
62 57
63static DECLARE_MUTEX(rfcomm_sem); 58static DECLARE_MUTEX(rfcomm_sem);
@@ -2001,117 +1996,32 @@ static struct hci_cb rfcomm_cb = {
2001 .encrypt_cfm = rfcomm_encrypt_cfm 1996 .encrypt_cfm = rfcomm_encrypt_cfm
2002}; 1997};
2003 1998
2004/* ---- Proc fs support ---- */ 1999static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf)
2005#ifdef CONFIG_PROC_FS
2006static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
2007{ 2000{
2008 struct rfcomm_session *s; 2001 struct rfcomm_session *s;
2009 struct list_head *pp, *p; 2002 struct list_head *pp, *p;
2010 loff_t l = *pos; 2003 char *str = buf;
2011 2004
2012 rfcomm_lock(); 2005 rfcomm_lock();
2013 2006
2014 list_for_each(p, &session_list) { 2007 list_for_each(p, &session_list) {
2015 s = list_entry(p, struct rfcomm_session, list); 2008 s = list_entry(p, struct rfcomm_session, list);
2016 list_for_each(pp, &s->dlcs) 2009 list_for_each(pp, &s->dlcs) {
2017 if (!l--) { 2010 struct sock *sk = s->sock->sk;
2018 seq->private = s; 2011 struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
2019 return pp;
2020 }
2021 }
2022 return NULL;
2023}
2024 2012
2025static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos) 2013 str += sprintf(str, "%s %s %ld %d %d %d %d\n",
2026{ 2014 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
2027 struct rfcomm_session *s = seq->private; 2015 d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
2028 struct list_head *pp, *p = e;
2029 (*pos)++;
2030
2031 if (p->next != &s->dlcs)
2032 return p->next;
2033
2034 list_for_each(p, &session_list) {
2035 s = list_entry(p, struct rfcomm_session, list);
2036 __list_for_each(pp, &s->dlcs) {
2037 seq->private = s;
2038 return pp;
2039 } 2016 }
2040 } 2017 }
2041 return NULL;
2042}
2043 2018
2044static void rfcomm_seq_stop(struct seq_file *seq, void *e)
2045{
2046 rfcomm_unlock(); 2019 rfcomm_unlock();
2047}
2048
2049static int rfcomm_seq_show(struct seq_file *seq, void *e)
2050{
2051 struct rfcomm_session *s = seq->private;
2052 struct sock *sk = s->sock->sk;
2053 struct rfcomm_dlc *d = list_entry(e, struct rfcomm_dlc, list);
2054
2055 seq_printf(seq, "%s %s %ld %d %d %d %d\n",
2056 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
2057 d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
2058 return 0;
2059}
2060
2061static struct seq_operations rfcomm_seq_ops = {
2062 .start = rfcomm_seq_start,
2063 .next = rfcomm_seq_next,
2064 .stop = rfcomm_seq_stop,
2065 .show = rfcomm_seq_show
2066};
2067
2068static int rfcomm_seq_open(struct inode *inode, struct file *file)
2069{
2070 return seq_open(file, &rfcomm_seq_ops);
2071}
2072
2073static struct file_operations rfcomm_seq_fops = {
2074 .owner = THIS_MODULE,
2075 .open = rfcomm_seq_open,
2076 .read = seq_read,
2077 .llseek = seq_lseek,
2078 .release = seq_release,
2079};
2080
2081static int __init rfcomm_proc_init(void)
2082{
2083 struct proc_dir_entry *p;
2084
2085 proc_bt_rfcomm = proc_mkdir("rfcomm", proc_bt);
2086 if (proc_bt_rfcomm) {
2087 proc_bt_rfcomm->owner = THIS_MODULE;
2088
2089 p = create_proc_entry("dlc", S_IRUGO, proc_bt_rfcomm);
2090 if (p)
2091 p->proc_fops = &rfcomm_seq_fops;
2092 }
2093 return 0;
2094}
2095
2096static void __exit rfcomm_proc_cleanup(void)
2097{
2098 remove_proc_entry("dlc", proc_bt_rfcomm);
2099 2020
2100 remove_proc_entry("rfcomm", proc_bt); 2021 return (str - buf);
2101} 2022}
2102 2023
2103#else /* CONFIG_PROC_FS */ 2024static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
2104
2105static int __init rfcomm_proc_init(void)
2106{
2107 return 0;
2108}
2109
2110static void __exit rfcomm_proc_cleanup(void)
2111{
2112 return;
2113}
2114#endif /* CONFIG_PROC_FS */
2115 2025
2116/* ---- Initialization ---- */ 2026/* ---- Initialization ---- */
2117static int __init rfcomm_init(void) 2027static int __init rfcomm_init(void)
@@ -2122,9 +2032,7 @@ static int __init rfcomm_init(void)
2122 2032
2123 kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); 2033 kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
2124 2034
2125 BT_INFO("RFCOMM ver %s", VERSION); 2035 class_create_file(&bt_class, &class_attr_rfcomm_dlc);
2126
2127 rfcomm_proc_init();
2128 2036
2129 rfcomm_init_sockets(); 2037 rfcomm_init_sockets();
2130 2038
@@ -2132,11 +2040,15 @@ static int __init rfcomm_init(void)
2132 rfcomm_init_ttys(); 2040 rfcomm_init_ttys();
2133#endif 2041#endif
2134 2042
2043 BT_INFO("RFCOMM ver %s", VERSION);
2044
2135 return 0; 2045 return 0;
2136} 2046}
2137 2047
2138static void __exit rfcomm_exit(void) 2048static void __exit rfcomm_exit(void)
2139{ 2049{
2050 class_remove_file(&bt_class, &class_attr_rfcomm_dlc);
2051
2140 hci_unregister_cb(&rfcomm_cb); 2052 hci_unregister_cb(&rfcomm_cb);
2141 2053
2142 /* Terminate working thread. 2054 /* Terminate working thread.
@@ -2153,8 +2065,6 @@ static void __exit rfcomm_exit(void)
2153#endif 2065#endif
2154 2066
2155 rfcomm_cleanup_sockets(); 2067 rfcomm_cleanup_sockets();
2156
2157 rfcomm_proc_cleanup();
2158} 2068}
2159 2069
2160module_init(rfcomm_init); 2070module_init(rfcomm_init);
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index a2b30f0aedb7..6c34261b232e 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -42,8 +42,7 @@
42#include <linux/socket.h> 42#include <linux/socket.h>
43#include <linux/skbuff.h> 43#include <linux/skbuff.h>
44#include <linux/list.h> 44#include <linux/list.h>
45#include <linux/proc_fs.h> 45#include <linux/device.h>
46#include <linux/seq_file.h>
47#include <net/sock.h> 46#include <net/sock.h>
48 47
49#include <asm/system.h> 48#include <asm/system.h>
@@ -887,89 +886,26 @@ done:
887 return result; 886 return result;
888} 887}
889 888
890/* ---- Proc fs support ---- */ 889static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf)
891#ifdef CONFIG_PROC_FS
892static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
893{ 890{
894 struct sock *sk; 891 struct sock *sk;
895 struct hlist_node *node; 892 struct hlist_node *node;
896 loff_t l = *pos; 893 char *str = buf;
897 894
898 read_lock_bh(&rfcomm_sk_list.lock); 895 read_lock_bh(&rfcomm_sk_list.lock);
899 896
900 sk_for_each(sk, node, &rfcomm_sk_list.head) 897 sk_for_each(sk, node, &rfcomm_sk_list.head) {
901 if (!l--) 898 str += sprintf(str, "%s %s %d %d\n",
902 return sk; 899 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
903 return NULL; 900 sk->sk_state, rfcomm_pi(sk)->channel);
904} 901 }
905
906static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos)
907{
908 struct sock *sk = e;
909 (*pos)++;
910 return sk_next(sk);
911}
912 902
913static void rfcomm_seq_stop(struct seq_file *seq, void *e)
914{
915 read_unlock_bh(&rfcomm_sk_list.lock); 903 read_unlock_bh(&rfcomm_sk_list.lock);
916}
917 904
918static int rfcomm_seq_show(struct seq_file *seq, void *e) 905 return (str - buf);
919{
920 struct sock *sk = e;
921 seq_printf(seq, "%s %s %d %d\n",
922 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
923 sk->sk_state, rfcomm_pi(sk)->channel);
924 return 0;
925}
926
927static struct seq_operations rfcomm_seq_ops = {
928 .start = rfcomm_seq_start,
929 .next = rfcomm_seq_next,
930 .stop = rfcomm_seq_stop,
931 .show = rfcomm_seq_show
932};
933
934static int rfcomm_seq_open(struct inode *inode, struct file *file)
935{
936 return seq_open(file, &rfcomm_seq_ops);
937} 906}
938 907
939static struct file_operations rfcomm_seq_fops = { 908static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
940 .owner = THIS_MODULE,
941 .open = rfcomm_seq_open,
942 .read = seq_read,
943 .llseek = seq_lseek,
944 .release = seq_release,
945};
946
947static int __init rfcomm_sock_proc_init(void)
948{
949 struct proc_dir_entry *p = create_proc_entry("sock", S_IRUGO, proc_bt_rfcomm);
950 if (!p)
951 return -ENOMEM;
952 p->proc_fops = &rfcomm_seq_fops;
953 return 0;
954}
955
956static void __exit rfcomm_sock_proc_cleanup(void)
957{
958 remove_proc_entry("sock", proc_bt_rfcomm);
959}
960
961#else /* CONFIG_PROC_FS */
962
963static int __init rfcomm_sock_proc_init(void)
964{
965 return 0;
966}
967
968static void __exit rfcomm_sock_proc_cleanup(void)
969{
970 return;
971}
972#endif /* CONFIG_PROC_FS */
973 909
974static struct proto_ops rfcomm_sock_ops = { 910static struct proto_ops rfcomm_sock_ops = {
975 .family = PF_BLUETOOTH, 911 .family = PF_BLUETOOTH,
@@ -997,7 +933,7 @@ static struct net_proto_family rfcomm_sock_family_ops = {
997 .create = rfcomm_sock_create 933 .create = rfcomm_sock_create
998}; 934};
999 935
1000int __init rfcomm_init_sockets(void) 936int __init rfcomm_init_sockets(void)
1001{ 937{
1002 int err; 938 int err;
1003 939
@@ -1009,7 +945,7 @@ int __init rfcomm_init_sockets(void)
1009 if (err < 0) 945 if (err < 0)
1010 goto error; 946 goto error;
1011 947
1012 rfcomm_sock_proc_init(); 948 class_create_file(&bt_class, &class_attr_rfcomm);
1013 949
1014 BT_INFO("RFCOMM socket layer initialized"); 950 BT_INFO("RFCOMM socket layer initialized");
1015 951
@@ -1023,7 +959,7 @@ error:
1023 959
1024void __exit rfcomm_cleanup_sockets(void) 960void __exit rfcomm_cleanup_sockets(void)
1025{ 961{
1026 rfcomm_sock_proc_cleanup(); 962 class_remove_file(&bt_class, &class_attr_rfcomm);
1027 963
1028 if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) 964 if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
1029 BT_ERR("RFCOMM socket layer unregistration failed"); 965 BT_ERR("RFCOMM socket layer unregistration failed");
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 997e42df115c..9cb00dc6c08c 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -38,8 +38,7 @@
38#include <linux/interrupt.h> 38#include <linux/interrupt.h>
39#include <linux/socket.h> 39#include <linux/socket.h>
40#include <linux/skbuff.h> 40#include <linux/skbuff.h>
41#include <linux/proc_fs.h> 41#include <linux/device.h>
42#include <linux/seq_file.h>
43#include <linux/list.h> 42#include <linux/list.h>
44#include <net/sock.h> 43#include <net/sock.h>
45 44
@@ -55,7 +54,7 @@
55#define BT_DBG(D...) 54#define BT_DBG(D...)
56#endif 55#endif
57 56
58#define VERSION "0.4" 57#define VERSION "0.5"
59 58
60static struct proto_ops sco_sock_ops; 59static struct proto_ops sco_sock_ops;
61 60
@@ -893,91 +892,26 @@ drop:
893 return 0; 892 return 0;
894} 893}
895 894
896/* ---- Proc fs support ---- */ 895static ssize_t sco_sysfs_show(struct class *dev, char *buf)
897#ifdef CONFIG_PROC_FS
898static void *sco_seq_start(struct seq_file *seq, loff_t *pos)
899{ 896{
900 struct sock *sk; 897 struct sock *sk;
901 struct hlist_node *node; 898 struct hlist_node *node;
902 loff_t l = *pos; 899 char *str = buf;
903 900
904 read_lock_bh(&sco_sk_list.lock); 901 read_lock_bh(&sco_sk_list.lock);
905 902
906 sk_for_each(sk, node, &sco_sk_list.head) 903 sk_for_each(sk, node, &sco_sk_list.head) {
907 if (!l--) 904 str += sprintf(str, "%s %s %d\n",
908 goto found; 905 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
909 sk = NULL; 906 sk->sk_state);
910found: 907 }
911 return sk;
912}
913
914static void *sco_seq_next(struct seq_file *seq, void *e, loff_t *pos)
915{
916 struct sock *sk = e;
917 (*pos)++;
918 return sk_next(sk);
919}
920 908
921static void sco_seq_stop(struct seq_file *seq, void *e)
922{
923 read_unlock_bh(&sco_sk_list.lock); 909 read_unlock_bh(&sco_sk_list.lock);
924}
925
926static int sco_seq_show(struct seq_file *seq, void *e)
927{
928 struct sock *sk = e;
929 seq_printf(seq, "%s %s %d\n",
930 batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), sk->sk_state);
931 return 0;
932}
933 910
934static struct seq_operations sco_seq_ops = { 911 return (str - buf);
935 .start = sco_seq_start,
936 .next = sco_seq_next,
937 .stop = sco_seq_stop,
938 .show = sco_seq_show
939};
940
941static int sco_seq_open(struct inode *inode, struct file *file)
942{
943 return seq_open(file, &sco_seq_ops);
944} 912}
945 913
946static struct file_operations sco_seq_fops = { 914static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
947 .owner = THIS_MODULE,
948 .open = sco_seq_open,
949 .read = seq_read,
950 .llseek = seq_lseek,
951 .release = seq_release,
952};
953
954static int __init sco_proc_init(void)
955{
956 struct proc_dir_entry *p = create_proc_entry("sco", S_IRUGO, proc_bt);
957 if (!p)
958 return -ENOMEM;
959 p->owner = THIS_MODULE;
960 p->proc_fops = &sco_seq_fops;
961 return 0;
962}
963
964static void __exit sco_proc_cleanup(void)
965{
966 remove_proc_entry("sco", proc_bt);
967}
968
969#else /* CONFIG_PROC_FS */
970
971static int __init sco_proc_init(void)
972{
973 return 0;
974}
975
976static void __exit sco_proc_cleanup(void)
977{
978 return;
979}
980#endif /* CONFIG_PROC_FS */
981 915
982static struct proto_ops sco_sock_ops = { 916static struct proto_ops sco_sock_ops = {
983 .family = PF_BLUETOOTH, 917 .family = PF_BLUETOOTH,
@@ -1035,7 +969,7 @@ static int __init sco_init(void)
1035 goto error; 969 goto error;
1036 } 970 }
1037 971
1038 sco_proc_init(); 972 class_create_file(&bt_class, &class_attr_sco);
1039 973
1040 BT_INFO("SCO (Voice Link) ver %s", VERSION); 974 BT_INFO("SCO (Voice Link) ver %s", VERSION);
1041 BT_INFO("SCO socket layer initialized"); 975 BT_INFO("SCO socket layer initialized");
@@ -1049,7 +983,7 @@ error:
1049 983
1050static void __exit sco_exit(void) 984static void __exit sco_exit(void)
1051{ 985{
1052 sco_proc_cleanup(); 986 class_remove_file(&bt_class, &class_attr_sco);
1053 987
1054 if (bt_sock_unregister(BTPROTO_SCO) < 0) 988 if (bt_sock_unregister(BTPROTO_SCO) < 0)
1055 BT_ERR("SCO socket unregistration failed"); 989 BT_ERR("SCO socket unregistration failed");
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index db098ff3cd6a..cb530eef0e39 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -194,8 +194,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
194 194
195done: 195done:
196 spin_unlock_bh(&dev->xmit_lock); 196 spin_unlock_bh(&dev->xmit_lock);
197 if (dmi1) 197 kfree(dmi1);
198 kfree(dmi1);
199 return err; 198 return err;
200} 199}
201 200
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 9bed7569ce3f..8700379685e0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -49,6 +49,7 @@
49#include <net/udp.h> 49#include <net/udp.h>
50#include <net/sock.h> 50#include <net/sock.h>
51#include <net/pkt_sched.h> 51#include <net/pkt_sched.h>
52#include <net/netlink.h>
52 53
53DECLARE_MUTEX(rtnl_sem); 54DECLARE_MUTEX(rtnl_sem);
54 55
@@ -462,11 +463,6 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
462 netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_KERNEL); 463 netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_KERNEL);
463} 464}
464 465
465static int rtnetlink_done(struct netlink_callback *cb)
466{
467 return 0;
468}
469
470/* Protected by RTNL sempahore. */ 466/* Protected by RTNL sempahore. */
471static struct rtattr **rta_buf; 467static struct rtattr **rta_buf;
472static int rtattr_max; 468static int rtattr_max;
@@ -524,8 +520,6 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
524 } 520 }
525 521
526 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { 522 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
527 u32 rlen;
528
529 if (link->dumpit == NULL) 523 if (link->dumpit == NULL)
530 link = &(rtnetlink_links[PF_UNSPEC][type]); 524 link = &(rtnetlink_links[PF_UNSPEC][type]);
531 525
@@ -533,14 +527,11 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
533 goto err_inval; 527 goto err_inval;
534 528
535 if ((*errp = netlink_dump_start(rtnl, skb, nlh, 529 if ((*errp = netlink_dump_start(rtnl, skb, nlh,
536 link->dumpit, 530 link->dumpit, NULL)) != 0) {
537 rtnetlink_done)) != 0) {
538 return -1; 531 return -1;
539 } 532 }
540 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 533
541 if (rlen > skb->len) 534 netlink_queue_skip(nlh, skb);
542 rlen = skb->len;
543 skb_pull(skb, rlen);
544 return -1; 535 return -1;
545 } 536 }
546 537
@@ -579,75 +570,13 @@ err_inval:
579 return -1; 570 return -1;
580} 571}
581 572
582/*
583 * Process one packet of messages.
584 * Malformed skbs with wrong lengths of messages are discarded silently.
585 */
586
587static inline int rtnetlink_rcv_skb(struct sk_buff *skb)
588{
589 int err;
590 struct nlmsghdr * nlh;
591
592 while (skb->len >= NLMSG_SPACE(0)) {
593 u32 rlen;
594
595 nlh = (struct nlmsghdr *)skb->data;
596 if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
597 return 0;
598 rlen = NLMSG_ALIGN(nlh->nlmsg_len);
599 if (rlen > skb->len)
600 rlen = skb->len;
601 if (rtnetlink_rcv_msg(skb, nlh, &err)) {
602 /* Not error, but we must interrupt processing here:
603 * Note, that in this case we do not pull message
604 * from skb, it will be processed later.
605 */
606 if (err == 0)
607 return -1;
608 netlink_ack(skb, nlh, err);
609 } else if (nlh->nlmsg_flags&NLM_F_ACK)
610 netlink_ack(skb, nlh, 0);
611 skb_pull(skb, rlen);
612 }
613
614 return 0;
615}
616
617/*
618 * rtnetlink input queue processing routine:
619 * - process as much as there was in the queue upon entry.
620 * - feed skbs to rtnetlink_rcv_skb, until it refuse a message,
621 * that will occur, when a dump started.
622 */
623
624static void rtnetlink_rcv(struct sock *sk, int len) 573static void rtnetlink_rcv(struct sock *sk, int len)
625{ 574{
626 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); 575 unsigned int qlen = 0;
627 576
628 do { 577 do {
629 struct sk_buff *skb;
630
631 rtnl_lock(); 578 rtnl_lock();
632 579 netlink_run_queue(sk, &qlen, &rtnetlink_rcv_msg);
633 if (qlen > skb_queue_len(&sk->sk_receive_queue))
634 qlen = skb_queue_len(&sk->sk_receive_queue);
635
636 for (; qlen; qlen--) {
637 skb = skb_dequeue(&sk->sk_receive_queue);
638 if (rtnetlink_rcv_skb(skb)) {
639 if (skb->len)
640 skb_queue_head(&sk->sk_receive_queue,
641 skb);
642 else {
643 kfree_skb(skb);
644 qlen--;
645 }
646 break;
647 }
648 kfree_skb(skb);
649 }
650
651 up(&rtnl_sem); 580 up(&rtnl_sem);
652 581
653 netdev_run_todo(); 582 netdev_run_todo();
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 95501e40100e..b7d13a4fff48 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -336,6 +336,9 @@ void __kfree_skb(struct sk_buff *skb)
336 } 336 }
337#ifdef CONFIG_NETFILTER 337#ifdef CONFIG_NETFILTER
338 nf_conntrack_put(skb->nfct); 338 nf_conntrack_put(skb->nfct);
339#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
340 nf_conntrack_put_reasm(skb->nfct_reasm);
341#endif
339#ifdef CONFIG_BRIDGE_NETFILTER 342#ifdef CONFIG_BRIDGE_NETFILTER
340 nf_bridge_put(skb->nf_bridge); 343 nf_bridge_put(skb->nf_bridge);
341#endif 344#endif
@@ -414,9 +417,17 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
414 C(nfct); 417 C(nfct);
415 nf_conntrack_get(skb->nfct); 418 nf_conntrack_get(skb->nfct);
416 C(nfctinfo); 419 C(nfctinfo);
420#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
421 C(nfct_reasm);
422 nf_conntrack_get_reasm(skb->nfct_reasm);
423#endif
417#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 424#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
418 C(ipvs_property); 425 C(ipvs_property);
419#endif 426#endif
427#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
428 C(nfct_reasm);
429 nf_conntrack_get_reasm(skb->nfct_reasm);
430#endif
420#ifdef CONFIG_BRIDGE_NETFILTER 431#ifdef CONFIG_BRIDGE_NETFILTER
421 C(nf_bridge); 432 C(nf_bridge);
422 nf_bridge_get(skb->nf_bridge); 433 nf_bridge_get(skb->nf_bridge);
@@ -474,6 +485,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
474 new->nfct = old->nfct; 485 new->nfct = old->nfct;
475 nf_conntrack_get(old->nfct); 486 nf_conntrack_get(old->nfct);
476 new->nfctinfo = old->nfctinfo; 487 new->nfctinfo = old->nfctinfo;
488#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
489 new->nfct_reasm = old->nfct_reasm;
490 nf_conntrack_get_reasm(old->nfct_reasm);
491#endif
477#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 492#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
478 new->ipvs_property = old->ipvs_property; 493 new->ipvs_property = old->ipvs_property;
479#endif 494#endif
diff --git a/net/core/sock.c b/net/core/sock.c
index 9602ceb3bac9..13cc3be4f056 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1242,8 +1242,7 @@ static void sock_def_write_space(struct sock *sk)
1242 1242
1243static void sock_def_destruct(struct sock *sk) 1243static void sock_def_destruct(struct sock *sk)
1244{ 1244{
1245 if (sk->sk_protinfo) 1245 kfree(sk->sk_protinfo);
1246 kfree(sk->sk_protinfo);
1247} 1246}
1248 1247
1249void sk_send_sigurg(struct sock *sk) 1248void sk_send_sigurg(struct sock *sk)
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 4b9bc81ae1a3..ca03521112c5 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1263,10 +1263,8 @@ static int dccp_v4_destroy_sock(struct sock *sk)
1263 if (inet_csk(sk)->icsk_bind_hash != NULL) 1263 if (inet_csk(sk)->icsk_bind_hash != NULL)
1264 inet_put_port(&dccp_hashinfo, sk); 1264 inet_put_port(&dccp_hashinfo, sk);
1265 1265
1266 if (dp->dccps_service_list != NULL) { 1266 kfree(dp->dccps_service_list);
1267 kfree(dp->dccps_service_list); 1267 dp->dccps_service_list = NULL;
1268 dp->dccps_service_list = NULL;
1269 }
1270 1268
1271 ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk); 1269 ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
1272 ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk); 1270 ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index a021c3422f67..e0ace7cbb996 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -238,8 +238,7 @@ static int dccp_setsockopt_service(struct sock *sk, const u32 service,
238 lock_sock(sk); 238 lock_sock(sk);
239 dp->dccps_service = service; 239 dp->dccps_service = service;
240 240
241 if (dp->dccps_service_list != NULL) 241 kfree(dp->dccps_service_list);
242 kfree(dp->dccps_service_list);
243 242
244 dp->dccps_service_list = sl; 243 dp->dccps_service_list = sl;
245 release_sock(sk); 244 release_sock(sk);
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index eeba56f99323..6f8b5658cb4e 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -784,16 +784,14 @@ struct dn_fib_table *dn_fib_get_table(int n, int create)
784 784
785static void dn_fib_del_tree(int n) 785static void dn_fib_del_tree(int n)
786{ 786{
787 struct dn_fib_table *t; 787 struct dn_fib_table *t;
788 788
789 write_lock(&dn_fib_tables_lock); 789 write_lock(&dn_fib_tables_lock);
790 t = dn_fib_tables[n]; 790 t = dn_fib_tables[n];
791 dn_fib_tables[n] = NULL; 791 dn_fib_tables[n] = NULL;
792 write_unlock(&dn_fib_tables_lock); 792 write_unlock(&dn_fib_tables_lock);
793 793
794 if (t) { 794 kfree(t);
795 kfree(t);
796 }
797} 795}
798 796
799struct dn_fib_table *dn_fib_empty_table(void) 797struct dn_fib_table *dn_fib_empty_table(void)
diff --git a/net/ethernet/pe2.c b/net/ethernet/pe2.c
index 98a494be6039..9d57b4fb6440 100644
--- a/net/ethernet/pe2.c
+++ b/net/ethernet/pe2.c
@@ -32,8 +32,7 @@ struct datalink_proto *make_EII_client(void)
32 32
33void destroy_EII_client(struct datalink_proto *dl) 33void destroy_EII_client(struct datalink_proto *dl)
34{ 34{
35 if (dl) 35 kfree(dl);
36 kfree(dl);
37} 36}
38 37
39EXPORT_SYMBOL(destroy_EII_client); 38EXPORT_SYMBOL(destroy_EII_client);
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
index 20cc580a07e0..ecc9bb196abc 100644
--- a/net/ieee80211/ieee80211_crypt.c
+++ b/net/ieee80211/ieee80211_crypt.c
@@ -11,15 +11,14 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/config.h> 14#include <linux/errno.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <asm/string.h> 18#include <linux/string.h>
19#include <asm/errno.h>
20
21#include <net/ieee80211.h> 19#include <net/ieee80211.h>
22 20
21
23MODULE_AUTHOR("Jouni Malinen"); 22MODULE_AUTHOR("Jouni Malinen");
24MODULE_DESCRIPTION("HostAP crypto"); 23MODULE_DESCRIPTION("HostAP crypto");
25MODULE_LICENSE("GPL"); 24MODULE_LICENSE("GPL");
@@ -29,32 +28,20 @@ struct ieee80211_crypto_alg {
29 struct ieee80211_crypto_ops *ops; 28 struct ieee80211_crypto_ops *ops;
30}; 29};
31 30
32struct ieee80211_crypto { 31static LIST_HEAD(ieee80211_crypto_algs);
33 struct list_head algs; 32static DEFINE_SPINLOCK(ieee80211_crypto_lock);
34 spinlock_t lock;
35};
36
37static struct ieee80211_crypto *hcrypt;
38 33
39void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) 34void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
40{ 35{
41 struct list_head *ptr, *n; 36 struct ieee80211_crypt_data *entry, *next;
42 struct ieee80211_crypt_data *entry;
43 unsigned long flags; 37 unsigned long flags;
44 38
45 spin_lock_irqsave(&ieee->lock, flags); 39 spin_lock_irqsave(&ieee->lock, flags);
46 40 list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) {
47 if (list_empty(&ieee->crypt_deinit_list))
48 goto unlock;
49
50 for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
51 ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
52 entry = list_entry(ptr, struct ieee80211_crypt_data, list);
53
54 if (atomic_read(&entry->refcnt) != 0 && !force) 41 if (atomic_read(&entry->refcnt) != 0 && !force)
55 continue; 42 continue;
56 43
57 list_del(ptr); 44 list_del(&entry->list);
58 45
59 if (entry->ops) { 46 if (entry->ops) {
60 entry->ops->deinit(entry->priv); 47 entry->ops->deinit(entry->priv);
@@ -62,7 +49,6 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
62 } 49 }
63 kfree(entry); 50 kfree(entry);
64 } 51 }
65 unlock:
66 spin_unlock_irqrestore(&ieee->lock, flags); 52 spin_unlock_irqrestore(&ieee->lock, flags);
67} 53}
68 54
@@ -125,9 +111,6 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
125 unsigned long flags; 111 unsigned long flags;
126 struct ieee80211_crypto_alg *alg; 112 struct ieee80211_crypto_alg *alg;
127 113
128 if (hcrypt == NULL)
129 return -1;
130
131 alg = kmalloc(sizeof(*alg), GFP_KERNEL); 114 alg = kmalloc(sizeof(*alg), GFP_KERNEL);
132 if (alg == NULL) 115 if (alg == NULL)
133 return -ENOMEM; 116 return -ENOMEM;
@@ -135,9 +118,9 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
135 memset(alg, 0, sizeof(*alg)); 118 memset(alg, 0, sizeof(*alg));
136 alg->ops = ops; 119 alg->ops = ops;
137 120
138 spin_lock_irqsave(&hcrypt->lock, flags); 121 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
139 list_add(&alg->list, &hcrypt->algs); 122 list_add(&alg->list, &ieee80211_crypto_algs);
140 spin_unlock_irqrestore(&hcrypt->lock, flags); 123 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
141 124
142 printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n", 125 printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
143 ops->name); 126 ops->name);
@@ -147,64 +130,49 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
147 130
148int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) 131int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
149{ 132{
133 struct ieee80211_crypto_alg *alg;
150 unsigned long flags; 134 unsigned long flags;
151 struct list_head *ptr;
152 struct ieee80211_crypto_alg *del_alg = NULL;
153
154 if (hcrypt == NULL)
155 return -1;
156
157 spin_lock_irqsave(&hcrypt->lock, flags);
158 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
159 struct ieee80211_crypto_alg *alg =
160 (struct ieee80211_crypto_alg *)ptr;
161 if (alg->ops == ops) {
162 list_del(&alg->list);
163 del_alg = alg;
164 break;
165 }
166 }
167 spin_unlock_irqrestore(&hcrypt->lock, flags);
168 135
169 if (del_alg) { 136 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
170 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " 137 list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
171 "'%s'\n", ops->name); 138 if (alg->ops == ops)
172 kfree(del_alg); 139 goto found;
173 } 140 }
174 141 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
175 return del_alg ? 0 : -1; 142 return -EINVAL;
143
144 found:
145 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
146 "'%s'\n", ops->name);
147 list_del(&alg->list);
148 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
149 kfree(alg);
150 return 0;
176} 151}
177 152
178struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name) 153struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
179{ 154{
155 struct ieee80211_crypto_alg *alg;
180 unsigned long flags; 156 unsigned long flags;
181 struct list_head *ptr; 157
182 struct ieee80211_crypto_alg *found_alg = NULL; 158 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
183 159 list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
184 if (hcrypt == NULL) 160 if (strcmp(alg->ops->name, name) == 0)
185 return NULL; 161 goto found;
186
187 spin_lock_irqsave(&hcrypt->lock, flags);
188 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
189 struct ieee80211_crypto_alg *alg =
190 (struct ieee80211_crypto_alg *)ptr;
191 if (strcmp(alg->ops->name, name) == 0) {
192 found_alg = alg;
193 break;
194 }
195 } 162 }
196 spin_unlock_irqrestore(&hcrypt->lock, flags); 163 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
164 return NULL;
197 165
198 if (found_alg) 166 found:
199 return found_alg->ops; 167 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
200 else 168 return alg->ops;
201 return NULL;
202} 169}
203 170
204static void *ieee80211_crypt_null_init(int keyidx) 171static void *ieee80211_crypt_null_init(int keyidx)
205{ 172{
206 return (void *)1; 173 return (void *)1;
207} 174}
175
208static void ieee80211_crypt_null_deinit(void *priv) 176static void ieee80211_crypt_null_deinit(void *priv)
209{ 177{
210} 178}
@@ -213,56 +181,18 @@ static struct ieee80211_crypto_ops ieee80211_crypt_null = {
213 .name = "NULL", 181 .name = "NULL",
214 .init = ieee80211_crypt_null_init, 182 .init = ieee80211_crypt_null_init,
215 .deinit = ieee80211_crypt_null_deinit, 183 .deinit = ieee80211_crypt_null_deinit,
216 .encrypt_mpdu = NULL,
217 .decrypt_mpdu = NULL,
218 .encrypt_msdu = NULL,
219 .decrypt_msdu = NULL,
220 .set_key = NULL,
221 .get_key = NULL,
222 .extra_mpdu_prefix_len = 0,
223 .extra_mpdu_postfix_len = 0,
224 .owner = THIS_MODULE, 184 .owner = THIS_MODULE,
225}; 185};
226 186
227static int __init ieee80211_crypto_init(void) 187static int __init ieee80211_crypto_init(void)
228{ 188{
229 int ret = -ENOMEM; 189 return ieee80211_register_crypto_ops(&ieee80211_crypt_null);
230
231 hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
232 if (!hcrypt)
233 goto out;
234
235 memset(hcrypt, 0, sizeof(*hcrypt));
236 INIT_LIST_HEAD(&hcrypt->algs);
237 spin_lock_init(&hcrypt->lock);
238
239 ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
240 if (ret < 0) {
241 kfree(hcrypt);
242 hcrypt = NULL;
243 }
244 out:
245 return ret;
246} 190}
247 191
248static void __exit ieee80211_crypto_deinit(void) 192static void __exit ieee80211_crypto_deinit(void)
249{ 193{
250 struct list_head *ptr, *n; 194 ieee80211_unregister_crypto_ops(&ieee80211_crypt_null);
251 195 BUG_ON(!list_empty(&ieee80211_crypto_algs));
252 if (hcrypt == NULL)
253 return;
254
255 for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
256 ptr = n, n = ptr->next) {
257 struct ieee80211_crypto_alg *alg =
258 (struct ieee80211_crypto_alg *)ptr;
259 list_del(ptr);
260 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
261 "'%s' (deinit)\n", alg->ops->name);
262 kfree(alg);
263 }
264
265 kfree(hcrypt);
266} 196}
267 197
268EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); 198EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 6ad88218f573..03efaacbdb73 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -369,6 +369,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
369 /* Put this code here so that we avoid duplicating it in all 369 /* Put this code here so that we avoid duplicating it in all
370 * Rx paths. - Jean II */ 370 * Rx paths. - Jean II */
371#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ 371#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
372#ifdef CONFIG_NET_RADIO
372 /* If spy monitoring on */ 373 /* If spy monitoring on */
373 if (ieee->spy_data.spy_number > 0) { 374 if (ieee->spy_data.spy_number > 0) {
374 struct iw_quality wstats; 375 struct iw_quality wstats;
@@ -395,6 +396,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
395 /* Update spy records */ 396 /* Update spy records */
396 wireless_spy_update(ieee->dev, hdr->addr2, &wstats); 397 wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
397 } 398 }
399#endif /* CONFIG_NET_RADIO */
398#endif /* IW_WIRELESS_SPY */ 400#endif /* IW_WIRELESS_SPY */
399 401
400#ifdef NOT_YET 402#ifdef NOT_YET
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 1ce7af9bec35..181755f2aa8b 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -161,9 +161,11 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
161 (ieee->perfect_rssi - ieee->worst_rssi) - 161 (ieee->perfect_rssi - ieee->worst_rssi) -
162 (ieee->perfect_rssi - network->stats.rssi) * 162 (ieee->perfect_rssi - network->stats.rssi) *
163 (15 * (ieee->perfect_rssi - ieee->worst_rssi) + 163 (15 * (ieee->perfect_rssi - ieee->worst_rssi) +
164 62 * (ieee->perfect_rssi - network->stats.rssi))) / 164 62 * (ieee->perfect_rssi -
165 ((ieee->perfect_rssi - ieee->worst_rssi) * 165 network->stats.rssi))) /
166 (ieee->perfect_rssi - ieee->worst_rssi)); 166 ((ieee->perfect_rssi -
167 ieee->worst_rssi) * (ieee->perfect_rssi -
168 ieee->worst_rssi));
167 if (iwe.u.qual.qual > 100) 169 if (iwe.u.qual.qual > 100)
168 iwe.u.qual.qual = 100; 170 iwe.u.qual.qual = 100;
169 else if (iwe.u.qual.qual < 1) 171 else if (iwe.u.qual.qual < 1)
@@ -520,7 +522,8 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
520 crypt = &ieee->crypt[idx]; 522 crypt = &ieee->crypt[idx];
521 group_key = 1; 523 group_key = 1;
522 } else { 524 } else {
523 if (idx != 0) 525 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
526 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
524 return -EINVAL; 527 return -EINVAL;
525 if (ieee->iw_mode == IW_MODE_INFRA) 528 if (ieee->iw_mode == IW_MODE_INFRA)
526 crypt = &ieee->crypt[idx]; 529 crypt = &ieee->crypt[idx];
@@ -688,7 +691,8 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
688 } else 691 } else
689 idx = ieee->tx_keyidx; 692 idx = ieee->tx_keyidx;
690 693
691 if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) 694 if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
695 ext->alg != IW_ENCODE_ALG_WEP)
692 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA) 696 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
693 return -EINVAL; 697 return -EINVAL;
694 698
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index a9d84f93442c..eaa150c33b04 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -147,8 +147,7 @@ void inet_sock_destruct(struct sock *sk)
147 BUG_TRAP(!sk->sk_wmem_queued); 147 BUG_TRAP(!sk->sk_wmem_queued);
148 BUG_TRAP(!sk->sk_forward_alloc); 148 BUG_TRAP(!sk->sk_forward_alloc);
149 149
150 if (inet->opt) 150 kfree(inet->opt);
151 kfree(inet->opt);
152 dst_release(sk->sk_dst_cache); 151 dst_release(sk->sk_dst_cache);
153 sk_refcnt_debug_dec(sk); 152 sk_refcnt_debug_dec(sk);
154} 153}
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 990633c09dfe..2267c1fad879 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -266,8 +266,7 @@ int ip_rt_ioctl(unsigned int cmd, void __user *arg)
266 if (tb) 266 if (tb)
267 err = tb->tb_insert(tb, &req.rtm, &rta, &req.nlh, NULL); 267 err = tb->tb_insert(tb, &req.rtm, &rta, &req.nlh, NULL);
268 } 268 }
269 if (rta.rta_mx) 269 kfree(rta.rta_mx);
270 kfree(rta.rta_mx);
271 } 270 }
272 rtnl_unlock(); 271 rtnl_unlock();
273 return err; 272 return err;
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 71f3c7350c6e..39061ed53cfd 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -724,12 +724,6 @@ done:
724 return skb->len; 724 return skb->len;
725} 725}
726 726
727static int inet_diag_dump_done(struct netlink_callback *cb)
728{
729 return 0;
730}
731
732
733static __inline__ int 727static __inline__ int
734inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) 728inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
735{ 729{
@@ -760,8 +754,7 @@ inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
760 goto err_inval; 754 goto err_inval;
761 } 755 }
762 return netlink_dump_start(idiagnl, skb, nlh, 756 return netlink_dump_start(idiagnl, skb, nlh,
763 inet_diag_dump, 757 inet_diag_dump, NULL);
764 inet_diag_dump_done);
765 } else { 758 } else {
766 return inet_diag_get_exact(skb, nlh); 759 return inet_diag_get_exact(skb, nlh);
767 } 760 }
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index bce4e875193b..dbe12da8d8b3 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -510,8 +510,7 @@ static int ip_options_get_finish(struct ip_options **optp,
510 kfree(opt); 510 kfree(opt);
511 return -EINVAL; 511 return -EINVAL;
512 } 512 }
513 if (*optp) 513 kfree(*optp);
514 kfree(*optp);
515 *optp = opt; 514 *optp = opt;
516 return 0; 515 return 0;
517} 516}
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 17758234a3e3..11c2f68254f0 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -353,7 +353,8 @@ packet_routed:
353 ip_options_build(skb, opt, inet->daddr, rt, 0); 353 ip_options_build(skb, opt, inet->daddr, rt, 0);
354 } 354 }
355 355
356 ip_select_ident_more(iph, &rt->u.dst, sk, skb_shinfo(skb)->tso_segs); 356 ip_select_ident_more(iph, &rt->u.dst, sk,
357 (skb_shinfo(skb)->tso_segs ?: 1) - 1);
357 358
358 /* Add an IP checksum. */ 359 /* Add an IP checksum. */
359 ip_send_check(iph); 360 ip_send_check(iph);
@@ -1262,10 +1263,8 @@ int ip_push_pending_frames(struct sock *sk)
1262 1263
1263out: 1264out:
1264 inet->cork.flags &= ~IPCORK_OPT; 1265 inet->cork.flags &= ~IPCORK_OPT;
1265 if (inet->cork.opt) { 1266 kfree(inet->cork.opt);
1266 kfree(inet->cork.opt); 1267 inet->cork.opt = NULL;
1267 inet->cork.opt = NULL;
1268 }
1269 if (inet->cork.rt) { 1268 if (inet->cork.rt) {
1270 ip_rt_put(inet->cork.rt); 1269 ip_rt_put(inet->cork.rt);
1271 inet->cork.rt = NULL; 1270 inet->cork.rt = NULL;
@@ -1289,10 +1288,8 @@ void ip_flush_pending_frames(struct sock *sk)
1289 kfree_skb(skb); 1288 kfree_skb(skb);
1290 1289
1291 inet->cork.flags &= ~IPCORK_OPT; 1290 inet->cork.flags &= ~IPCORK_OPT;
1292 if (inet->cork.opt) { 1291 kfree(inet->cork.opt);
1293 kfree(inet->cork.opt); 1292 inet->cork.opt = NULL;
1294 inet->cork.opt = NULL;
1295 }
1296 if (inet->cork.rt) { 1293 if (inet->cork.rt) {
1297 ip_rt_put(inet->cork.rt); 1294 ip_rt_put(inet->cork.rt);
1298 inet->cork.rt = NULL; 1295 inet->cork.rt = NULL;
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 2f0b47da5b37..4f2d87257309 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -202,8 +202,7 @@ int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct s
202 if (ra->sk == sk) { 202 if (ra->sk == sk) {
203 if (on) { 203 if (on) {
204 write_unlock_bh(&ip_ra_lock); 204 write_unlock_bh(&ip_ra_lock);
205 if (new_ra) 205 kfree(new_ra);
206 kfree(new_ra);
207 return -EADDRINUSE; 206 return -EADDRINUSE;
208 } 207 }
209 *rap = ra->next; 208 *rap = ra->next;
@@ -446,8 +445,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
446#endif 445#endif
447 } 446 }
448 opt = xchg(&inet->opt, opt); 447 opt = xchg(&inet->opt, opt);
449 if (opt) 448 kfree(opt);
450 kfree(opt);
451 break; 449 break;
452 } 450 }
453 case IP_PKTINFO: 451 case IP_PKTINFO:
@@ -828,10 +826,8 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
828 826
829 err = ip_mc_msfilter(sk, msf, ifindex); 827 err = ip_mc_msfilter(sk, msf, ifindex);
830mc_msf_out: 828mc_msf_out:
831 if (msf) 829 kfree(msf);
832 kfree(msf); 830 kfree(gsf);
833 if (gsf)
834 kfree(gsf);
835 break; 831 break;
836 } 832 }
837 case IP_ROUTER_ALERT: 833 case IP_ROUTER_ALERT:
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index fc6f95aaa969..d7eb680101c2 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -110,8 +110,7 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port)
110 return 0; 110 return 0;
111 111
112 out: 112 out:
113 if (inc->timeout_table) 113 kfree(inc->timeout_table);
114 kfree(inc->timeout_table);
115 kfree(inc); 114 kfree(inc);
116 return ret; 115 return ret;
117} 116}
@@ -136,8 +135,7 @@ ip_vs_app_inc_release(struct ip_vs_app *inc)
136 135
137 list_del(&inc->a_list); 136 list_del(&inc->a_list);
138 137
139 if (inc->timeout_table != NULL) 138 kfree(inc->timeout_table);
140 kfree(inc->timeout_table);
141 kfree(inc); 139 kfree(inc);
142} 140}
143 141
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 981cc3244ef2..1a0843cd58a9 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -1009,11 +1009,10 @@ ip_vs_in(unsigned int hooknum, struct sk_buff **pskb,
1009 if (sysctl_ip_vs_expire_nodest_conn) { 1009 if (sysctl_ip_vs_expire_nodest_conn) {
1010 /* try to expire the connection immediately */ 1010 /* try to expire the connection immediately */
1011 ip_vs_conn_expire_now(cp); 1011 ip_vs_conn_expire_now(cp);
1012 } else {
1013 /* don't restart its timer, and silently
1014 drop the packet. */
1015 __ip_vs_conn_put(cp);
1016 } 1012 }
1013 /* don't restart its timer, and silently
1014 drop the packet. */
1015 __ip_vs_conn_put(cp);
1017 return NF_DROP; 1016 return NF_DROP;
1018 } 1017 }
1019 1018
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index bd7d75b6abe0..d34a9fa608e0 100644
--- a/net/ipv4/multipath_wrandom.c
+++ b/net/ipv4/multipath_wrandom.c
@@ -207,16 +207,12 @@ static void wrandom_select_route(const struct flowi *flp,
207 decision = mpc->rt; 207 decision = mpc->rt;
208 208
209 last_power = mpc->power; 209 last_power = mpc->power;
210 if (last_mpc) 210 kfree(last_mpc);
211 kfree(last_mpc);
212
213 last_mpc = mpc; 211 last_mpc = mpc;
214 } 212 }
215 213
216 if (last_mpc) { 214 /* concurrent __multipath_flush may lead to !last_mpc */
217 /* concurrent __multipath_flush may lead to !last_mpc */ 215 kfree(last_mpc);
218 kfree(last_mpc);
219 }
220 216
221 decision->u.dst.__use++; 217 decision->u.dst.__use++;
222 *rp = decision; 218 *rp = decision;
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 7d917e4ce1d9..9d3c8b5f327e 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -5,6 +5,20 @@
5menu "IP: Netfilter Configuration" 5menu "IP: Netfilter Configuration"
6 depends on INET && NETFILTER 6 depends on INET && NETFILTER
7 7
8config NF_CONNTRACK_IPV4
9 tristate "IPv4 support for new connection tracking (EXPERIMENTAL)"
10 depends on EXPERIMENTAL && NF_CONNTRACK
11 ---help---
12 Connection tracking keeps a record of what packets have passed
13 through your machine, in order to figure out how they are related
14 into connections.
15
16 This is IPv4 support on Layer 3 independent connection tracking.
17 Layer 3 independent connection tracking is experimental scheme
18 which generalize ip_conntrack to support other layer 3 protocols.
19
20 To compile it as a module, choose M here. If unsure, say N.
21
8# connection tracking, helpers and protocols 22# connection tracking, helpers and protocols
9config IP_NF_CONNTRACK 23config IP_NF_CONNTRACK
10 tristate "Connection tracking (required for masq/NAT)" 24 tristate "Connection tracking (required for masq/NAT)"
@@ -209,8 +223,8 @@ config IP_NF_MATCH_PKTTYPE
209 tristate "Packet type match support" 223 tristate "Packet type match support"
210 depends on IP_NF_IPTABLES 224 depends on IP_NF_IPTABLES
211 help 225 help
212 Packet type matching allows you to match a packet by 226 Packet type matching allows you to match a packet by
213 its "class", eg. BROADCAST, MULTICAST, ... 227 its "class", eg. BROADCAST, MULTICAST, ...
214 228
215 Typical usage: 229 Typical usage:
216 iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG 230 iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG
@@ -317,7 +331,8 @@ config IP_NF_MATCH_TCPMSS
317 331
318config IP_NF_MATCH_HELPER 332config IP_NF_MATCH_HELPER
319 tristate "Helper match support" 333 tristate "Helper match support"
320 depends on IP_NF_CONNTRACK && IP_NF_IPTABLES 334 depends on IP_NF_IPTABLES
335 depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
321 help 336 help
322 Helper matching allows you to match packets in dynamic connections 337 Helper matching allows you to match packets in dynamic connections
323 tracked by a conntrack-helper, ie. ip_conntrack_ftp 338 tracked by a conntrack-helper, ie. ip_conntrack_ftp
@@ -326,7 +341,8 @@ config IP_NF_MATCH_HELPER
326 341
327config IP_NF_MATCH_STATE 342config IP_NF_MATCH_STATE
328 tristate "Connection state match support" 343 tristate "Connection state match support"
329 depends on IP_NF_CONNTRACK && IP_NF_IPTABLES 344 depends on IP_NF_IPTABLES
345 depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
330 help 346 help
331 Connection state matching allows you to match packets based on their 347 Connection state matching allows you to match packets based on their
332 relationship to a tracked connection (ie. previous packets). This 348 relationship to a tracked connection (ie. previous packets). This
@@ -336,7 +352,8 @@ config IP_NF_MATCH_STATE
336 352
337config IP_NF_MATCH_CONNTRACK 353config IP_NF_MATCH_CONNTRACK
338 tristate "Connection tracking match support" 354 tristate "Connection tracking match support"
339 depends on IP_NF_CONNTRACK && IP_NF_IPTABLES 355 depends on IP_NF_IPTABLES
356 depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
340 help 357 help
341 This is a general conntrack match module, a superset of the state match. 358 This is a general conntrack match module, a superset of the state match.
342 359
@@ -422,7 +439,8 @@ config IP_NF_MATCH_COMMENT
422 439
423config IP_NF_MATCH_CONNMARK 440config IP_NF_MATCH_CONNMARK
424 tristate 'Connection mark match support' 441 tristate 'Connection mark match support'
425 depends on IP_NF_CONNTRACK_MARK && IP_NF_IPTABLES 442 depends on IP_NF_IPTABLES
443 depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
426 help 444 help
427 This option adds a `connmark' match, which allows you to match the 445 This option adds a `connmark' match, which allows you to match the
428 connection mark value previously set for the session by `CONNMARK'. 446 connection mark value previously set for the session by `CONNMARK'.
@@ -433,7 +451,8 @@ config IP_NF_MATCH_CONNMARK
433 451
434config IP_NF_MATCH_CONNBYTES 452config IP_NF_MATCH_CONNBYTES
435 tristate 'Connection byte/packet counter match support' 453 tristate 'Connection byte/packet counter match support'
436 depends on IP_NF_CT_ACCT && IP_NF_IPTABLES 454 depends on IP_NF_IPTABLES
455 depends on IP_NF_CT_ACCT || (NF_CT_ACCT && NF_CONNTRACK_IPV4)
437 help 456 help
438 This option adds a `connbytes' match, which allows you to match the 457 This option adds a `connbytes' match, which allows you to match the
439 number of bytes and/or packets for each direction within a connection. 458 number of bytes and/or packets for each direction within a connection.
@@ -747,7 +766,8 @@ config IP_NF_TARGET_TTL
747 766
748config IP_NF_TARGET_CONNMARK 767config IP_NF_TARGET_CONNMARK
749 tristate 'CONNMARK target support' 768 tristate 'CONNMARK target support'
750 depends on IP_NF_CONNTRACK_MARK && IP_NF_MANGLE 769 depends on IP_NF_MANGLE
770 depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
751 help 771 help
752 This option adds a `CONNMARK' target, which allows one to manipulate 772 This option adds a `CONNMARK' target, which allows one to manipulate
753 the connection mark value. Similar to the MARK target, but 773 the connection mark value. Similar to the MARK target, but
@@ -759,7 +779,8 @@ config IP_NF_TARGET_CONNMARK
759 779
760config IP_NF_TARGET_CLUSTERIP 780config IP_NF_TARGET_CLUSTERIP
761 tristate "CLUSTERIP target support (EXPERIMENTAL)" 781 tristate "CLUSTERIP target support (EXPERIMENTAL)"
762 depends on IP_NF_CONNTRACK_MARK && IP_NF_IPTABLES && EXPERIMENTAL 782 depends on IP_NF_IPTABLES && EXPERIMENTAL
783 depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
763 help 784 help
764 The CLUSTERIP target allows you to build load-balancing clusters of 785 The CLUSTERIP target allows you to build load-balancing clusters of
765 network servers without having a dedicated load-balancing 786 network servers without having a dedicated load-balancing
@@ -782,7 +803,7 @@ config IP_NF_RAW
782config IP_NF_TARGET_NOTRACK 803config IP_NF_TARGET_NOTRACK
783 tristate 'NOTRACK target support' 804 tristate 'NOTRACK target support'
784 depends on IP_NF_RAW 805 depends on IP_NF_RAW
785 depends on IP_NF_CONNTRACK 806 depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4
786 help 807 help
787 The NOTRACK target allows a select rule to specify 808 The NOTRACK target allows a select rule to specify
788 which packets *not* to enter the conntrack/NAT 809 which packets *not* to enter the conntrack/NAT
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index dab4b58dd31e..058c48e258fc 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -103,3 +103,9 @@ obj-$(CONFIG_IP_NF_ARP_MANGLE) += arpt_mangle.o
103obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o 103obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o
104 104
105obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o 105obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o
106
107# objects for l3 independent conntrack
108nf_conntrack_ipv4-objs := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o
109
110# l3 independent conntrack
111obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 82a65043a8ef..d2a4fec22862 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -28,11 +28,8 @@
28#include <linux/netlink.h> 28#include <linux/netlink.h>
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/notifier.h> 30#include <linux/notifier.h>
31#include <linux/rtnetlink.h>
32 31
33#include <linux/netfilter.h> 32#include <linux/netfilter.h>
34#include <linux/netfilter_ipv4.h>
35#include <linux/netfilter_ipv4/ip_tables.h>
36#include <linux/netfilter_ipv4/ip_conntrack.h> 33#include <linux/netfilter_ipv4/ip_conntrack.h>
37#include <linux/netfilter_ipv4/ip_conntrack_core.h> 34#include <linux/netfilter_ipv4/ip_conntrack_core.h>
38#include <linux/netfilter_ipv4/ip_conntrack_helper.h> 35#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
@@ -58,14 +55,17 @@ ctnetlink_dump_tuples_proto(struct sk_buff *skb,
58 const struct ip_conntrack_tuple *tuple) 55 const struct ip_conntrack_tuple *tuple)
59{ 56{
60 struct ip_conntrack_protocol *proto; 57 struct ip_conntrack_protocol *proto;
58 int ret = 0;
61 59
62 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); 60 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
63 61
64 proto = ip_conntrack_proto_find_get(tuple->dst.protonum); 62 proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
65 if (proto && proto->tuple_to_nfattr) 63 if (likely(proto && proto->tuple_to_nfattr)) {
66 return proto->tuple_to_nfattr(skb, tuple); 64 ret = proto->tuple_to_nfattr(skb, tuple);
65 ip_conntrack_proto_put(proto);
66 }
67 67
68 return 0; 68 return ret;
69 69
70nfattr_failure: 70nfattr_failure:
71 return -1; 71 return -1;
@@ -175,7 +175,7 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct ip_conntrack *ct,
175{ 175{
176 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG; 176 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
177 struct nfattr *nest_count = NFA_NEST(skb, type); 177 struct nfattr *nest_count = NFA_NEST(skb, type);
178 u_int64_t tmp; 178 u_int32_t tmp;
179 179
180 tmp = htonl(ct->counters[dir].packets); 180 tmp = htonl(ct->counters[dir].packets);
181 NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp); 181 NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
@@ -479,9 +479,7 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
479 479
480 DEBUGP("entered %s\n", __FUNCTION__); 480 DEBUGP("entered %s\n", __FUNCTION__);
481 481
482 482 nfattr_parse_nested(tb, CTA_IP_MAX, attr);
483 if (nfattr_parse_nested(tb, CTA_IP_MAX, attr) < 0)
484 goto nfattr_failure;
485 483
486 if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) 484 if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
487 return -EINVAL; 485 return -EINVAL;
@@ -497,9 +495,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
497 DEBUGP("leaving\n"); 495 DEBUGP("leaving\n");
498 496
499 return 0; 497 return 0;
500
501nfattr_failure:
502 return -1;
503} 498}
504 499
505static const int cta_min_proto[CTA_PROTO_MAX] = { 500static const int cta_min_proto[CTA_PROTO_MAX] = {
@@ -521,8 +516,7 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
521 516
522 DEBUGP("entered %s\n", __FUNCTION__); 517 DEBUGP("entered %s\n", __FUNCTION__);
523 518
524 if (nfattr_parse_nested(tb, CTA_PROTO_MAX, attr) < 0) 519 nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
525 goto nfattr_failure;
526 520
527 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) 521 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
528 return -EINVAL; 522 return -EINVAL;
@@ -539,9 +533,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
539 } 533 }
540 534
541 return ret; 535 return ret;
542
543nfattr_failure:
544 return -1;
545} 536}
546 537
547static inline int 538static inline int
@@ -555,8 +546,7 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
555 546
556 memset(tuple, 0, sizeof(*tuple)); 547 memset(tuple, 0, sizeof(*tuple));
557 548
558 if (nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]) < 0) 549 nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
559 goto nfattr_failure;
560 550
561 if (!tb[CTA_TUPLE_IP-1]) 551 if (!tb[CTA_TUPLE_IP-1])
562 return -EINVAL; 552 return -EINVAL;
@@ -583,9 +573,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
583 DEBUGP("leaving\n"); 573 DEBUGP("leaving\n");
584 574
585 return 0; 575 return 0;
586
587nfattr_failure:
588 return -1;
589} 576}
590 577
591#ifdef CONFIG_IP_NF_NAT_NEEDED 578#ifdef CONFIG_IP_NF_NAT_NEEDED
@@ -603,11 +590,10 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
603 590
604 DEBUGP("entered %s\n", __FUNCTION__); 591 DEBUGP("entered %s\n", __FUNCTION__);
605 592
606 if (nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr) < 0) 593 nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
607 goto nfattr_failure;
608 594
609 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) 595 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
610 goto nfattr_failure; 596 return -EINVAL;
611 597
612 npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); 598 npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
613 if (!npt) 599 if (!npt)
@@ -626,9 +612,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
626 612
627 DEBUGP("leaving\n"); 613 DEBUGP("leaving\n");
628 return 0; 614 return 0;
629
630nfattr_failure:
631 return -1;
632} 615}
633 616
634static inline int 617static inline int
@@ -642,8 +625,7 @@ ctnetlink_parse_nat(struct nfattr *cda[],
642 625
643 memset(range, 0, sizeof(*range)); 626 memset(range, 0, sizeof(*range));
644 627
645 if (nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]) < 0) 628 nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]);
646 goto nfattr_failure;
647 629
648 if (tb[CTA_NAT_MINIP-1]) 630 if (tb[CTA_NAT_MINIP-1])
649 range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]); 631 range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
@@ -665,9 +647,6 @@ ctnetlink_parse_nat(struct nfattr *cda[],
665 647
666 DEBUGP("leaving\n"); 648 DEBUGP("leaving\n");
667 return 0; 649 return 0;
668
669nfattr_failure:
670 return -1;
671} 650}
672#endif 651#endif
673 652
@@ -678,8 +657,7 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
678 657
679 DEBUGP("entered %s\n", __FUNCTION__); 658 DEBUGP("entered %s\n", __FUNCTION__);
680 659
681 if (nfattr_parse_nested(tb, CTA_HELP_MAX, attr) < 0) 660 nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
682 goto nfattr_failure;
683 661
684 if (!tb[CTA_HELP_NAME-1]) 662 if (!tb[CTA_HELP_NAME-1])
685 return -EINVAL; 663 return -EINVAL;
@@ -687,9 +665,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
687 *helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]); 665 *helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]);
688 666
689 return 0; 667 return 0;
690
691nfattr_failure:
692 return -1;
693} 668}
694 669
695static int 670static int
@@ -804,7 +779,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
804 ct = tuplehash_to_ctrack(h); 779 ct = tuplehash_to_ctrack(h);
805 780
806 err = -ENOMEM; 781 err = -ENOMEM;
807 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); 782 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
808 if (!skb2) { 783 if (!skb2) {
809 ip_conntrack_put(ct); 784 ip_conntrack_put(ct);
810 return -ENOMEM; 785 return -ENOMEM;
@@ -827,7 +802,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
827free: 802free:
828 kfree_skb(skb2); 803 kfree_skb(skb2);
829out: 804out:
830 return -1; 805 return err;
831} 806}
832 807
833static inline int 808static inline int
@@ -957,8 +932,7 @@ ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
957 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; 932 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
958 int err = 0; 933 int err = 0;
959 934
960 if (nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr) < 0) 935 nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
961 goto nfattr_failure;
962 936
963 proto = ip_conntrack_proto_find_get(npt); 937 proto = ip_conntrack_proto_find_get(npt);
964 if (!proto) 938 if (!proto)
@@ -969,9 +943,6 @@ ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
969 ip_conntrack_proto_put(proto); 943 ip_conntrack_proto_put(proto);
970 944
971 return err; 945 return err;
972
973nfattr_failure:
974 return -ENOMEM;
975} 946}
976 947
977static int 948static int
@@ -1005,6 +976,11 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
1005 return err; 976 return err;
1006 } 977 }
1007 978
979#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
980 if (cda[CTA_MARK-1])
981 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
982#endif
983
1008 DEBUGP("all done\n"); 984 DEBUGP("all done\n");
1009 return 0; 985 return 0;
1010} 986}
@@ -1048,6 +1024,11 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
1048 if (ct->helper) 1024 if (ct->helper)
1049 ip_conntrack_helper_put(ct->helper); 1025 ip_conntrack_helper_put(ct->helper);
1050 1026
1027#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
1028 if (cda[CTA_MARK-1])
1029 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
1030#endif
1031
1051 DEBUGP("conntrack with id %u inserted\n", ct->id); 1032 DEBUGP("conntrack with id %u inserted\n", ct->id);
1052 return 0; 1033 return 0;
1053 1034
@@ -1312,6 +1293,14 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1312 if (!exp) 1293 if (!exp)
1313 return -ENOENT; 1294 return -ENOENT;
1314 1295
1296 if (cda[CTA_EXPECT_ID-1]) {
1297 u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
1298 if (exp->id != ntohl(id)) {
1299 ip_conntrack_expect_put(exp);
1300 return -ENOENT;
1301 }
1302 }
1303
1315 err = -ENOMEM; 1304 err = -ENOMEM;
1316 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 1305 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1317 if (!skb2) 1306 if (!skb2)
@@ -1387,7 +1376,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1387 ip_conntrack_expect_put(exp); 1376 ip_conntrack_expect_put(exp);
1388 } 1377 }
1389 } 1378 }
1390 write_unlock(&ip_conntrack_lock); 1379 write_unlock_bh(&ip_conntrack_lock);
1391 } else { 1380 } else {
1392 /* This basically means we have to flush everything*/ 1381 /* This basically means we have to flush everything*/
1393 write_lock_bh(&ip_conntrack_lock); 1382 write_lock_bh(&ip_conntrack_lock);
@@ -1554,6 +1543,8 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
1554 .cb = ctnl_exp_cb, 1543 .cb = ctnl_exp_cb,
1555}; 1544};
1556 1545
1546MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
1547
1557static int __init ctnetlink_init(void) 1548static int __init ctnetlink_init(void)
1558{ 1549{
1559 int ret; 1550 int ret;
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index 98f0015dd255..5198f3a1e2cd 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -151,13 +151,13 @@ icmp_error_message(struct sk_buff *skb,
151 /* Not enough header? */ 151 /* Not enough header? */
152 inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in); 152 inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
153 if (inside == NULL) 153 if (inside == NULL)
154 return NF_ACCEPT; 154 return -NF_ACCEPT;
155 155
156 /* Ignore ICMP's containing fragments (shouldn't happen) */ 156 /* Ignore ICMP's containing fragments (shouldn't happen) */
157 if (inside->ip.frag_off & htons(IP_OFFSET)) { 157 if (inside->ip.frag_off & htons(IP_OFFSET)) {
158 DEBUGP("icmp_error_track: fragment of proto %u\n", 158 DEBUGP("icmp_error_track: fragment of proto %u\n",
159 inside->ip.protocol); 159 inside->ip.protocol);
160 return NF_ACCEPT; 160 return -NF_ACCEPT;
161 } 161 }
162 162
163 innerproto = ip_conntrack_proto_find_get(inside->ip.protocol); 163 innerproto = ip_conntrack_proto_find_get(inside->ip.protocol);
@@ -166,7 +166,7 @@ icmp_error_message(struct sk_buff *skb,
166 if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) { 166 if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) {
167 DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol); 167 DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol);
168 ip_conntrack_proto_put(innerproto); 168 ip_conntrack_proto_put(innerproto);
169 return NF_ACCEPT; 169 return -NF_ACCEPT;
170 } 170 }
171 171
172 /* Ordinarily, we'd expect the inverted tupleproto, but it's 172 /* Ordinarily, we'd expect the inverted tupleproto, but it's
@@ -174,7 +174,7 @@ icmp_error_message(struct sk_buff *skb,
174 if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) { 174 if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) {
175 DEBUGP("icmp_error_track: Can't invert tuple\n"); 175 DEBUGP("icmp_error_track: Can't invert tuple\n");
176 ip_conntrack_proto_put(innerproto); 176 ip_conntrack_proto_put(innerproto);
177 return NF_ACCEPT; 177 return -NF_ACCEPT;
178 } 178 }
179 ip_conntrack_proto_put(innerproto); 179 ip_conntrack_proto_put(innerproto);
180 180
@@ -190,7 +190,7 @@ icmp_error_message(struct sk_buff *skb,
190 190
191 if (!h) { 191 if (!h) {
192 DEBUGP("icmp_error_track: no match\n"); 192 DEBUGP("icmp_error_track: no match\n");
193 return NF_ACCEPT; 193 return -NF_ACCEPT;
194 } 194 }
195 /* Reverse direction from that found */ 195 /* Reverse direction from that found */
196 if (DIRECTION(h) != IP_CT_DIR_REPLY) 196 if (DIRECTION(h) != IP_CT_DIR_REPLY)
@@ -296,7 +296,8 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
296 struct ip_conntrack_tuple *tuple) 296 struct ip_conntrack_tuple *tuple)
297{ 297{
298 if (!tb[CTA_PROTO_ICMP_TYPE-1] 298 if (!tb[CTA_PROTO_ICMP_TYPE-1]
299 || !tb[CTA_PROTO_ICMP_CODE-1]) 299 || !tb[CTA_PROTO_ICMP_CODE-1]
300 || !tb[CTA_PROTO_ICMP_ID-1])
300 return -1; 301 return -1;
301 302
302 tuple->dst.u.icmp.type = 303 tuple->dst.u.icmp.type =
@@ -304,7 +305,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
304 tuple->dst.u.icmp.code = 305 tuple->dst.u.icmp.code =
305 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]); 306 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
306 tuple->src.u.icmp.id = 307 tuple->src.u.icmp.id =
307 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); 308 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
308 309
309 return 0; 310 return 0;
310} 311}
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index d6701cafbcc2..468c6003b4c7 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -362,8 +362,12 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
362 struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1]; 362 struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
363 struct nfattr *tb[CTA_PROTOINFO_TCP_MAX]; 363 struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
364 364
365 if (nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr) < 0) 365 /* updates could not contain anything about the private
366 goto nfattr_failure; 366 * protocol info, in that case skip the parsing */
367 if (!attr)
368 return 0;
369
370 nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
367 371
368 if (!tb[CTA_PROTOINFO_TCP_STATE-1]) 372 if (!tb[CTA_PROTOINFO_TCP_STATE-1])
369 return -EINVAL; 373 return -EINVAL;
@@ -374,9 +378,6 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
374 write_unlock_bh(&tcp_lock); 378 write_unlock_bh(&tcp_lock);
375 379
376 return 0; 380 return 0;
377
378nfattr_failure:
379 return -1;
380} 381}
381#endif 382#endif
382 383
diff --git a/net/ipv4/netfilter/ip_nat_helper_pptp.c b/net/ipv4/netfilter/ip_nat_helper_pptp.c
index ee6ab74ad3a9..e546203f5662 100644
--- a/net/ipv4/netfilter/ip_nat_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_nat_helper_pptp.c
@@ -73,6 +73,7 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
73 struct ip_conntrack_tuple t; 73 struct ip_conntrack_tuple t;
74 struct ip_ct_pptp_master *ct_pptp_info; 74 struct ip_ct_pptp_master *ct_pptp_info;
75 struct ip_nat_pptp *nat_pptp_info; 75 struct ip_nat_pptp *nat_pptp_info;
76 struct ip_nat_range range;
76 77
77 ct_pptp_info = &master->help.ct_pptp_info; 78 ct_pptp_info = &master->help.ct_pptp_info;
78 nat_pptp_info = &master->nat.help.nat_pptp_info; 79 nat_pptp_info = &master->nat.help.nat_pptp_info;
@@ -110,7 +111,30 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
110 DEBUGP("not found!\n"); 111 DEBUGP("not found!\n");
111 } 112 }
112 113
113 ip_nat_follow_master(ct, exp); 114 /* This must be a fresh one. */
115 BUG_ON(ct->status & IPS_NAT_DONE_MASK);
116
117 /* Change src to where master sends to */
118 range.flags = IP_NAT_RANGE_MAP_IPS;
119 range.min_ip = range.max_ip
120 = ct->master->tuplehash[!exp->dir].tuple.dst.ip;
121 if (exp->dir == IP_CT_DIR_ORIGINAL) {
122 range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
123 range.min = range.max = exp->saved_proto;
124 }
125 /* hook doesn't matter, but it has to do source manip */
126 ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
127
128 /* For DST manip, map port here to where it's expected. */
129 range.flags = IP_NAT_RANGE_MAP_IPS;
130 range.min_ip = range.max_ip
131 = ct->master->tuplehash[!exp->dir].tuple.src.ip;
132 if (exp->dir == IP_CT_DIR_REPLY) {
133 range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
134 range.min = range.max = exp->saved_proto;
135 }
136 /* hook doesn't matter, but it has to do destination manip */
137 ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
114} 138}
115 139
116/* outbound packets == from PNS to PAC */ 140/* outbound packets == from PNS to PAC */
@@ -213,7 +237,7 @@ pptp_exp_gre(struct ip_conntrack_expect *expect_orig,
213 237
214 /* alter expectation for PNS->PAC direction */ 238 /* alter expectation for PNS->PAC direction */
215 invert_tuplepr(&inv_t, &expect_orig->tuple); 239 invert_tuplepr(&inv_t, &expect_orig->tuple);
216 expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id); 240 expect_orig->saved_proto.gre.key = htons(ct_pptp_info->pns_call_id);
217 expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id); 241 expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
218 expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id); 242 expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
219 expect_orig->dir = IP_CT_DIR_ORIGINAL; 243 expect_orig->dir = IP_CT_DIR_ORIGINAL;
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
index 93b2c5111bb2..8acb7ed40b47 100644
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -1161,8 +1161,7 @@ static int snmp_parse_mangle(unsigned char *msg,
1161 1161
1162 if (!snmp_object_decode(&ctx, obj)) { 1162 if (!snmp_object_decode(&ctx, obj)) {
1163 if (*obj) { 1163 if (*obj) {
1164 if ((*obj)->id) 1164 kfree((*obj)->id);
1165 kfree((*obj)->id);
1166 kfree(*obj); 1165 kfree(*obj);
1167 } 1166 }
1168 kfree(obj); 1167 kfree(obj);
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 9bcb398fbc1f..45c52d8f4d99 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -29,7 +29,7 @@
29 29
30#include <linux/netfilter_ipv4/ip_tables.h> 30#include <linux/netfilter_ipv4/ip_tables.h>
31#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h> 31#include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
32#include <linux/netfilter_ipv4/ip_conntrack.h> 32#include <net/netfilter/nf_conntrack_compat.h>
33 33
34#define CLUSTERIP_VERSION "0.8" 34#define CLUSTERIP_VERSION "0.8"
35 35
@@ -316,14 +316,14 @@ target(struct sk_buff **pskb,
316{ 316{
317 const struct ipt_clusterip_tgt_info *cipinfo = targinfo; 317 const struct ipt_clusterip_tgt_info *cipinfo = targinfo;
318 enum ip_conntrack_info ctinfo; 318 enum ip_conntrack_info ctinfo;
319 struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo); 319 u_int32_t *mark, hash;
320 u_int32_t hash;
321 320
322 /* don't need to clusterip_config_get() here, since refcount 321 /* don't need to clusterip_config_get() here, since refcount
323 * is only decremented by destroy() - and ip_tables guarantees 322 * is only decremented by destroy() - and ip_tables guarantees
324 * that the ->target() function isn't called after ->destroy() */ 323 * that the ->target() function isn't called after ->destroy() */
325 324
326 if (!ct) { 325 mark = nf_ct_get_mark((*pskb), &ctinfo);
326 if (mark == NULL) {
327 printk(KERN_ERR "CLUSTERIP: no conntrack!\n"); 327 printk(KERN_ERR "CLUSTERIP: no conntrack!\n");
328 /* FIXME: need to drop invalid ones, since replies 328 /* FIXME: need to drop invalid ones, since replies
329 * to outgoing connections of other nodes will be 329 * to outgoing connections of other nodes will be
@@ -346,7 +346,7 @@ target(struct sk_buff **pskb,
346 346
347 switch (ctinfo) { 347 switch (ctinfo) {
348 case IP_CT_NEW: 348 case IP_CT_NEW:
349 ct->mark = hash; 349 *mark = hash;
350 break; 350 break;
351 case IP_CT_RELATED: 351 case IP_CT_RELATED:
352 case IP_CT_RELATED+IP_CT_IS_REPLY: 352 case IP_CT_RELATED+IP_CT_IS_REPLY:
@@ -363,7 +363,7 @@ target(struct sk_buff **pskb,
363#ifdef DEBUG_CLUSTERP 363#ifdef DEBUG_CLUSTERP
364 DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 364 DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
365#endif 365#endif
366 DEBUGP("hash=%u ct_hash=%u ", hash, ct->mark); 366 DEBUGP("hash=%u ct_hash=%u ", hash, *mark);
367 if (!clusterip_responsible(cipinfo->config, hash)) { 367 if (!clusterip_responsible(cipinfo->config, hash)) {
368 DEBUGP("not responsible\n"); 368 DEBUGP("not responsible\n");
369 return NF_DROP; 369 return NF_DROP;
diff --git a/net/ipv4/netfilter/ipt_CONNMARK.c b/net/ipv4/netfilter/ipt_CONNMARK.c
index 05d66ab59424..8acac5a40a92 100644
--- a/net/ipv4/netfilter/ipt_CONNMARK.c
+++ b/net/ipv4/netfilter/ipt_CONNMARK.c
@@ -29,7 +29,7 @@ MODULE_LICENSE("GPL");
29 29
30#include <linux/netfilter_ipv4/ip_tables.h> 30#include <linux/netfilter_ipv4/ip_tables.h>
31#include <linux/netfilter_ipv4/ipt_CONNMARK.h> 31#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
32#include <linux/netfilter_ipv4/ip_conntrack.h> 32#include <net/netfilter/nf_conntrack_compat.h>
33 33
34static unsigned int 34static unsigned int
35target(struct sk_buff **pskb, 35target(struct sk_buff **pskb,
@@ -43,24 +43,24 @@ target(struct sk_buff **pskb,
43 u_int32_t diff; 43 u_int32_t diff;
44 u_int32_t nfmark; 44 u_int32_t nfmark;
45 u_int32_t newmark; 45 u_int32_t newmark;
46 u_int32_t ctinfo;
47 u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo);
46 48
47 enum ip_conntrack_info ctinfo; 49 if (ctmark) {
48 struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
49 if (ct) {
50 switch(markinfo->mode) { 50 switch(markinfo->mode) {
51 case IPT_CONNMARK_SET: 51 case IPT_CONNMARK_SET:
52 newmark = (ct->mark & ~markinfo->mask) | markinfo->mark; 52 newmark = (*ctmark & ~markinfo->mask) | markinfo->mark;
53 if (newmark != ct->mark) 53 if (newmark != *ctmark)
54 ct->mark = newmark; 54 *ctmark = newmark;
55 break; 55 break;
56 case IPT_CONNMARK_SAVE: 56 case IPT_CONNMARK_SAVE:
57 newmark = (ct->mark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); 57 newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask);
58 if (ct->mark != newmark) 58 if (*ctmark != newmark)
59 ct->mark = newmark; 59 *ctmark = newmark;
60 break; 60 break;
61 case IPT_CONNMARK_RESTORE: 61 case IPT_CONNMARK_RESTORE:
62 nfmark = (*pskb)->nfmark; 62 nfmark = (*pskb)->nfmark;
63 diff = (ct->mark ^ nfmark) & markinfo->mask; 63 diff = (*ctmark ^ nfmark) & markinfo->mask;
64 if (diff != 0) 64 if (diff != 0)
65 (*pskb)->nfmark = nfmark ^ diff; 65 (*pskb)->nfmark = nfmark ^ diff;
66 break; 66 break;
diff --git a/net/ipv4/netfilter/ipt_NOTRACK.c b/net/ipv4/netfilter/ipt_NOTRACK.c
index a4bb9b3bc292..e3c69d072c6e 100644
--- a/net/ipv4/netfilter/ipt_NOTRACK.c
+++ b/net/ipv4/netfilter/ipt_NOTRACK.c
@@ -5,7 +5,7 @@
5#include <linux/skbuff.h> 5#include <linux/skbuff.h>
6 6
7#include <linux/netfilter_ipv4/ip_tables.h> 7#include <linux/netfilter_ipv4/ip_tables.h>
8#include <linux/netfilter_ipv4/ip_conntrack.h> 8#include <net/netfilter/nf_conntrack_compat.h>
9 9
10static unsigned int 10static unsigned int
11target(struct sk_buff **pskb, 11target(struct sk_buff **pskb,
@@ -23,7 +23,7 @@ target(struct sk_buff **pskb,
23 If there is a real ct entry correspondig to this packet, 23 If there is a real ct entry correspondig to this packet,
24 it'll hang aroun till timing out. We don't deal with it 24 it'll hang aroun till timing out. We don't deal with it
25 for performance reasons. JK */ 25 for performance reasons. JK */
26 (*pskb)->nfct = &ip_conntrack_untracked.ct_general; 26 nf_ct_untrack(*pskb);
27 (*pskb)->nfctinfo = IP_CT_NEW; 27 (*pskb)->nfctinfo = IP_CT_NEW;
28 nf_conntrack_get((*pskb)->nfct); 28 nf_conntrack_get((*pskb)->nfct);
29 29
diff --git a/net/ipv4/netfilter/ipt_connbytes.c b/net/ipv4/netfilter/ipt_connbytes.c
index df4a42c6da22..d68a048b7176 100644
--- a/net/ipv4/netfilter/ipt_connbytes.c
+++ b/net/ipv4/netfilter/ipt_connbytes.c
@@ -10,7 +10,7 @@
10 */ 10 */
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/skbuff.h> 12#include <linux/skbuff.h>
13#include <linux/netfilter_ipv4/ip_conntrack.h> 13#include <net/netfilter/nf_conntrack_compat.h>
14#include <linux/netfilter_ipv4/ip_tables.h> 14#include <linux/netfilter_ipv4/ip_tables.h>
15#include <linux/netfilter_ipv4/ipt_connbytes.h> 15#include <linux/netfilter_ipv4/ipt_connbytes.h>
16 16
@@ -46,60 +46,59 @@ match(const struct sk_buff *skb,
46 int *hotdrop) 46 int *hotdrop)
47{ 47{
48 const struct ipt_connbytes_info *sinfo = matchinfo; 48 const struct ipt_connbytes_info *sinfo = matchinfo;
49 enum ip_conntrack_info ctinfo;
50 struct ip_conntrack *ct;
51 u_int64_t what = 0; /* initialize to make gcc happy */ 49 u_int64_t what = 0; /* initialize to make gcc happy */
50 const struct ip_conntrack_counter *counters;
52 51
53 if (!(ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo))) 52 if (!(counters = nf_ct_get_counters(skb)))
54 return 0; /* no match */ 53 return 0; /* no match */
55 54
56 switch (sinfo->what) { 55 switch (sinfo->what) {
57 case IPT_CONNBYTES_PKTS: 56 case IPT_CONNBYTES_PKTS:
58 switch (sinfo->direction) { 57 switch (sinfo->direction) {
59 case IPT_CONNBYTES_DIR_ORIGINAL: 58 case IPT_CONNBYTES_DIR_ORIGINAL:
60 what = ct->counters[IP_CT_DIR_ORIGINAL].packets; 59 what = counters[IP_CT_DIR_ORIGINAL].packets;
61 break; 60 break;
62 case IPT_CONNBYTES_DIR_REPLY: 61 case IPT_CONNBYTES_DIR_REPLY:
63 what = ct->counters[IP_CT_DIR_REPLY].packets; 62 what = counters[IP_CT_DIR_REPLY].packets;
64 break; 63 break;
65 case IPT_CONNBYTES_DIR_BOTH: 64 case IPT_CONNBYTES_DIR_BOTH:
66 what = ct->counters[IP_CT_DIR_ORIGINAL].packets; 65 what = counters[IP_CT_DIR_ORIGINAL].packets;
67 what += ct->counters[IP_CT_DIR_REPLY].packets; 66 what += counters[IP_CT_DIR_REPLY].packets;
68 break; 67 break;
69 } 68 }
70 break; 69 break;
71 case IPT_CONNBYTES_BYTES: 70 case IPT_CONNBYTES_BYTES:
72 switch (sinfo->direction) { 71 switch (sinfo->direction) {
73 case IPT_CONNBYTES_DIR_ORIGINAL: 72 case IPT_CONNBYTES_DIR_ORIGINAL:
74 what = ct->counters[IP_CT_DIR_ORIGINAL].bytes; 73 what = counters[IP_CT_DIR_ORIGINAL].bytes;
75 break; 74 break;
76 case IPT_CONNBYTES_DIR_REPLY: 75 case IPT_CONNBYTES_DIR_REPLY:
77 what = ct->counters[IP_CT_DIR_REPLY].bytes; 76 what = counters[IP_CT_DIR_REPLY].bytes;
78 break; 77 break;
79 case IPT_CONNBYTES_DIR_BOTH: 78 case IPT_CONNBYTES_DIR_BOTH:
80 what = ct->counters[IP_CT_DIR_ORIGINAL].bytes; 79 what = counters[IP_CT_DIR_ORIGINAL].bytes;
81 what += ct->counters[IP_CT_DIR_REPLY].bytes; 80 what += counters[IP_CT_DIR_REPLY].bytes;
82 break; 81 break;
83 } 82 }
84 break; 83 break;
85 case IPT_CONNBYTES_AVGPKT: 84 case IPT_CONNBYTES_AVGPKT:
86 switch (sinfo->direction) { 85 switch (sinfo->direction) {
87 case IPT_CONNBYTES_DIR_ORIGINAL: 86 case IPT_CONNBYTES_DIR_ORIGINAL:
88 what = div64_64(ct->counters[IP_CT_DIR_ORIGINAL].bytes, 87 what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes,
89 ct->counters[IP_CT_DIR_ORIGINAL].packets); 88 counters[IP_CT_DIR_ORIGINAL].packets);
90 break; 89 break;
91 case IPT_CONNBYTES_DIR_REPLY: 90 case IPT_CONNBYTES_DIR_REPLY:
92 what = div64_64(ct->counters[IP_CT_DIR_REPLY].bytes, 91 what = div64_64(counters[IP_CT_DIR_REPLY].bytes,
93 ct->counters[IP_CT_DIR_REPLY].packets); 92 counters[IP_CT_DIR_REPLY].packets);
94 break; 93 break;
95 case IPT_CONNBYTES_DIR_BOTH: 94 case IPT_CONNBYTES_DIR_BOTH:
96 { 95 {
97 u_int64_t bytes; 96 u_int64_t bytes;
98 u_int64_t pkts; 97 u_int64_t pkts;
99 bytes = ct->counters[IP_CT_DIR_ORIGINAL].bytes + 98 bytes = counters[IP_CT_DIR_ORIGINAL].bytes +
100 ct->counters[IP_CT_DIR_REPLY].bytes; 99 counters[IP_CT_DIR_REPLY].bytes;
101 pkts = ct->counters[IP_CT_DIR_ORIGINAL].packets+ 100 pkts = counters[IP_CT_DIR_ORIGINAL].packets+
102 ct->counters[IP_CT_DIR_REPLY].packets; 101 counters[IP_CT_DIR_REPLY].packets;
103 102
104 /* FIXME_THEORETICAL: what to do if sum 103 /* FIXME_THEORETICAL: what to do if sum
105 * overflows ? */ 104 * overflows ? */
diff --git a/net/ipv4/netfilter/ipt_connmark.c b/net/ipv4/netfilter/ipt_connmark.c
index bf8de47ce004..5306ef293b92 100644
--- a/net/ipv4/netfilter/ipt_connmark.c
+++ b/net/ipv4/netfilter/ipt_connmark.c
@@ -28,7 +28,7 @@ MODULE_LICENSE("GPL");
28 28
29#include <linux/netfilter_ipv4/ip_tables.h> 29#include <linux/netfilter_ipv4/ip_tables.h>
30#include <linux/netfilter_ipv4/ipt_connmark.h> 30#include <linux/netfilter_ipv4/ipt_connmark.h>
31#include <linux/netfilter_ipv4/ip_conntrack.h> 31#include <net/netfilter/nf_conntrack_compat.h>
32 32
33static int 33static int
34match(const struct sk_buff *skb, 34match(const struct sk_buff *skb,
@@ -39,12 +39,12 @@ match(const struct sk_buff *skb,
39 int *hotdrop) 39 int *hotdrop)
40{ 40{
41 const struct ipt_connmark_info *info = matchinfo; 41 const struct ipt_connmark_info *info = matchinfo;
42 enum ip_conntrack_info ctinfo; 42 u_int32_t ctinfo;
43 struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); 43 const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo);
44 if (!ct) 44 if (!ctmark)
45 return 0; 45 return 0;
46 46
47 return ((ct->mark & info->mask) == info->mark) ^ info->invert; 47 return (((*ctmark) & info->mask) == info->mark) ^ info->invert;
48} 48}
49 49
50static int 50static int
diff --git a/net/ipv4/netfilter/ipt_conntrack.c b/net/ipv4/netfilter/ipt_conntrack.c
index c1d22801b7cf..c8d18705469b 100644
--- a/net/ipv4/netfilter/ipt_conntrack.c
+++ b/net/ipv4/netfilter/ipt_conntrack.c
@@ -10,7 +10,14 @@
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/skbuff.h> 12#include <linux/skbuff.h>
13
14#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
13#include <linux/netfilter_ipv4/ip_conntrack.h> 15#include <linux/netfilter_ipv4/ip_conntrack.h>
16#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
17#else
18#include <net/netfilter/nf_conntrack.h>
19#endif
20
14#include <linux/netfilter_ipv4/ip_tables.h> 21#include <linux/netfilter_ipv4/ip_tables.h>
15#include <linux/netfilter_ipv4/ipt_conntrack.h> 22#include <linux/netfilter_ipv4/ipt_conntrack.h>
16 23
@@ -18,6 +25,8 @@ MODULE_LICENSE("GPL");
18MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 25MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
19MODULE_DESCRIPTION("iptables connection tracking match module"); 26MODULE_DESCRIPTION("iptables connection tracking match module");
20 27
28#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
29
21static int 30static int
22match(const struct sk_buff *skb, 31match(const struct sk_buff *skb,
23 const struct net_device *in, 32 const struct net_device *in,
@@ -102,6 +111,93 @@ match(const struct sk_buff *skb,
102 return 1; 111 return 1;
103} 112}
104 113
114#else /* CONFIG_IP_NF_CONNTRACK */
115static int
116match(const struct sk_buff *skb,
117 const struct net_device *in,
118 const struct net_device *out,
119 const void *matchinfo,
120 int offset,
121 int *hotdrop)
122{
123 const struct ipt_conntrack_info *sinfo = matchinfo;
124 struct nf_conn *ct;
125 enum ip_conntrack_info ctinfo;
126 unsigned int statebit;
127
128 ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
129
130#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
131
132 if (ct == &nf_conntrack_untracked)
133 statebit = IPT_CONNTRACK_STATE_UNTRACKED;
134 else if (ct)
135 statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
136 else
137 statebit = IPT_CONNTRACK_STATE_INVALID;
138
139 if(sinfo->flags & IPT_CONNTRACK_STATE) {
140 if (ct) {
141 if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip !=
142 ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip)
143 statebit |= IPT_CONNTRACK_STATE_SNAT;
144
145 if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip !=
146 ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip)
147 statebit |= IPT_CONNTRACK_STATE_DNAT;
148 }
149
150 if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE))
151 return 0;
152 }
153
154 if(sinfo->flags & IPT_CONNTRACK_PROTO) {
155 if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO))
156 return 0;
157 }
158
159 if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) {
160 if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC))
161 return 0;
162 }
163
164 if(sinfo->flags & IPT_CONNTRACK_ORIGDST) {
165 if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST))
166 return 0;
167 }
168
169 if(sinfo->flags & IPT_CONNTRACK_REPLSRC) {
170 if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC))
171 return 0;
172 }
173
174 if(sinfo->flags & IPT_CONNTRACK_REPLDST) {
175 if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST))
176 return 0;
177 }
178
179 if(sinfo->flags & IPT_CONNTRACK_STATUS) {
180 if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS))
181 return 0;
182 }
183
184 if(sinfo->flags & IPT_CONNTRACK_EXPIRES) {
185 unsigned long expires;
186
187 if(!ct)
188 return 0;
189
190 expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0;
191
192 if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES))
193 return 0;
194 }
195
196 return 1;
197}
198
199#endif /* CONFIG_NF_IP_CONNTRACK */
200
105static int check(const char *tablename, 201static int check(const char *tablename,
106 const struct ipt_ip *ip, 202 const struct ipt_ip *ip,
107 void *matchinfo, 203 void *matchinfo,
diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c
index 3e7dd014de43..bf14e1c7798a 100644
--- a/net/ipv4/netfilter/ipt_helper.c
+++ b/net/ipv4/netfilter/ipt_helper.c
@@ -13,9 +13,15 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/skbuff.h> 14#include <linux/skbuff.h>
15#include <linux/netfilter.h> 15#include <linux/netfilter.h>
16#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
16#include <linux/netfilter_ipv4/ip_conntrack.h> 17#include <linux/netfilter_ipv4/ip_conntrack.h>
17#include <linux/netfilter_ipv4/ip_conntrack_core.h> 18#include <linux/netfilter_ipv4/ip_conntrack_core.h>
18#include <linux/netfilter_ipv4/ip_conntrack_helper.h> 19#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
20#else
21#include <net/netfilter/nf_conntrack.h>
22#include <net/netfilter/nf_conntrack_core.h>
23#include <net/netfilter/nf_conntrack_helper.h>
24#endif
19#include <linux/netfilter_ipv4/ip_tables.h> 25#include <linux/netfilter_ipv4/ip_tables.h>
20#include <linux/netfilter_ipv4/ipt_helper.h> 26#include <linux/netfilter_ipv4/ipt_helper.h>
21 27
@@ -29,6 +35,7 @@ MODULE_DESCRIPTION("iptables helper match module");
29#define DEBUGP(format, args...) 35#define DEBUGP(format, args...)
30#endif 36#endif
31 37
38#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
32static int 39static int
33match(const struct sk_buff *skb, 40match(const struct sk_buff *skb,
34 const struct net_device *in, 41 const struct net_device *in,
@@ -73,6 +80,53 @@ out_unlock:
73 return ret; 80 return ret;
74} 81}
75 82
83#else /* CONFIG_IP_NF_CONNTRACK */
84
85static int
86match(const struct sk_buff *skb,
87 const struct net_device *in,
88 const struct net_device *out,
89 const void *matchinfo,
90 int offset,
91 int *hotdrop)
92{
93 const struct ipt_helper_info *info = matchinfo;
94 struct nf_conn *ct;
95 enum ip_conntrack_info ctinfo;
96 int ret = info->invert;
97
98 ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
99 if (!ct) {
100 DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
101 return ret;
102 }
103
104 if (!ct->master) {
105 DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
106 return ret;
107 }
108
109 read_lock_bh(&nf_conntrack_lock);
110 if (!ct->master->helper) {
111 DEBUGP("ipt_helper: master ct %p has no helper\n",
112 exp->expectant);
113 goto out_unlock;
114 }
115
116 DEBUGP("master's name = %s , info->name = %s\n",
117 ct->master->helper->name, info->name);
118
119 if (info->name[0] == '\0')
120 ret ^= 1;
121 else
122 ret ^= !strncmp(ct->master->helper->name, info->name,
123 strlen(ct->master->helper->name));
124out_unlock:
125 read_unlock_bh(&nf_conntrack_lock);
126 return ret;
127}
128#endif
129
76static int check(const char *tablename, 130static int check(const char *tablename,
77 const struct ipt_ip *ip, 131 const struct ipt_ip *ip,
78 void *matchinfo, 132 void *matchinfo,
diff --git a/net/ipv4/netfilter/ipt_state.c b/net/ipv4/netfilter/ipt_state.c
index b1511b97ea5f..4d7f16b70cec 100644
--- a/net/ipv4/netfilter/ipt_state.c
+++ b/net/ipv4/netfilter/ipt_state.c
@@ -10,7 +10,7 @@
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/skbuff.h> 12#include <linux/skbuff.h>
13#include <linux/netfilter_ipv4/ip_conntrack.h> 13#include <net/netfilter/nf_conntrack_compat.h>
14#include <linux/netfilter_ipv4/ip_tables.h> 14#include <linux/netfilter_ipv4/ip_tables.h>
15#include <linux/netfilter_ipv4/ipt_state.h> 15#include <linux/netfilter_ipv4/ipt_state.h>
16 16
@@ -30,9 +30,9 @@ match(const struct sk_buff *skb,
30 enum ip_conntrack_info ctinfo; 30 enum ip_conntrack_info ctinfo;
31 unsigned int statebit; 31 unsigned int statebit;
32 32
33 if (skb->nfct == &ip_conntrack_untracked.ct_general) 33 if (nf_ct_is_untracked(skb))
34 statebit = IPT_STATE_UNTRACKED; 34 statebit = IPT_STATE_UNTRACKED;
35 else if (!ip_conntrack_get(skb, &ctinfo)) 35 else if (!nf_ct_get_ctinfo(skb, &ctinfo))
36 statebit = IPT_STATE_INVALID; 36 statebit = IPT_STATE_INVALID;
37 else 37 else
38 statebit = IPT_STATE_BIT(ctinfo); 38 statebit = IPT_STATE_BIT(ctinfo);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
new file mode 100644
index 000000000000..8202c1c0afad
--- /dev/null
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -0,0 +1,571 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
9 * - move L3 protocol dependent part to this file.
10 * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
11 * - add get_features() to support various size of conntrack
12 * structures.
13 *
14 * Derived from net/ipv4/netfilter/ip_conntrack_standalone.c
15 */
16
17#include <linux/config.h>
18#include <linux/types.h>
19#include <linux/ip.h>
20#include <linux/netfilter.h>
21#include <linux/module.h>
22#include <linux/skbuff.h>
23#include <linux/icmp.h>
24#include <linux/sysctl.h>
25#include <net/ip.h>
26
27#include <linux/netfilter_ipv4.h>
28#include <net/netfilter/nf_conntrack.h>
29#include <net/netfilter/nf_conntrack_helper.h>
30#include <net/netfilter/nf_conntrack_protocol.h>
31#include <net/netfilter/nf_conntrack_l3proto.h>
32#include <net/netfilter/nf_conntrack_core.h>
33#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
34
35#if 0
36#define DEBUGP printk
37#else
38#define DEBUGP(format, args...)
39#endif
40
41DECLARE_PER_CPU(struct nf_conntrack_stat, nf_conntrack_stat);
42
43static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
44 struct nf_conntrack_tuple *tuple)
45{
46 u_int32_t _addrs[2], *ap;
47 ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr),
48 sizeof(u_int32_t) * 2, _addrs);
49 if (ap == NULL)
50 return 0;
51
52 tuple->src.u3.ip = ap[0];
53 tuple->dst.u3.ip = ap[1];
54
55 return 1;
56}
57
58static int ipv4_invert_tuple(struct nf_conntrack_tuple *tuple,
59 const struct nf_conntrack_tuple *orig)
60{
61 tuple->src.u3.ip = orig->dst.u3.ip;
62 tuple->dst.u3.ip = orig->src.u3.ip;
63
64 return 1;
65}
66
67static int ipv4_print_tuple(struct seq_file *s,
68 const struct nf_conntrack_tuple *tuple)
69{
70 return seq_printf(s, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ",
71 NIPQUAD(tuple->src.u3.ip),
72 NIPQUAD(tuple->dst.u3.ip));
73}
74
75static int ipv4_print_conntrack(struct seq_file *s,
76 const struct nf_conn *conntrack)
77{
78 return 0;
79}
80
81/* Returns new sk_buff, or NULL */
82static struct sk_buff *
83nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
84{
85 skb_orphan(skb);
86
87 local_bh_disable();
88 skb = ip_defrag(skb, user);
89 local_bh_enable();
90
91 if (skb)
92 ip_send_check(skb->nh.iph);
93
94 return skb;
95}
96
97static int
98ipv4_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
99 u_int8_t *protonum)
100{
101 /* Never happen */
102 if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
103 if (net_ratelimit()) {
104 printk(KERN_ERR "ipv4_prepare: Frag of proto %u (hook=%u)\n",
105 (*pskb)->nh.iph->protocol, hooknum);
106 }
107 return -NF_DROP;
108 }
109
110 *dataoff = (*pskb)->nh.raw - (*pskb)->data + (*pskb)->nh.iph->ihl*4;
111 *protonum = (*pskb)->nh.iph->protocol;
112
113 return NF_ACCEPT;
114}
115
116int nat_module_is_loaded = 0;
117static u_int32_t ipv4_get_features(const struct nf_conntrack_tuple *tuple)
118{
119 if (nat_module_is_loaded)
120 return NF_CT_F_NAT;
121
122 return NF_CT_F_BASIC;
123}
124
125static unsigned int ipv4_confirm(unsigned int hooknum,
126 struct sk_buff **pskb,
127 const struct net_device *in,
128 const struct net_device *out,
129 int (*okfn)(struct sk_buff *))
130{
131 /* We've seen it coming out the other side: confirm it */
132 return nf_conntrack_confirm(pskb);
133}
134
135static unsigned int ipv4_conntrack_help(unsigned int hooknum,
136 struct sk_buff **pskb,
137 const struct net_device *in,
138 const struct net_device *out,
139 int (*okfn)(struct sk_buff *))
140{
141 struct nf_conn *ct;
142 enum ip_conntrack_info ctinfo;
143
144 /* This is where we call the helper: as the packet goes out. */
145 ct = nf_ct_get(*pskb, &ctinfo);
146 if (ct && ct->helper) {
147 unsigned int ret;
148 ret = ct->helper->help(pskb,
149 (*pskb)->nh.raw - (*pskb)->data
150 + (*pskb)->nh.iph->ihl*4,
151 ct, ctinfo);
152 if (ret != NF_ACCEPT)
153 return ret;
154 }
155 return NF_ACCEPT;
156}
157
158static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
159 struct sk_buff **pskb,
160 const struct net_device *in,
161 const struct net_device *out,
162 int (*okfn)(struct sk_buff *))
163{
164#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
165 /* Previously seen (loopback)? Ignore. Do this before
166 fragment check. */
167 if ((*pskb)->nfct)
168 return NF_ACCEPT;
169#endif
170
171 /* Gather fragments. */
172 if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
173 *pskb = nf_ct_ipv4_gather_frags(*pskb,
174 hooknum == NF_IP_PRE_ROUTING ?
175 IP_DEFRAG_CONNTRACK_IN :
176 IP_DEFRAG_CONNTRACK_OUT);
177 if (!*pskb)
178 return NF_STOLEN;
179 }
180 return NF_ACCEPT;
181}
182
183static unsigned int ipv4_refrag(unsigned int hooknum,
184 struct sk_buff **pskb,
185 const struct net_device *in,
186 const struct net_device *out,
187 int (*okfn)(struct sk_buff *))
188{
189 struct rtable *rt = (struct rtable *)(*pskb)->dst;
190
191 /* We've seen it coming out the other side: confirm */
192 if (ipv4_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
193 return NF_DROP;
194
195 /* Local packets are never produced too large for their
196 interface. We degfragment them at LOCAL_OUT, however,
197 so we have to refragment them here. */
198 if ((*pskb)->len > dst_mtu(&rt->u.dst) &&
199 !skb_shinfo(*pskb)->tso_size) {
200 /* No hook can be after us, so this should be OK. */
201 ip_fragment(*pskb, okfn);
202 return NF_STOLEN;
203 }
204 return NF_ACCEPT;
205}
206
207static unsigned int ipv4_conntrack_in(unsigned int hooknum,
208 struct sk_buff **pskb,
209 const struct net_device *in,
210 const struct net_device *out,
211 int (*okfn)(struct sk_buff *))
212{
213 return nf_conntrack_in(PF_INET, hooknum, pskb);
214}
215
216static unsigned int ipv4_conntrack_local(unsigned int hooknum,
217 struct sk_buff **pskb,
218 const struct net_device *in,
219 const struct net_device *out,
220 int (*okfn)(struct sk_buff *))
221{
222 /* root is playing with raw sockets. */
223 if ((*pskb)->len < sizeof(struct iphdr)
224 || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
225 if (net_ratelimit())
226 printk("ipt_hook: happy cracking.\n");
227 return NF_ACCEPT;
228 }
229 return nf_conntrack_in(PF_INET, hooknum, pskb);
230}
231
232/* Connection tracking may drop packets, but never alters them, so
233 make it the first hook. */
234static struct nf_hook_ops ipv4_conntrack_defrag_ops = {
235 .hook = ipv4_conntrack_defrag,
236 .owner = THIS_MODULE,
237 .pf = PF_INET,
238 .hooknum = NF_IP_PRE_ROUTING,
239 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
240};
241
242static struct nf_hook_ops ipv4_conntrack_in_ops = {
243 .hook = ipv4_conntrack_in,
244 .owner = THIS_MODULE,
245 .pf = PF_INET,
246 .hooknum = NF_IP_PRE_ROUTING,
247 .priority = NF_IP_PRI_CONNTRACK,
248};
249
250static struct nf_hook_ops ipv4_conntrack_defrag_local_out_ops = {
251 .hook = ipv4_conntrack_defrag,
252 .owner = THIS_MODULE,
253 .pf = PF_INET,
254 .hooknum = NF_IP_LOCAL_OUT,
255 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
256};
257
258static struct nf_hook_ops ipv4_conntrack_local_out_ops = {
259 .hook = ipv4_conntrack_local,
260 .owner = THIS_MODULE,
261 .pf = PF_INET,
262 .hooknum = NF_IP_LOCAL_OUT,
263 .priority = NF_IP_PRI_CONNTRACK,
264};
265
266/* helpers */
267static struct nf_hook_ops ipv4_conntrack_helper_out_ops = {
268 .hook = ipv4_conntrack_help,
269 .owner = THIS_MODULE,
270 .pf = PF_INET,
271 .hooknum = NF_IP_POST_ROUTING,
272 .priority = NF_IP_PRI_CONNTRACK_HELPER,
273};
274
275static struct nf_hook_ops ipv4_conntrack_helper_in_ops = {
276 .hook = ipv4_conntrack_help,
277 .owner = THIS_MODULE,
278 .pf = PF_INET,
279 .hooknum = NF_IP_LOCAL_IN,
280 .priority = NF_IP_PRI_CONNTRACK_HELPER,
281};
282
283
284/* Refragmenter; last chance. */
285static struct nf_hook_ops ipv4_conntrack_out_ops = {
286 .hook = ipv4_refrag,
287 .owner = THIS_MODULE,
288 .pf = PF_INET,
289 .hooknum = NF_IP_POST_ROUTING,
290 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
291};
292
293static struct nf_hook_ops ipv4_conntrack_local_in_ops = {
294 .hook = ipv4_confirm,
295 .owner = THIS_MODULE,
296 .pf = PF_INET,
297 .hooknum = NF_IP_LOCAL_IN,
298 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
299};
300
301#ifdef CONFIG_SYSCTL
302/* From nf_conntrack_proto_icmp.c */
303extern unsigned long nf_ct_icmp_timeout;
304static struct ctl_table_header *nf_ct_ipv4_sysctl_header;
305
306static ctl_table nf_ct_sysctl_table[] = {
307 {
308 .ctl_name = NET_NF_CONNTRACK_ICMP_TIMEOUT,
309 .procname = "nf_conntrack_icmp_timeout",
310 .data = &nf_ct_icmp_timeout,
311 .maxlen = sizeof(unsigned int),
312 .mode = 0644,
313 .proc_handler = &proc_dointvec_jiffies,
314 },
315 { .ctl_name = 0 }
316};
317
318static ctl_table nf_ct_netfilter_table[] = {
319 {
320 .ctl_name = NET_NETFILTER,
321 .procname = "netfilter",
322 .mode = 0555,
323 .child = nf_ct_sysctl_table,
324 },
325 { .ctl_name = 0 }
326};
327
328static ctl_table nf_ct_net_table[] = {
329 {
330 .ctl_name = CTL_NET,
331 .procname = "net",
332 .mode = 0555,
333 .child = nf_ct_netfilter_table,
334 },
335 { .ctl_name = 0 }
336};
337#endif
338
339/* Fast function for those who don't want to parse /proc (and I don't
340 blame them). */
341/* Reversing the socket's dst/src point of view gives us the reply
342 mapping. */
343static int
344getorigdst(struct sock *sk, int optval, void __user *user, int *len)
345{
346 struct inet_sock *inet = inet_sk(sk);
347 struct nf_conntrack_tuple_hash *h;
348 struct nf_conntrack_tuple tuple;
349
350 NF_CT_TUPLE_U_BLANK(&tuple);
351 tuple.src.u3.ip = inet->rcv_saddr;
352 tuple.src.u.tcp.port = inet->sport;
353 tuple.dst.u3.ip = inet->daddr;
354 tuple.dst.u.tcp.port = inet->dport;
355 tuple.src.l3num = PF_INET;
356 tuple.dst.protonum = IPPROTO_TCP;
357
358 /* We only do TCP at the moment: is there a better way? */
359 if (strcmp(sk->sk_prot->name, "TCP")) {
360 DEBUGP("SO_ORIGINAL_DST: Not a TCP socket\n");
361 return -ENOPROTOOPT;
362 }
363
364 if ((unsigned int) *len < sizeof(struct sockaddr_in)) {
365 DEBUGP("SO_ORIGINAL_DST: len %u not %u\n",
366 *len, sizeof(struct sockaddr_in));
367 return -EINVAL;
368 }
369
370 h = nf_conntrack_find_get(&tuple, NULL);
371 if (h) {
372 struct sockaddr_in sin;
373 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
374
375 sin.sin_family = AF_INET;
376 sin.sin_port = ct->tuplehash[IP_CT_DIR_ORIGINAL]
377 .tuple.dst.u.tcp.port;
378 sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL]
379 .tuple.dst.u3.ip;
380
381 DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
382 NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
383 nf_ct_put(ct);
384 if (copy_to_user(user, &sin, sizeof(sin)) != 0)
385 return -EFAULT;
386 else
387 return 0;
388 }
389 DEBUGP("SO_ORIGINAL_DST: Can't find %u.%u.%u.%u/%u-%u.%u.%u.%u/%u.\n",
390 NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port),
391 NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port));
392 return -ENOENT;
393}
394
395static struct nf_sockopt_ops so_getorigdst = {
396 .pf = PF_INET,
397 .get_optmin = SO_ORIGINAL_DST,
398 .get_optmax = SO_ORIGINAL_DST+1,
399 .get = &getorigdst,
400};
401
402struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = {
403 .l3proto = PF_INET,
404 .name = "ipv4",
405 .pkt_to_tuple = ipv4_pkt_to_tuple,
406 .invert_tuple = ipv4_invert_tuple,
407 .print_tuple = ipv4_print_tuple,
408 .print_conntrack = ipv4_print_conntrack,
409 .prepare = ipv4_prepare,
410 .get_features = ipv4_get_features,
411 .me = THIS_MODULE,
412};
413
414extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp4;
415extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4;
416extern struct nf_conntrack_protocol nf_conntrack_protocol_icmp;
417static int init_or_cleanup(int init)
418{
419 int ret = 0;
420
421 if (!init) goto cleanup;
422
423 ret = nf_register_sockopt(&so_getorigdst);
424 if (ret < 0) {
425 printk(KERN_ERR "Unable to register netfilter socket option\n");
426 goto cleanup_nothing;
427 }
428
429 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp4);
430 if (ret < 0) {
431 printk("nf_conntrack_ipv4: can't register tcp.\n");
432 goto cleanup_sockopt;
433 }
434
435 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_udp4);
436 if (ret < 0) {
437 printk("nf_conntrack_ipv4: can't register udp.\n");
438 goto cleanup_tcp;
439 }
440
441 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_icmp);
442 if (ret < 0) {
443 printk("nf_conntrack_ipv4: can't register icmp.\n");
444 goto cleanup_udp;
445 }
446
447 ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4);
448 if (ret < 0) {
449 printk("nf_conntrack_ipv4: can't register ipv4\n");
450 goto cleanup_icmp;
451 }
452
453 ret = nf_register_hook(&ipv4_conntrack_defrag_ops);
454 if (ret < 0) {
455 printk("nf_conntrack_ipv4: can't register pre-routing defrag hook.\n");
456 goto cleanup_ipv4;
457 }
458 ret = nf_register_hook(&ipv4_conntrack_defrag_local_out_ops);
459 if (ret < 0) {
460 printk("nf_conntrack_ipv4: can't register local_out defrag hook.\n");
461 goto cleanup_defragops;
462 }
463
464 ret = nf_register_hook(&ipv4_conntrack_in_ops);
465 if (ret < 0) {
466 printk("nf_conntrack_ipv4: can't register pre-routing hook.\n");
467 goto cleanup_defraglocalops;
468 }
469
470 ret = nf_register_hook(&ipv4_conntrack_local_out_ops);
471 if (ret < 0) {
472 printk("nf_conntrack_ipv4: can't register local out hook.\n");
473 goto cleanup_inops;
474 }
475
476 ret = nf_register_hook(&ipv4_conntrack_helper_in_ops);
477 if (ret < 0) {
478 printk("nf_conntrack_ipv4: can't register local helper hook.\n");
479 goto cleanup_inandlocalops;
480 }
481
482 ret = nf_register_hook(&ipv4_conntrack_helper_out_ops);
483 if (ret < 0) {
484 printk("nf_conntrack_ipv4: can't register postrouting helper hook.\n");
485 goto cleanup_helperinops;
486 }
487
488 ret = nf_register_hook(&ipv4_conntrack_out_ops);
489 if (ret < 0) {
490 printk("nf_conntrack_ipv4: can't register post-routing hook.\n");
491 goto cleanup_helperoutops;
492 }
493
494 ret = nf_register_hook(&ipv4_conntrack_local_in_ops);
495 if (ret < 0) {
496 printk("nf_conntrack_ipv4: can't register local in hook.\n");
497 goto cleanup_inoutandlocalops;
498 }
499
500#ifdef CONFIG_SYSCTL
501 nf_ct_ipv4_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
502 if (nf_ct_ipv4_sysctl_header == NULL) {
503 printk("nf_conntrack: can't register to sysctl.\n");
504 ret = -ENOMEM;
505 goto cleanup_localinops;
506 }
507#endif
508
509 /* For use by REJECT target */
510 ip_ct_attach = __nf_conntrack_attach;
511
512 return ret;
513
514 cleanup:
515 synchronize_net();
516 ip_ct_attach = NULL;
517#ifdef CONFIG_SYSCTL
518 unregister_sysctl_table(nf_ct_ipv4_sysctl_header);
519 cleanup_localinops:
520#endif
521 nf_unregister_hook(&ipv4_conntrack_local_in_ops);
522 cleanup_inoutandlocalops:
523 nf_unregister_hook(&ipv4_conntrack_out_ops);
524 cleanup_helperoutops:
525 nf_unregister_hook(&ipv4_conntrack_helper_out_ops);
526 cleanup_helperinops:
527 nf_unregister_hook(&ipv4_conntrack_helper_in_ops);
528 cleanup_inandlocalops:
529 nf_unregister_hook(&ipv4_conntrack_local_out_ops);
530 cleanup_inops:
531 nf_unregister_hook(&ipv4_conntrack_in_ops);
532 cleanup_defraglocalops:
533 nf_unregister_hook(&ipv4_conntrack_defrag_local_out_ops);
534 cleanup_defragops:
535 nf_unregister_hook(&ipv4_conntrack_defrag_ops);
536 cleanup_ipv4:
537 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
538 cleanup_icmp:
539 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmp);
540 cleanup_udp:
541 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp4);
542 cleanup_tcp:
543 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4);
544 cleanup_sockopt:
545 nf_unregister_sockopt(&so_getorigdst);
546 cleanup_nothing:
547 return ret;
548}
549
550MODULE_LICENSE("GPL");
551
552static int __init init(void)
553{
554 need_nf_conntrack();
555 return init_or_cleanup(1);
556}
557
558static void __exit fini(void)
559{
560 init_or_cleanup(0);
561}
562
563module_init(init);
564module_exit(fini);
565
566void need_ip_conntrack(void)
567{
568}
569
570EXPORT_SYMBOL(need_ip_conntrack);
571EXPORT_SYMBOL(nf_ct_ipv4_gather_frags);
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
new file mode 100644
index 000000000000..7ddb5c08f7b8
--- /dev/null
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -0,0 +1,301 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
9 * - enable working with Layer 3 protocol independent connection tracking.
10 *
11 * Derived from net/ipv4/netfilter/ip_conntrack_proto_icmp.c
12 */
13
14#include <linux/types.h>
15#include <linux/sched.h>
16#include <linux/timer.h>
17#include <linux/netfilter.h>
18#include <linux/in.h>
19#include <linux/icmp.h>
20#include <linux/seq_file.h>
21#include <net/ip.h>
22#include <net/checksum.h>
23#include <linux/netfilter_ipv4.h>
24#include <net/netfilter/nf_conntrack_tuple.h>
25#include <net/netfilter/nf_conntrack_protocol.h>
26#include <net/netfilter/nf_conntrack_core.h>
27
28unsigned long nf_ct_icmp_timeout = 30*HZ;
29
30#if 0
31#define DEBUGP printk
32#else
33#define DEBUGP(format, args...)
34#endif
35
36static int icmp_pkt_to_tuple(const struct sk_buff *skb,
37 unsigned int dataoff,
38 struct nf_conntrack_tuple *tuple)
39{
40 struct icmphdr _hdr, *hp;
41
42 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
43 if (hp == NULL)
44 return 0;
45
46 tuple->dst.u.icmp.type = hp->type;
47 tuple->src.u.icmp.id = hp->un.echo.id;
48 tuple->dst.u.icmp.code = hp->code;
49
50 return 1;
51}
52
53static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple,
54 const struct nf_conntrack_tuple *orig)
55{
56 /* Add 1; spaces filled with 0. */
57 static u_int8_t invmap[]
58 = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
59 [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
60 [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
61 [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
62 [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
63 [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
64 [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
65 [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
66
67 if (orig->dst.u.icmp.type >= sizeof(invmap)
68 || !invmap[orig->dst.u.icmp.type])
69 return 0;
70
71 tuple->src.u.icmp.id = orig->src.u.icmp.id;
72 tuple->dst.u.icmp.type = invmap[orig->dst.u.icmp.type] - 1;
73 tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
74 return 1;
75}
76
77/* Print out the per-protocol part of the tuple. */
78static int icmp_print_tuple(struct seq_file *s,
79 const struct nf_conntrack_tuple *tuple)
80{
81 return seq_printf(s, "type=%u code=%u id=%u ",
82 tuple->dst.u.icmp.type,
83 tuple->dst.u.icmp.code,
84 ntohs(tuple->src.u.icmp.id));
85}
86
87/* Print out the private part of the conntrack. */
88static int icmp_print_conntrack(struct seq_file *s,
89 const struct nf_conn *conntrack)
90{
91 return 0;
92}
93
94/* Returns verdict for packet, or -1 for invalid. */
95static int icmp_packet(struct nf_conn *ct,
96 const struct sk_buff *skb,
97 unsigned int dataoff,
98 enum ip_conntrack_info ctinfo,
99 int pf,
100 unsigned int hooknum)
101{
102 /* Try to delete connection immediately after all replies:
103 won't actually vanish as we still have skb, and del_timer
104 means this will only run once even if count hits zero twice
105 (theoretically possible with SMP) */
106 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
107 if (atomic_dec_and_test(&ct->proto.icmp.count)
108 && del_timer(&ct->timeout))
109 ct->timeout.function((unsigned long)ct);
110 } else {
111 atomic_inc(&ct->proto.icmp.count);
112 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
113 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
114 }
115
116 return NF_ACCEPT;
117}
118
119/* Called when a new connection for this protocol found. */
120static int icmp_new(struct nf_conn *conntrack,
121 const struct sk_buff *skb, unsigned int dataoff)
122{
123 static u_int8_t valid_new[]
124 = { [ICMP_ECHO] = 1,
125 [ICMP_TIMESTAMP] = 1,
126 [ICMP_INFO_REQUEST] = 1,
127 [ICMP_ADDRESS] = 1 };
128
129 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
130 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
131 /* Can't create a new ICMP `conn' with this. */
132 DEBUGP("icmp: can't create new conn with type %u\n",
133 conntrack->tuplehash[0].tuple.dst.u.icmp.type);
134 NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
135 return 0;
136 }
137 atomic_set(&conntrack->proto.icmp.count, 0);
138 return 1;
139}
140
141extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
142/* Returns conntrack if it dealt with ICMP, and filled in skb fields */
143static int
144icmp_error_message(struct sk_buff *skb,
145 enum ip_conntrack_info *ctinfo,
146 unsigned int hooknum)
147{
148 struct nf_conntrack_tuple innertuple, origtuple;
149 struct {
150 struct icmphdr icmp;
151 struct iphdr ip;
152 } _in, *inside;
153 struct nf_conntrack_protocol *innerproto;
154 struct nf_conntrack_tuple_hash *h;
155 int dataoff;
156
157 NF_CT_ASSERT(skb->nfct == NULL);
158
159 /* Not enough header? */
160 inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
161 if (inside == NULL)
162 return -NF_ACCEPT;
163
164 /* Ignore ICMP's containing fragments (shouldn't happen) */
165 if (inside->ip.frag_off & htons(IP_OFFSET)) {
166 DEBUGP("icmp_error_message: fragment of proto %u\n",
167 inside->ip.protocol);
168 return -NF_ACCEPT;
169 }
170
171 innerproto = nf_ct_find_proto(PF_INET, inside->ip.protocol);
172 dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp);
173 /* Are they talking about one of our connections? */
174 if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET,
175 inside->ip.protocol, &origtuple,
176 &nf_conntrack_l3proto_ipv4, innerproto)) {
177 DEBUGP("icmp_error_message: ! get_tuple p=%u",
178 inside->ip.protocol);
179 return -NF_ACCEPT;
180 }
181
182 /* Ordinarily, we'd expect the inverted tupleproto, but it's
183 been preserved inside the ICMP. */
184 if (!nf_ct_invert_tuple(&innertuple, &origtuple,
185 &nf_conntrack_l3proto_ipv4, innerproto)) {
186 DEBUGP("icmp_error_message: no match\n");
187 return -NF_ACCEPT;
188 }
189
190 *ctinfo = IP_CT_RELATED;
191
192 h = nf_conntrack_find_get(&innertuple, NULL);
193 if (!h) {
194 /* Locally generated ICMPs will match inverted if they
195 haven't been SNAT'ed yet */
196 /* FIXME: NAT code has to handle half-done double NAT --RR */
197 if (hooknum == NF_IP_LOCAL_OUT)
198 h = nf_conntrack_find_get(&origtuple, NULL);
199
200 if (!h) {
201 DEBUGP("icmp_error_message: no match\n");
202 return -NF_ACCEPT;
203 }
204
205 /* Reverse direction from that found */
206 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
207 *ctinfo += IP_CT_IS_REPLY;
208 } else {
209 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
210 *ctinfo += IP_CT_IS_REPLY;
211 }
212
213 /* Update skb to refer to this connection */
214 skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
215 skb->nfctinfo = *ctinfo;
216 return -NF_ACCEPT;
217}
218
219/* Small and modified version of icmp_rcv */
220static int
221icmp_error(struct sk_buff *skb, unsigned int dataoff,
222 enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
223{
224 struct icmphdr _ih, *icmph;
225
226 /* Not enough header? */
227 icmph = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_ih), &_ih);
228 if (icmph == NULL) {
229 if (LOG_INVALID(IPPROTO_ICMP))
230 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
231 "nf_ct_icmp: short packet ");
232 return -NF_ACCEPT;
233 }
234
235 /* See ip_conntrack_proto_tcp.c */
236 if (hooknum != NF_IP_PRE_ROUTING)
237 goto checksum_skipped;
238
239 switch (skb->ip_summed) {
240 case CHECKSUM_HW:
241 if (!(u16)csum_fold(skb->csum))
242 break;
243 if (LOG_INVALID(IPPROTO_ICMP))
244 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
245 "nf_ct_icmp: bad HW ICMP checksum ");
246 return -NF_ACCEPT;
247 case CHECKSUM_NONE:
248 if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) {
249 if (LOG_INVALID(IPPROTO_ICMP))
250 nf_log_packet(PF_INET, 0, skb, NULL, NULL,
251 NULL,
252 "nf_ct_icmp: bad ICMP checksum ");
253 return -NF_ACCEPT;
254 }
255 default:
256 break;
257 }
258
259checksum_skipped:
260 /*
261 * 18 is the highest 'known' ICMP type. Anything else is a mystery
262 *
263 * RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently
264 * discarded.
265 */
266 if (icmph->type > NR_ICMP_TYPES) {
267 if (LOG_INVALID(IPPROTO_ICMP))
268 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
269 "nf_ct_icmp: invalid ICMP type ");
270 return -NF_ACCEPT;
271 }
272
273 /* Need to track icmp error message? */
274 if (icmph->type != ICMP_DEST_UNREACH
275 && icmph->type != ICMP_SOURCE_QUENCH
276 && icmph->type != ICMP_TIME_EXCEEDED
277 && icmph->type != ICMP_PARAMETERPROB
278 && icmph->type != ICMP_REDIRECT)
279 return NF_ACCEPT;
280
281 return icmp_error_message(skb, ctinfo, hooknum);
282}
283
284struct nf_conntrack_protocol nf_conntrack_protocol_icmp =
285{
286 .list = { NULL, NULL },
287 .l3proto = PF_INET,
288 .proto = IPPROTO_ICMP,
289 .name = "icmp",
290 .pkt_to_tuple = icmp_pkt_to_tuple,
291 .invert_tuple = icmp_invert_tuple,
292 .print_tuple = icmp_print_tuple,
293 .print_conntrack = icmp_print_conntrack,
294 .packet = icmp_packet,
295 .new = icmp_new,
296 .error = icmp_error,
297 .destroy = NULL,
298 .me = NULL
299};
300
301EXPORT_SYMBOL(nf_conntrack_protocol_icmp);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 49d67cd75edd..634dabb558fd 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -823,8 +823,7 @@ out:
823 */ 823 */
824static void tcp_v4_reqsk_destructor(struct request_sock *req) 824static void tcp_v4_reqsk_destructor(struct request_sock *req)
825{ 825{
826 if (inet_rsk(req)->opt) 826 kfree(inet_rsk(req)->opt);
827 kfree(inet_rsk(req)->opt);
828} 827}
829 828
830static inline void syn_flood_warning(struct sk_buff *skb) 829static inline void syn_flood_warning(struct sk_buff *skb)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 2c5f57299d63..ddcf7754eec2 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -35,6 +35,9 @@
35 * YOSHIFUJI Hideaki @USAGI : ARCnet support 35 * YOSHIFUJI Hideaki @USAGI : ARCnet support
36 * YOSHIFUJI Hideaki @USAGI : convert /proc/net/if_inet6 to 36 * YOSHIFUJI Hideaki @USAGI : convert /proc/net/if_inet6 to
37 * seq_file. 37 * seq_file.
38 * YOSHIFUJI Hideaki @USAGI : improved source address
39 * selection; consider scope,
40 * status etc.
38 */ 41 */
39 42
40#include <linux/config.h> 43#include <linux/config.h>
@@ -193,46 +196,51 @@ const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
193#endif 196#endif
194const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; 197const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
195 198
196int ipv6_addr_type(const struct in6_addr *addr) 199#define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16)
200
201static inline unsigned ipv6_addr_scope2type(unsigned scope)
202{
203 switch(scope) {
204 case IPV6_ADDR_SCOPE_NODELOCAL:
205 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL) |
206 IPV6_ADDR_LOOPBACK);
207 case IPV6_ADDR_SCOPE_LINKLOCAL:
208 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL) |
209 IPV6_ADDR_LINKLOCAL);
210 case IPV6_ADDR_SCOPE_SITELOCAL:
211 return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL) |
212 IPV6_ADDR_SITELOCAL);
213 }
214 return IPV6_ADDR_SCOPE_TYPE(scope);
215}
216
217int __ipv6_addr_type(const struct in6_addr *addr)
197{ 218{
198 int type;
199 u32 st; 219 u32 st;
200 220
201 st = addr->s6_addr32[0]; 221 st = addr->s6_addr32[0];
202 222
203 if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
204 type = IPV6_ADDR_MULTICAST;
205
206 switch((st & htonl(0x00FF0000))) {
207 case __constant_htonl(0x00010000):
208 type |= IPV6_ADDR_LOOPBACK;
209 break;
210
211 case __constant_htonl(0x00020000):
212 type |= IPV6_ADDR_LINKLOCAL;
213 break;
214
215 case __constant_htonl(0x00050000):
216 type |= IPV6_ADDR_SITELOCAL;
217 break;
218 };
219 return type;
220 }
221
222 type = IPV6_ADDR_UNICAST;
223
224 /* Consider all addresses with the first three bits different of 223 /* Consider all addresses with the first three bits different of
225 000 and 111 as finished. 224 000 and 111 as unicasts.
226 */ 225 */
227 if ((st & htonl(0xE0000000)) != htonl(0x00000000) && 226 if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
228 (st & htonl(0xE0000000)) != htonl(0xE0000000)) 227 (st & htonl(0xE0000000)) != htonl(0xE0000000))
229 return type; 228 return (IPV6_ADDR_UNICAST |
230 229 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));
231 if ((st & htonl(0xFFC00000)) == htonl(0xFE800000)) 230
232 return (IPV6_ADDR_LINKLOCAL | type); 231 if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
232 /* multicast */
233 /* addr-select 3.1 */
234 return (IPV6_ADDR_MULTICAST |
235 ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr)));
236 }
233 237
238 if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
239 return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST |
240 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.1 */
234 if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000)) 241 if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
235 return (IPV6_ADDR_SITELOCAL | type); 242 return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST |
243 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL)); /* addr-select 3.1 */
236 244
237 if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) { 245 if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
238 if (addr->s6_addr32[2] == 0) { 246 if (addr->s6_addr32[2] == 0) {
@@ -240,24 +248,20 @@ int ipv6_addr_type(const struct in6_addr *addr)
240 return IPV6_ADDR_ANY; 248 return IPV6_ADDR_ANY;
241 249
242 if (addr->s6_addr32[3] == htonl(0x00000001)) 250 if (addr->s6_addr32[3] == htonl(0x00000001))
243 return (IPV6_ADDR_LOOPBACK | type); 251 return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST |
252 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.4 */
244 253
245 return (IPV6_ADDR_COMPATv4 | type); 254 return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST |
255 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */
246 } 256 }
247 257
248 if (addr->s6_addr32[2] == htonl(0x0000ffff)) 258 if (addr->s6_addr32[2] == htonl(0x0000ffff))
249 return IPV6_ADDR_MAPPED; 259 return (IPV6_ADDR_MAPPED |
260 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */
250 } 261 }
251 262
252 st &= htonl(0xFF000000); 263 return (IPV6_ADDR_RESERVED |
253 if (st == 0) 264 IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.4 */
254 return IPV6_ADDR_RESERVED;
255 st &= htonl(0xFE000000);
256 if (st == htonl(0x02000000))
257 return IPV6_ADDR_RESERVED; /* for NSAP */
258 if (st == htonl(0x04000000))
259 return IPV6_ADDR_RESERVED; /* for IPX */
260 return type;
261} 265}
262 266
263static void addrconf_del_timer(struct inet6_ifaddr *ifp) 267static void addrconf_del_timer(struct inet6_ifaddr *ifp)
@@ -805,138 +809,275 @@ out:
805#endif 809#endif
806 810
807/* 811/*
808 * Choose an appropriate source address 812 * Choose an appropriate source address (RFC3484)
809 * should do:
810 * i) get an address with an appropriate scope
811 * ii) see if there is a specific route for the destination and use
812 * an address of the attached interface
813 * iii) don't use deprecated addresses
814 */ 813 */
815static int inline ipv6_saddr_pref(const struct inet6_ifaddr *ifp, u8 invpref) 814struct ipv6_saddr_score {
815 int addr_type;
816 unsigned int attrs;
817 int matchlen;
818 unsigned int scope;
819 unsigned int rule;
820};
821
822#define IPV6_SADDR_SCORE_LOCAL 0x0001
823#define IPV6_SADDR_SCORE_PREFERRED 0x0004
824#define IPV6_SADDR_SCORE_HOA 0x0008
825#define IPV6_SADDR_SCORE_OIF 0x0010
826#define IPV6_SADDR_SCORE_LABEL 0x0020
827#define IPV6_SADDR_SCORE_PRIVACY 0x0040
828
829static int inline ipv6_saddr_preferred(int type)
816{ 830{
817 int pref; 831 if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
818 pref = ifp->flags&IFA_F_DEPRECATED ? 0 : 2; 832 IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
819#ifdef CONFIG_IPV6_PRIVACY 833 return 1;
820 pref |= (ifp->flags^invpref)&IFA_F_TEMPORARY ? 0 : 1; 834 return 0;
821#endif
822 return pref;
823} 835}
824 836
825#ifdef CONFIG_IPV6_PRIVACY 837/* static matching label */
826#define IPV6_GET_SADDR_MAXSCORE(score) ((score) == 3) 838static int inline ipv6_saddr_label(const struct in6_addr *addr, int type)
827#else 839{
828#define IPV6_GET_SADDR_MAXSCORE(score) (score) 840 /*
829#endif 841 * prefix (longest match) label
842 * -----------------------------
843 * ::1/128 0
844 * ::/0 1
845 * 2002::/16 2
846 * ::/96 3
847 * ::ffff:0:0/96 4
848 */
849 if (type & IPV6_ADDR_LOOPBACK)
850 return 0;
851 else if (type & IPV6_ADDR_COMPATv4)
852 return 3;
853 else if (type & IPV6_ADDR_MAPPED)
854 return 4;
855 else if (addr->s6_addr16[0] == htons(0x2002))
856 return 2;
857 return 1;
858}
830 859
831int ipv6_dev_get_saddr(struct net_device *dev, 860int ipv6_dev_get_saddr(struct net_device *daddr_dev,
832 struct in6_addr *daddr, struct in6_addr *saddr) 861 struct in6_addr *daddr, struct in6_addr *saddr)
833{ 862{
834 struct inet6_ifaddr *ifp = NULL; 863 struct ipv6_saddr_score hiscore;
835 struct inet6_ifaddr *match = NULL; 864 struct inet6_ifaddr *ifa_result = NULL;
836 struct inet6_dev *idev; 865 int daddr_type = __ipv6_addr_type(daddr);
837 int scope; 866 int daddr_scope = __ipv6_addr_src_scope(daddr_type);
838 int err; 867 u32 daddr_label = ipv6_saddr_label(daddr, daddr_type);
839 int hiscore = -1, score; 868 struct net_device *dev;
840 869
841 scope = ipv6_addr_scope(daddr); 870 memset(&hiscore, 0, sizeof(hiscore));
842 871
843 /* 872 read_lock(&dev_base_lock);
844 * known dev 873 read_lock(&addrconf_lock);
845 * search dev and walk through dev addresses
846 */
847 874
848 if (dev) { 875 for (dev = dev_base; dev; dev=dev->next) {
849 if (dev->flags & IFF_LOOPBACK) 876 struct inet6_dev *idev;
850 scope = IFA_HOST; 877 struct inet6_ifaddr *ifa;
878
879 /* Rule 0: Candidate Source Address (section 4)
880 * - multicast and link-local destination address,
881 * the set of candidate source address MUST only
882 * include addresses assigned to interfaces
883 * belonging to the same link as the outgoing
884 * interface.
885 * (- For site-local destination addresses, the
886 * set of candidate source addresses MUST only
887 * include addresses assigned to interfaces
888 * belonging to the same site as the outgoing
889 * interface.)
890 */
891 if ((daddr_type & IPV6_ADDR_MULTICAST ||
892 daddr_scope <= IPV6_ADDR_SCOPE_LINKLOCAL) &&
893 daddr_dev && dev != daddr_dev)
894 continue;
851 895
852 read_lock(&addrconf_lock);
853 idev = __in6_dev_get(dev); 896 idev = __in6_dev_get(dev);
854 if (idev) { 897 if (!idev)
855 read_lock_bh(&idev->lock); 898 continue;
856 for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
857 if (ifp->scope == scope) {
858 if (ifp->flags&IFA_F_TENTATIVE)
859 continue;
860#ifdef CONFIG_IPV6_PRIVACY
861 score = ipv6_saddr_pref(ifp, idev->cnf.use_tempaddr > 1 ? IFA_F_TEMPORARY : 0);
862#else
863 score = ipv6_saddr_pref(ifp, 0);
864#endif
865 if (score <= hiscore)
866 continue;
867 899
868 if (match) 900 read_lock_bh(&idev->lock);
869 in6_ifa_put(match); 901 for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) {
870 match = ifp; 902 struct ipv6_saddr_score score;
871 hiscore = score;
872 in6_ifa_hold(ifp);
873 903
874 if (IPV6_GET_SADDR_MAXSCORE(score)) { 904 score.addr_type = __ipv6_addr_type(&ifa->addr);
875 read_unlock_bh(&idev->lock); 905
876 read_unlock(&addrconf_lock); 906 /* Rule 0: Candidate Source Address (section 4)
877 goto out; 907 * - In any case, anycast addresses, multicast
878 } 908 * addresses, and the unspecified address MUST
909 * NOT be included in a candidate set.
910 */
911 if (unlikely(score.addr_type == IPV6_ADDR_ANY ||
912 score.addr_type & IPV6_ADDR_MULTICAST)) {
913 LIMIT_NETDEBUG(KERN_DEBUG
914 "ADDRCONF: unspecified / multicast address"
915 "assigned as unicast address on %s",
916 dev->name);
917 continue;
918 }
919
920 score.attrs = 0;
921 score.matchlen = 0;
922 score.scope = 0;
923 score.rule = 0;
924
925 if (ifa_result == NULL) {
926 /* record it if the first available entry */
927 goto record_it;
928 }
929
930 /* Rule 1: Prefer same address */
931 if (hiscore.rule < 1) {
932 if (ipv6_addr_equal(&ifa_result->addr, daddr))
933 hiscore.attrs |= IPV6_SADDR_SCORE_LOCAL;
934 hiscore.rule++;
935 }
936 if (ipv6_addr_equal(&ifa->addr, daddr)) {
937 score.attrs |= IPV6_SADDR_SCORE_LOCAL;
938 if (!(hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)) {
939 score.rule = 1;
940 goto record_it;
879 } 941 }
942 } else {
943 if (hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)
944 continue;
880 } 945 }
881 read_unlock_bh(&idev->lock);
882 }
883 read_unlock(&addrconf_lock);
884 }
885 946
886 if (scope == IFA_LINK) 947 /* Rule 2: Prefer appropriate scope */
887 goto out; 948 if (hiscore.rule < 2) {
949 hiscore.scope = __ipv6_addr_src_scope(hiscore.addr_type);
950 hiscore.rule++;
951 }
952 score.scope = __ipv6_addr_src_scope(score.addr_type);
953 if (hiscore.scope < score.scope) {
954 if (hiscore.scope < daddr_scope) {
955 score.rule = 2;
956 goto record_it;
957 } else
958 continue;
959 } else if (score.scope < hiscore.scope) {
960 if (score.scope < daddr_scope)
961 continue;
962 else {
963 score.rule = 2;
964 goto record_it;
965 }
966 }
888 967
889 /* 968 /* Rule 3: Avoid deprecated address */
890 * dev == NULL or search failed for specified dev 969 if (hiscore.rule < 3) {
891 */ 970 if (ipv6_saddr_preferred(hiscore.addr_type) ||
971 !(ifa_result->flags & IFA_F_DEPRECATED))
972 hiscore.attrs |= IPV6_SADDR_SCORE_PREFERRED;
973 hiscore.rule++;
974 }
975 if (ipv6_saddr_preferred(score.addr_type) ||
976 !(ifa->flags & IFA_F_DEPRECATED)) {
977 score.attrs |= IPV6_SADDR_SCORE_PREFERRED;
978 if (!(hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)) {
979 score.rule = 3;
980 goto record_it;
981 }
982 } else {
983 if (hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)
984 continue;
985 }
892 986
893 read_lock(&dev_base_lock); 987 /* Rule 4: Prefer home address -- not implemented yet */
894 read_lock(&addrconf_lock);
895 for (dev = dev_base; dev; dev=dev->next) {
896 idev = __in6_dev_get(dev);
897 if (idev) {
898 read_lock_bh(&idev->lock);
899 for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
900 if (ifp->scope == scope) {
901 if (ifp->flags&IFA_F_TENTATIVE)
902 continue;
903#ifdef CONFIG_IPV6_PRIVACY
904 score = ipv6_saddr_pref(ifp, idev->cnf.use_tempaddr > 1 ? IFA_F_TEMPORARY : 0);
905#else
906 score = ipv6_saddr_pref(ifp, 0);
907#endif
908 if (score <= hiscore)
909 continue;
910 988
911 if (match) 989 /* Rule 5: Prefer outgoing interface */
912 in6_ifa_put(match); 990 if (hiscore.rule < 5) {
913 match = ifp; 991 if (daddr_dev == NULL ||
914 hiscore = score; 992 daddr_dev == ifa_result->idev->dev)
915 in6_ifa_hold(ifp); 993 hiscore.attrs |= IPV6_SADDR_SCORE_OIF;
994 hiscore.rule++;
995 }
996 if (daddr_dev == NULL ||
997 daddr_dev == ifa->idev->dev) {
998 score.attrs |= IPV6_SADDR_SCORE_OIF;
999 if (!(hiscore.attrs & IPV6_SADDR_SCORE_OIF)) {
1000 score.rule = 5;
1001 goto record_it;
1002 }
1003 } else {
1004 if (hiscore.attrs & IPV6_SADDR_SCORE_OIF)
1005 continue;
1006 }
916 1007
917 if (IPV6_GET_SADDR_MAXSCORE(score)) { 1008 /* Rule 6: Prefer matching label */
918 read_unlock_bh(&idev->lock); 1009 if (hiscore.rule < 6) {
919 goto out_unlock_base; 1010 if (ipv6_saddr_label(&ifa_result->addr, hiscore.addr_type) == daddr_label)
920 } 1011 hiscore.attrs |= IPV6_SADDR_SCORE_LABEL;
1012 hiscore.rule++;
1013 }
1014 if (ipv6_saddr_label(&ifa->addr, score.addr_type) == daddr_label) {
1015 score.attrs |= IPV6_SADDR_SCORE_LABEL;
1016 if (!(hiscore.attrs & IPV6_SADDR_SCORE_LABEL)) {
1017 score.rule = 6;
1018 goto record_it;
921 } 1019 }
1020 } else {
1021 if (hiscore.attrs & IPV6_SADDR_SCORE_LABEL)
1022 continue;
922 } 1023 }
923 read_unlock_bh(&idev->lock); 1024
1025#ifdef CONFIG_IPV6_PRIVACY
1026 /* Rule 7: Prefer public address
1027 * Note: prefer temprary address if use_tempaddr >= 2
1028 */
1029 if (hiscore.rule < 7) {
1030 if ((!(ifa_result->flags & IFA_F_TEMPORARY)) ^
1031 (ifa_result->idev->cnf.use_tempaddr >= 2))
1032 hiscore.attrs |= IPV6_SADDR_SCORE_PRIVACY;
1033 hiscore.rule++;
1034 }
1035 if ((!(ifa->flags & IFA_F_TEMPORARY)) ^
1036 (ifa->idev->cnf.use_tempaddr >= 2)) {
1037 score.attrs |= IPV6_SADDR_SCORE_PRIVACY;
1038 if (!(hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)) {
1039 score.rule = 7;
1040 goto record_it;
1041 }
1042 } else {
1043 if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
1044 continue;
1045 }
1046#endif
1047 /* Rule 8: Use longest matching prefix */
1048 if (hiscore.rule < 8)
1049 hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr);
1050 score.rule++;
1051 score.matchlen = ipv6_addr_diff(&ifa->addr, daddr);
1052 if (score.matchlen > hiscore.matchlen) {
1053 score.rule = 8;
1054 goto record_it;
1055 }
1056#if 0
1057 else if (score.matchlen < hiscore.matchlen)
1058 continue;
1059#endif
1060
1061 /* Final Rule: choose first available one */
1062 continue;
1063record_it:
1064 if (ifa_result)
1065 in6_ifa_put(ifa_result);
1066 in6_ifa_hold(ifa);
1067 ifa_result = ifa;
1068 hiscore = score;
924 } 1069 }
1070 read_unlock_bh(&idev->lock);
925 } 1071 }
926
927out_unlock_base:
928 read_unlock(&addrconf_lock); 1072 read_unlock(&addrconf_lock);
929 read_unlock(&dev_base_lock); 1073 read_unlock(&dev_base_lock);
930 1074
931out: 1075 if (!ifa_result)
932 err = -EADDRNOTAVAIL; 1076 return -EADDRNOTAVAIL;
933 if (match) { 1077
934 ipv6_addr_copy(saddr, &match->addr); 1078 ipv6_addr_copy(saddr, &ifa_result->addr);
935 err = 0; 1079 in6_ifa_put(ifa_result);
936 in6_ifa_put(match); 1080 return 0;
937 }
938
939 return err;
940} 1081}
941 1082
942 1083
@@ -2950,8 +3091,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
2950 3091
2951nlmsg_failure: 3092nlmsg_failure:
2952rtattr_failure: 3093rtattr_failure:
2953 if (array) 3094 kfree(array);
2954 kfree(array);
2955 skb_trim(skb, b - skb->data); 3095 skb_trim(skb, b - skb->data);
2956 return -1; 3096 return -1;
2957} 3097}
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 4fcc5a7acf6e..1bf6d9a769e6 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -127,56 +127,6 @@ static __inline__ int addr_bit_set(void *token, int fn_bit)
127 return htonl(1 << ((~fn_bit)&0x1F)) & addr[fn_bit>>5]; 127 return htonl(1 << ((~fn_bit)&0x1F)) & addr[fn_bit>>5];
128} 128}
129 129
130/*
131 * find the first different bit between two addresses
132 * length of address must be a multiple of 32bits
133 */
134
135static __inline__ int addr_diff(void *token1, void *token2, int addrlen)
136{
137 __u32 *a1 = token1;
138 __u32 *a2 = token2;
139 int i;
140
141 addrlen >>= 2;
142
143 for (i = 0; i < addrlen; i++) {
144 __u32 xb;
145
146 xb = a1[i] ^ a2[i];
147
148 if (xb) {
149 int j = 31;
150
151 xb = ntohl(xb);
152
153 while ((xb & (1 << j)) == 0)
154 j--;
155
156 return (i * 32 + 31 - j);
157 }
158 }
159
160 /*
161 * we should *never* get to this point since that
162 * would mean the addrs are equal
163 *
164 * However, we do get to it 8) And exacly, when
165 * addresses are equal 8)
166 *
167 * ip route add 1111::/128 via ...
168 * ip route add 1111::/64 via ...
169 * and we are here.
170 *
171 * Ideally, this function should stop comparison
172 * at prefix length. It does not, but it is still OK,
173 * if returned value is greater than prefix length.
174 * --ANK (980803)
175 */
176
177 return addrlen<<5;
178}
179
180static __inline__ struct fib6_node * node_alloc(void) 130static __inline__ struct fib6_node * node_alloc(void)
181{ 131{
182 struct fib6_node *fn; 132 struct fib6_node *fn;
@@ -296,11 +246,11 @@ insert_above:
296 246
297 /* find 1st bit in difference between the 2 addrs. 247 /* find 1st bit in difference between the 2 addrs.
298 248
299 See comment in addr_diff: bit may be an invalid value, 249 See comment in __ipv6_addr_diff: bit may be an invalid value,
300 but if it is >= plen, the value is ignored in any case. 250 but if it is >= plen, the value is ignored in any case.
301 */ 251 */
302 252
303 bit = addr_diff(addr, &key->addr, addrlen); 253 bit = __ipv6_addr_diff(addr, &key->addr, addrlen);
304 254
305 /* 255 /*
306 * (intermediate)[in] 256 * (intermediate)[in]
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 6e3480426939..a6026d2787d2 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -176,6 +176,11 @@ resubmit:
176 if (ipprot->flags & INET6_PROTO_FINAL) { 176 if (ipprot->flags & INET6_PROTO_FINAL) {
177 struct ipv6hdr *hdr; 177 struct ipv6hdr *hdr;
178 178
179 /* Free reference early: we don't need it any more,
180 and it may hold ip_conntrack module loaded
181 indefinitely. */
182 nf_reset(skb);
183
179 skb_postpull_rcsum(skb, skb->nh.raw, 184 skb_postpull_rcsum(skb, skb->nh.raw,
180 skb->h.raw - skb->nh.raw); 185 skb->h.raw - skb->nh.raw);
181 hdr = skb->nh.ipv6h; 186 hdr = skb->nh.ipv6h;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 614296a920c6..c1fa693511a1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -441,9 +441,15 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
441#ifdef CONFIG_NETFILTER 441#ifdef CONFIG_NETFILTER
442 to->nfmark = from->nfmark; 442 to->nfmark = from->nfmark;
443 /* Connection association is same as pre-frag packet */ 443 /* Connection association is same as pre-frag packet */
444 nf_conntrack_put(to->nfct);
444 to->nfct = from->nfct; 445 to->nfct = from->nfct;
445 nf_conntrack_get(to->nfct); 446 nf_conntrack_get(to->nfct);
446 to->nfctinfo = from->nfctinfo; 447 to->nfctinfo = from->nfctinfo;
448#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
449 nf_conntrack_put_reasm(to->nfct_reasm);
450 to->nfct_reasm = from->nfct_reasm;
451 nf_conntrack_get_reasm(to->nfct_reasm);
452#endif
447#ifdef CONFIG_BRIDGE_NETFILTER 453#ifdef CONFIG_BRIDGE_NETFILTER
448 nf_bridge_put(to->nf_bridge); 454 nf_bridge_put(to->nf_bridge);
449 to->nf_bridge = from->nf_bridge; 455 to->nf_bridge = from->nf_bridge;
@@ -587,8 +593,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
587 skb->next = NULL; 593 skb->next = NULL;
588 } 594 }
589 595
590 if (tmp_hdr) 596 kfree(tmp_hdr);
591 kfree(tmp_hdr);
592 597
593 if (err == 0) { 598 if (err == 0) {
594 IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); 599 IP6_INC_STATS(IPSTATS_MIB_FRAGOKS);
@@ -1186,10 +1191,8 @@ int ip6_push_pending_frames(struct sock *sk)
1186 1191
1187out: 1192out:
1188 inet->cork.flags &= ~IPCORK_OPT; 1193 inet->cork.flags &= ~IPCORK_OPT;
1189 if (np->cork.opt) { 1194 kfree(np->cork.opt);
1190 kfree(np->cork.opt); 1195 np->cork.opt = NULL;
1191 np->cork.opt = NULL;
1192 }
1193 if (np->cork.rt) { 1196 if (np->cork.rt) {
1194 dst_release(&np->cork.rt->u.dst); 1197 dst_release(&np->cork.rt->u.dst);
1195 np->cork.rt = NULL; 1198 np->cork.rt = NULL;
@@ -1214,10 +1217,8 @@ void ip6_flush_pending_frames(struct sock *sk)
1214 1217
1215 inet->cork.flags &= ~IPCORK_OPT; 1218 inet->cork.flags &= ~IPCORK_OPT;
1216 1219
1217 if (np->cork.opt) { 1220 kfree(np->cork.opt);
1218 kfree(np->cork.opt); 1221 np->cork.opt = NULL;
1219 np->cork.opt = NULL;
1220 }
1221 if (np->cork.rt) { 1222 if (np->cork.rt) {
1222 dst_release(&np->cork.rt->u.dst); 1223 dst_release(&np->cork.rt->u.dst);
1223 np->cork.rt = NULL; 1224 np->cork.rt = NULL;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index cf94372d1af3..e315d0f80af1 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -525,6 +525,7 @@ ip6ip6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
525 525
526 if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) { 526 if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) {
527 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 527 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
528 read_unlock(&ip6ip6_lock);
528 kfree_skb(skb); 529 kfree_skb(skb);
529 return 0; 530 return 0;
530 } 531 }
@@ -756,8 +757,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
756 } 757 }
757 ip6_tnl_dst_store(t, dst); 758 ip6_tnl_dst_store(t, dst);
758 759
759 if (opt) 760 kfree(opt);
760 kfree(opt);
761 761
762 t->recursion--; 762 t->recursion--;
763 return 0; 763 return 0;
@@ -766,8 +766,7 @@ tx_err_link_failure:
766 dst_link_failure(skb); 766 dst_link_failure(skb);
767tx_err_dst_release: 767tx_err_dst_release:
768 dst_release(dst); 768 dst_release(dst);
769 if (opt) 769 kfree(opt);
770 kfree(opt);
771tx_err: 770tx_err:
772 stats->tx_errors++; 771 stats->tx_errors++;
773 stats->tx_dropped++; 772 stats->tx_dropped++;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 85bfbc69b2c3..55917fb17094 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -130,8 +130,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s
130out_put_cpu: 130out_put_cpu:
131 put_cpu(); 131 put_cpu();
132out: 132out:
133 if (tmp_hdr) 133 kfree(tmp_hdr);
134 kfree(tmp_hdr);
135 if (err) 134 if (err)
136 goto error_out; 135 goto error_out;
137 return nexthdr; 136 return nexthdr;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 8567873d0dd8..003fd99ff597 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -80,8 +80,7 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
80 if (ra->sk == sk) { 80 if (ra->sk == sk) {
81 if (sel>=0) { 81 if (sel>=0) {
82 write_unlock_bh(&ip6_ra_lock); 82 write_unlock_bh(&ip6_ra_lock);
83 if (new_ra) 83 kfree(new_ra);
84 kfree(new_ra);
85 return -EADDRINUSE; 84 return -EADDRINUSE;
86 } 85 }
87 86
diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
index 37a4a99c9fe9..16482785bdfd 100644
--- a/net/ipv6/ipv6_syms.c
+++ b/net/ipv6/ipv6_syms.c
@@ -7,7 +7,7 @@
7#include <net/ip6_route.h> 7#include <net/ip6_route.h>
8#include <net/xfrm.h> 8#include <net/xfrm.h>
9 9
10EXPORT_SYMBOL(ipv6_addr_type); 10EXPORT_SYMBOL(__ipv6_addr_type);
11EXPORT_SYMBOL(icmpv6_send); 11EXPORT_SYMBOL(icmpv6_send);
12EXPORT_SYMBOL(icmpv6_statistics); 12EXPORT_SYMBOL(icmpv6_statistics);
13EXPORT_SYMBOL(icmpv6_err_convert); 13EXPORT_SYMBOL(icmpv6_err_convert);
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index bb7ccfe33f23..971ba60bf6e9 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -278,5 +278,19 @@ config IP6_NF_RAW
278 If you want to compile it as a module, say M here and read 278 If you want to compile it as a module, say M here and read
279 <file:Documentation/modules.txt>. If unsure, say `N'. 279 <file:Documentation/modules.txt>. If unsure, say `N'.
280 280
281config NF_CONNTRACK_IPV6
282 tristate "IPv6 support for new connection tracking (EXPERIMENTAL)"
283 depends on EXPERIMENTAL && NF_CONNTRACK
284 ---help---
285 Connection tracking keeps a record of what packets have passed
286 through your machine, in order to figure out how they are related
287 into connections.
288
289 This is IPv6 support on Layer 3 independent connection tracking.
290 Layer 3 independent connection tracking is experimental scheme
291 which generalize ip_conntrack to support other layer 3 protocols.
292
293 To compile it as a module, choose M here. If unsure, say N.
294
281endmenu 295endmenu
282 296
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 2b2c370e8b1c..9ab5b2ca1f59 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -27,3 +27,9 @@ obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
27obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o 27obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
28obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o 28obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
29obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o 29obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
30
31# objects for l3 independent conntrack
32nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
33
34# l3 independent conntrack
35obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o
diff --git a/net/ipv6/netfilter/ip6t_MARK.c b/net/ipv6/netfilter/ip6t_MARK.c
index 0c7584f92172..eab8fb864ee0 100644
--- a/net/ipv6/netfilter/ip6t_MARK.c
+++ b/net/ipv6/netfilter/ip6t_MARK.c
@@ -56,9 +56,9 @@ checkentry(const char *tablename,
56 return 1; 56 return 1;
57} 57}
58 58
59static struct ip6t_target ip6t_mark_reg = { 59static struct ip6t_target ip6t_mark_reg = {
60 .name = "MARK", 60 .name = "MARK",
61 .target = target, 61 .target = target,
62 .checkentry = checkentry, 62 .checkentry = checkentry,
63 .me = THIS_MODULE 63 .me = THIS_MODULE
64}; 64};
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
new file mode 100644
index 000000000000..e2c90b3a8074
--- /dev/null
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -0,0 +1,556 @@
1/*
2 * Copyright (C)2004 USAGI/WIDE Project
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Author:
9 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
10 *
11 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
12 * - support Layer 3 protocol independent connection tracking.
13 * Based on the original ip_conntrack code which had the following
14 * copyright information:
15 * (C) 1999-2001 Paul `Rusty' Russell
16 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
17 *
18 * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
19 * - add get_features() to support various size of conntrack
20 * structures.
21 */
22
23#include <linux/config.h>
24#include <linux/types.h>
25#include <linux/ipv6.h>
26#include <linux/in6.h>
27#include <linux/netfilter.h>
28#include <linux/module.h>
29#include <linux/skbuff.h>
30#include <linux/icmp.h>
31#include <linux/sysctl.h>
32#include <net/ipv6.h>
33
34#include <linux/netfilter_ipv6.h>
35#include <net/netfilter/nf_conntrack.h>
36#include <net/netfilter/nf_conntrack_helper.h>
37#include <net/netfilter/nf_conntrack_protocol.h>
38#include <net/netfilter/nf_conntrack_l3proto.h>
39#include <net/netfilter/nf_conntrack_core.h>
40
41#if 0
42#define DEBUGP printk
43#else
44#define DEBUGP(format, args...)
45#endif
46
47DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
48
49static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
50 struct nf_conntrack_tuple *tuple)
51{
52 u_int32_t _addrs[8], *ap;
53
54 ap = skb_header_pointer(skb, nhoff + offsetof(struct ipv6hdr, saddr),
55 sizeof(_addrs), _addrs);
56 if (ap == NULL)
57 return 0;
58
59 memcpy(tuple->src.u3.ip6, ap, sizeof(tuple->src.u3.ip6));
60 memcpy(tuple->dst.u3.ip6, ap + 4, sizeof(tuple->dst.u3.ip6));
61
62 return 1;
63}
64
65static int ipv6_invert_tuple(struct nf_conntrack_tuple *tuple,
66 const struct nf_conntrack_tuple *orig)
67{
68 memcpy(tuple->src.u3.ip6, orig->dst.u3.ip6, sizeof(tuple->src.u3.ip6));
69 memcpy(tuple->dst.u3.ip6, orig->src.u3.ip6, sizeof(tuple->dst.u3.ip6));
70
71 return 1;
72}
73
74static int ipv6_print_tuple(struct seq_file *s,
75 const struct nf_conntrack_tuple *tuple)
76{
77 return seq_printf(s, "src=%x:%x:%x:%x:%x:%x:%x:%x dst=%x:%x:%x:%x:%x:%x:%x:%x ",
78 NIP6(*((struct in6_addr *)tuple->src.u3.ip6)),
79 NIP6(*((struct in6_addr *)tuple->dst.u3.ip6)));
80}
81
82static int ipv6_print_conntrack(struct seq_file *s,
83 const struct nf_conn *conntrack)
84{
85 return 0;
86}
87
88/*
89 * Based on ipv6_skip_exthdr() in net/ipv6/exthdr.c
90 *
91 * This function parses (probably truncated) exthdr set "hdr"
92 * of length "len". "nexthdrp" initially points to some place,
93 * where type of the first header can be found.
94 *
95 * It skips all well-known exthdrs, and returns pointer to the start
96 * of unparsable area i.e. the first header with unknown type.
97 * if success, *nexthdr is updated by type/protocol of this header.
98 *
99 * NOTES: - it may return pointer pointing beyond end of packet,
100 * if the last recognized header is truncated in the middle.
101 * - if packet is truncated, so that all parsed headers are skipped,
102 * it returns -1.
103 * - if packet is fragmented, return pointer of the fragment header.
104 * - ESP is unparsable for now and considered like
105 * normal payload protocol.
106 * - Note also special handling of AUTH header. Thanks to IPsec wizards.
107 */
108
109int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp,
110 int len)
111{
112 u8 nexthdr = *nexthdrp;
113
114 while (ipv6_ext_hdr(nexthdr)) {
115 struct ipv6_opt_hdr hdr;
116 int hdrlen;
117
118 if (len < (int)sizeof(struct ipv6_opt_hdr))
119 return -1;
120 if (nexthdr == NEXTHDR_NONE)
121 break;
122 if (nexthdr == NEXTHDR_FRAGMENT)
123 break;
124 if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
125 BUG();
126 if (nexthdr == NEXTHDR_AUTH)
127 hdrlen = (hdr.hdrlen+2)<<2;
128 else
129 hdrlen = ipv6_optlen(&hdr);
130
131 nexthdr = hdr.nexthdr;
132 len -= hdrlen;
133 start += hdrlen;
134 }
135
136 *nexthdrp = nexthdr;
137 return start;
138}
139
140static int
141ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
142 u_int8_t *protonum)
143{
144 unsigned int extoff;
145 unsigned char pnum;
146 int protoff;
147
148 extoff = (u8*)((*pskb)->nh.ipv6h + 1) - (*pskb)->data;
149 pnum = (*pskb)->nh.ipv6h->nexthdr;
150
151 protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
152 (*pskb)->len - extoff);
153
154 /*
155 * (protoff == (*pskb)->len) mean that the packet doesn't have no data
156 * except of IPv6 & ext headers. but it's tracked anyway. - YK
157 */
158 if ((protoff < 0) || (protoff > (*pskb)->len)) {
159 DEBUGP("ip6_conntrack_core: can't find proto in pkt\n");
160 NF_CT_STAT_INC(error);
161 NF_CT_STAT_INC(invalid);
162 return -NF_ACCEPT;
163 }
164
165 *dataoff = protoff;
166 *protonum = pnum;
167 return NF_ACCEPT;
168}
169
170static u_int32_t ipv6_get_features(const struct nf_conntrack_tuple *tuple)
171{
172 return NF_CT_F_BASIC;
173}
174
175static unsigned int ipv6_confirm(unsigned int hooknum,
176 struct sk_buff **pskb,
177 const struct net_device *in,
178 const struct net_device *out,
179 int (*okfn)(struct sk_buff *))
180{
181 struct nf_conn *ct;
182 enum ip_conntrack_info ctinfo;
183
184 /* This is where we call the helper: as the packet goes out. */
185 ct = nf_ct_get(*pskb, &ctinfo);
186 if (ct && ct->helper) {
187 unsigned int ret, protoff;
188 unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1)
189 - (*pskb)->data;
190 unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr;
191
192 protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
193 (*pskb)->len - extoff);
194 if (protoff < 0 || protoff > (*pskb)->len ||
195 pnum == NEXTHDR_FRAGMENT) {
196 DEBUGP("proto header not found\n");
197 return NF_ACCEPT;
198 }
199
200 ret = ct->helper->help(pskb, protoff, ct, ctinfo);
201 if (ret != NF_ACCEPT)
202 return ret;
203 }
204
205 /* We've seen it coming out the other side: confirm it */
206
207 return nf_conntrack_confirm(pskb);
208}
209
210extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb);
211extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
212 struct net_device *in,
213 struct net_device *out,
214 int (*okfn)(struct sk_buff *));
215static unsigned int ipv6_defrag(unsigned int hooknum,
216 struct sk_buff **pskb,
217 const struct net_device *in,
218 const struct net_device *out,
219 int (*okfn)(struct sk_buff *))
220{
221 struct sk_buff *reasm;
222
223 /* Previously seen (loopback)? */
224 if ((*pskb)->nfct)
225 return NF_ACCEPT;
226
227 reasm = nf_ct_frag6_gather(*pskb);
228
229 /* queued */
230 if (reasm == NULL)
231 return NF_STOLEN;
232
233 /* error occured or not fragmented */
234 if (reasm == *pskb)
235 return NF_ACCEPT;
236
237 nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
238 (struct net_device *)out, okfn);
239
240 return NF_STOLEN;
241}
242
243static unsigned int ipv6_conntrack_in(unsigned int hooknum,
244 struct sk_buff **pskb,
245 const struct net_device *in,
246 const struct net_device *out,
247 int (*okfn)(struct sk_buff *))
248{
249 struct sk_buff *reasm = (*pskb)->nfct_reasm;
250
251 /* This packet is fragmented and has reassembled packet. */
252 if (reasm) {
253 /* Reassembled packet isn't parsed yet ? */
254 if (!reasm->nfct) {
255 unsigned int ret;
256
257 ret = nf_conntrack_in(PF_INET6, hooknum, &reasm);
258 if (ret != NF_ACCEPT)
259 return ret;
260 }
261 nf_conntrack_get(reasm->nfct);
262 (*pskb)->nfct = reasm->nfct;
263 return NF_ACCEPT;
264 }
265
266 return nf_conntrack_in(PF_INET6, hooknum, pskb);
267}
268
269static unsigned int ipv6_conntrack_local(unsigned int hooknum,
270 struct sk_buff **pskb,
271 const struct net_device *in,
272 const struct net_device *out,
273 int (*okfn)(struct sk_buff *))
274{
275 /* root is playing with raw sockets. */
276 if ((*pskb)->len < sizeof(struct ipv6hdr)) {
277 if (net_ratelimit())
278 printk("ipv6_conntrack_local: packet too short\n");
279 return NF_ACCEPT;
280 }
281 return ipv6_conntrack_in(hooknum, pskb, in, out, okfn);
282}
283
284/* Connection tracking may drop packets, but never alters them, so
285 make it the first hook. */
286static struct nf_hook_ops ipv6_conntrack_defrag_ops = {
287 .hook = ipv6_defrag,
288 .owner = THIS_MODULE,
289 .pf = PF_INET6,
290 .hooknum = NF_IP6_PRE_ROUTING,
291 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
292};
293
294static struct nf_hook_ops ipv6_conntrack_in_ops = {
295 .hook = ipv6_conntrack_in,
296 .owner = THIS_MODULE,
297 .pf = PF_INET6,
298 .hooknum = NF_IP6_PRE_ROUTING,
299 .priority = NF_IP6_PRI_CONNTRACK,
300};
301
302static struct nf_hook_ops ipv6_conntrack_local_out_ops = {
303 .hook = ipv6_conntrack_local,
304 .owner = THIS_MODULE,
305 .pf = PF_INET6,
306 .hooknum = NF_IP6_LOCAL_OUT,
307 .priority = NF_IP6_PRI_CONNTRACK,
308};
309
310static struct nf_hook_ops ipv6_conntrack_defrag_local_out_ops = {
311 .hook = ipv6_defrag,
312 .owner = THIS_MODULE,
313 .pf = PF_INET6,
314 .hooknum = NF_IP6_LOCAL_OUT,
315 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
316};
317
318/* Refragmenter; last chance. */
319static struct nf_hook_ops ipv6_conntrack_out_ops = {
320 .hook = ipv6_confirm,
321 .owner = THIS_MODULE,
322 .pf = PF_INET6,
323 .hooknum = NF_IP6_POST_ROUTING,
324 .priority = NF_IP6_PRI_LAST,
325};
326
327static struct nf_hook_ops ipv6_conntrack_local_in_ops = {
328 .hook = ipv6_confirm,
329 .owner = THIS_MODULE,
330 .pf = PF_INET6,
331 .hooknum = NF_IP6_LOCAL_IN,
332 .priority = NF_IP6_PRI_LAST-1,
333};
334
335#ifdef CONFIG_SYSCTL
336
337/* From nf_conntrack_proto_icmpv6.c */
338extern unsigned long nf_ct_icmpv6_timeout;
339
340/* From nf_conntrack_frag6.c */
341extern unsigned long nf_ct_frag6_timeout;
342extern unsigned long nf_ct_frag6_low_thresh;
343extern unsigned long nf_ct_frag6_high_thresh;
344
345static struct ctl_table_header *nf_ct_ipv6_sysctl_header;
346
347static ctl_table nf_ct_sysctl_table[] = {
348 {
349 .ctl_name = NET_NF_CONNTRACK_ICMPV6_TIMEOUT,
350 .procname = "nf_conntrack_icmpv6_timeout",
351 .data = &nf_ct_icmpv6_timeout,
352 .maxlen = sizeof(unsigned int),
353 .mode = 0644,
354 .proc_handler = &proc_dointvec_jiffies,
355 },
356 {
357 .ctl_name = NET_NF_CONNTRACK_FRAG6_TIMEOUT,
358 .procname = "nf_conntrack_frag6_timeout",
359 .data = &nf_ct_frag6_timeout,
360 .maxlen = sizeof(unsigned int),
361 .mode = 0644,
362 .proc_handler = &proc_dointvec_jiffies,
363 },
364 {
365 .ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH,
366 .procname = "nf_conntrack_frag6_low_thresh",
367 .data = &nf_ct_frag6_low_thresh,
368 .maxlen = sizeof(unsigned int),
369 .mode = 0644,
370 .proc_handler = &proc_dointvec_jiffies,
371 },
372 {
373 .ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
374 .procname = "nf_conntrack_frag6_high_thresh",
375 .data = &nf_ct_frag6_high_thresh,
376 .maxlen = sizeof(unsigned int),
377 .mode = 0644,
378 .proc_handler = &proc_dointvec_jiffies,
379 },
380 { .ctl_name = 0 }
381};
382
383static ctl_table nf_ct_netfilter_table[] = {
384 {
385 .ctl_name = NET_NETFILTER,
386 .procname = "netfilter",
387 .mode = 0555,
388 .child = nf_ct_sysctl_table,
389 },
390 { .ctl_name = 0 }
391};
392
393static ctl_table nf_ct_net_table[] = {
394 {
395 .ctl_name = CTL_NET,
396 .procname = "net",
397 .mode = 0555,
398 .child = nf_ct_netfilter_table,
399 },
400 { .ctl_name = 0 }
401};
402#endif
403
404struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
405 .l3proto = PF_INET6,
406 .name = "ipv6",
407 .pkt_to_tuple = ipv6_pkt_to_tuple,
408 .invert_tuple = ipv6_invert_tuple,
409 .print_tuple = ipv6_print_tuple,
410 .print_conntrack = ipv6_print_conntrack,
411 .prepare = ipv6_prepare,
412 .get_features = ipv6_get_features,
413 .me = THIS_MODULE,
414};
415
416extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp6;
417extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6;
418extern struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6;
419extern int nf_ct_frag6_init(void);
420extern void nf_ct_frag6_cleanup(void);
421static int init_or_cleanup(int init)
422{
423 int ret = 0;
424
425 if (!init) goto cleanup;
426
427 ret = nf_ct_frag6_init();
428 if (ret < 0) {
429 printk("nf_conntrack_ipv6: can't initialize frag6.\n");
430 goto cleanup_nothing;
431 }
432 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp6);
433 if (ret < 0) {
434 printk("nf_conntrack_ipv6: can't register tcp.\n");
435 goto cleanup_frag6;
436 }
437
438 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_udp6);
439 if (ret < 0) {
440 printk("nf_conntrack_ipv6: can't register udp.\n");
441 goto cleanup_tcp;
442 }
443
444 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_icmpv6);
445 if (ret < 0) {
446 printk("nf_conntrack_ipv6: can't register icmpv6.\n");
447 goto cleanup_udp;
448 }
449
450 ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6);
451 if (ret < 0) {
452 printk("nf_conntrack_ipv6: can't register ipv6\n");
453 goto cleanup_icmpv6;
454 }
455
456 ret = nf_register_hook(&ipv6_conntrack_defrag_ops);
457 if (ret < 0) {
458 printk("nf_conntrack_ipv6: can't register pre-routing defrag "
459 "hook.\n");
460 goto cleanup_ipv6;
461 }
462
463 ret = nf_register_hook(&ipv6_conntrack_defrag_local_out_ops);
464 if (ret < 0) {
465 printk("nf_conntrack_ipv6: can't register local_out defrag "
466 "hook.\n");
467 goto cleanup_defragops;
468 }
469
470 ret = nf_register_hook(&ipv6_conntrack_in_ops);
471 if (ret < 0) {
472 printk("nf_conntrack_ipv6: can't register pre-routing hook.\n");
473 goto cleanup_defraglocalops;
474 }
475
476 ret = nf_register_hook(&ipv6_conntrack_local_out_ops);
477 if (ret < 0) {
478 printk("nf_conntrack_ipv6: can't register local out hook.\n");
479 goto cleanup_inops;
480 }
481
482 ret = nf_register_hook(&ipv6_conntrack_out_ops);
483 if (ret < 0) {
484 printk("nf_conntrack_ipv6: can't register post-routing hook.\n");
485 goto cleanup_inandlocalops;
486 }
487
488 ret = nf_register_hook(&ipv6_conntrack_local_in_ops);
489 if (ret < 0) {
490 printk("nf_conntrack_ipv6: can't register local in hook.\n");
491 goto cleanup_inoutandlocalops;
492 }
493
494#ifdef CONFIG_SYSCTL
495 nf_ct_ipv6_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
496 if (nf_ct_ipv6_sysctl_header == NULL) {
497 printk("nf_conntrack: can't register to sysctl.\n");
498 ret = -ENOMEM;
499 goto cleanup_localinops;
500 }
501#endif
502 return ret;
503
504 cleanup:
505 synchronize_net();
506#ifdef CONFIG_SYSCTL
507 unregister_sysctl_table(nf_ct_ipv6_sysctl_header);
508 cleanup_localinops:
509#endif
510 nf_unregister_hook(&ipv6_conntrack_local_in_ops);
511 cleanup_inoutandlocalops:
512 nf_unregister_hook(&ipv6_conntrack_out_ops);
513 cleanup_inandlocalops:
514 nf_unregister_hook(&ipv6_conntrack_local_out_ops);
515 cleanup_inops:
516 nf_unregister_hook(&ipv6_conntrack_in_ops);
517 cleanup_defraglocalops:
518 nf_unregister_hook(&ipv6_conntrack_defrag_local_out_ops);
519 cleanup_defragops:
520 nf_unregister_hook(&ipv6_conntrack_defrag_ops);
521 cleanup_ipv6:
522 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
523 cleanup_icmpv6:
524 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmpv6);
525 cleanup_udp:
526 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp6);
527 cleanup_tcp:
528 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp6);
529 cleanup_frag6:
530 nf_ct_frag6_cleanup();
531 cleanup_nothing:
532 return ret;
533}
534
535MODULE_LICENSE("GPL");
536MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
537
538static int __init init(void)
539{
540 need_nf_conntrack();
541 return init_or_cleanup(1);
542}
543
544static void __exit fini(void)
545{
546 init_or_cleanup(0);
547}
548
549module_init(init);
550module_exit(fini);
551
552void need_ip6_conntrack(void)
553{
554}
555
556EXPORT_SYMBOL(need_ip6_conntrack);
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
new file mode 100644
index 000000000000..c0f1da5497a9
--- /dev/null
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -0,0 +1,272 @@
1/*
2 * Copyright (C)2003,2004 USAGI/WIDE Project
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Author:
9 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
10 *
11 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
12 * - ICMPv6 tracking support. Derived from the original ip_conntrack code
13 * net/ipv4/netfilter/ip_conntrack_proto_icmp.c which had the following
14 * copyright information:
15 * (C) 1999-2001 Paul `Rusty' Russell
16 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
17 */
18
19#include <linux/types.h>
20#include <linux/sched.h>
21#include <linux/timer.h>
22#include <linux/module.h>
23#include <linux/netfilter.h>
24#include <linux/in6.h>
25#include <linux/icmpv6.h>
26#include <linux/ipv6.h>
27#include <net/ipv6.h>
28#include <net/ip6_checksum.h>
29#include <linux/seq_file.h>
30#include <linux/netfilter_ipv6.h>
31#include <net/netfilter/nf_conntrack_tuple.h>
32#include <net/netfilter/nf_conntrack_protocol.h>
33#include <net/netfilter/nf_conntrack_core.h>
34#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
35
36unsigned long nf_ct_icmpv6_timeout = 30*HZ;
37
38#if 0
39#define DEBUGP printk
40#else
41#define DEBUGP(format, args...)
42#endif
43
44static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
45 unsigned int dataoff,
46 struct nf_conntrack_tuple *tuple)
47{
48 struct icmp6hdr _hdr, *hp;
49
50 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
51 if (hp == NULL)
52 return 0;
53 tuple->dst.u.icmp.type = hp->icmp6_type;
54 tuple->src.u.icmp.id = hp->icmp6_identifier;
55 tuple->dst.u.icmp.code = hp->icmp6_code;
56
57 return 1;
58}
59
60static int icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple,
61 const struct nf_conntrack_tuple *orig)
62{
63 /* Add 1; spaces filled with 0. */
64 static u_int8_t invmap[] = {
65 [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1,
66 [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1,
67 [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1,
68 [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1
69 };
70
71 __u8 type = orig->dst.u.icmp.type - 128;
72 if (type >= sizeof(invmap) || !invmap[type])
73 return 0;
74
75 tuple->src.u.icmp.id = orig->src.u.icmp.id;
76 tuple->dst.u.icmp.type = invmap[type] - 1;
77 tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
78 return 1;
79}
80
81/* Print out the per-protocol part of the tuple. */
82static int icmpv6_print_tuple(struct seq_file *s,
83 const struct nf_conntrack_tuple *tuple)
84{
85 return seq_printf(s, "type=%u code=%u id=%u ",
86 tuple->dst.u.icmp.type,
87 tuple->dst.u.icmp.code,
88 ntohs(tuple->src.u.icmp.id));
89}
90
91/* Print out the private part of the conntrack. */
92static int icmpv6_print_conntrack(struct seq_file *s,
93 const struct nf_conn *conntrack)
94{
95 return 0;
96}
97
98/* Returns verdict for packet, or -1 for invalid. */
99static int icmpv6_packet(struct nf_conn *ct,
100 const struct sk_buff *skb,
101 unsigned int dataoff,
102 enum ip_conntrack_info ctinfo,
103 int pf,
104 unsigned int hooknum)
105{
106 /* Try to delete connection immediately after all replies:
107 won't actually vanish as we still have skb, and del_timer
108 means this will only run once even if count hits zero twice
109 (theoretically possible with SMP) */
110 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
111 if (atomic_dec_and_test(&ct->proto.icmp.count)
112 && del_timer(&ct->timeout))
113 ct->timeout.function((unsigned long)ct);
114 } else {
115 atomic_inc(&ct->proto.icmp.count);
116 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
117 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
118 }
119
120 return NF_ACCEPT;
121}
122
123/* Called when a new connection for this protocol found. */
124static int icmpv6_new(struct nf_conn *conntrack,
125 const struct sk_buff *skb,
126 unsigned int dataoff)
127{
128 static u_int8_t valid_new[] = {
129 [ICMPV6_ECHO_REQUEST - 128] = 1,
130 [ICMPV6_NI_QUERY - 128] = 1
131 };
132
133 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type - 128 >= sizeof(valid_new)
134 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type - 128]) {
135 /* Can't create a new ICMPv6 `conn' with this. */
136 DEBUGP("icmp: can't create new conn with type %u\n",
137 conntrack->tuplehash[0].tuple.dst.u.icmp.type);
138 NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
139 return 0;
140 }
141 atomic_set(&conntrack->proto.icmp.count, 0);
142 return 1;
143}
144
145extern int
146nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp, int len);
147extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
148static int
149icmpv6_error_message(struct sk_buff *skb,
150 unsigned int icmp6off,
151 enum ip_conntrack_info *ctinfo,
152 unsigned int hooknum)
153{
154 struct nf_conntrack_tuple intuple, origtuple;
155 struct nf_conntrack_tuple_hash *h;
156 struct icmp6hdr _hdr, *hp;
157 unsigned int inip6off;
158 struct nf_conntrack_protocol *inproto;
159 u_int8_t inprotonum;
160 unsigned int inprotoff;
161
162 NF_CT_ASSERT(skb->nfct == NULL);
163
164 hp = skb_header_pointer(skb, icmp6off, sizeof(_hdr), &_hdr);
165 if (hp == NULL) {
166 DEBUGP("icmpv6_error: Can't get ICMPv6 hdr.\n");
167 return -NF_ACCEPT;
168 }
169
170 inip6off = icmp6off + sizeof(_hdr);
171 if (skb_copy_bits(skb, inip6off+offsetof(struct ipv6hdr, nexthdr),
172 &inprotonum, sizeof(inprotonum)) != 0) {
173 DEBUGP("icmpv6_error: Can't get nexthdr in inner IPv6 header.\n");
174 return -NF_ACCEPT;
175 }
176 inprotoff = nf_ct_ipv6_skip_exthdr(skb,
177 inip6off + sizeof(struct ipv6hdr),
178 &inprotonum,
179 skb->len - inip6off
180 - sizeof(struct ipv6hdr));
181
182 if ((inprotoff < 0) || (inprotoff > skb->len) ||
183 (inprotonum == NEXTHDR_FRAGMENT)) {
184 DEBUGP("icmpv6_error: Can't get protocol header in ICMPv6 payload.\n");
185 return -NF_ACCEPT;
186 }
187
188 inproto = nf_ct_find_proto(PF_INET6, inprotonum);
189
190 /* Are they talking about one of our connections? */
191 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
192 &origtuple, &nf_conntrack_l3proto_ipv6, inproto)) {
193 DEBUGP("icmpv6_error: Can't get tuple\n");
194 return -NF_ACCEPT;
195 }
196
197 /* Ordinarily, we'd expect the inverted tupleproto, but it's
198 been preserved inside the ICMP. */
199 if (!nf_ct_invert_tuple(&intuple, &origtuple,
200 &nf_conntrack_l3proto_ipv6, inproto)) {
201 DEBUGP("icmpv6_error: Can't invert tuple\n");
202 return -NF_ACCEPT;
203 }
204
205 *ctinfo = IP_CT_RELATED;
206
207 h = nf_conntrack_find_get(&intuple, NULL);
208 if (!h) {
209 DEBUGP("icmpv6_error: no match\n");
210 return -NF_ACCEPT;
211 } else {
212 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
213 *ctinfo += IP_CT_IS_REPLY;
214 }
215
216 /* Update skb to refer to this connection */
217 skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
218 skb->nfctinfo = *ctinfo;
219 return -NF_ACCEPT;
220}
221
222static int
223icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
224 enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
225{
226 struct icmp6hdr _ih, *icmp6h;
227
228 icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
229 if (icmp6h == NULL) {
230 if (LOG_INVALID(IPPROTO_ICMPV6))
231 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
232 "nf_ct_icmpv6: short packet ");
233 return -NF_ACCEPT;
234 }
235
236 if (hooknum != NF_IP6_PRE_ROUTING)
237 goto skipped;
238
239 /* Ignore it if the checksum's bogus. */
240 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
241 skb->len - dataoff, IPPROTO_ICMPV6,
242 skb_checksum(skb, dataoff,
243 skb->len - dataoff, 0))) {
244 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
245 "nf_ct_icmpv6: ICMPv6 checksum failed\n");
246 return -NF_ACCEPT;
247 }
248
249skipped:
250
251 /* is not error message ? */
252 if (icmp6h->icmp6_type >= 128)
253 return NF_ACCEPT;
254
255 return icmpv6_error_message(skb, dataoff, ctinfo, hooknum);
256}
257
258struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 =
259{
260 .l3proto = PF_INET6,
261 .proto = IPPROTO_ICMPV6,
262 .name = "icmpv6",
263 .pkt_to_tuple = icmpv6_pkt_to_tuple,
264 .invert_tuple = icmpv6_invert_tuple,
265 .print_tuple = icmpv6_print_tuple,
266 .print_conntrack = icmpv6_print_conntrack,
267 .packet = icmpv6_packet,
268 .new = icmpv6_new,
269 .error = icmpv6_error,
270};
271
272EXPORT_SYMBOL(nf_conntrack_protocol_icmpv6);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
new file mode 100644
index 000000000000..7640b9bb7694
--- /dev/null
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -0,0 +1,885 @@
1/*
2 * IPv6 fragment reassembly for connection tracking
3 *
4 * Copyright (C)2004 USAGI/WIDE Project
5 *
6 * Author:
7 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
8 *
9 * Based on: net/ipv6/reassembly.c
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16
17#include <linux/config.h>
18#include <linux/errno.h>
19#include <linux/types.h>
20#include <linux/string.h>
21#include <linux/socket.h>
22#include <linux/sockios.h>
23#include <linux/jiffies.h>
24#include <linux/net.h>
25#include <linux/list.h>
26#include <linux/netdevice.h>
27#include <linux/in6.h>
28#include <linux/ipv6.h>
29#include <linux/icmpv6.h>
30#include <linux/random.h>
31#include <linux/jhash.h>
32
33#include <net/sock.h>
34#include <net/snmp.h>
35
36#include <net/ipv6.h>
37#include <net/protocol.h>
38#include <net/transp_v6.h>
39#include <net/rawv6.h>
40#include <net/ndisc.h>
41#include <net/addrconf.h>
42#include <linux/sysctl.h>
43#include <linux/netfilter.h>
44#include <linux/netfilter_ipv6.h>
45#include <linux/kernel.h>
46#include <linux/module.h>
47
48#if 0
49#define DEBUGP printk
50#else
51#define DEBUGP(format, args...)
52#endif
53
54#define NF_CT_FRAG6_HIGH_THRESH 262144 /* == 256*1024 */
55#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */
56#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
57
58int nf_ct_frag6_high_thresh = 256*1024;
59int nf_ct_frag6_low_thresh = 192*1024;
60int nf_ct_frag6_timeout = IPV6_FRAG_TIMEOUT;
61
62struct nf_ct_frag6_skb_cb
63{
64 struct inet6_skb_parm h;
65 int offset;
66 struct sk_buff *orig;
67};
68
69#define NFCT_FRAG6_CB(skb) ((struct nf_ct_frag6_skb_cb*)((skb)->cb))
70
71struct nf_ct_frag6_queue
72{
73 struct nf_ct_frag6_queue *next;
74 struct list_head lru_list; /* lru list member */
75
76 __u32 id; /* fragment id */
77 struct in6_addr saddr;
78 struct in6_addr daddr;
79
80 spinlock_t lock;
81 atomic_t refcnt;
82 struct timer_list timer; /* expire timer */
83 struct sk_buff *fragments;
84 int len;
85 int meat;
86 struct timeval stamp;
87 unsigned int csum;
88 __u8 last_in; /* has first/last segment arrived? */
89#define COMPLETE 4
90#define FIRST_IN 2
91#define LAST_IN 1
92 __u16 nhoffset;
93 struct nf_ct_frag6_queue **pprev;
94};
95
96/* Hash table. */
97
98#define FRAG6Q_HASHSZ 64
99
100static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ];
101static rwlock_t nf_ct_frag6_lock = RW_LOCK_UNLOCKED;
102static u32 nf_ct_frag6_hash_rnd;
103static LIST_HEAD(nf_ct_frag6_lru_list);
104int nf_ct_frag6_nqueues = 0;
105
106static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq)
107{
108 if (fq->next)
109 fq->next->pprev = fq->pprev;
110 *fq->pprev = fq->next;
111 list_del(&fq->lru_list);
112 nf_ct_frag6_nqueues--;
113}
114
115static __inline__ void fq_unlink(struct nf_ct_frag6_queue *fq)
116{
117 write_lock(&nf_ct_frag6_lock);
118 __fq_unlink(fq);
119 write_unlock(&nf_ct_frag6_lock);
120}
121
122static unsigned int ip6qhashfn(u32 id, struct in6_addr *saddr,
123 struct in6_addr *daddr)
124{
125 u32 a, b, c;
126
127 a = saddr->s6_addr32[0];
128 b = saddr->s6_addr32[1];
129 c = saddr->s6_addr32[2];
130
131 a += JHASH_GOLDEN_RATIO;
132 b += JHASH_GOLDEN_RATIO;
133 c += nf_ct_frag6_hash_rnd;
134 __jhash_mix(a, b, c);
135
136 a += saddr->s6_addr32[3];
137 b += daddr->s6_addr32[0];
138 c += daddr->s6_addr32[1];
139 __jhash_mix(a, b, c);
140
141 a += daddr->s6_addr32[2];
142 b += daddr->s6_addr32[3];
143 c += id;
144 __jhash_mix(a, b, c);
145
146 return c & (FRAG6Q_HASHSZ - 1);
147}
148
149static struct timer_list nf_ct_frag6_secret_timer;
150int nf_ct_frag6_secret_interval = 10 * 60 * HZ;
151
152static void nf_ct_frag6_secret_rebuild(unsigned long dummy)
153{
154 unsigned long now = jiffies;
155 int i;
156
157 write_lock(&nf_ct_frag6_lock);
158 get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32));
159 for (i = 0; i < FRAG6Q_HASHSZ; i++) {
160 struct nf_ct_frag6_queue *q;
161
162 q = nf_ct_frag6_hash[i];
163 while (q) {
164 struct nf_ct_frag6_queue *next = q->next;
165 unsigned int hval = ip6qhashfn(q->id,
166 &q->saddr,
167 &q->daddr);
168
169 if (hval != i) {
170 /* Unlink. */
171 if (q->next)
172 q->next->pprev = q->pprev;
173 *q->pprev = q->next;
174
175 /* Relink to new hash chain. */
176 if ((q->next = nf_ct_frag6_hash[hval]) != NULL)
177 q->next->pprev = &q->next;
178 nf_ct_frag6_hash[hval] = q;
179 q->pprev = &nf_ct_frag6_hash[hval];
180 }
181
182 q = next;
183 }
184 }
185 write_unlock(&nf_ct_frag6_lock);
186
187 mod_timer(&nf_ct_frag6_secret_timer, now + nf_ct_frag6_secret_interval);
188}
189
190atomic_t nf_ct_frag6_mem = ATOMIC_INIT(0);
191
192/* Memory Tracking Functions. */
193static inline void frag_kfree_skb(struct sk_buff *skb)
194{
195 atomic_sub(skb->truesize, &nf_ct_frag6_mem);
196 if (NFCT_FRAG6_CB(skb)->orig)
197 kfree_skb(NFCT_FRAG6_CB(skb)->orig);
198
199 kfree_skb(skb);
200}
201
202static inline void frag_free_queue(struct nf_ct_frag6_queue *fq)
203{
204 atomic_sub(sizeof(struct nf_ct_frag6_queue), &nf_ct_frag6_mem);
205 kfree(fq);
206}
207
208static inline struct nf_ct_frag6_queue *frag_alloc_queue(void)
209{
210 struct nf_ct_frag6_queue *fq = kmalloc(sizeof(struct nf_ct_frag6_queue), GFP_ATOMIC);
211
212 if (!fq)
213 return NULL;
214 atomic_add(sizeof(struct nf_ct_frag6_queue), &nf_ct_frag6_mem);
215 return fq;
216}
217
218/* Destruction primitives. */
219
220/* Complete destruction of fq. */
221static void nf_ct_frag6_destroy(struct nf_ct_frag6_queue *fq)
222{
223 struct sk_buff *fp;
224
225 BUG_TRAP(fq->last_in&COMPLETE);
226 BUG_TRAP(del_timer(&fq->timer) == 0);
227
228 /* Release all fragment data. */
229 fp = fq->fragments;
230 while (fp) {
231 struct sk_buff *xp = fp->next;
232
233 frag_kfree_skb(fp);
234 fp = xp;
235 }
236
237 frag_free_queue(fq);
238}
239
240static __inline__ void fq_put(struct nf_ct_frag6_queue *fq)
241{
242 if (atomic_dec_and_test(&fq->refcnt))
243 nf_ct_frag6_destroy(fq);
244}
245
246/* Kill fq entry. It is not destroyed immediately,
247 * because caller (and someone more) holds reference count.
248 */
249static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
250{
251 if (del_timer(&fq->timer))
252 atomic_dec(&fq->refcnt);
253
254 if (!(fq->last_in & COMPLETE)) {
255 fq_unlink(fq);
256 atomic_dec(&fq->refcnt);
257 fq->last_in |= COMPLETE;
258 }
259}
260
261static void nf_ct_frag6_evictor(void)
262{
263 struct nf_ct_frag6_queue *fq;
264 struct list_head *tmp;
265
266 for (;;) {
267 if (atomic_read(&nf_ct_frag6_mem) <= nf_ct_frag6_low_thresh)
268 return;
269 read_lock(&nf_ct_frag6_lock);
270 if (list_empty(&nf_ct_frag6_lru_list)) {
271 read_unlock(&nf_ct_frag6_lock);
272 return;
273 }
274 tmp = nf_ct_frag6_lru_list.next;
275 fq = list_entry(tmp, struct nf_ct_frag6_queue, lru_list);
276 atomic_inc(&fq->refcnt);
277 read_unlock(&nf_ct_frag6_lock);
278
279 spin_lock(&fq->lock);
280 if (!(fq->last_in&COMPLETE))
281 fq_kill(fq);
282 spin_unlock(&fq->lock);
283
284 fq_put(fq);
285 }
286}
287
288static void nf_ct_frag6_expire(unsigned long data)
289{
290 struct nf_ct_frag6_queue *fq = (struct nf_ct_frag6_queue *) data;
291
292 spin_lock(&fq->lock);
293
294 if (fq->last_in & COMPLETE)
295 goto out;
296
297 fq_kill(fq);
298
299out:
300 spin_unlock(&fq->lock);
301 fq_put(fq);
302}
303
304/* Creation primitives. */
305
306
307static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
308 struct nf_ct_frag6_queue *fq_in)
309{
310 struct nf_ct_frag6_queue *fq;
311
312 write_lock(&nf_ct_frag6_lock);
313#ifdef CONFIG_SMP
314 for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) {
315 if (fq->id == fq_in->id &&
316 !ipv6_addr_cmp(&fq_in->saddr, &fq->saddr) &&
317 !ipv6_addr_cmp(&fq_in->daddr, &fq->daddr)) {
318 atomic_inc(&fq->refcnt);
319 write_unlock(&nf_ct_frag6_lock);
320 fq_in->last_in |= COMPLETE;
321 fq_put(fq_in);
322 return fq;
323 }
324 }
325#endif
326 fq = fq_in;
327
328 if (!mod_timer(&fq->timer, jiffies + nf_ct_frag6_timeout))
329 atomic_inc(&fq->refcnt);
330
331 atomic_inc(&fq->refcnt);
332 if ((fq->next = nf_ct_frag6_hash[hash]) != NULL)
333 fq->next->pprev = &fq->next;
334 nf_ct_frag6_hash[hash] = fq;
335 fq->pprev = &nf_ct_frag6_hash[hash];
336 INIT_LIST_HEAD(&fq->lru_list);
337 list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list);
338 nf_ct_frag6_nqueues++;
339 write_unlock(&nf_ct_frag6_lock);
340 return fq;
341}
342
343
344static struct nf_ct_frag6_queue *
345nf_ct_frag6_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr *dst)
346{
347 struct nf_ct_frag6_queue *fq;
348
349 if ((fq = frag_alloc_queue()) == NULL) {
350 DEBUGP("Can't alloc new queue\n");
351 goto oom;
352 }
353
354 memset(fq, 0, sizeof(struct nf_ct_frag6_queue));
355
356 fq->id = id;
357 ipv6_addr_copy(&fq->saddr, src);
358 ipv6_addr_copy(&fq->daddr, dst);
359
360 init_timer(&fq->timer);
361 fq->timer.function = nf_ct_frag6_expire;
362 fq->timer.data = (long) fq;
363 fq->lock = SPIN_LOCK_UNLOCKED;
364 atomic_set(&fq->refcnt, 1);
365
366 return nf_ct_frag6_intern(hash, fq);
367
368oom:
369 return NULL;
370}
371
372static __inline__ struct nf_ct_frag6_queue *
373fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst)
374{
375 struct nf_ct_frag6_queue *fq;
376 unsigned int hash = ip6qhashfn(id, src, dst);
377
378 read_lock(&nf_ct_frag6_lock);
379 for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) {
380 if (fq->id == id &&
381 !ipv6_addr_cmp(src, &fq->saddr) &&
382 !ipv6_addr_cmp(dst, &fq->daddr)) {
383 atomic_inc(&fq->refcnt);
384 read_unlock(&nf_ct_frag6_lock);
385 return fq;
386 }
387 }
388 read_unlock(&nf_ct_frag6_lock);
389
390 return nf_ct_frag6_create(hash, id, src, dst);
391}
392
393
394static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
395 struct frag_hdr *fhdr, int nhoff)
396{
397 struct sk_buff *prev, *next;
398 int offset, end;
399
400 if (fq->last_in & COMPLETE) {
401 DEBUGP("Allready completed\n");
402 goto err;
403 }
404
405 offset = ntohs(fhdr->frag_off) & ~0x7;
406 end = offset + (ntohs(skb->nh.ipv6h->payload_len) -
407 ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
408
409 if ((unsigned int)end > IPV6_MAXPLEN) {
410 DEBUGP("offset is too large.\n");
411 return -1;
412 }
413
414 if (skb->ip_summed == CHECKSUM_HW)
415 skb->csum = csum_sub(skb->csum,
416 csum_partial(skb->nh.raw,
417 (u8*)(fhdr + 1) - skb->nh.raw,
418 0));
419
420 /* Is this the final fragment? */
421 if (!(fhdr->frag_off & htons(IP6_MF))) {
422 /* If we already have some bits beyond end
423 * or have different end, the segment is corrupted.
424 */
425 if (end < fq->len ||
426 ((fq->last_in & LAST_IN) && end != fq->len)) {
427 DEBUGP("already received last fragment\n");
428 goto err;
429 }
430 fq->last_in |= LAST_IN;
431 fq->len = end;
432 } else {
433 /* Check if the fragment is rounded to 8 bytes.
434 * Required by the RFC.
435 */
436 if (end & 0x7) {
437 /* RFC2460 says always send parameter problem in
438 * this case. -DaveM
439 */
440 DEBUGP("the end of this fragment is not rounded to 8 bytes.\n");
441 return -1;
442 }
443 if (end > fq->len) {
444 /* Some bits beyond end -> corruption. */
445 if (fq->last_in & LAST_IN) {
446 DEBUGP("last packet already reached.\n");
447 goto err;
448 }
449 fq->len = end;
450 }
451 }
452
453 if (end == offset)
454 goto err;
455
456 /* Point into the IP datagram 'data' part. */
457 if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) {
458 DEBUGP("queue: message is too short.\n");
459 goto err;
460 }
461 if (end-offset < skb->len) {
462 if (pskb_trim(skb, end - offset)) {
463 DEBUGP("Can't trim\n");
464 goto err;
465 }
466 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
467 skb->ip_summed = CHECKSUM_NONE;
468 }
469
470 /* Find out which fragments are in front and at the back of us
471 * in the chain of fragments so far. We must know where to put
472 * this fragment, right?
473 */
474 prev = NULL;
475 for (next = fq->fragments; next != NULL; next = next->next) {
476 if (NFCT_FRAG6_CB(next)->offset >= offset)
477 break; /* bingo! */
478 prev = next;
479 }
480
481 /* We found where to put this one. Check for overlap with
482 * preceding fragment, and, if needed, align things so that
483 * any overlaps are eliminated.
484 */
485 if (prev) {
486 int i = (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset;
487
488 if (i > 0) {
489 offset += i;
490 if (end <= offset) {
491 DEBUGP("overlap\n");
492 goto err;
493 }
494 if (!pskb_pull(skb, i)) {
495 DEBUGP("Can't pull\n");
496 goto err;
497 }
498 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
499 skb->ip_summed = CHECKSUM_NONE;
500 }
501 }
502
503 /* Look for overlap with succeeding segments.
504 * If we can merge fragments, do it.
505 */
506 while (next && NFCT_FRAG6_CB(next)->offset < end) {
507 /* overlap is 'i' bytes */
508 int i = end - NFCT_FRAG6_CB(next)->offset;
509
510 if (i < next->len) {
511 /* Eat head of the next overlapped fragment
512 * and leave the loop. The next ones cannot overlap.
513 */
514 DEBUGP("Eat head of the overlapped parts.: %d", i);
515 if (!pskb_pull(next, i))
516 goto err;
517
518 /* next fragment */
519 NFCT_FRAG6_CB(next)->offset += i;
520 fq->meat -= i;
521 if (next->ip_summed != CHECKSUM_UNNECESSARY)
522 next->ip_summed = CHECKSUM_NONE;
523 break;
524 } else {
525 struct sk_buff *free_it = next;
526
527 /* Old fragmnet is completely overridden with
528 * new one drop it.
529 */
530 next = next->next;
531
532 if (prev)
533 prev->next = next;
534 else
535 fq->fragments = next;
536
537 fq->meat -= free_it->len;
538 frag_kfree_skb(free_it);
539 }
540 }
541
542 NFCT_FRAG6_CB(skb)->offset = offset;
543
544 /* Insert this fragment in the chain of fragments. */
545 skb->next = next;
546 if (prev)
547 prev->next = skb;
548 else
549 fq->fragments = skb;
550
551 skb->dev = NULL;
552 skb_get_timestamp(skb, &fq->stamp);
553 fq->meat += skb->len;
554 atomic_add(skb->truesize, &nf_ct_frag6_mem);
555
556 /* The first fragment.
557 * nhoffset is obtained from the first fragment, of course.
558 */
559 if (offset == 0) {
560 fq->nhoffset = nhoff;
561 fq->last_in |= FIRST_IN;
562 }
563 write_lock(&nf_ct_frag6_lock);
564 list_move_tail(&fq->lru_list, &nf_ct_frag6_lru_list);
565 write_unlock(&nf_ct_frag6_lock);
566 return 0;
567
568err:
569 return -1;
570}
571
572/*
573 * Check if this packet is complete.
574 * Returns NULL on failure by any reason, and pointer
575 * to current nexthdr field in reassembled frame.
576 *
577 * It is called with locked fq, and caller must check that
578 * queue is eligible for reassembly i.e. it is not COMPLETE,
579 * the last and the first frames arrived and all the bits are here.
580 */
581static struct sk_buff *
582nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
583{
584 struct sk_buff *fp, *op, *head = fq->fragments;
585 int payload_len;
586
587 fq_kill(fq);
588
589 BUG_TRAP(head != NULL);
590 BUG_TRAP(NFCT_FRAG6_CB(head)->offset == 0);
591
592 /* Unfragmented part is taken from the first segment. */
593 payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr);
594 if (payload_len > IPV6_MAXPLEN) {
595 DEBUGP("payload len is too large.\n");
596 goto out_oversize;
597 }
598
599 /* Head of list must not be cloned. */
600 if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) {
601 DEBUGP("skb is cloned but can't expand head");
602 goto out_oom;
603 }
604
605 /* If the first fragment is fragmented itself, we split
606 * it to two chunks: the first with data and paged part
607 * and the second, holding only fragments. */
608 if (skb_shinfo(head)->frag_list) {
609 struct sk_buff *clone;
610 int i, plen = 0;
611
612 if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL) {
613 DEBUGP("Can't alloc skb\n");
614 goto out_oom;
615 }
616 clone->next = head->next;
617 head->next = clone;
618 skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list;
619 skb_shinfo(head)->frag_list = NULL;
620 for (i=0; i<skb_shinfo(head)->nr_frags; i++)
621 plen += skb_shinfo(head)->frags[i].size;
622 clone->len = clone->data_len = head->data_len - plen;
623 head->data_len -= clone->len;
624 head->len -= clone->len;
625 clone->csum = 0;
626 clone->ip_summed = head->ip_summed;
627
628 NFCT_FRAG6_CB(clone)->orig = NULL;
629 atomic_add(clone->truesize, &nf_ct_frag6_mem);
630 }
631
632 /* We have to remove fragment header from datagram and to relocate
633 * header in order to calculate ICV correctly. */
634 head->nh.raw[fq->nhoffset] = head->h.raw[0];
635 memmove(head->head + sizeof(struct frag_hdr), head->head,
636 (head->data - head->head) - sizeof(struct frag_hdr));
637 head->mac.raw += sizeof(struct frag_hdr);
638 head->nh.raw += sizeof(struct frag_hdr);
639
640 skb_shinfo(head)->frag_list = head->next;
641 head->h.raw = head->data;
642 skb_push(head, head->data - head->nh.raw);
643 atomic_sub(head->truesize, &nf_ct_frag6_mem);
644
645 for (fp=head->next; fp; fp = fp->next) {
646 head->data_len += fp->len;
647 head->len += fp->len;
648 if (head->ip_summed != fp->ip_summed)
649 head->ip_summed = CHECKSUM_NONE;
650 else if (head->ip_summed == CHECKSUM_HW)
651 head->csum = csum_add(head->csum, fp->csum);
652 head->truesize += fp->truesize;
653 atomic_sub(fp->truesize, &nf_ct_frag6_mem);
654 }
655
656 head->next = NULL;
657 head->dev = dev;
658 skb_set_timestamp(head, &fq->stamp);
659 head->nh.ipv6h->payload_len = htons(payload_len);
660
661 /* Yes, and fold redundant checksum back. 8) */
662 if (head->ip_summed == CHECKSUM_HW)
663 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
664
665 fq->fragments = NULL;
666
667 /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */
668 fp = skb_shinfo(head)->frag_list;
669 if (NFCT_FRAG6_CB(fp)->orig == NULL)
670 /* at above code, head skb is divided into two skbs. */
671 fp = fp->next;
672
673 op = NFCT_FRAG6_CB(head)->orig;
674 for (; fp; fp = fp->next) {
675 struct sk_buff *orig = NFCT_FRAG6_CB(fp)->orig;
676
677 op->next = orig;
678 op = orig;
679 NFCT_FRAG6_CB(fp)->orig = NULL;
680 }
681
682 return head;
683
684out_oversize:
685 if (net_ratelimit())
686 printk(KERN_DEBUG "nf_ct_frag6_reasm: payload len = %d\n", payload_len);
687 goto out_fail;
688out_oom:
689 if (net_ratelimit())
690 printk(KERN_DEBUG "nf_ct_frag6_reasm: no memory for reassembly\n");
691out_fail:
692 return NULL;
693}
694
695/*
696 * find the header just before Fragment Header.
697 *
698 * if success return 0 and set ...
699 * (*prevhdrp): the value of "Next Header Field" in the header
700 * just before Fragment Header.
701 * (*prevhoff): the offset of "Next Header Field" in the header
702 * just before Fragment Header.
703 * (*fhoff) : the offset of Fragment Header.
704 *
705 * Based on ipv6_skip_hdr() in net/ipv6/exthdr.c
706 *
707 */
708static int
709find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
710{
711 u8 nexthdr = skb->nh.ipv6h->nexthdr;
712 u8 prev_nhoff = (u8 *)&skb->nh.ipv6h->nexthdr - skb->data;
713 int start = (u8 *)(skb->nh.ipv6h+1) - skb->data;
714 int len = skb->len - start;
715 u8 prevhdr = NEXTHDR_IPV6;
716
717 while (nexthdr != NEXTHDR_FRAGMENT) {
718 struct ipv6_opt_hdr hdr;
719 int hdrlen;
720
721 if (!ipv6_ext_hdr(nexthdr)) {
722 return -1;
723 }
724 if (len < (int)sizeof(struct ipv6_opt_hdr)) {
725 DEBUGP("too short\n");
726 return -1;
727 }
728 if (nexthdr == NEXTHDR_NONE) {
729 DEBUGP("next header is none\n");
730 return -1;
731 }
732 if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
733 BUG();
734 if (nexthdr == NEXTHDR_AUTH)
735 hdrlen = (hdr.hdrlen+2)<<2;
736 else
737 hdrlen = ipv6_optlen(&hdr);
738
739 prevhdr = nexthdr;
740 prev_nhoff = start;
741
742 nexthdr = hdr.nexthdr;
743 len -= hdrlen;
744 start += hdrlen;
745 }
746
747 if (len < 0)
748 return -1;
749
750 *prevhdrp = prevhdr;
751 *prevhoff = prev_nhoff;
752 *fhoff = start;
753
754 return 0;
755}
756
757struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
758{
759 struct sk_buff *clone;
760 struct net_device *dev = skb->dev;
761 struct frag_hdr *fhdr;
762 struct nf_ct_frag6_queue *fq;
763 struct ipv6hdr *hdr;
764 int fhoff, nhoff;
765 u8 prevhdr;
766 struct sk_buff *ret_skb = NULL;
767
768 /* Jumbo payload inhibits frag. header */
769 if (skb->nh.ipv6h->payload_len == 0) {
770 DEBUGP("payload len = 0\n");
771 return skb;
772 }
773
774 if (find_prev_fhdr(skb, &prevhdr, &nhoff, &fhoff) < 0)
775 return skb;
776
777 clone = skb_clone(skb, GFP_ATOMIC);
778 if (clone == NULL) {
779 DEBUGP("Can't clone skb\n");
780 return skb;
781 }
782
783 NFCT_FRAG6_CB(clone)->orig = skb;
784
785 if (!pskb_may_pull(clone, fhoff + sizeof(*fhdr))) {
786 DEBUGP("message is too short.\n");
787 goto ret_orig;
788 }
789
790 clone->h.raw = clone->data + fhoff;
791 hdr = clone->nh.ipv6h;
792 fhdr = (struct frag_hdr *)clone->h.raw;
793
794 if (!(fhdr->frag_off & htons(0xFFF9))) {
795 DEBUGP("Invalid fragment offset\n");
796 /* It is not a fragmented frame */
797 goto ret_orig;
798 }
799
800 if (atomic_read(&nf_ct_frag6_mem) > nf_ct_frag6_high_thresh)
801 nf_ct_frag6_evictor();
802
803 fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
804 if (fq == NULL) {
805 DEBUGP("Can't find and can't create new queue\n");
806 goto ret_orig;
807 }
808
809 spin_lock(&fq->lock);
810
811 if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
812 spin_unlock(&fq->lock);
813 DEBUGP("Can't insert skb to queue\n");
814 fq_put(fq);
815 goto ret_orig;
816 }
817
818 if (fq->last_in == (FIRST_IN|LAST_IN) && fq->meat == fq->len) {
819 ret_skb = nf_ct_frag6_reasm(fq, dev);
820 if (ret_skb == NULL)
821 DEBUGP("Can't reassemble fragmented packets\n");
822 }
823 spin_unlock(&fq->lock);
824
825 fq_put(fq);
826 return ret_skb;
827
828ret_orig:
829 kfree_skb(clone);
830 return skb;
831}
832
833void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
834 struct net_device *in, struct net_device *out,
835 int (*okfn)(struct sk_buff *))
836{
837 struct sk_buff *s, *s2;
838
839 for (s = NFCT_FRAG6_CB(skb)->orig; s;) {
840 nf_conntrack_put_reasm(s->nfct_reasm);
841 nf_conntrack_get_reasm(skb);
842 s->nfct_reasm = skb;
843
844 s2 = s->next;
845 NF_HOOK_THRESH(PF_INET6, hooknum, s, in, out, okfn,
846 NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
847 s = s2;
848 }
849 nf_conntrack_put_reasm(skb);
850}
851
852int nf_ct_frag6_kfree_frags(struct sk_buff *skb)
853{
854 struct sk_buff *s, *s2;
855
856 for (s = NFCT_FRAG6_CB(skb)->orig; s; s = s2) {
857
858 s2 = s->next;
859 kfree_skb(s);
860 }
861
862 kfree_skb(skb);
863
864 return 0;
865}
866
867int nf_ct_frag6_init(void)
868{
869 nf_ct_frag6_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
870 (jiffies ^ (jiffies >> 6)));
871
872 init_timer(&nf_ct_frag6_secret_timer);
873 nf_ct_frag6_secret_timer.function = nf_ct_frag6_secret_rebuild;
874 nf_ct_frag6_secret_timer.expires = jiffies
875 + nf_ct_frag6_secret_interval;
876 add_timer(&nf_ct_frag6_secret_timer);
877
878 return 0;
879}
880
881void nf_ct_frag6_cleanup(void)
882{
883 del_timer(&nf_ct_frag6_secret_timer);
884 nf_ct_frag6_evictor();
885}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index a1265a320b11..651c79b41eeb 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -174,8 +174,10 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
174 struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); 174 struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
175 175
176 /* Not releasing hash table! */ 176 /* Not releasing hash table! */
177 if (clone) 177 if (clone) {
178 nf_reset(clone);
178 rawv6_rcv(sk, clone); 179 rawv6_rcv(sk, clone);
180 }
179 } 181 }
180 sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr, 182 sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr,
181 IP6CB(skb)->iif); 183 IP6CB(skb)->iif);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 227e99ed510c..f7f42c3e96cb 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1710,7 +1710,7 @@ static void fib6_dump_end(struct netlink_callback *cb)
1710static int fib6_dump_done(struct netlink_callback *cb) 1710static int fib6_dump_done(struct netlink_callback *cb)
1711{ 1711{
1712 fib6_dump_end(cb); 1712 fib6_dump_end(cb);
1713 return cb->done(cb); 1713 return cb->done ? cb->done(cb) : 0;
1714} 1714}
1715 1715
1716int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) 1716int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index c4ba5fa1446a..3fefc822c1c0 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -194,8 +194,7 @@ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force)
194 194
195 /* Remove it from the log */ 195 /* Remove it from the log */
196 curr = hashbin_remove_this(log, (irda_queue_t *) curr); 196 curr = hashbin_remove_this(log, (irda_queue_t *) curr);
197 if (curr) 197 kfree(curr);
198 kfree(curr);
199 } 198 }
200 } 199 }
201 200
diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c
index 6fec428b4512..75f2666e8630 100644
--- a/net/irda/irias_object.c
+++ b/net/irda/irias_object.c
@@ -122,8 +122,7 @@ static void __irias_delete_attrib(struct ias_attrib *attrib)
122 IRDA_ASSERT(attrib != NULL, return;); 122 IRDA_ASSERT(attrib != NULL, return;);
123 IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;); 123 IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
124 124
125 if (attrib->name) 125 kfree(attrib->name);
126 kfree(attrib->name);
127 126
128 irias_delete_value(attrib->value); 127 irias_delete_value(attrib->value);
129 attrib->magic = ~IAS_ATTRIB_MAGIC; 128 attrib->magic = ~IAS_ATTRIB_MAGIC;
@@ -136,8 +135,7 @@ void __irias_delete_object(struct ias_object *obj)
136 IRDA_ASSERT(obj != NULL, return;); 135 IRDA_ASSERT(obj != NULL, return;);
137 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;); 136 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
138 137
139 if (obj->name) 138 kfree(obj->name);
140 kfree(obj->name);
141 139
142 hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib); 140 hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib);
143 141
@@ -562,14 +560,12 @@ void irias_delete_value(struct ias_value *value)
562 /* No need to deallocate */ 560 /* No need to deallocate */
563 break; 561 break;
564 case IAS_STRING: 562 case IAS_STRING:
565 /* If string, deallocate string */ 563 /* Deallocate string */
566 if (value->t.string != NULL) 564 kfree(value->t.string);
567 kfree(value->t.string);
568 break; 565 break;
569 case IAS_OCT_SEQ: 566 case IAS_OCT_SEQ:
570 /* If byte stream, deallocate byte stream */ 567 /* Deallocate byte stream */
571 if (value->t.oct_seq != NULL) 568 kfree(value->t.oct_seq);
572 kfree(value->t.oct_seq);
573 break; 569 break;
574 default: 570 default:
575 IRDA_DEBUG(0, "%s(), Unknown value type!\n", __FUNCTION__); 571 IRDA_DEBUG(0, "%s(), Unknown value type!\n", __FUNCTION__);
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 8296b38bf270..a84f9221e5f0 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -1,3 +1,6 @@
1menu "Core Netfilter Configuration"
2 depends on NET && NETFILTER
3
1config NETFILTER_NETLINK 4config NETFILTER_NETLINK
2 tristate "Netfilter netlink interface" 5 tristate "Netfilter netlink interface"
3 help 6 help
@@ -22,3 +25,74 @@ config NETFILTER_NETLINK_LOG
22 and is also scheduled to replace the old syslog-based ipt_LOG 25 and is also scheduled to replace the old syslog-based ipt_LOG
23 and ip6t_LOG modules. 26 and ip6t_LOG modules.
24 27
28config NF_CONNTRACK
29 tristate "Layer 3 Independent Connection tracking (EXPERIMENTAL)"
30 depends on EXPERIMENTAL && IP_NF_CONNTRACK=n
31 default n
32 ---help---
33 Connection tracking keeps a record of what packets have passed
34 through your machine, in order to figure out how they are related
35 into connections.
36
37 Layer 3 independent connection tracking is experimental scheme
38 which generalize ip_conntrack to support other layer 3 protocols.
39
40 To compile it as a module, choose M here. If unsure, say N.
41
42config NF_CT_ACCT
43 bool "Connection tracking flow accounting"
44 depends on NF_CONNTRACK
45 help
46 If this option is enabled, the connection tracking code will
47 keep per-flow packet and byte counters.
48
49 Those counters can be used for flow-based accounting or the
50 `connbytes' match.
51
52 If unsure, say `N'.
53
54config NF_CONNTRACK_MARK
55 bool 'Connection mark tracking support'
56 depends on NF_CONNTRACK
57 help
58 This option enables support for connection marks, used by the
59 `CONNMARK' target and `connmark' match. Similar to the mark value
60 of packets, but this mark value is kept in the conntrack session
61 instead of the individual packets.
62
63config NF_CONNTRACK_EVENTS
64 bool "Connection tracking events"
65 depends on NF_CONNTRACK
66 help
67 If this option is enabled, the connection tracking code will
68 provide a notifier chain that can be used by other kernel code
69 to get notified aboutchanges in the connection tracking state.
70
71 If unsure, say `N'.
72
73config NF_CT_PROTO_SCTP
74 tristate 'SCTP protocol on new connection tracking support (EXPERIMENTAL)'
75 depends on EXPERIMENTAL && NF_CONNTRACK
76 default n
77 help
78 With this option enabled, the layer 3 independent connection
79 tracking code will be able to do state tracking on SCTP connections.
80
81 If you want to compile it as a module, say M here and read
82 Documentation/modules.txt. If unsure, say `N'.
83
84config NF_CONNTRACK_FTP
85 tristate "FTP support on new connection tracking (EXPERIMENTAL)"
86 depends on EXPERIMENTAL && NF_CONNTRACK
87 help
88 Tracking FTP connections is problematic: special helpers are
89 required for tracking them, and doing masquerading and other forms
90 of Network Address Translation on them.
91
92 This is FTP support on Layer 3 independent connection tracking.
93 Layer 3 independent connection tracking is experimental scheme
94 which generalize ip_conntrack to support other layer 3 protocols.
95
96 To compile it as a module, choose M here. If unsure, say N.
97
98endmenu
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index b3b44f8b415a..55f019ad2c08 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -5,3 +5,11 @@ obj-$(CONFIG_NETFILTER) = netfilter.o
5obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o 5obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
6obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o 6obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
7obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o 7obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
8
9nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o
10
11obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
12obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o
13
14# SCTP protocol connection tracking
15obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
new file mode 100644
index 000000000000..9a67c796b385
--- /dev/null
+++ b/net/netfilter/nf_conntrack_core.c
@@ -0,0 +1,1538 @@
1/* Connection state tracking for netfilter. This is separated from,
2 but required by, the NAT layer; it can also be used by an iptables
3 extension. */
4
5/* (C) 1999-2001 Paul `Rusty' Russell
6 * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org>
7 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * 23 Apr 2001: Harald Welte <laforge@gnumonks.org>
14 * - new API and handling of conntrack/nat helpers
15 * - now capable of multiple expectations for one master
16 * 16 Jul 2002: Harald Welte <laforge@gnumonks.org>
17 * - add usage/reference counts to ip_conntrack_expect
18 * - export ip_conntrack[_expect]_{find_get,put} functions
19 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
20 * - generalize L3 protocol denendent part.
21 * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
22 * - add support various size of conntrack structures.
23 *
24 * Derived from net/ipv4/netfilter/ip_conntrack_core.c
25 */
26
27#include <linux/config.h>
28#include <linux/types.h>
29#include <linux/netfilter.h>
30#include <linux/module.h>
31#include <linux/skbuff.h>
32#include <linux/proc_fs.h>
33#include <linux/vmalloc.h>
34#include <linux/stddef.h>
35#include <linux/slab.h>
36#include <linux/random.h>
37#include <linux/jhash.h>
38#include <linux/err.h>
39#include <linux/percpu.h>
40#include <linux/moduleparam.h>
41#include <linux/notifier.h>
42#include <linux/kernel.h>
43#include <linux/netdevice.h>
44#include <linux/socket.h>
45
46/* This rwlock protects the main hash table, protocol/helper/expected
47 registrations, conntrack timers*/
48#define ASSERT_READ_LOCK(x)
49#define ASSERT_WRITE_LOCK(x)
50
51#include <net/netfilter/nf_conntrack.h>
52#include <net/netfilter/nf_conntrack_l3proto.h>
53#include <net/netfilter/nf_conntrack_protocol.h>
54#include <net/netfilter/nf_conntrack_helper.h>
55#include <net/netfilter/nf_conntrack_core.h>
56#include <linux/netfilter_ipv4/listhelp.h>
57
58#define NF_CONNTRACK_VERSION "0.4.1"
59
60#if 0
61#define DEBUGP printk
62#else
63#define DEBUGP(format, args...)
64#endif
65
66DEFINE_RWLOCK(nf_conntrack_lock);
67
68/* nf_conntrack_standalone needs this */
69atomic_t nf_conntrack_count = ATOMIC_INIT(0);
70
71void (*nf_conntrack_destroyed)(struct nf_conn *conntrack) = NULL;
72LIST_HEAD(nf_conntrack_expect_list);
73struct nf_conntrack_protocol **nf_ct_protos[PF_MAX];
74struct nf_conntrack_l3proto *nf_ct_l3protos[PF_MAX];
75static LIST_HEAD(helpers);
76unsigned int nf_conntrack_htable_size = 0;
77int nf_conntrack_max;
78struct list_head *nf_conntrack_hash;
79static kmem_cache_t *nf_conntrack_expect_cachep;
80struct nf_conn nf_conntrack_untracked;
81unsigned int nf_ct_log_invalid;
82static LIST_HEAD(unconfirmed);
83static int nf_conntrack_vmalloc;
84
85#ifdef CONFIG_NF_CONNTRACK_EVENTS
86struct notifier_block *nf_conntrack_chain;
87struct notifier_block *nf_conntrack_expect_chain;
88
89DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
90
91/* deliver cached events and clear cache entry - must be called with locally
92 * disabled softirqs */
93static inline void
94__nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
95{
96 DEBUGP("ecache: delivering events for %p\n", ecache->ct);
97 if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
98 && ecache->events)
99 notifier_call_chain(&nf_conntrack_chain, ecache->events,
100 ecache->ct);
101
102 ecache->events = 0;
103 nf_ct_put(ecache->ct);
104 ecache->ct = NULL;
105}
106
107/* Deliver all cached events for a particular conntrack. This is called
108 * by code prior to async packet handling for freeing the skb */
109void nf_ct_deliver_cached_events(const struct nf_conn *ct)
110{
111 struct nf_conntrack_ecache *ecache;
112
113 local_bh_disable();
114 ecache = &__get_cpu_var(nf_conntrack_ecache);
115 if (ecache->ct == ct)
116 __nf_ct_deliver_cached_events(ecache);
117 local_bh_enable();
118}
119
120/* Deliver cached events for old pending events, if current conntrack != old */
121void __nf_ct_event_cache_init(struct nf_conn *ct)
122{
123 struct nf_conntrack_ecache *ecache;
124
125 /* take care of delivering potentially old events */
126 ecache = &__get_cpu_var(nf_conntrack_ecache);
127 BUG_ON(ecache->ct == ct);
128 if (ecache->ct)
129 __nf_ct_deliver_cached_events(ecache);
130 /* initialize for this conntrack/packet */
131 ecache->ct = ct;
132 nf_conntrack_get(&ct->ct_general);
133}
134
135/* flush the event cache - touches other CPU's data and must not be called
136 * while packets are still passing through the code */
137static void nf_ct_event_cache_flush(void)
138{
139 struct nf_conntrack_ecache *ecache;
140 int cpu;
141
142 for_each_cpu(cpu) {
143 ecache = &per_cpu(nf_conntrack_ecache, cpu);
144 if (ecache->ct)
145 nf_ct_put(ecache->ct);
146 }
147}
148#else
149static inline void nf_ct_event_cache_flush(void) {}
150#endif /* CONFIG_NF_CONNTRACK_EVENTS */
151
152DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
153EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat);
154
155/*
156 * This scheme offers various size of "struct nf_conn" dependent on
157 * features(helper, nat, ...)
158 */
159
160#define NF_CT_FEATURES_NAMELEN 256
161static struct {
162 /* name of slab cache. printed in /proc/slabinfo */
163 char *name;
164
165 /* size of slab cache */
166 size_t size;
167
168 /* slab cache pointer */
169 kmem_cache_t *cachep;
170
171 /* allocated slab cache + modules which uses this slab cache */
172 int use;
173
174 /* Initialization */
175 int (*init_conntrack)(struct nf_conn *, u_int32_t);
176
177} nf_ct_cache[NF_CT_F_NUM];
178
179/* protect members of nf_ct_cache except of "use" */
180DEFINE_RWLOCK(nf_ct_cache_lock);
181
182/* This avoids calling kmem_cache_create() with same name simultaneously */
183DECLARE_MUTEX(nf_ct_cache_mutex);
184
185extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
186struct nf_conntrack_protocol *
187nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol)
188{
189 if (unlikely(nf_ct_protos[l3proto] == NULL))
190 return &nf_conntrack_generic_protocol;
191
192 return nf_ct_protos[l3proto][protocol];
193}
194
195static int nf_conntrack_hash_rnd_initted;
196static unsigned int nf_conntrack_hash_rnd;
197
198static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
199 unsigned int size, unsigned int rnd)
200{
201 unsigned int a, b;
202 a = jhash((void *)tuple->src.u3.all, sizeof(tuple->src.u3.all),
203 ((tuple->src.l3num) << 16) | tuple->dst.protonum);
204 b = jhash((void *)tuple->dst.u3.all, sizeof(tuple->dst.u3.all),
205 (tuple->src.u.all << 16) | tuple->dst.u.all);
206
207 return jhash_2words(a, b, rnd) % size;
208}
209
210static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
211{
212 return __hash_conntrack(tuple, nf_conntrack_htable_size,
213 nf_conntrack_hash_rnd);
214}
215
216/* Initialize "struct nf_conn" which has spaces for helper */
217static int
218init_conntrack_for_helper(struct nf_conn *conntrack, u_int32_t features)
219{
220
221 conntrack->help = (union nf_conntrack_help *)
222 (((unsigned long)conntrack->data
223 + (__alignof__(union nf_conntrack_help) - 1))
224 & (~((unsigned long)(__alignof__(union nf_conntrack_help) -1))));
225 return 0;
226}
227
228int nf_conntrack_register_cache(u_int32_t features, const char *name,
229 size_t size,
230 int (*init)(struct nf_conn *, u_int32_t))
231{
232 int ret = 0;
233 char *cache_name;
234 kmem_cache_t *cachep;
235
236 DEBUGP("nf_conntrack_register_cache: features=0x%x, name=%s, size=%d\n",
237 features, name, size);
238
239 if (features < NF_CT_F_BASIC || features >= NF_CT_F_NUM) {
240 DEBUGP("nf_conntrack_register_cache: invalid features.: 0x%x\n",
241 features);
242 return -EINVAL;
243 }
244
245 down(&nf_ct_cache_mutex);
246
247 write_lock_bh(&nf_ct_cache_lock);
248 /* e.g: multiple helpers are loaded */
249 if (nf_ct_cache[features].use > 0) {
250 DEBUGP("nf_conntrack_register_cache: already resisterd.\n");
251 if ((!strncmp(nf_ct_cache[features].name, name,
252 NF_CT_FEATURES_NAMELEN))
253 && nf_ct_cache[features].size == size
254 && nf_ct_cache[features].init_conntrack == init) {
255 DEBUGP("nf_conntrack_register_cache: reusing.\n");
256 nf_ct_cache[features].use++;
257 ret = 0;
258 } else
259 ret = -EBUSY;
260
261 write_unlock_bh(&nf_ct_cache_lock);
262 up(&nf_ct_cache_mutex);
263 return ret;
264 }
265 write_unlock_bh(&nf_ct_cache_lock);
266
267 /*
268 * The memory space for name of slab cache must be alive until
269 * cache is destroyed.
270 */
271 cache_name = kmalloc(sizeof(char)*NF_CT_FEATURES_NAMELEN, GFP_ATOMIC);
272 if (cache_name == NULL) {
273 DEBUGP("nf_conntrack_register_cache: can't alloc cache_name\n");
274 ret = -ENOMEM;
275 goto out_up_mutex;
276 }
277
278 if (strlcpy(cache_name, name, NF_CT_FEATURES_NAMELEN)
279 >= NF_CT_FEATURES_NAMELEN) {
280 printk("nf_conntrack_register_cache: name too long\n");
281 ret = -EINVAL;
282 goto out_free_name;
283 }
284
285 cachep = kmem_cache_create(cache_name, size, 0, 0,
286 NULL, NULL);
287 if (!cachep) {
288 printk("nf_conntrack_register_cache: Can't create slab cache "
289 "for the features = 0x%x\n", features);
290 ret = -ENOMEM;
291 goto out_free_name;
292 }
293
294 write_lock_bh(&nf_ct_cache_lock);
295 nf_ct_cache[features].use = 1;
296 nf_ct_cache[features].size = size;
297 nf_ct_cache[features].init_conntrack = init;
298 nf_ct_cache[features].cachep = cachep;
299 nf_ct_cache[features].name = cache_name;
300 write_unlock_bh(&nf_ct_cache_lock);
301
302 goto out_up_mutex;
303
304out_free_name:
305 kfree(cache_name);
306out_up_mutex:
307 up(&nf_ct_cache_mutex);
308 return ret;
309}
310
311/* FIXME: In the current, only nf_conntrack_cleanup() can call this function. */
312void nf_conntrack_unregister_cache(u_int32_t features)
313{
314 kmem_cache_t *cachep;
315 char *name;
316
317 /*
318 * This assures that kmem_cache_create() isn't called before destroying
319 * slab cache.
320 */
321 DEBUGP("nf_conntrack_unregister_cache: 0x%04x\n", features);
322 down(&nf_ct_cache_mutex);
323
324 write_lock_bh(&nf_ct_cache_lock);
325 if (--nf_ct_cache[features].use > 0) {
326 write_unlock_bh(&nf_ct_cache_lock);
327 up(&nf_ct_cache_mutex);
328 return;
329 }
330 cachep = nf_ct_cache[features].cachep;
331 name = nf_ct_cache[features].name;
332 nf_ct_cache[features].cachep = NULL;
333 nf_ct_cache[features].name = NULL;
334 nf_ct_cache[features].init_conntrack = NULL;
335 nf_ct_cache[features].size = 0;
336 write_unlock_bh(&nf_ct_cache_lock);
337
338 synchronize_net();
339
340 kmem_cache_destroy(cachep);
341 kfree(name);
342
343 up(&nf_ct_cache_mutex);
344}
345
346int
347nf_ct_get_tuple(const struct sk_buff *skb,
348 unsigned int nhoff,
349 unsigned int dataoff,
350 u_int16_t l3num,
351 u_int8_t protonum,
352 struct nf_conntrack_tuple *tuple,
353 const struct nf_conntrack_l3proto *l3proto,
354 const struct nf_conntrack_protocol *protocol)
355{
356 NF_CT_TUPLE_U_BLANK(tuple);
357
358 tuple->src.l3num = l3num;
359 if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0)
360 return 0;
361
362 tuple->dst.protonum = protonum;
363 tuple->dst.dir = IP_CT_DIR_ORIGINAL;
364
365 return protocol->pkt_to_tuple(skb, dataoff, tuple);
366}
367
368int
369nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
370 const struct nf_conntrack_tuple *orig,
371 const struct nf_conntrack_l3proto *l3proto,
372 const struct nf_conntrack_protocol *protocol)
373{
374 NF_CT_TUPLE_U_BLANK(inverse);
375
376 inverse->src.l3num = orig->src.l3num;
377 if (l3proto->invert_tuple(inverse, orig) == 0)
378 return 0;
379
380 inverse->dst.dir = !orig->dst.dir;
381
382 inverse->dst.protonum = orig->dst.protonum;
383 return protocol->invert_tuple(inverse, orig);
384}
385
386/* nf_conntrack_expect helper functions */
387static void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
388{
389 ASSERT_WRITE_LOCK(&nf_conntrack_lock);
390 NF_CT_ASSERT(!timer_pending(&exp_timeout));
391 list_del(&exp->list);
392 NF_CT_STAT_INC(expect_delete);
393 exp->master->expecting--;
394 nf_conntrack_expect_put(exp);
395}
396
397static void expectation_timed_out(unsigned long ul_expect)
398{
399 struct nf_conntrack_expect *exp = (void *)ul_expect;
400
401 write_lock_bh(&nf_conntrack_lock);
402 nf_ct_unlink_expect(exp);
403 write_unlock_bh(&nf_conntrack_lock);
404 nf_conntrack_expect_put(exp);
405}
406
407/* If an expectation for this connection is found, it gets delete from
408 * global list then returned. */
409static struct nf_conntrack_expect *
410find_expectation(const struct nf_conntrack_tuple *tuple)
411{
412 struct nf_conntrack_expect *i;
413
414 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
415 /* If master is not in hash table yet (ie. packet hasn't left
416 this machine yet), how can other end know about expected?
417 Hence these are not the droids you are looking for (if
418 master ct never got confirmed, we'd hold a reference to it
419 and weird things would happen to future packets). */
420 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)
421 && nf_ct_is_confirmed(i->master)) {
422 if (i->flags & NF_CT_EXPECT_PERMANENT) {
423 atomic_inc(&i->use);
424 return i;
425 } else if (del_timer(&i->timeout)) {
426 nf_ct_unlink_expect(i);
427 return i;
428 }
429 }
430 }
431 return NULL;
432}
433
434/* delete all expectations for this conntrack */
435static void remove_expectations(struct nf_conn *ct)
436{
437 struct nf_conntrack_expect *i, *tmp;
438
439 /* Optimization: most connection never expect any others. */
440 if (ct->expecting == 0)
441 return;
442
443 list_for_each_entry_safe(i, tmp, &nf_conntrack_expect_list, list) {
444 if (i->master == ct && del_timer(&i->timeout)) {
445 nf_ct_unlink_expect(i);
446 nf_conntrack_expect_put(i);
447 }
448 }
449}
450
451static void
452clean_from_lists(struct nf_conn *ct)
453{
454 unsigned int ho, hr;
455
456 DEBUGP("clean_from_lists(%p)\n", ct);
457 ASSERT_WRITE_LOCK(&nf_conntrack_lock);
458
459 ho = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
460 hr = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
461 LIST_DELETE(&nf_conntrack_hash[ho], &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
462 LIST_DELETE(&nf_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]);
463
464 /* Destroy all pending expectations */
465 remove_expectations(ct);
466}
467
468static void
469destroy_conntrack(struct nf_conntrack *nfct)
470{
471 struct nf_conn *ct = (struct nf_conn *)nfct;
472 struct nf_conntrack_l3proto *l3proto;
473 struct nf_conntrack_protocol *proto;
474
475 DEBUGP("destroy_conntrack(%p)\n", ct);
476 NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
477 NF_CT_ASSERT(!timer_pending(&ct->timeout));
478
479 nf_conntrack_event(IPCT_DESTROY, ct);
480 set_bit(IPS_DYING_BIT, &ct->status);
481
482 /* To make sure we don't get any weird locking issues here:
483 * destroy_conntrack() MUST NOT be called with a write lock
484 * to nf_conntrack_lock!!! -HW */
485 l3proto = nf_ct_find_l3proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num);
486 if (l3proto && l3proto->destroy)
487 l3proto->destroy(ct);
488
489 proto = nf_ct_find_proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num,
490 ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum);
491 if (proto && proto->destroy)
492 proto->destroy(ct);
493
494 if (nf_conntrack_destroyed)
495 nf_conntrack_destroyed(ct);
496
497 write_lock_bh(&nf_conntrack_lock);
498 /* Expectations will have been removed in clean_from_lists,
499 * except TFTP can create an expectation on the first packet,
500 * before connection is in the list, so we need to clean here,
501 * too. */
502 remove_expectations(ct);
503
504 /* We overload first tuple to link into unconfirmed list. */
505 if (!nf_ct_is_confirmed(ct)) {
506 BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list));
507 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
508 }
509
510 NF_CT_STAT_INC(delete);
511 write_unlock_bh(&nf_conntrack_lock);
512
513 if (ct->master)
514 nf_ct_put(ct->master);
515
516 DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
517 nf_conntrack_free(ct);
518}
519
520static void death_by_timeout(unsigned long ul_conntrack)
521{
522 struct nf_conn *ct = (void *)ul_conntrack;
523
524 write_lock_bh(&nf_conntrack_lock);
525 /* Inside lock so preempt is disabled on module removal path.
526 * Otherwise we can get spurious warnings. */
527 NF_CT_STAT_INC(delete_list);
528 clean_from_lists(ct);
529 write_unlock_bh(&nf_conntrack_lock);
530 nf_ct_put(ct);
531}
532
533static inline int
534conntrack_tuple_cmp(const struct nf_conntrack_tuple_hash *i,
535 const struct nf_conntrack_tuple *tuple,
536 const struct nf_conn *ignored_conntrack)
537{
538 ASSERT_READ_LOCK(&nf_conntrack_lock);
539 return nf_ct_tuplehash_to_ctrack(i) != ignored_conntrack
540 && nf_ct_tuple_equal(tuple, &i->tuple);
541}
542
543static struct nf_conntrack_tuple_hash *
544__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
545 const struct nf_conn *ignored_conntrack)
546{
547 struct nf_conntrack_tuple_hash *h;
548 unsigned int hash = hash_conntrack(tuple);
549
550 ASSERT_READ_LOCK(&nf_conntrack_lock);
551 list_for_each_entry(h, &nf_conntrack_hash[hash], list) {
552 if (conntrack_tuple_cmp(h, tuple, ignored_conntrack)) {
553 NF_CT_STAT_INC(found);
554 return h;
555 }
556 NF_CT_STAT_INC(searched);
557 }
558
559 return NULL;
560}
561
562/* Find a connection corresponding to a tuple. */
563struct nf_conntrack_tuple_hash *
564nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
565 const struct nf_conn *ignored_conntrack)
566{
567 struct nf_conntrack_tuple_hash *h;
568
569 read_lock_bh(&nf_conntrack_lock);
570 h = __nf_conntrack_find(tuple, ignored_conntrack);
571 if (h)
572 atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
573 read_unlock_bh(&nf_conntrack_lock);
574
575 return h;
576}
577
578/* Confirm a connection given skb; places it in hash table */
579int
580__nf_conntrack_confirm(struct sk_buff **pskb)
581{
582 unsigned int hash, repl_hash;
583 struct nf_conn *ct;
584 enum ip_conntrack_info ctinfo;
585
586 ct = nf_ct_get(*pskb, &ctinfo);
587
588 /* ipt_REJECT uses nf_conntrack_attach to attach related
589 ICMP/TCP RST packets in other direction. Actual packet
590 which created connection will be IP_CT_NEW or for an
591 expected connection, IP_CT_RELATED. */
592 if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
593 return NF_ACCEPT;
594
595 hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
596 repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
597
598 /* We're not in hash table, and we refuse to set up related
599 connections for unconfirmed conns. But packet copies and
600 REJECT will give spurious warnings here. */
601 /* NF_CT_ASSERT(atomic_read(&ct->ct_general.use) == 1); */
602
603 /* No external references means noone else could have
604 confirmed us. */
605 NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
606 DEBUGP("Confirming conntrack %p\n", ct);
607
608 write_lock_bh(&nf_conntrack_lock);
609
610 /* See if there's one in the list already, including reverse:
611 NAT could have grabbed it without realizing, since we're
612 not in the hash. If there is, we lost race. */
613 if (!LIST_FIND(&nf_conntrack_hash[hash],
614 conntrack_tuple_cmp,
615 struct nf_conntrack_tuple_hash *,
616 &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, NULL)
617 && !LIST_FIND(&nf_conntrack_hash[repl_hash],
618 conntrack_tuple_cmp,
619 struct nf_conntrack_tuple_hash *,
620 &ct->tuplehash[IP_CT_DIR_REPLY].tuple, NULL)) {
621 /* Remove from unconfirmed list */
622 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
623
624 list_prepend(&nf_conntrack_hash[hash],
625 &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
626 list_prepend(&nf_conntrack_hash[repl_hash],
627 &ct->tuplehash[IP_CT_DIR_REPLY]);
628 /* Timer relative to confirmation time, not original
629 setting time, otherwise we'd get timer wrap in
630 weird delay cases. */
631 ct->timeout.expires += jiffies;
632 add_timer(&ct->timeout);
633 atomic_inc(&ct->ct_general.use);
634 set_bit(IPS_CONFIRMED_BIT, &ct->status);
635 NF_CT_STAT_INC(insert);
636 write_unlock_bh(&nf_conntrack_lock);
637 if (ct->helper)
638 nf_conntrack_event_cache(IPCT_HELPER, *pskb);
639#ifdef CONFIG_NF_NAT_NEEDED
640 if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) ||
641 test_bit(IPS_DST_NAT_DONE_BIT, &ct->status))
642 nf_conntrack_event_cache(IPCT_NATINFO, *pskb);
643#endif
644 nf_conntrack_event_cache(master_ct(ct) ?
645 IPCT_RELATED : IPCT_NEW, *pskb);
646 return NF_ACCEPT;
647 }
648
649 NF_CT_STAT_INC(insert_failed);
650 write_unlock_bh(&nf_conntrack_lock);
651 return NF_DROP;
652}
653
654/* Returns true if a connection correspondings to the tuple (required
655 for NAT). */
656int
657nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
658 const struct nf_conn *ignored_conntrack)
659{
660 struct nf_conntrack_tuple_hash *h;
661
662 read_lock_bh(&nf_conntrack_lock);
663 h = __nf_conntrack_find(tuple, ignored_conntrack);
664 read_unlock_bh(&nf_conntrack_lock);
665
666 return h != NULL;
667}
668
669/* There's a small race here where we may free a just-assured
670 connection. Too bad: we're in trouble anyway. */
671static inline int unreplied(const struct nf_conntrack_tuple_hash *i)
672{
673 return !(test_bit(IPS_ASSURED_BIT,
674 &nf_ct_tuplehash_to_ctrack(i)->status));
675}
676
677static int early_drop(struct list_head *chain)
678{
679 /* Traverse backwards: gives us oldest, which is roughly LRU */
680 struct nf_conntrack_tuple_hash *h;
681 struct nf_conn *ct = NULL;
682 int dropped = 0;
683
684 read_lock_bh(&nf_conntrack_lock);
685 h = LIST_FIND_B(chain, unreplied, struct nf_conntrack_tuple_hash *);
686 if (h) {
687 ct = nf_ct_tuplehash_to_ctrack(h);
688 atomic_inc(&ct->ct_general.use);
689 }
690 read_unlock_bh(&nf_conntrack_lock);
691
692 if (!ct)
693 return dropped;
694
695 if (del_timer(&ct->timeout)) {
696 death_by_timeout((unsigned long)ct);
697 dropped = 1;
698 NF_CT_STAT_INC(early_drop);
699 }
700 nf_ct_put(ct);
701 return dropped;
702}
703
704static inline int helper_cmp(const struct nf_conntrack_helper *i,
705 const struct nf_conntrack_tuple *rtuple)
706{
707 return nf_ct_tuple_mask_cmp(rtuple, &i->tuple, &i->mask);
708}
709
710static struct nf_conntrack_helper *
711nf_ct_find_helper(const struct nf_conntrack_tuple *tuple)
712{
713 return LIST_FIND(&helpers, helper_cmp,
714 struct nf_conntrack_helper *,
715 tuple);
716}
717
718static struct nf_conn *
719__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
720 const struct nf_conntrack_tuple *repl,
721 const struct nf_conntrack_l3proto *l3proto)
722{
723 struct nf_conn *conntrack = NULL;
724 u_int32_t features = 0;
725
726 if (!nf_conntrack_hash_rnd_initted) {
727 get_random_bytes(&nf_conntrack_hash_rnd, 4);
728 nf_conntrack_hash_rnd_initted = 1;
729 }
730
731 if (nf_conntrack_max
732 && atomic_read(&nf_conntrack_count) >= nf_conntrack_max) {
733 unsigned int hash = hash_conntrack(orig);
734 /* Try dropping from this hash chain. */
735 if (!early_drop(&nf_conntrack_hash[hash])) {
736 if (net_ratelimit())
737 printk(KERN_WARNING
738 "nf_conntrack: table full, dropping"
739 " packet.\n");
740 return ERR_PTR(-ENOMEM);
741 }
742 }
743
744 /* find features needed by this conntrack. */
745 features = l3proto->get_features(orig);
746 read_lock_bh(&nf_conntrack_lock);
747 if (nf_ct_find_helper(repl) != NULL)
748 features |= NF_CT_F_HELP;
749 read_unlock_bh(&nf_conntrack_lock);
750
751 DEBUGP("nf_conntrack_alloc: features=0x%x\n", features);
752
753 read_lock_bh(&nf_ct_cache_lock);
754
755 if (!nf_ct_cache[features].use) {
756 DEBUGP("nf_conntrack_alloc: not supported features = 0x%x\n",
757 features);
758 goto out;
759 }
760
761 conntrack = kmem_cache_alloc(nf_ct_cache[features].cachep, GFP_ATOMIC);
762 if (conntrack == NULL) {
763 DEBUGP("nf_conntrack_alloc: Can't alloc conntrack from cache\n");
764 goto out;
765 }
766
767 memset(conntrack, 0, nf_ct_cache[features].size);
768 conntrack->features = features;
769 if (nf_ct_cache[features].init_conntrack &&
770 nf_ct_cache[features].init_conntrack(conntrack, features) < 0) {
771 DEBUGP("nf_conntrack_alloc: failed to init\n");
772 kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
773 conntrack = NULL;
774 goto out;
775 }
776
777 atomic_set(&conntrack->ct_general.use, 1);
778 conntrack->ct_general.destroy = destroy_conntrack;
779 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
780 conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
781 /* Don't set timer yet: wait for confirmation */
782 init_timer(&conntrack->timeout);
783 conntrack->timeout.data = (unsigned long)conntrack;
784 conntrack->timeout.function = death_by_timeout;
785
786 atomic_inc(&nf_conntrack_count);
787out:
788 read_unlock_bh(&nf_ct_cache_lock);
789 return conntrack;
790}
791
792struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
793 const struct nf_conntrack_tuple *repl)
794{
795 struct nf_conntrack_l3proto *l3proto;
796
797 l3proto = nf_ct_find_l3proto(orig->src.l3num);
798 return __nf_conntrack_alloc(orig, repl, l3proto);
799}
800
801void nf_conntrack_free(struct nf_conn *conntrack)
802{
803 u_int32_t features = conntrack->features;
804 NF_CT_ASSERT(features >= NF_CT_F_BASIC && features < NF_CT_F_NUM);
805 DEBUGP("nf_conntrack_free: features = 0x%x, conntrack=%p\n", features,
806 conntrack);
807 kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
808 atomic_dec(&nf_conntrack_count);
809}
810
811/* Allocate a new conntrack: we return -ENOMEM if classification
812 failed due to stress. Otherwise it really is unclassifiable. */
813static struct nf_conntrack_tuple_hash *
814init_conntrack(const struct nf_conntrack_tuple *tuple,
815 struct nf_conntrack_l3proto *l3proto,
816 struct nf_conntrack_protocol *protocol,
817 struct sk_buff *skb,
818 unsigned int dataoff)
819{
820 struct nf_conn *conntrack;
821 struct nf_conntrack_tuple repl_tuple;
822 struct nf_conntrack_expect *exp;
823
824 if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, protocol)) {
825 DEBUGP("Can't invert tuple.\n");
826 return NULL;
827 }
828
829 conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto);
830 if (conntrack == NULL || IS_ERR(conntrack)) {
831 DEBUGP("Can't allocate conntrack.\n");
832 return (struct nf_conntrack_tuple_hash *)conntrack;
833 }
834
835 if (!protocol->new(conntrack, skb, dataoff)) {
836 nf_conntrack_free(conntrack);
837 DEBUGP("init conntrack: can't track with proto module\n");
838 return NULL;
839 }
840
841 write_lock_bh(&nf_conntrack_lock);
842 exp = find_expectation(tuple);
843
844 if (exp) {
845 DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
846 conntrack, exp);
847 /* Welcome, Mr. Bond. We've been expecting you... */
848 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
849 conntrack->master = exp->master;
850#ifdef CONFIG_NF_CONNTRACK_MARK
851 conntrack->mark = exp->master->mark;
852#endif
853 nf_conntrack_get(&conntrack->master->ct_general);
854 NF_CT_STAT_INC(expect_new);
855 } else {
856 conntrack->helper = nf_ct_find_helper(&repl_tuple);
857
858 NF_CT_STAT_INC(new);
859 }
860
861 /* Overload tuple linked list to put us in unconfirmed list. */
862 list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
863
864 write_unlock_bh(&nf_conntrack_lock);
865
866 if (exp) {
867 if (exp->expectfn)
868 exp->expectfn(conntrack, exp);
869 nf_conntrack_expect_put(exp);
870 }
871
872 return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
873}
874
875/* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
876static inline struct nf_conn *
877resolve_normal_ct(struct sk_buff *skb,
878 unsigned int dataoff,
879 u_int16_t l3num,
880 u_int8_t protonum,
881 struct nf_conntrack_l3proto *l3proto,
882 struct nf_conntrack_protocol *proto,
883 int *set_reply,
884 enum ip_conntrack_info *ctinfo)
885{
886 struct nf_conntrack_tuple tuple;
887 struct nf_conntrack_tuple_hash *h;
888 struct nf_conn *ct;
889
890 if (!nf_ct_get_tuple(skb, (unsigned int)(skb->nh.raw - skb->data),
891 dataoff, l3num, protonum, &tuple, l3proto,
892 proto)) {
893 DEBUGP("resolve_normal_ct: Can't get tuple\n");
894 return NULL;
895 }
896
897 /* look for tuple match */
898 h = nf_conntrack_find_get(&tuple, NULL);
899 if (!h) {
900 h = init_conntrack(&tuple, l3proto, proto, skb, dataoff);
901 if (!h)
902 return NULL;
903 if (IS_ERR(h))
904 return (void *)h;
905 }
906 ct = nf_ct_tuplehash_to_ctrack(h);
907
908 /* It exists; we have (non-exclusive) reference. */
909 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) {
910 *ctinfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY;
911 /* Please set reply bit if this packet OK */
912 *set_reply = 1;
913 } else {
914 /* Once we've had two way comms, always ESTABLISHED. */
915 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
916 DEBUGP("nf_conntrack_in: normal packet for %p\n", ct);
917 *ctinfo = IP_CT_ESTABLISHED;
918 } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {
919 DEBUGP("nf_conntrack_in: related packet for %p\n", ct);
920 *ctinfo = IP_CT_RELATED;
921 } else {
922 DEBUGP("nf_conntrack_in: new packet for %p\n", ct);
923 *ctinfo = IP_CT_NEW;
924 }
925 *set_reply = 0;
926 }
927 skb->nfct = &ct->ct_general;
928 skb->nfctinfo = *ctinfo;
929 return ct;
930}
931
932unsigned int
933nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
934{
935 struct nf_conn *ct;
936 enum ip_conntrack_info ctinfo;
937 struct nf_conntrack_l3proto *l3proto;
938 struct nf_conntrack_protocol *proto;
939 unsigned int dataoff;
940 u_int8_t protonum;
941 int set_reply = 0;
942 int ret;
943
944 /* Previously seen (loopback or untracked)? Ignore. */
945 if ((*pskb)->nfct) {
946 NF_CT_STAT_INC(ignore);
947 return NF_ACCEPT;
948 }
949
950 l3proto = nf_ct_find_l3proto((u_int16_t)pf);
951 if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) {
952 DEBUGP("not prepared to track yet or error occured\n");
953 return -ret;
954 }
955
956 proto = nf_ct_find_proto((u_int16_t)pf, protonum);
957
958 /* It may be an special packet, error, unclean...
959 * inverse of the return code tells to the netfilter
960 * core what to do with the packet. */
961 if (proto->error != NULL &&
962 (ret = proto->error(*pskb, dataoff, &ctinfo, pf, hooknum)) <= 0) {
963 NF_CT_STAT_INC(error);
964 NF_CT_STAT_INC(invalid);
965 return -ret;
966 }
967
968 ct = resolve_normal_ct(*pskb, dataoff, pf, protonum, l3proto, proto,
969 &set_reply, &ctinfo);
970 if (!ct) {
971 /* Not valid part of a connection */
972 NF_CT_STAT_INC(invalid);
973 return NF_ACCEPT;
974 }
975
976 if (IS_ERR(ct)) {
977 /* Too stressed to deal. */
978 NF_CT_STAT_INC(drop);
979 return NF_DROP;
980 }
981
982 NF_CT_ASSERT((*pskb)->nfct);
983
984 ret = proto->packet(ct, *pskb, dataoff, ctinfo, pf, hooknum);
985 if (ret < 0) {
986 /* Invalid: inverse of the return code tells
987 * the netfilter core what to do */
988 DEBUGP("nf_conntrack_in: Can't track with proto module\n");
989 nf_conntrack_put((*pskb)->nfct);
990 (*pskb)->nfct = NULL;
991 NF_CT_STAT_INC(invalid);
992 return -ret;
993 }
994
995 if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
996 nf_conntrack_event_cache(IPCT_STATUS, *pskb);
997
998 return ret;
999}
1000
1001int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
1002 const struct nf_conntrack_tuple *orig)
1003{
1004 return nf_ct_invert_tuple(inverse, orig,
1005 nf_ct_find_l3proto(orig->src.l3num),
1006 nf_ct_find_proto(orig->src.l3num,
1007 orig->dst.protonum));
1008}
1009
1010/* Would two expected things clash? */
1011static inline int expect_clash(const struct nf_conntrack_expect *a,
1012 const struct nf_conntrack_expect *b)
1013{
1014 /* Part covered by intersection of masks must be unequal,
1015 otherwise they clash */
1016 struct nf_conntrack_tuple intersect_mask;
1017 int count;
1018
1019 intersect_mask.src.l3num = a->mask.src.l3num & b->mask.src.l3num;
1020 intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all;
1021 intersect_mask.dst.u.all = a->mask.dst.u.all & b->mask.dst.u.all;
1022 intersect_mask.dst.protonum = a->mask.dst.protonum
1023 & b->mask.dst.protonum;
1024
1025 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
1026 intersect_mask.src.u3.all[count] =
1027 a->mask.src.u3.all[count] & b->mask.src.u3.all[count];
1028 }
1029
1030 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
1031 intersect_mask.dst.u3.all[count] =
1032 a->mask.dst.u3.all[count] & b->mask.dst.u3.all[count];
1033 }
1034
1035 return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask);
1036}
1037
1038static inline int expect_matches(const struct nf_conntrack_expect *a,
1039 const struct nf_conntrack_expect *b)
1040{
1041 return a->master == b->master
1042 && nf_ct_tuple_equal(&a->tuple, &b->tuple)
1043 && nf_ct_tuple_equal(&a->mask, &b->mask);
1044}
1045
1046/* Generally a bad idea to call this: could have matched already. */
1047void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp)
1048{
1049 struct nf_conntrack_expect *i;
1050
1051 write_lock_bh(&nf_conntrack_lock);
1052 /* choose the the oldest expectation to evict */
1053 list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
1054 if (expect_matches(i, exp) && del_timer(&i->timeout)) {
1055 nf_ct_unlink_expect(i);
1056 write_unlock_bh(&nf_conntrack_lock);
1057 nf_conntrack_expect_put(i);
1058 return;
1059 }
1060 }
1061 write_unlock_bh(&nf_conntrack_lock);
1062}
1063
1064/* We don't increase the master conntrack refcount for non-fulfilled
1065 * conntracks. During the conntrack destruction, the expectations are
1066 * always killed before the conntrack itself */
1067struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me)
1068{
1069 struct nf_conntrack_expect *new;
1070
1071 new = kmem_cache_alloc(nf_conntrack_expect_cachep, GFP_ATOMIC);
1072 if (!new) {
1073 DEBUGP("expect_related: OOM allocating expect\n");
1074 return NULL;
1075 }
1076 new->master = me;
1077 atomic_set(&new->use, 1);
1078 return new;
1079}
1080
1081void nf_conntrack_expect_put(struct nf_conntrack_expect *exp)
1082{
1083 if (atomic_dec_and_test(&exp->use))
1084 kmem_cache_free(nf_conntrack_expect_cachep, exp);
1085}
1086
1087static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
1088{
1089 atomic_inc(&exp->use);
1090 exp->master->expecting++;
1091 list_add(&exp->list, &nf_conntrack_expect_list);
1092
1093 init_timer(&exp->timeout);
1094 exp->timeout.data = (unsigned long)exp;
1095 exp->timeout.function = expectation_timed_out;
1096 exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ;
1097 add_timer(&exp->timeout);
1098
1099 atomic_inc(&exp->use);
1100 NF_CT_STAT_INC(expect_create);
1101}
1102
1103/* Race with expectations being used means we could have none to find; OK. */
1104static void evict_oldest_expect(struct nf_conn *master)
1105{
1106 struct nf_conntrack_expect *i;
1107
1108 list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
1109 if (i->master == master) {
1110 if (del_timer(&i->timeout)) {
1111 nf_ct_unlink_expect(i);
1112 nf_conntrack_expect_put(i);
1113 }
1114 break;
1115 }
1116 }
1117}
1118
1119static inline int refresh_timer(struct nf_conntrack_expect *i)
1120{
1121 if (!del_timer(&i->timeout))
1122 return 0;
1123
1124 i->timeout.expires = jiffies + i->master->helper->timeout*HZ;
1125 add_timer(&i->timeout);
1126 return 1;
1127}
1128
1129int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
1130{
1131 struct nf_conntrack_expect *i;
1132 int ret;
1133
1134 DEBUGP("nf_conntrack_expect_related %p\n", related_to);
1135 DEBUGP("tuple: "); NF_CT_DUMP_TUPLE(&expect->tuple);
1136 DEBUGP("mask: "); NF_CT_DUMP_TUPLE(&expect->mask);
1137
1138 write_lock_bh(&nf_conntrack_lock);
1139 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
1140 if (expect_matches(i, expect)) {
1141 /* Refresh timer: if it's dying, ignore.. */
1142 if (refresh_timer(i)) {
1143 ret = 0;
1144 goto out;
1145 }
1146 } else if (expect_clash(i, expect)) {
1147 ret = -EBUSY;
1148 goto out;
1149 }
1150 }
1151 /* Will be over limit? */
1152 if (expect->master->helper->max_expected &&
1153 expect->master->expecting >= expect->master->helper->max_expected)
1154 evict_oldest_expect(expect->master);
1155
1156 nf_conntrack_expect_insert(expect);
1157 nf_conntrack_expect_event(IPEXP_NEW, expect);
1158 ret = 0;
1159out:
1160 write_unlock_bh(&nf_conntrack_lock);
1161 return ret;
1162}
1163
1164/* Alter reply tuple (maybe alter helper). This is for NAT, and is
1165 implicitly racy: see __nf_conntrack_confirm */
1166void nf_conntrack_alter_reply(struct nf_conn *conntrack,
1167 const struct nf_conntrack_tuple *newreply)
1168{
1169 write_lock_bh(&nf_conntrack_lock);
1170 /* Should be unconfirmed, so not in hash table yet */
1171 NF_CT_ASSERT(!nf_ct_is_confirmed(conntrack));
1172
1173 DEBUGP("Altering reply tuple of %p to ", conntrack);
1174 NF_CT_DUMP_TUPLE(newreply);
1175
1176 conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
1177 if (!conntrack->master && conntrack->expecting == 0)
1178 conntrack->helper = nf_ct_find_helper(newreply);
1179 write_unlock_bh(&nf_conntrack_lock);
1180}
1181
1182int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
1183{
1184 int ret;
1185 BUG_ON(me->timeout == 0);
1186
1187 ret = nf_conntrack_register_cache(NF_CT_F_HELP, "nf_conntrack:help",
1188 sizeof(struct nf_conn)
1189 + sizeof(union nf_conntrack_help)
1190 + __alignof__(union nf_conntrack_help),
1191 init_conntrack_for_helper);
1192 if (ret < 0) {
1193 printk(KERN_ERR "nf_conntrack_helper_reigster: Unable to create slab cache for conntracks\n");
1194 return ret;
1195 }
1196 write_lock_bh(&nf_conntrack_lock);
1197 list_prepend(&helpers, me);
1198 write_unlock_bh(&nf_conntrack_lock);
1199
1200 return 0;
1201}
1202
1203static inline int unhelp(struct nf_conntrack_tuple_hash *i,
1204 const struct nf_conntrack_helper *me)
1205{
1206 if (nf_ct_tuplehash_to_ctrack(i)->helper == me) {
1207 nf_conntrack_event(IPCT_HELPER, nf_ct_tuplehash_to_ctrack(i));
1208 nf_ct_tuplehash_to_ctrack(i)->helper = NULL;
1209 }
1210 return 0;
1211}
1212
1213void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
1214{
1215 unsigned int i;
1216 struct nf_conntrack_expect *exp, *tmp;
1217
1218 /* Need write lock here, to delete helper. */
1219 write_lock_bh(&nf_conntrack_lock);
1220 LIST_DELETE(&helpers, me);
1221
1222 /* Get rid of expectations */
1223 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
1224 if (exp->master->helper == me && del_timer(&exp->timeout)) {
1225 nf_ct_unlink_expect(exp);
1226 nf_conntrack_expect_put(exp);
1227 }
1228 }
1229
1230 /* Get rid of expecteds, set helpers to NULL. */
1231 LIST_FIND_W(&unconfirmed, unhelp, struct nf_conntrack_tuple_hash*, me);
1232 for (i = 0; i < nf_conntrack_htable_size; i++)
1233 LIST_FIND_W(&nf_conntrack_hash[i], unhelp,
1234 struct nf_conntrack_tuple_hash *, me);
1235 write_unlock_bh(&nf_conntrack_lock);
1236
1237 /* Someone could be still looking at the helper in a bh. */
1238 synchronize_net();
1239}
1240
1241/* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */
1242void __nf_ct_refresh_acct(struct nf_conn *ct,
1243 enum ip_conntrack_info ctinfo,
1244 const struct sk_buff *skb,
1245 unsigned long extra_jiffies,
1246 int do_acct)
1247{
1248 int event = 0;
1249
1250 NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct);
1251 NF_CT_ASSERT(skb);
1252
1253 write_lock_bh(&nf_conntrack_lock);
1254
1255 /* If not in hash table, timer will not be active yet */
1256 if (!nf_ct_is_confirmed(ct)) {
1257 ct->timeout.expires = extra_jiffies;
1258 event = IPCT_REFRESH;
1259 } else {
1260 /* Need del_timer for race avoidance (may already be dying). */
1261 if (del_timer(&ct->timeout)) {
1262 ct->timeout.expires = jiffies + extra_jiffies;
1263 add_timer(&ct->timeout);
1264 event = IPCT_REFRESH;
1265 }
1266 }
1267
1268#ifdef CONFIG_NF_CT_ACCT
1269 if (do_acct) {
1270 ct->counters[CTINFO2DIR(ctinfo)].packets++;
1271 ct->counters[CTINFO2DIR(ctinfo)].bytes +=
1272 skb->len - (unsigned int)(skb->nh.raw - skb->data);
1273 if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
1274 || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
1275 event |= IPCT_COUNTER_FILLING;
1276 }
1277#endif
1278
1279 write_unlock_bh(&nf_conntrack_lock);
1280
1281 /* must be unlocked when calling event cache */
1282 if (event)
1283 nf_conntrack_event_cache(event, skb);
1284}
1285
1286/* Used by ipt_REJECT and ip6t_REJECT. */
1287void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
1288{
1289 struct nf_conn *ct;
1290 enum ip_conntrack_info ctinfo;
1291
1292 /* This ICMP is in reverse direction to the packet which caused it */
1293 ct = nf_ct_get(skb, &ctinfo);
1294 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
1295 ctinfo = IP_CT_RELATED + IP_CT_IS_REPLY;
1296 else
1297 ctinfo = IP_CT_RELATED;
1298
1299 /* Attach to new skbuff, and increment count */
1300 nskb->nfct = &ct->ct_general;
1301 nskb->nfctinfo = ctinfo;
1302 nf_conntrack_get(nskb->nfct);
1303}
1304
1305static inline int
1306do_iter(const struct nf_conntrack_tuple_hash *i,
1307 int (*iter)(struct nf_conn *i, void *data),
1308 void *data)
1309{
1310 return iter(nf_ct_tuplehash_to_ctrack(i), data);
1311}
1312
1313/* Bring out ya dead! */
1314static struct nf_conntrack_tuple_hash *
1315get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
1316 void *data, unsigned int *bucket)
1317{
1318 struct nf_conntrack_tuple_hash *h = NULL;
1319
1320 write_lock_bh(&nf_conntrack_lock);
1321 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
1322 h = LIST_FIND_W(&nf_conntrack_hash[*bucket], do_iter,
1323 struct nf_conntrack_tuple_hash *, iter, data);
1324 if (h)
1325 break;
1326 }
1327 if (!h)
1328 h = LIST_FIND_W(&unconfirmed, do_iter,
1329 struct nf_conntrack_tuple_hash *, iter, data);
1330 if (h)
1331 atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
1332 write_unlock_bh(&nf_conntrack_lock);
1333
1334 return h;
1335}
1336
1337void
1338nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data)
1339{
1340 struct nf_conntrack_tuple_hash *h;
1341 unsigned int bucket = 0;
1342
1343 while ((h = get_next_corpse(iter, data, &bucket)) != NULL) {
1344 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
1345 /* Time to push up daises... */
1346 if (del_timer(&ct->timeout))
1347 death_by_timeout((unsigned long)ct);
1348 /* ... else the timer will get him soon. */
1349
1350 nf_ct_put(ct);
1351 }
1352}
1353
1354static int kill_all(struct nf_conn *i, void *data)
1355{
1356 return 1;
1357}
1358
1359static void free_conntrack_hash(struct list_head *hash, int vmalloced, int size)
1360{
1361 if (vmalloced)
1362 vfree(hash);
1363 else
1364 free_pages((unsigned long)hash,
1365 get_order(sizeof(struct list_head) * size));
1366}
1367
1368/* Mishearing the voices in his head, our hero wonders how he's
1369 supposed to kill the mall. */
1370void nf_conntrack_cleanup(void)
1371{
1372 int i;
1373
1374 /* This makes sure all current packets have passed through
1375 netfilter framework. Roll on, two-stage module
1376 delete... */
1377 synchronize_net();
1378
1379 nf_ct_event_cache_flush();
1380 i_see_dead_people:
1381 nf_ct_iterate_cleanup(kill_all, NULL);
1382 if (atomic_read(&nf_conntrack_count) != 0) {
1383 schedule();
1384 goto i_see_dead_people;
1385 }
1386
1387 for (i = 0; i < NF_CT_F_NUM; i++) {
1388 if (nf_ct_cache[i].use == 0)
1389 continue;
1390
1391 NF_CT_ASSERT(nf_ct_cache[i].use == 1);
1392 nf_ct_cache[i].use = 1;
1393 nf_conntrack_unregister_cache(i);
1394 }
1395 kmem_cache_destroy(nf_conntrack_expect_cachep);
1396 free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
1397 nf_conntrack_htable_size);
1398}
1399
1400static struct list_head *alloc_hashtable(int size, int *vmalloced)
1401{
1402 struct list_head *hash;
1403 unsigned int i;
1404
1405 *vmalloced = 0;
1406 hash = (void*)__get_free_pages(GFP_KERNEL,
1407 get_order(sizeof(struct list_head)
1408 * size));
1409 if (!hash) {
1410 *vmalloced = 1;
1411 printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
1412 hash = vmalloc(sizeof(struct list_head) * size);
1413 }
1414
1415 if (hash)
1416 for (i = 0; i < size; i++)
1417 INIT_LIST_HEAD(&hash[i]);
1418
1419 return hash;
1420}
1421
1422int set_hashsize(const char *val, struct kernel_param *kp)
1423{
1424 int i, bucket, hashsize, vmalloced;
1425 int old_vmalloced, old_size;
1426 int rnd;
1427 struct list_head *hash, *old_hash;
1428 struct nf_conntrack_tuple_hash *h;
1429
1430 /* On boot, we can set this without any fancy locking. */
1431 if (!nf_conntrack_htable_size)
1432 return param_set_uint(val, kp);
1433
1434 hashsize = simple_strtol(val, NULL, 0);
1435 if (!hashsize)
1436 return -EINVAL;
1437
1438 hash = alloc_hashtable(hashsize, &vmalloced);
1439 if (!hash)
1440 return -ENOMEM;
1441
1442 /* We have to rehahs for the new table anyway, so we also can
1443 * use a newrandom seed */
1444 get_random_bytes(&rnd, 4);
1445
1446 write_lock_bh(&nf_conntrack_lock);
1447 for (i = 0; i < nf_conntrack_htable_size; i++) {
1448 while (!list_empty(&nf_conntrack_hash[i])) {
1449 h = list_entry(nf_conntrack_hash[i].next,
1450 struct nf_conntrack_tuple_hash, list);
1451 list_del(&h->list);
1452 bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
1453 list_add_tail(&h->list, &hash[bucket]);
1454 }
1455 }
1456 old_size = nf_conntrack_htable_size;
1457 old_vmalloced = nf_conntrack_vmalloc;
1458 old_hash = nf_conntrack_hash;
1459
1460 nf_conntrack_htable_size = hashsize;
1461 nf_conntrack_vmalloc = vmalloced;
1462 nf_conntrack_hash = hash;
1463 nf_conntrack_hash_rnd = rnd;
1464 write_unlock_bh(&nf_conntrack_lock);
1465
1466 free_conntrack_hash(old_hash, old_vmalloced, old_size);
1467 return 0;
1468}
1469
1470module_param_call(hashsize, set_hashsize, param_get_uint,
1471 &nf_conntrack_htable_size, 0600);
1472
1473int __init nf_conntrack_init(void)
1474{
1475 unsigned int i;
1476 int ret;
1477
1478 /* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
1479 * machine has 256 buckets. >= 1GB machines have 8192 buckets. */
1480 if (!nf_conntrack_htable_size) {
1481 nf_conntrack_htable_size
1482 = (((num_physpages << PAGE_SHIFT) / 16384)
1483 / sizeof(struct list_head));
1484 if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
1485 nf_conntrack_htable_size = 8192;
1486 if (nf_conntrack_htable_size < 16)
1487 nf_conntrack_htable_size = 16;
1488 }
1489 nf_conntrack_max = 8 * nf_conntrack_htable_size;
1490
1491 printk("nf_conntrack version %s (%u buckets, %d max)\n",
1492 NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
1493 nf_conntrack_max);
1494
1495 nf_conntrack_hash = alloc_hashtable(nf_conntrack_htable_size,
1496 &nf_conntrack_vmalloc);
1497 if (!nf_conntrack_hash) {
1498 printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
1499 goto err_out;
1500 }
1501
1502 ret = nf_conntrack_register_cache(NF_CT_F_BASIC, "nf_conntrack:basic",
1503 sizeof(struct nf_conn), NULL);
1504 if (ret < 0) {
1505 printk(KERN_ERR "Unable to create nf_conn slab cache\n");
1506 goto err_free_hash;
1507 }
1508
1509 nf_conntrack_expect_cachep = kmem_cache_create("nf_conntrack_expect",
1510 sizeof(struct nf_conntrack_expect),
1511 0, 0, NULL, NULL);
1512 if (!nf_conntrack_expect_cachep) {
1513 printk(KERN_ERR "Unable to create nf_expect slab cache\n");
1514 goto err_free_conntrack_slab;
1515 }
1516
1517 /* Don't NEED lock here, but good form anyway. */
1518 write_lock_bh(&nf_conntrack_lock);
1519 for (i = 0; i < PF_MAX; i++)
1520 nf_ct_l3protos[i] = &nf_conntrack_generic_l3proto;
1521 write_unlock_bh(&nf_conntrack_lock);
1522
1523 /* Set up fake conntrack:
1524 - to never be deleted, not in any hashes */
1525 atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
1526 /* - and look it like as a confirmed connection */
1527 set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
1528
1529 return ret;
1530
1531err_free_conntrack_slab:
1532 nf_conntrack_unregister_cache(NF_CT_F_BASIC);
1533err_free_hash:
1534 free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
1535 nf_conntrack_htable_size);
1536err_out:
1537 return -ENOMEM;
1538}
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
new file mode 100644
index 000000000000..65080e269f27
--- /dev/null
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -0,0 +1,698 @@
1/* FTP extension for connection tracking. */
2
3/* (C) 1999-2001 Paul `Rusty' Russell
4 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
5 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
12 * - enable working with Layer 3 protocol independent connection tracking.
13 * - track EPRT and EPSV commands with IPv6 address.
14 *
15 * Derived from net/ipv4/netfilter/ip_conntrack_ftp.c
16 */
17
18#include <linux/config.h>
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/netfilter.h>
22#include <linux/ip.h>
23#include <linux/ipv6.h>
24#include <linux/ctype.h>
25#include <net/checksum.h>
26#include <net/tcp.h>
27
28#include <net/netfilter/nf_conntrack.h>
29#include <net/netfilter/nf_conntrack_helper.h>
30#include <linux/netfilter/nf_conntrack_ftp.h>
31
32MODULE_LICENSE("GPL");
33MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
34MODULE_DESCRIPTION("ftp connection tracking helper");
35
36/* This is slow, but it's simple. --RR */
37static char *ftp_buffer;
38
39static DEFINE_SPINLOCK(nf_ftp_lock);
40
41#define MAX_PORTS 8
42static u_int16_t ports[MAX_PORTS];
43static unsigned int ports_c;
44module_param_array(ports, ushort, &ports_c, 0400);
45
46static int loose;
47module_param(loose, int, 0600);
48
49unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
50 enum ip_conntrack_info ctinfo,
51 enum ip_ct_ftp_type type,
52 unsigned int matchoff,
53 unsigned int matchlen,
54 struct nf_conntrack_expect *exp,
55 u32 *seq);
56EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
57
58#if 0
59#define DEBUGP printk
60#else
61#define DEBUGP(format, args...)
62#endif
63
64static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, char);
65static int try_eprt(const char *, size_t, struct nf_conntrack_man *, char);
66static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *,
67 char);
68
69static struct ftp_search {
70 enum ip_conntrack_dir dir;
71 const char *pattern;
72 size_t plen;
73 char skip;
74 char term;
75 enum ip_ct_ftp_type ftptype;
76 int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char);
77} search[] = {
78 {
79 IP_CT_DIR_ORIGINAL,
80 "PORT", sizeof("PORT") - 1, ' ', '\r',
81 IP_CT_FTP_PORT,
82 try_rfc959,
83 },
84 {
85 IP_CT_DIR_REPLY,
86 "227 ", sizeof("227 ") - 1, '(', ')',
87 IP_CT_FTP_PASV,
88 try_rfc959,
89 },
90 {
91 IP_CT_DIR_ORIGINAL,
92 "EPRT", sizeof("EPRT") - 1, ' ', '\r',
93 IP_CT_FTP_EPRT,
94 try_eprt,
95 },
96 {
97 IP_CT_DIR_REPLY,
98 "229 ", sizeof("229 ") - 1, '(', ')',
99 IP_CT_FTP_EPSV,
100 try_epsv_response,
101 },
102};
103
104/* This code is based on inet_pton() in glibc-2.2.4 */
105static int
106get_ipv6_addr(const char *src, size_t dlen, struct in6_addr *dst, u_int8_t term)
107{
108 static const char xdigits[] = "0123456789abcdef";
109 u_int8_t tmp[16], *tp, *endp, *colonp;
110 int ch, saw_xdigit;
111 u_int32_t val;
112 size_t clen = 0;
113
114 tp = memset(tmp, '\0', sizeof(tmp));
115 endp = tp + sizeof(tmp);
116 colonp = NULL;
117
118 /* Leading :: requires some special handling. */
119 if (*src == ':'){
120 if (*++src != ':') {
121 DEBUGP("invalid \":\" at the head of addr\n");
122 return 0;
123 }
124 clen++;
125 }
126
127 saw_xdigit = 0;
128 val = 0;
129 while ((clen < dlen) && (*src != term)) {
130 const char *pch;
131
132 ch = tolower(*src++);
133 clen++;
134
135 pch = strchr(xdigits, ch);
136 if (pch != NULL) {
137 val <<= 4;
138 val |= (pch - xdigits);
139 if (val > 0xffff)
140 return 0;
141
142 saw_xdigit = 1;
143 continue;
144 }
145 if (ch != ':') {
146 DEBUGP("get_ipv6_addr: invalid char. \'%c\'\n", ch);
147 return 0;
148 }
149
150 if (!saw_xdigit) {
151 if (colonp) {
152 DEBUGP("invalid location of \"::\".\n");
153 return 0;
154 }
155 colonp = tp;
156 continue;
157 } else if (*src == term) {
158 DEBUGP("trancated IPv6 addr\n");
159 return 0;
160 }
161
162 if (tp + 2 > endp)
163 return 0;
164 *tp++ = (u_int8_t) (val >> 8) & 0xff;
165 *tp++ = (u_int8_t) val & 0xff;
166
167 saw_xdigit = 0;
168 val = 0;
169 continue;
170 }
171 if (saw_xdigit) {
172 if (tp + 2 > endp)
173 return 0;
174 *tp++ = (u_int8_t) (val >> 8) & 0xff;
175 *tp++ = (u_int8_t) val & 0xff;
176 }
177 if (colonp != NULL) {
178 /*
179 * Since some memmove()'s erroneously fail to handle
180 * overlapping regions, we'll do the shift by hand.
181 */
182 const int n = tp - colonp;
183 int i;
184
185 if (tp == endp)
186 return 0;
187
188 for (i = 1; i <= n; i++) {
189 endp[- i] = colonp[n - i];
190 colonp[n - i] = 0;
191 }
192 tp = endp;
193 }
194 if (tp != endp || (*src != term))
195 return 0;
196
197 memcpy(dst->s6_addr, tmp, sizeof(dst->s6_addr));
198 return clen;
199}
200
201static int try_number(const char *data, size_t dlen, u_int32_t array[],
202 int array_size, char sep, char term)
203{
204 u_int32_t i, len;
205
206 memset(array, 0, sizeof(array[0])*array_size);
207
208 /* Keep data pointing at next char. */
209 for (i = 0, len = 0; len < dlen && i < array_size; len++, data++) {
210 if (*data >= '0' && *data <= '9') {
211 array[i] = array[i]*10 + *data - '0';
212 }
213 else if (*data == sep)
214 i++;
215 else {
216 /* Unexpected character; true if it's the
217 terminator and we're finished. */
218 if (*data == term && i == array_size - 1)
219 return len;
220
221 DEBUGP("Char %u (got %u nums) `%u' unexpected\n",
222 len, i, *data);
223 return 0;
224 }
225 }
226 DEBUGP("Failed to fill %u numbers separated by %c\n", array_size, sep);
227
228 return 0;
229}
230
231/* Returns 0, or length of numbers: 192,168,1,1,5,6 */
232static int try_rfc959(const char *data, size_t dlen,
233 struct nf_conntrack_man *cmd, char term)
234{
235 int length;
236 u_int32_t array[6];
237
238 length = try_number(data, dlen, array, 6, ',', term);
239 if (length == 0)
240 return 0;
241
242 cmd->u3.ip = htonl((array[0] << 24) | (array[1] << 16) |
243 (array[2] << 8) | array[3]);
244 cmd->u.tcp.port = htons((array[4] << 8) | array[5]);
245 return length;
246}
247
248/* Grab port: number up to delimiter */
249static int get_port(const char *data, int start, size_t dlen, char delim,
250 u_int16_t *port)
251{
252 u_int16_t tmp_port = 0;
253 int i;
254
255 for (i = start; i < dlen; i++) {
256 /* Finished? */
257 if (data[i] == delim) {
258 if (tmp_port == 0)
259 break;
260 *port = htons(tmp_port);
261 DEBUGP("get_port: return %d\n", tmp_port);
262 return i + 1;
263 }
264 else if (data[i] >= '0' && data[i] <= '9')
265 tmp_port = tmp_port*10 + data[i] - '0';
266 else { /* Some other crap */
267 DEBUGP("get_port: invalid char.\n");
268 break;
269 }
270 }
271 return 0;
272}
273
274/* Returns 0, or length of numbers: |1|132.235.1.2|6275| or |2|3ffe::1|6275| */
275static int try_eprt(const char *data, size_t dlen, struct nf_conntrack_man *cmd,
276 char term)
277{
278 char delim;
279 int length;
280
281 /* First character is delimiter, then "1" for IPv4 or "2" for IPv6,
282 then delimiter again. */
283 if (dlen <= 3) {
284 DEBUGP("EPRT: too short\n");
285 return 0;
286 }
287 delim = data[0];
288 if (isdigit(delim) || delim < 33 || delim > 126 || data[2] != delim) {
289 DEBUGP("try_eprt: invalid delimitter.\n");
290 return 0;
291 }
292
293 if ((cmd->l3num == PF_INET && data[1] != '1') ||
294 (cmd->l3num == PF_INET6 && data[1] != '2')) {
295 DEBUGP("EPRT: invalid protocol number.\n");
296 return 0;
297 }
298
299 DEBUGP("EPRT: Got %c%c%c\n", delim, data[1], delim);
300
301 if (data[1] == '1') {
302 u_int32_t array[4];
303
304 /* Now we have IP address. */
305 length = try_number(data + 3, dlen - 3, array, 4, '.', delim);
306 if (length != 0)
307 cmd->u3.ip = htonl((array[0] << 24) | (array[1] << 16)
308 | (array[2] << 8) | array[3]);
309 } else {
310 /* Now we have IPv6 address. */
311 length = get_ipv6_addr(data + 3, dlen - 3,
312 (struct in6_addr *)cmd->u3.ip6, delim);
313 }
314
315 if (length == 0)
316 return 0;
317 DEBUGP("EPRT: Got IP address!\n");
318 /* Start offset includes initial "|1|", and trailing delimiter */
319 return get_port(data, 3 + length + 1, dlen, delim, &cmd->u.tcp.port);
320}
321
322/* Returns 0, or length of numbers: |||6446| */
323static int try_epsv_response(const char *data, size_t dlen,
324 struct nf_conntrack_man *cmd, char term)
325{
326 char delim;
327
328 /* Three delimiters. */
329 if (dlen <= 3) return 0;
330 delim = data[0];
331 if (isdigit(delim) || delim < 33 || delim > 126
332 || data[1] != delim || data[2] != delim)
333 return 0;
334
335 return get_port(data, 3, dlen, delim, &cmd->u.tcp.port);
336}
337
338/* Return 1 for match, 0 for accept, -1 for partial. */
339static int find_pattern(const char *data, size_t dlen,
340 const char *pattern, size_t plen,
341 char skip, char term,
342 unsigned int *numoff,
343 unsigned int *numlen,
344 struct nf_conntrack_man *cmd,
345 int (*getnum)(const char *, size_t,
346 struct nf_conntrack_man *, char))
347{
348 size_t i;
349
350 DEBUGP("find_pattern `%s': dlen = %u\n", pattern, dlen);
351 if (dlen == 0)
352 return 0;
353
354 if (dlen <= plen) {
355 /* Short packet: try for partial? */
356 if (strnicmp(data, pattern, dlen) == 0)
357 return -1;
358 else return 0;
359 }
360
361 if (strnicmp(data, pattern, plen) != 0) {
362#if 0
363 size_t i;
364
365 DEBUGP("ftp: string mismatch\n");
366 for (i = 0; i < plen; i++) {
367 DEBUGP("ftp:char %u `%c'(%u) vs `%c'(%u)\n",
368 i, data[i], data[i],
369 pattern[i], pattern[i]);
370 }
371#endif
372 return 0;
373 }
374
375 DEBUGP("Pattern matches!\n");
376 /* Now we've found the constant string, try to skip
377 to the 'skip' character */
378 for (i = plen; data[i] != skip; i++)
379 if (i == dlen - 1) return -1;
380
381 /* Skip over the last character */
382 i++;
383
384 DEBUGP("Skipped up to `%c'!\n", skip);
385
386 *numoff = i;
387 *numlen = getnum(data + i, dlen - i, cmd, term);
388 if (!*numlen)
389 return -1;
390
391 DEBUGP("Match succeeded!\n");
392 return 1;
393}
394
395/* Look up to see if we're just after a \n. */
396static int find_nl_seq(u32 seq, const struct ip_ct_ftp_master *info, int dir)
397{
398 unsigned int i;
399
400 for (i = 0; i < info->seq_aft_nl_num[dir]; i++)
401 if (info->seq_aft_nl[dir][i] == seq)
402 return 1;
403 return 0;
404}
405
406/* We don't update if it's older than what we have. */
407static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir,
408 struct sk_buff *skb)
409{
410 unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
411
412 /* Look for oldest: if we find exact match, we're done. */
413 for (i = 0; i < info->seq_aft_nl_num[dir]; i++) {
414 if (info->seq_aft_nl[dir][i] == nl_seq)
415 return;
416
417 if (oldest == info->seq_aft_nl_num[dir]
418 || before(info->seq_aft_nl[dir][i], oldest))
419 oldest = i;
420 }
421
422 if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
423 info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
424 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
425 } else if (oldest != NUM_SEQ_TO_REMEMBER) {
426 info->seq_aft_nl[dir][oldest] = nl_seq;
427 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
428 }
429}
430
431static int help(struct sk_buff **pskb,
432 unsigned int protoff,
433 struct nf_conn *ct,
434 enum ip_conntrack_info ctinfo)
435{
436 unsigned int dataoff, datalen;
437 struct tcphdr _tcph, *th;
438 char *fb_ptr;
439 int ret;
440 u32 seq;
441 int dir = CTINFO2DIR(ctinfo);
442 unsigned int matchlen, matchoff;
443 struct ip_ct_ftp_master *ct_ftp_info = &ct->help->ct_ftp_info;
444 struct nf_conntrack_expect *exp;
445 struct nf_conntrack_man cmd = {};
446
447 unsigned int i;
448 int found = 0, ends_in_nl;
449
450 /* Until there's been traffic both ways, don't look in packets. */
451 if (ctinfo != IP_CT_ESTABLISHED
452 && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {
453 DEBUGP("ftp: Conntrackinfo = %u\n", ctinfo);
454 return NF_ACCEPT;
455 }
456
457 th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph);
458 if (th == NULL)
459 return NF_ACCEPT;
460
461 dataoff = protoff + th->doff * 4;
462 /* No data? */
463 if (dataoff >= (*pskb)->len) {
464 DEBUGP("ftp: dataoff(%u) >= skblen(%u)\n", dataoff,
465 (*pskb)->len);
466 return NF_ACCEPT;
467 }
468 datalen = (*pskb)->len - dataoff;
469
470 spin_lock_bh(&nf_ftp_lock);
471 fb_ptr = skb_header_pointer(*pskb, dataoff, datalen, ftp_buffer);
472 BUG_ON(fb_ptr == NULL);
473
474 ends_in_nl = (fb_ptr[datalen - 1] == '\n');
475 seq = ntohl(th->seq) + datalen;
476
477 /* Look up to see if we're just after a \n. */
478 if (!find_nl_seq(ntohl(th->seq), ct_ftp_info, dir)) {
479 /* Now if this ends in \n, update ftp info. */
480 DEBUGP("nf_conntrack_ftp_help: wrong seq pos %s(%u) or %s(%u)\n",
481 ct_ftp_info->seq_aft_nl_num[dir] > 0 ? "" : "(UNSET)",
482 ct_ftp_info->seq_aft_nl[dir][0],
483 ct_ftp_info->seq_aft_nl_num[dir] > 1 ? "" : "(UNSET)",
484 ct_ftp_info->seq_aft_nl[dir][1]);
485 ret = NF_ACCEPT;
486 goto out_update_nl;
487 }
488
489 /* Initialize IP/IPv6 addr to expected address (it's not mentioned
490 in EPSV responses) */
491 cmd.l3num = ct->tuplehash[dir].tuple.src.l3num;
492 memcpy(cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all,
493 sizeof(cmd.u3.all));
494
495 for (i = 0; i < ARRAY_SIZE(search); i++) {
496 if (search[i].dir != dir) continue;
497
498 found = find_pattern(fb_ptr, datalen,
499 search[i].pattern,
500 search[i].plen,
501 search[i].skip,
502 search[i].term,
503 &matchoff, &matchlen,
504 &cmd,
505 search[i].getnum);
506 if (found) break;
507 }
508 if (found == -1) {
509 /* We don't usually drop packets. After all, this is
510 connection tracking, not packet filtering.
511 However, it is necessary for accurate tracking in
512 this case. */
513 if (net_ratelimit())
514 printk("conntrack_ftp: partial %s %u+%u\n",
515 search[i].pattern,
516 ntohl(th->seq), datalen);
517 ret = NF_DROP;
518 goto out;
519 } else if (found == 0) { /* No match */
520 ret = NF_ACCEPT;
521 goto out_update_nl;
522 }
523
524 DEBUGP("conntrack_ftp: match `%.*s' (%u bytes at %u)\n",
525 (int)matchlen, fb_ptr + matchoff,
526 matchlen, ntohl(th->seq) + matchoff);
527
528 exp = nf_conntrack_expect_alloc(ct);
529 if (exp == NULL) {
530 ret = NF_DROP;
531 goto out;
532 }
533
534 /* We refer to the reverse direction ("!dir") tuples here,
535 * because we're expecting something in the other direction.
536 * Doesn't matter unless NAT is happening. */
537 exp->tuple.dst.u3 = ct->tuplehash[!dir].tuple.dst.u3;
538
539 /* Update the ftp info */
540 if ((cmd.l3num == ct->tuplehash[dir].tuple.src.l3num) &&
541 memcmp(&cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all,
542 sizeof(cmd.u3.all))) {
543 /* Enrico Scholz's passive FTP to partially RNAT'd ftp
544 server: it really wants us to connect to a
545 different IP address. Simply don't record it for
546 NAT. */
547 if (cmd.l3num == PF_INET) {
548 DEBUGP("conntrack_ftp: NOT RECORDING: %u,%u,%u,%u != %u.%u.%u.%u\n",
549 NIPQUAD(cmd.u3.ip),
550 NIPQUAD(ct->tuplehash[dir].tuple.src.u3.ip));
551 } else {
552 DEBUGP("conntrack_ftp: NOT RECORDING: %x:%x:%x:%x:%x:%x:%x:%x != %x:%x:%x:%x:%x:%x:%x:%x\n",
553 NIP6(*((struct in6_addr *)cmd.u3.ip6)),
554 NIP6(*((struct in6_addr *)ct->tuplehash[dir]
555 .tuple.src.u3.ip6)));
556 }
557
558 /* Thanks to Cristiano Lincoln Mattos
559 <lincoln@cesar.org.br> for reporting this potential
560 problem (DMZ machines opening holes to internal
561 networks, or the packet filter itself). */
562 if (!loose) {
563 ret = NF_ACCEPT;
564 goto out_put_expect;
565 }
566 memcpy(&exp->tuple.dst.u3, &cmd.u3.all,
567 sizeof(exp->tuple.dst.u3));
568 }
569
570 exp->tuple.src.u3 = ct->tuplehash[!dir].tuple.src.u3;
571 exp->tuple.src.l3num = cmd.l3num;
572 exp->tuple.src.u.tcp.port = 0;
573 exp->tuple.dst.u.tcp.port = cmd.u.tcp.port;
574 exp->tuple.dst.protonum = IPPROTO_TCP;
575
576 exp->mask = (struct nf_conntrack_tuple)
577 { .src = { .l3num = 0xFFFF,
578 .u = { .tcp = { 0 }},
579 },
580 .dst = { .protonum = 0xFF,
581 .u = { .tcp = { 0xFFFF }},
582 },
583 };
584 if (cmd.l3num == PF_INET) {
585 exp->mask.src.u3.ip = 0xFFFFFFFF;
586 exp->mask.dst.u3.ip = 0xFFFFFFFF;
587 } else {
588 memset(exp->mask.src.u3.ip6, 0xFF,
589 sizeof(exp->mask.src.u3.ip6));
590 memset(exp->mask.dst.u3.ip6, 0xFF,
591 sizeof(exp->mask.src.u3.ip6));
592 }
593
594 exp->expectfn = NULL;
595 exp->flags = 0;
596
597 /* Now, NAT might want to mangle the packet, and register the
598 * (possibly changed) expectation itself. */
599 if (nf_nat_ftp_hook)
600 ret = nf_nat_ftp_hook(pskb, ctinfo, search[i].ftptype,
601 matchoff, matchlen, exp, &seq);
602 else {
603 /* Can't expect this? Best to drop packet now. */
604 if (nf_conntrack_expect_related(exp) != 0)
605 ret = NF_DROP;
606 else
607 ret = NF_ACCEPT;
608 }
609
610out_put_expect:
611 nf_conntrack_expect_put(exp);
612
613out_update_nl:
614 /* Now if this ends in \n, update ftp info. Seq may have been
615 * adjusted by NAT code. */
616 if (ends_in_nl)
617 update_nl_seq(seq, ct_ftp_info, dir, *pskb);
618 out:
619 spin_unlock_bh(&nf_ftp_lock);
620 return ret;
621}
622
623static struct nf_conntrack_helper ftp[MAX_PORTS][2];
624static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")];
625
626/* don't make this __exit, since it's called from __init ! */
627static void fini(void)
628{
629 int i, j;
630 for (i = 0; i < ports_c; i++) {
631 for (j = 0; j < 2; j++) {
632 if (ftp[i][j].me == NULL)
633 continue;
634
635 DEBUGP("nf_ct_ftp: unregistering helper for pf: %d "
636 "port: %d\n",
637 ftp[i][j].tuple.src.l3num, ports[i]);
638 nf_conntrack_helper_unregister(&ftp[i][j]);
639 }
640 }
641
642 kfree(ftp_buffer);
643}
644
645static int __init init(void)
646{
647 int i, j = -1, ret = 0;
648 char *tmpname;
649
650 ftp_buffer = kmalloc(65536, GFP_KERNEL);
651 if (!ftp_buffer)
652 return -ENOMEM;
653
654 if (ports_c == 0)
655 ports[ports_c++] = FTP_PORT;
656
657 /* FIXME should be configurable whether IPv4 and IPv6 FTP connections
658 are tracked or not - YK */
659 for (i = 0; i < ports_c; i++) {
660 memset(&ftp[i], 0, sizeof(struct nf_conntrack_helper));
661
662 ftp[i][0].tuple.src.l3num = PF_INET;
663 ftp[i][1].tuple.src.l3num = PF_INET6;
664 for (j = 0; j < 2; j++) {
665 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]);
666 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP;
667 ftp[i][j].mask.src.u.tcp.port = 0xFFFF;
668 ftp[i][j].mask.dst.protonum = 0xFF;
669 ftp[i][j].max_expected = 1;
670 ftp[i][j].timeout = 5 * 60; /* 5 Minutes */
671 ftp[i][j].me = THIS_MODULE;
672 ftp[i][j].help = help;
673 tmpname = &ftp_names[i][j][0];
674 if (ports[i] == FTP_PORT)
675 sprintf(tmpname, "ftp");
676 else
677 sprintf(tmpname, "ftp-%d", ports[i]);
678 ftp[i][j].name = tmpname;
679
680 DEBUGP("nf_ct_ftp: registering helper for pf: %d "
681 "port: %d\n",
682 ftp[i][j].tuple.src.l3num, ports[i]);
683 ret = nf_conntrack_helper_register(&ftp[i][j]);
684 if (ret) {
685 printk("nf_ct_ftp: failed to register helper "
686 " for pf: %d port: %d\n",
687 ftp[i][j].tuple.src.l3num, ports[i]);
688 fini();
689 return ret;
690 }
691 }
692 }
693
694 return 0;
695}
696
697module_init(init);
698module_exit(fini);
diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c
new file mode 100644
index 000000000000..7de4f06c63c5
--- /dev/null
+++ b/net/netfilter/nf_conntrack_l3proto_generic.c
@@ -0,0 +1,98 @@
1/*
2 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
3 *
4 * Based largely upon the original ip_conntrack code which
5 * had the following copyright information:
6 *
7 * (C) 1999-2001 Paul `Rusty' Russell
8 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
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 version 2 as
12 * published by the Free Software Foundation.
13 *
14 * Author:
15 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
16 */
17
18#include <linux/config.h>
19#include <linux/types.h>
20#include <linux/ip.h>
21#include <linux/netfilter.h>
22#include <linux/module.h>
23#include <linux/skbuff.h>
24#include <linux/icmp.h>
25#include <linux/sysctl.h>
26#include <net/ip.h>
27
28#include <linux/netfilter_ipv4.h>
29#include <net/netfilter/nf_conntrack.h>
30#include <net/netfilter/nf_conntrack_protocol.h>
31#include <net/netfilter/nf_conntrack_l3proto.h>
32#include <net/netfilter/nf_conntrack_core.h>
33#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
34
35#if 0
36#define DEBUGP printk
37#else
38#define DEBUGP(format, args...)
39#endif
40
41DECLARE_PER_CPU(struct nf_conntrack_stat, nf_conntrack_stat);
42
43static int generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
44 struct nf_conntrack_tuple *tuple)
45{
46 memset(&tuple->src.u3, 0, sizeof(tuple->src.u3));
47 memset(&tuple->dst.u3, 0, sizeof(tuple->dst.u3));
48
49 return 1;
50}
51
52static int generic_invert_tuple(struct nf_conntrack_tuple *tuple,
53 const struct nf_conntrack_tuple *orig)
54{
55 memset(&tuple->src.u3, 0, sizeof(tuple->src.u3));
56 memset(&tuple->dst.u3, 0, sizeof(tuple->dst.u3));
57
58 return 1;
59}
60
61static int generic_print_tuple(struct seq_file *s,
62 const struct nf_conntrack_tuple *tuple)
63{
64 return 0;
65}
66
67static int generic_print_conntrack(struct seq_file *s,
68 const struct nf_conn *conntrack)
69{
70 return 0;
71}
72
73static int
74generic_prepare(struct sk_buff **pskb, unsigned int hooknum,
75 unsigned int *dataoff, u_int8_t *protonum)
76{
77 /* Never track !!! */
78 return -NF_ACCEPT;
79}
80
81
82static u_int32_t generic_get_features(const struct nf_conntrack_tuple *tuple)
83
84{
85 return NF_CT_F_BASIC;
86}
87
88struct nf_conntrack_l3proto nf_conntrack_generic_l3proto = {
89 .l3proto = PF_UNSPEC,
90 .name = "unknown",
91 .pkt_to_tuple = generic_pkt_to_tuple,
92 .invert_tuple = generic_invert_tuple,
93 .print_tuple = generic_print_tuple,
94 .print_conntrack = generic_print_conntrack,
95 .prepare = generic_prepare,
96 .get_features = generic_get_features,
97 .me = THIS_MODULE,
98};
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
new file mode 100644
index 000000000000..36425f6c833f
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -0,0 +1,85 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
9 * - enable working with L3 protocol independent connection tracking.
10 *
11 * Derived from net/ipv4/netfilter/ip_conntrack_proto_generic.c
12 */
13
14#include <linux/types.h>
15#include <linux/sched.h>
16#include <linux/timer.h>
17#include <linux/netfilter.h>
18#include <net/netfilter/nf_conntrack_protocol.h>
19
20unsigned long nf_ct_generic_timeout = 600*HZ;
21
22static int generic_pkt_to_tuple(const struct sk_buff *skb,
23 unsigned int dataoff,
24 struct nf_conntrack_tuple *tuple)
25{
26 tuple->src.u.all = 0;
27 tuple->dst.u.all = 0;
28
29 return 1;
30}
31
32static int generic_invert_tuple(struct nf_conntrack_tuple *tuple,
33 const struct nf_conntrack_tuple *orig)
34{
35 tuple->src.u.all = 0;
36 tuple->dst.u.all = 0;
37
38 return 1;
39}
40
41/* Print out the per-protocol part of the tuple. */
42static int generic_print_tuple(struct seq_file *s,
43 const struct nf_conntrack_tuple *tuple)
44{
45 return 0;
46}
47
48/* Print out the private part of the conntrack. */
49static int generic_print_conntrack(struct seq_file *s,
50 const struct nf_conn *state)
51{
52 return 0;
53}
54
55/* Returns verdict for packet, or -1 for invalid. */
56static int packet(struct nf_conn *conntrack,
57 const struct sk_buff *skb,
58 unsigned int dataoff,
59 enum ip_conntrack_info ctinfo,
60 int pf,
61 unsigned int hooknum)
62{
63 nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_generic_timeout);
64 return NF_ACCEPT;
65}
66
67/* Called when a new connection for this protocol found. */
68static int new(struct nf_conn *conntrack, const struct sk_buff *skb,
69 unsigned int dataoff)
70{
71 return 1;
72}
73
74struct nf_conntrack_protocol nf_conntrack_generic_protocol =
75{
76 .l3proto = PF_UNSPEC,
77 .proto = 0,
78 .name = "unknown",
79 .pkt_to_tuple = generic_pkt_to_tuple,
80 .invert_tuple = generic_invert_tuple,
81 .print_tuple = generic_print_tuple,
82 .print_conntrack = generic_print_conntrack,
83 .packet = packet,
84 .new = new,
85};
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
new file mode 100644
index 000000000000..3a600f77b4e0
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -0,0 +1,670 @@
1/*
2 * Connection tracking protocol helper module for SCTP.
3 *
4 * SCTP is defined in RFC 2960. References to various sections in this code
5 * are to this RFC.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * 17 Oct 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
12 * - enable working with L3 protocol independent connection tracking.
13 *
14 * Derived from net/ipv4/ip_conntrack_sctp.c
15 */
16
17/*
18 * Added support for proc manipulation of timeouts.
19 */
20
21#include <linux/types.h>
22#include <linux/sched.h>
23#include <linux/timer.h>
24#include <linux/netfilter.h>
25#include <linux/module.h>
26#include <linux/in.h>
27#include <linux/ip.h>
28#include <linux/sctp.h>
29#include <linux/string.h>
30#include <linux/seq_file.h>
31
32#include <net/netfilter/nf_conntrack.h>
33#include <net/netfilter/nf_conntrack_protocol.h>
34
35#if 0
36#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
37#else
38#define DEBUGP(format, args...)
39#endif
40
41/* Protects conntrack->proto.sctp */
42static DEFINE_RWLOCK(sctp_lock);
43
44/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
45 closely. They're more complex. --RR
46
47 And so for me for SCTP :D -Kiran */
48
49static const char *sctp_conntrack_names[] = {
50 "NONE",
51 "CLOSED",
52 "COOKIE_WAIT",
53 "COOKIE_ECHOED",
54 "ESTABLISHED",
55 "SHUTDOWN_SENT",
56 "SHUTDOWN_RECD",
57 "SHUTDOWN_ACK_SENT",
58};
59
60#define SECS * HZ
61#define MINS * 60 SECS
62#define HOURS * 60 MINS
63#define DAYS * 24 HOURS
64
65static unsigned long nf_ct_sctp_timeout_closed = 10 SECS;
66static unsigned long nf_ct_sctp_timeout_cookie_wait = 3 SECS;
67static unsigned long nf_ct_sctp_timeout_cookie_echoed = 3 SECS;
68static unsigned long nf_ct_sctp_timeout_established = 5 DAYS;
69static unsigned long nf_ct_sctp_timeout_shutdown_sent = 300 SECS / 1000;
70static unsigned long nf_ct_sctp_timeout_shutdown_recd = 300 SECS / 1000;
71static unsigned long nf_ct_sctp_timeout_shutdown_ack_sent = 3 SECS;
72
73static unsigned long * sctp_timeouts[]
74= { NULL, /* SCTP_CONNTRACK_NONE */
75 &nf_ct_sctp_timeout_closed, /* SCTP_CONNTRACK_CLOSED */
76 &nf_ct_sctp_timeout_cookie_wait, /* SCTP_CONNTRACK_COOKIE_WAIT */
77 &nf_ct_sctp_timeout_cookie_echoed, /* SCTP_CONNTRACK_COOKIE_ECHOED */
78 &nf_ct_sctp_timeout_established, /* SCTP_CONNTRACK_ESTABLISHED */
79 &nf_ct_sctp_timeout_shutdown_sent, /* SCTP_CONNTRACK_SHUTDOWN_SENT */
80 &nf_ct_sctp_timeout_shutdown_recd, /* SCTP_CONNTRACK_SHUTDOWN_RECD */
81 &nf_ct_sctp_timeout_shutdown_ack_sent /* SCTP_CONNTRACK_SHUTDOWN_ACK_SENT */
82 };
83
84#define sNO SCTP_CONNTRACK_NONE
85#define sCL SCTP_CONNTRACK_CLOSED
86#define sCW SCTP_CONNTRACK_COOKIE_WAIT
87#define sCE SCTP_CONNTRACK_COOKIE_ECHOED
88#define sES SCTP_CONNTRACK_ESTABLISHED
89#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
90#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
91#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
92#define sIV SCTP_CONNTRACK_MAX
93
94/*
95 These are the descriptions of the states:
96
97NOTE: These state names are tantalizingly similar to the states of an
98SCTP endpoint. But the interpretation of the states is a little different,
99considering that these are the states of the connection and not of an end
100point. Please note the subtleties. -Kiran
101
102NONE - Nothing so far.
103COOKIE WAIT - We have seen an INIT chunk in the original direction, or also
104 an INIT_ACK chunk in the reply direction.
105COOKIE ECHOED - We have seen a COOKIE_ECHO chunk in the original direction.
106ESTABLISHED - We have seen a COOKIE_ACK in the reply direction.
107SHUTDOWN_SENT - We have seen a SHUTDOWN chunk in the original direction.
108SHUTDOWN_RECD - We have seen a SHUTDOWN chunk in the reply directoin.
109SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
110 to that of the SHUTDOWN chunk.
111CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
112 the SHUTDOWN chunk. Connection is closed.
113*/
114
115/* TODO
116 - I have assumed that the first INIT is in the original direction.
117 This messes things when an INIT comes in the reply direction in CLOSED
118 state.
119 - Check the error type in the reply dir before transitioning from
120cookie echoed to closed.
121 - Sec 5.2.4 of RFC 2960
122 - Multi Homing support.
123*/
124
125/* SCTP conntrack state transitions */
126static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
127 {
128/* ORIGINAL */
129/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
130/* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
131/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
132/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
133/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
134/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
135/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant have Stale cookie*/
136/* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */
137/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in orig dir */
138/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
139 },
140 {
141/* REPLY */
142/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
143/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL Big TODO */
144/* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
145/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
146/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
147/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
148/* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
149/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in reply dir */
150/* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
151/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
152 }
153};
154
155static int sctp_pkt_to_tuple(const struct sk_buff *skb,
156 unsigned int dataoff,
157 struct nf_conntrack_tuple *tuple)
158{
159 sctp_sctphdr_t _hdr, *hp;
160
161 DEBUGP(__FUNCTION__);
162 DEBUGP("\n");
163
164 /* Actually only need first 8 bytes. */
165 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
166 if (hp == NULL)
167 return 0;
168
169 tuple->src.u.sctp.port = hp->source;
170 tuple->dst.u.sctp.port = hp->dest;
171 return 1;
172}
173
174static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
175 const struct nf_conntrack_tuple *orig)
176{
177 DEBUGP(__FUNCTION__);
178 DEBUGP("\n");
179
180 tuple->src.u.sctp.port = orig->dst.u.sctp.port;
181 tuple->dst.u.sctp.port = orig->src.u.sctp.port;
182 return 1;
183}
184
185/* Print out the per-protocol part of the tuple. */
186static int sctp_print_tuple(struct seq_file *s,
187 const struct nf_conntrack_tuple *tuple)
188{
189 DEBUGP(__FUNCTION__);
190 DEBUGP("\n");
191
192 return seq_printf(s, "sport=%hu dport=%hu ",
193 ntohs(tuple->src.u.sctp.port),
194 ntohs(tuple->dst.u.sctp.port));
195}
196
197/* Print out the private part of the conntrack. */
198static int sctp_print_conntrack(struct seq_file *s,
199 const struct nf_conn *conntrack)
200{
201 enum sctp_conntrack state;
202
203 DEBUGP(__FUNCTION__);
204 DEBUGP("\n");
205
206 read_lock_bh(&sctp_lock);
207 state = conntrack->proto.sctp.state;
208 read_unlock_bh(&sctp_lock);
209
210 return seq_printf(s, "%s ", sctp_conntrack_names[state]);
211}
212
213#define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \
214for (offset = dataoff + sizeof(sctp_sctphdr_t), count = 0; \
215 offset < skb->len && \
216 (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \
217 offset += (htons(sch->length) + 3) & ~3, count++)
218
219/* Some validity checks to make sure the chunks are fine */
220static int do_basic_checks(struct nf_conn *conntrack,
221 const struct sk_buff *skb,
222 unsigned int dataoff,
223 char *map)
224{
225 u_int32_t offset, count;
226 sctp_chunkhdr_t _sch, *sch;
227 int flag;
228
229 DEBUGP(__FUNCTION__);
230 DEBUGP("\n");
231
232 flag = 0;
233
234 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
235 DEBUGP("Chunk Num: %d Type: %d\n", count, sch->type);
236
237 if (sch->type == SCTP_CID_INIT
238 || sch->type == SCTP_CID_INIT_ACK
239 || sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
240 flag = 1;
241 }
242
243 /* Cookie Ack/Echo chunks not the first OR
244 Init / Init Ack / Shutdown compl chunks not the only chunks */
245 if ((sch->type == SCTP_CID_COOKIE_ACK
246 || sch->type == SCTP_CID_COOKIE_ECHO
247 || flag)
248 && count !=0 ) {
249 DEBUGP("Basic checks failed\n");
250 return 1;
251 }
252
253 if (map) {
254 set_bit(sch->type, (void *)map);
255 }
256 }
257
258 DEBUGP("Basic checks passed\n");
259 return 0;
260}
261
262static int new_state(enum ip_conntrack_dir dir,
263 enum sctp_conntrack cur_state,
264 int chunk_type)
265{
266 int i;
267
268 DEBUGP(__FUNCTION__);
269 DEBUGP("\n");
270
271 DEBUGP("Chunk type: %d\n", chunk_type);
272
273 switch (chunk_type) {
274 case SCTP_CID_INIT:
275 DEBUGP("SCTP_CID_INIT\n");
276 i = 0; break;
277 case SCTP_CID_INIT_ACK:
278 DEBUGP("SCTP_CID_INIT_ACK\n");
279 i = 1; break;
280 case SCTP_CID_ABORT:
281 DEBUGP("SCTP_CID_ABORT\n");
282 i = 2; break;
283 case SCTP_CID_SHUTDOWN:
284 DEBUGP("SCTP_CID_SHUTDOWN\n");
285 i = 3; break;
286 case SCTP_CID_SHUTDOWN_ACK:
287 DEBUGP("SCTP_CID_SHUTDOWN_ACK\n");
288 i = 4; break;
289 case SCTP_CID_ERROR:
290 DEBUGP("SCTP_CID_ERROR\n");
291 i = 5; break;
292 case SCTP_CID_COOKIE_ECHO:
293 DEBUGP("SCTP_CID_COOKIE_ECHO\n");
294 i = 6; break;
295 case SCTP_CID_COOKIE_ACK:
296 DEBUGP("SCTP_CID_COOKIE_ACK\n");
297 i = 7; break;
298 case SCTP_CID_SHUTDOWN_COMPLETE:
299 DEBUGP("SCTP_CID_SHUTDOWN_COMPLETE\n");
300 i = 8; break;
301 default:
302 /* Other chunks like DATA, SACK, HEARTBEAT and
303 its ACK do not cause a change in state */
304 DEBUGP("Unknown chunk type, Will stay in %s\n",
305 sctp_conntrack_names[cur_state]);
306 return cur_state;
307 }
308
309 DEBUGP("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
310 dir, sctp_conntrack_names[cur_state], chunk_type,
311 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
312
313 return sctp_conntracks[dir][i][cur_state];
314}
315
316/* Returns verdict for packet, or -1 for invalid. */
317static int sctp_packet(struct nf_conn *conntrack,
318 const struct sk_buff *skb,
319 unsigned int dataoff,
320 enum ip_conntrack_info ctinfo,
321 int pf,
322 unsigned int hooknum)
323{
324 enum sctp_conntrack newconntrack, oldsctpstate;
325 sctp_sctphdr_t _sctph, *sh;
326 sctp_chunkhdr_t _sch, *sch;
327 u_int32_t offset, count;
328 char map[256 / sizeof (char)] = {0};
329
330 DEBUGP(__FUNCTION__);
331 DEBUGP("\n");
332
333 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
334 if (sh == NULL)
335 return -1;
336
337 if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
338 return -1;
339
340 /* Check the verification tag (Sec 8.5) */
341 if (!test_bit(SCTP_CID_INIT, (void *)map)
342 && !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, (void *)map)
343 && !test_bit(SCTP_CID_COOKIE_ECHO, (void *)map)
344 && !test_bit(SCTP_CID_ABORT, (void *)map)
345 && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map)
346 && (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
347 DEBUGP("Verification tag check failed\n");
348 return -1;
349 }
350
351 oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
352 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
353 write_lock_bh(&sctp_lock);
354
355 /* Special cases of Verification tag check (Sec 8.5.1) */
356 if (sch->type == SCTP_CID_INIT) {
357 /* Sec 8.5.1 (A) */
358 if (sh->vtag != 0) {
359 write_unlock_bh(&sctp_lock);
360 return -1;
361 }
362 } else if (sch->type == SCTP_CID_ABORT) {
363 /* Sec 8.5.1 (B) */
364 if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
365 && !(sh->vtag == conntrack->proto.sctp.vtag
366 [1 - CTINFO2DIR(ctinfo)])) {
367 write_unlock_bh(&sctp_lock);
368 return -1;
369 }
370 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
371 /* Sec 8.5.1 (C) */
372 if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
373 && !(sh->vtag == conntrack->proto.sctp.vtag
374 [1 - CTINFO2DIR(ctinfo)]
375 && (sch->flags & 1))) {
376 write_unlock_bh(&sctp_lock);
377 return -1;
378 }
379 } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
380 /* Sec 8.5.1 (D) */
381 if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
382 write_unlock_bh(&sctp_lock);
383 return -1;
384 }
385 }
386
387 oldsctpstate = conntrack->proto.sctp.state;
388 newconntrack = new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch->type);
389
390 /* Invalid */
391 if (newconntrack == SCTP_CONNTRACK_MAX) {
392 DEBUGP("nf_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
393 CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
394 write_unlock_bh(&sctp_lock);
395 return -1;
396 }
397
398 /* If it is an INIT or an INIT ACK note down the vtag */
399 if (sch->type == SCTP_CID_INIT
400 || sch->type == SCTP_CID_INIT_ACK) {
401 sctp_inithdr_t _inithdr, *ih;
402
403 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
404 sizeof(_inithdr), &_inithdr);
405 if (ih == NULL) {
406 write_unlock_bh(&sctp_lock);
407 return -1;
408 }
409 DEBUGP("Setting vtag %x for dir %d\n",
410 ih->init_tag, !CTINFO2DIR(ctinfo));
411 conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag;
412 }
413
414 conntrack->proto.sctp.state = newconntrack;
415 if (oldsctpstate != newconntrack)
416 nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
417 write_unlock_bh(&sctp_lock);
418 }
419
420 nf_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]);
421
422 if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED
423 && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY
424 && newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
425 DEBUGP("Setting assured bit\n");
426 set_bit(IPS_ASSURED_BIT, &conntrack->status);
427 nf_conntrack_event_cache(IPCT_STATUS, skb);
428 }
429
430 return NF_ACCEPT;
431}
432
433/* Called when a new connection for this protocol found. */
434static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
435 unsigned int dataoff)
436{
437 enum sctp_conntrack newconntrack;
438 sctp_sctphdr_t _sctph, *sh;
439 sctp_chunkhdr_t _sch, *sch;
440 u_int32_t offset, count;
441 char map[256 / sizeof (char)] = {0};
442
443 DEBUGP(__FUNCTION__);
444 DEBUGP("\n");
445
446 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
447 if (sh == NULL)
448 return 0;
449
450 if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
451 return 0;
452
453 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
454 if ((test_bit (SCTP_CID_ABORT, (void *)map))
455 || (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map))
456 || (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) {
457 return 0;
458 }
459
460 newconntrack = SCTP_CONNTRACK_MAX;
461 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
462 /* Don't need lock here: this conntrack not in circulation yet */
463 newconntrack = new_state(IP_CT_DIR_ORIGINAL,
464 SCTP_CONNTRACK_NONE, sch->type);
465
466 /* Invalid: delete conntrack */
467 if (newconntrack == SCTP_CONNTRACK_MAX) {
468 DEBUGP("nf_conntrack_sctp: invalid new deleting.\n");
469 return 0;
470 }
471
472 /* Copy the vtag into the state info */
473 if (sch->type == SCTP_CID_INIT) {
474 if (sh->vtag == 0) {
475 sctp_inithdr_t _inithdr, *ih;
476
477 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
478 sizeof(_inithdr), &_inithdr);
479 if (ih == NULL)
480 return 0;
481
482 DEBUGP("Setting vtag %x for new conn\n",
483 ih->init_tag);
484
485 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =
486 ih->init_tag;
487 } else {
488 /* Sec 8.5.1 (A) */
489 return 0;
490 }
491 }
492 /* If it is a shutdown ack OOTB packet, we expect a return
493 shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
494 else {
495 DEBUGP("Setting vtag %x for new conn OOTB\n",
496 sh->vtag);
497 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
498 }
499
500 conntrack->proto.sctp.state = newconntrack;
501 }
502
503 return 1;
504}
505
506struct nf_conntrack_protocol nf_conntrack_protocol_sctp4 = {
507 .l3proto = PF_INET,
508 .proto = IPPROTO_SCTP,
509 .name = "sctp",
510 .pkt_to_tuple = sctp_pkt_to_tuple,
511 .invert_tuple = sctp_invert_tuple,
512 .print_tuple = sctp_print_tuple,
513 .print_conntrack = sctp_print_conntrack,
514 .packet = sctp_packet,
515 .new = sctp_new,
516 .destroy = NULL,
517 .me = THIS_MODULE
518};
519
520struct nf_conntrack_protocol nf_conntrack_protocol_sctp6 = {
521 .l3proto = PF_INET6,
522 .proto = IPPROTO_SCTP,
523 .name = "sctp",
524 .pkt_to_tuple = sctp_pkt_to_tuple,
525 .invert_tuple = sctp_invert_tuple,
526 .print_tuple = sctp_print_tuple,
527 .print_conntrack = sctp_print_conntrack,
528 .packet = sctp_packet,
529 .new = sctp_new,
530 .destroy = NULL,
531 .me = THIS_MODULE
532};
533
534#ifdef CONFIG_SYSCTL
535static ctl_table nf_ct_sysctl_table[] = {
536 {
537 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
538 .procname = "nf_conntrack_sctp_timeout_closed",
539 .data = &nf_ct_sctp_timeout_closed,
540 .maxlen = sizeof(unsigned int),
541 .mode = 0644,
542 .proc_handler = &proc_dointvec_jiffies,
543 },
544 {
545 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
546 .procname = "nf_conntrack_sctp_timeout_cookie_wait",
547 .data = &nf_ct_sctp_timeout_cookie_wait,
548 .maxlen = sizeof(unsigned int),
549 .mode = 0644,
550 .proc_handler = &proc_dointvec_jiffies,
551 },
552 {
553 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
554 .procname = "nf_conntrack_sctp_timeout_cookie_echoed",
555 .data = &nf_ct_sctp_timeout_cookie_echoed,
556 .maxlen = sizeof(unsigned int),
557 .mode = 0644,
558 .proc_handler = &proc_dointvec_jiffies,
559 },
560 {
561 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
562 .procname = "nf_conntrack_sctp_timeout_established",
563 .data = &nf_ct_sctp_timeout_established,
564 .maxlen = sizeof(unsigned int),
565 .mode = 0644,
566 .proc_handler = &proc_dointvec_jiffies,
567 },
568 {
569 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
570 .procname = "nf_conntrack_sctp_timeout_shutdown_sent",
571 .data = &nf_ct_sctp_timeout_shutdown_sent,
572 .maxlen = sizeof(unsigned int),
573 .mode = 0644,
574 .proc_handler = &proc_dointvec_jiffies,
575 },
576 {
577 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
578 .procname = "nf_conntrack_sctp_timeout_shutdown_recd",
579 .data = &nf_ct_sctp_timeout_shutdown_recd,
580 .maxlen = sizeof(unsigned int),
581 .mode = 0644,
582 .proc_handler = &proc_dointvec_jiffies,
583 },
584 {
585 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
586 .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
587 .data = &nf_ct_sctp_timeout_shutdown_ack_sent,
588 .maxlen = sizeof(unsigned int),
589 .mode = 0644,
590 .proc_handler = &proc_dointvec_jiffies,
591 },
592 { .ctl_name = 0 }
593};
594
595static ctl_table nf_ct_netfilter_table[] = {
596 {
597 .ctl_name = NET_NETFILTER,
598 .procname = "netfilter",
599 .mode = 0555,
600 .child = nf_ct_sysctl_table,
601 },
602 { .ctl_name = 0 }
603};
604
605static ctl_table nf_ct_net_table[] = {
606 {
607 .ctl_name = CTL_NET,
608 .procname = "net",
609 .mode = 0555,
610 .child = nf_ct_netfilter_table,
611 },
612 { .ctl_name = 0 }
613};
614
615static struct ctl_table_header *nf_ct_sysctl_header;
616#endif
617
618int __init init(void)
619{
620 int ret;
621
622 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_sctp4);
623 if (ret) {
624 printk("nf_conntrack_proto_sctp4: protocol register failed\n");
625 goto out;
626 }
627 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_sctp6);
628 if (ret) {
629 printk("nf_conntrack_proto_sctp6: protocol register failed\n");
630 goto cleanup_sctp4;
631 }
632
633#ifdef CONFIG_SYSCTL
634 nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
635 if (nf_ct_sysctl_header == NULL) {
636 printk("nf_conntrack_proto_sctp: can't register to sysctl.\n");
637 goto cleanup;
638 }
639#endif
640
641 return ret;
642
643#ifdef CONFIG_SYSCTL
644 cleanup:
645 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6);
646#endif
647 cleanup_sctp4:
648 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4);
649 out:
650 DEBUGP("SCTP conntrack module loading %s\n",
651 ret ? "failed": "succeeded");
652 return ret;
653}
654
655void __exit fini(void)
656{
657 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6);
658 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4);
659#ifdef CONFIG_SYSCTL
660 unregister_sysctl_table(nf_ct_sysctl_header);
661#endif
662 DEBUGP("SCTP conntrack module unloaded\n");
663}
664
665module_init(init);
666module_exit(fini);
667
668MODULE_LICENSE("GPL");
669MODULE_AUTHOR("Kiran Kumar Immidi");
670MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
new file mode 100644
index 000000000000..83d90dd624f0
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -0,0 +1,1162 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>:
9 * - Real stateful connection tracking
10 * - Modified state transitions table
11 * - Window scaling support added
12 * - SACK support added
13 *
14 * Willy Tarreau:
15 * - State table bugfixes
16 * - More robust state changes
17 * - Tuning timer parameters
18 *
19 * 27 Oct 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
20 * - genelized Layer 3 protocol part.
21 *
22 * Derived from net/ipv4/netfilter/ip_conntrack_proto_tcp.c
23 *
24 * version 2.2
25 */
26
27#include <linux/config.h>
28#include <linux/types.h>
29#include <linux/sched.h>
30#include <linux/timer.h>
31#include <linux/netfilter.h>
32#include <linux/module.h>
33#include <linux/in.h>
34#include <linux/tcp.h>
35#include <linux/spinlock.h>
36#include <linux/skbuff.h>
37#include <linux/ipv6.h>
38#include <net/ip6_checksum.h>
39
40#include <net/tcp.h>
41
42#include <linux/netfilter.h>
43#include <linux/netfilter_ipv4.h>
44#include <linux/netfilter_ipv6.h>
45#include <net/netfilter/nf_conntrack.h>
46#include <net/netfilter/nf_conntrack_protocol.h>
47
48#if 0
49#define DEBUGP printk
50#define DEBUGP_VARS
51#else
52#define DEBUGP(format, args...)
53#endif
54
55/* Protects conntrack->proto.tcp */
56static DEFINE_RWLOCK(tcp_lock);
57
58/* "Be conservative in what you do,
59 be liberal in what you accept from others."
60 If it's non-zero, we mark only out of window RST segments as INVALID. */
61int nf_ct_tcp_be_liberal = 0;
62
63/* When connection is picked up from the middle, how many packets are required
64 to pass in each direction when we assume we are in sync - if any side uses
65 window scaling, we lost the game.
66 If it is set to zero, we disable picking up already established
67 connections. */
68int nf_ct_tcp_loose = 3;
69
70/* Max number of the retransmitted packets without receiving an (acceptable)
71 ACK from the destination. If this number is reached, a shorter timer
72 will be started. */
73int nf_ct_tcp_max_retrans = 3;
74
75 /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
76 closely. They're more complex. --RR */
77
78static const char *tcp_conntrack_names[] = {
79 "NONE",
80 "SYN_SENT",
81 "SYN_RECV",
82 "ESTABLISHED",
83 "FIN_WAIT",
84 "CLOSE_WAIT",
85 "LAST_ACK",
86 "TIME_WAIT",
87 "CLOSE",
88 "LISTEN"
89};
90
91#define SECS * HZ
92#define MINS * 60 SECS
93#define HOURS * 60 MINS
94#define DAYS * 24 HOURS
95
96unsigned long nf_ct_tcp_timeout_syn_sent = 2 MINS;
97unsigned long nf_ct_tcp_timeout_syn_recv = 60 SECS;
98unsigned long nf_ct_tcp_timeout_established = 5 DAYS;
99unsigned long nf_ct_tcp_timeout_fin_wait = 2 MINS;
100unsigned long nf_ct_tcp_timeout_close_wait = 60 SECS;
101unsigned long nf_ct_tcp_timeout_last_ack = 30 SECS;
102unsigned long nf_ct_tcp_timeout_time_wait = 2 MINS;
103unsigned long nf_ct_tcp_timeout_close = 10 SECS;
104
105/* RFC1122 says the R2 limit should be at least 100 seconds.
106 Linux uses 15 packets as limit, which corresponds
107 to ~13-30min depending on RTO. */
108unsigned long nf_ct_tcp_timeout_max_retrans = 5 MINS;
109
110static unsigned long * tcp_timeouts[]
111= { NULL, /* TCP_CONNTRACK_NONE */
112 &nf_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */
113 &nf_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */
114 &nf_ct_tcp_timeout_established, /* TCP_CONNTRACK_ESTABLISHED, */
115 &nf_ct_tcp_timeout_fin_wait, /* TCP_CONNTRACK_FIN_WAIT, */
116 &nf_ct_tcp_timeout_close_wait, /* TCP_CONNTRACK_CLOSE_WAIT, */
117 &nf_ct_tcp_timeout_last_ack, /* TCP_CONNTRACK_LAST_ACK, */
118 &nf_ct_tcp_timeout_time_wait, /* TCP_CONNTRACK_TIME_WAIT, */
119 &nf_ct_tcp_timeout_close, /* TCP_CONNTRACK_CLOSE, */
120 NULL, /* TCP_CONNTRACK_LISTEN */
121 };
122
123#define sNO TCP_CONNTRACK_NONE
124#define sSS TCP_CONNTRACK_SYN_SENT
125#define sSR TCP_CONNTRACK_SYN_RECV
126#define sES TCP_CONNTRACK_ESTABLISHED
127#define sFW TCP_CONNTRACK_FIN_WAIT
128#define sCW TCP_CONNTRACK_CLOSE_WAIT
129#define sLA TCP_CONNTRACK_LAST_ACK
130#define sTW TCP_CONNTRACK_TIME_WAIT
131#define sCL TCP_CONNTRACK_CLOSE
132#define sLI TCP_CONNTRACK_LISTEN
133#define sIV TCP_CONNTRACK_MAX
134#define sIG TCP_CONNTRACK_IGNORE
135
136/* What TCP flags are set from RST/SYN/FIN/ACK. */
137enum tcp_bit_set {
138 TCP_SYN_SET,
139 TCP_SYNACK_SET,
140 TCP_FIN_SET,
141 TCP_ACK_SET,
142 TCP_RST_SET,
143 TCP_NONE_SET,
144};
145
146/*
147 * The TCP state transition table needs a few words...
148 *
149 * We are the man in the middle. All the packets go through us
150 * but might get lost in transit to the destination.
151 * It is assumed that the destinations can't receive segments
152 * we haven't seen.
153 *
154 * The checked segment is in window, but our windows are *not*
155 * equivalent with the ones of the sender/receiver. We always
156 * try to guess the state of the current sender.
157 *
158 * The meaning of the states are:
159 *
160 * NONE: initial state
161 * SYN_SENT: SYN-only packet seen
162 * SYN_RECV: SYN-ACK packet seen
163 * ESTABLISHED: ACK packet seen
164 * FIN_WAIT: FIN packet seen
165 * CLOSE_WAIT: ACK seen (after FIN)
166 * LAST_ACK: FIN seen (after FIN)
167 * TIME_WAIT: last ACK seen
168 * CLOSE: closed connection
169 *
170 * LISTEN state is not used.
171 *
172 * Packets marked as IGNORED (sIG):
173 * if they may be either invalid or valid
174 * and the receiver may send back a connection
175 * closing RST or a SYN/ACK.
176 *
177 * Packets marked as INVALID (sIV):
178 * if they are invalid
179 * or we do not support the request (simultaneous open)
180 */
181static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
182 {
183/* ORIGINAL */
184/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
185/*syn*/ { sSS, sSS, sIG, sIG, sIG, sIG, sIG, sSS, sSS, sIV },
186/*
187 * sNO -> sSS Initialize a new connection
188 * sSS -> sSS Retransmitted SYN
189 * sSR -> sIG Late retransmitted SYN?
190 * sES -> sIG Error: SYNs in window outside the SYN_SENT state
191 * are errors. Receiver will reply with RST
192 * and close the connection.
193 * Or we are not in sync and hold a dead connection.
194 * sFW -> sIG
195 * sCW -> sIG
196 * sLA -> sIG
197 * sTW -> sSS Reopened connection (RFC 1122).
198 * sCL -> sSS
199 */
200/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
201/*synack*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV },
202/*
203 * A SYN/ACK from the client is always invalid:
204 * - either it tries to set up a simultaneous open, which is
205 * not supported;
206 * - or the firewall has just been inserted between the two hosts
207 * during the session set-up. The SYN will be retransmitted
208 * by the true client (or it'll time out).
209 */
210/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
211/*fin*/ { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
212/*
213 * sNO -> sIV Too late and no reason to do anything...
214 * sSS -> sIV Client migth not send FIN in this state:
215 * we enforce waiting for a SYN/ACK reply first.
216 * sSR -> sFW Close started.
217 * sES -> sFW
218 * sFW -> sLA FIN seen in both directions, waiting for
219 * the last ACK.
220 * Migth be a retransmitted FIN as well...
221 * sCW -> sLA
222 * sLA -> sLA Retransmitted FIN. Remain in the same state.
223 * sTW -> sTW
224 * sCL -> sCL
225 */
226/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
227/*ack*/ { sES, sIV, sES, sES, sCW, sCW, sTW, sTW, sCL, sIV },
228/*
229 * sNO -> sES Assumed.
230 * sSS -> sIV ACK is invalid: we haven't seen a SYN/ACK yet.
231 * sSR -> sES Established state is reached.
232 * sES -> sES :-)
233 * sFW -> sCW Normal close request answered by ACK.
234 * sCW -> sCW
235 * sLA -> sTW Last ACK detected.
236 * sTW -> sTW Retransmitted last ACK. Remain in the same state.
237 * sCL -> sCL
238 */
239/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
240/*rst*/ { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV },
241/*none*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
242 },
243 {
244/* REPLY */
245/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
246/*syn*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV },
247/*
248 * sNO -> sIV Never reached.
249 * sSS -> sIV Simultaneous open, not supported
250 * sSR -> sIV Simultaneous open, not supported.
251 * sES -> sIV Server may not initiate a connection.
252 * sFW -> sIV
253 * sCW -> sIV
254 * sLA -> sIV
255 * sTW -> sIV Reopened connection, but server may not do it.
256 * sCL -> sIV
257 */
258/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
259/*synack*/ { sIV, sSR, sSR, sIG, sIG, sIG, sIG, sIG, sIG, sIV },
260/*
261 * sSS -> sSR Standard open.
262 * sSR -> sSR Retransmitted SYN/ACK.
263 * sES -> sIG Late retransmitted SYN/ACK?
264 * sFW -> sIG Might be SYN/ACK answering ignored SYN
265 * sCW -> sIG
266 * sLA -> sIG
267 * sTW -> sIG
268 * sCL -> sIG
269 */
270/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
271/*fin*/ { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
272/*
273 * sSS -> sIV Server might not send FIN in this state.
274 * sSR -> sFW Close started.
275 * sES -> sFW
276 * sFW -> sLA FIN seen in both directions.
277 * sCW -> sLA
278 * sLA -> sLA Retransmitted FIN.
279 * sTW -> sTW
280 * sCL -> sCL
281 */
282/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
283/*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
284/*
285 * sSS -> sIV Might be a half-open connection.
286 * sSR -> sSR Might answer late resent SYN.
287 * sES -> sES :-)
288 * sFW -> sCW Normal close request answered by ACK.
289 * sCW -> sCW
290 * sLA -> sTW Last ACK detected.
291 * sTW -> sTW Retransmitted last ACK.
292 * sCL -> sCL
293 */
294/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
295/*rst*/ { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV },
296/*none*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
297 }
298};
299
300static int tcp_pkt_to_tuple(const struct sk_buff *skb,
301 unsigned int dataoff,
302 struct nf_conntrack_tuple *tuple)
303{
304 struct tcphdr _hdr, *hp;
305
306 /* Actually only need first 8 bytes. */
307 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
308 if (hp == NULL)
309 return 0;
310
311 tuple->src.u.tcp.port = hp->source;
312 tuple->dst.u.tcp.port = hp->dest;
313
314 return 1;
315}
316
317static int tcp_invert_tuple(struct nf_conntrack_tuple *tuple,
318 const struct nf_conntrack_tuple *orig)
319{
320 tuple->src.u.tcp.port = orig->dst.u.tcp.port;
321 tuple->dst.u.tcp.port = orig->src.u.tcp.port;
322 return 1;
323}
324
325/* Print out the per-protocol part of the tuple. */
326static int tcp_print_tuple(struct seq_file *s,
327 const struct nf_conntrack_tuple *tuple)
328{
329 return seq_printf(s, "sport=%hu dport=%hu ",
330 ntohs(tuple->src.u.tcp.port),
331 ntohs(tuple->dst.u.tcp.port));
332}
333
334/* Print out the private part of the conntrack. */
335static int tcp_print_conntrack(struct seq_file *s,
336 const struct nf_conn *conntrack)
337{
338 enum tcp_conntrack state;
339
340 read_lock_bh(&tcp_lock);
341 state = conntrack->proto.tcp.state;
342 read_unlock_bh(&tcp_lock);
343
344 return seq_printf(s, "%s ", tcp_conntrack_names[state]);
345}
346
347static unsigned int get_conntrack_index(const struct tcphdr *tcph)
348{
349 if (tcph->rst) return TCP_RST_SET;
350 else if (tcph->syn) return (tcph->ack ? TCP_SYNACK_SET : TCP_SYN_SET);
351 else if (tcph->fin) return TCP_FIN_SET;
352 else if (tcph->ack) return TCP_ACK_SET;
353 else return TCP_NONE_SET;
354}
355
356/* TCP connection tracking based on 'Real Stateful TCP Packet Filtering
357 in IP Filter' by Guido van Rooij.
358
359 http://www.nluug.nl/events/sane2000/papers.html
360 http://www.iae.nl/users/guido/papers/tcp_filtering.ps.gz
361
362 The boundaries and the conditions are changed according to RFC793:
363 the packet must intersect the window (i.e. segments may be
364 after the right or before the left edge) and thus receivers may ACK
365 segments after the right edge of the window.
366
367 td_maxend = max(sack + max(win,1)) seen in reply packets
368 td_maxwin = max(max(win, 1)) + (sack - ack) seen in sent packets
369 td_maxwin += seq + len - sender.td_maxend
370 if seq + len > sender.td_maxend
371 td_end = max(seq + len) seen in sent packets
372
373 I. Upper bound for valid data: seq <= sender.td_maxend
374 II. Lower bound for valid data: seq + len >= sender.td_end - receiver.td_maxwin
375 III. Upper bound for valid ack: sack <= receiver.td_end
376 IV. Lower bound for valid ack: ack >= receiver.td_end - MAXACKWINDOW
377
378 where sack is the highest right edge of sack block found in the packet.
379
380 The upper bound limit for a valid ack is not ignored -
381 we doesn't have to deal with fragments.
382*/
383
384static inline __u32 segment_seq_plus_len(__u32 seq,
385 size_t len,
386 unsigned int dataoff,
387 struct tcphdr *tcph)
388{
389 /* XXX Should I use payload length field in IP/IPv6 header ?
390 * - YK */
391 return (seq + len - dataoff - tcph->doff*4
392 + (tcph->syn ? 1 : 0) + (tcph->fin ? 1 : 0));
393}
394
395/* Fixme: what about big packets? */
396#define MAXACKWINCONST 66000
397#define MAXACKWINDOW(sender) \
398 ((sender)->td_maxwin > MAXACKWINCONST ? (sender)->td_maxwin \
399 : MAXACKWINCONST)
400
401/*
402 * Simplified tcp_parse_options routine from tcp_input.c
403 */
404static void tcp_options(const struct sk_buff *skb,
405 unsigned int dataoff,
406 struct tcphdr *tcph,
407 struct ip_ct_tcp_state *state)
408{
409 unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
410 unsigned char *ptr;
411 int length = (tcph->doff*4) - sizeof(struct tcphdr);
412
413 if (!length)
414 return;
415
416 ptr = skb_header_pointer(skb, dataoff + sizeof(struct tcphdr),
417 length, buff);
418 BUG_ON(ptr == NULL);
419
420 state->td_scale =
421 state->flags = 0;
422
423 while (length > 0) {
424 int opcode=*ptr++;
425 int opsize;
426
427 switch (opcode) {
428 case TCPOPT_EOL:
429 return;
430 case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */
431 length--;
432 continue;
433 default:
434 opsize=*ptr++;
435 if (opsize < 2) /* "silly options" */
436 return;
437 if (opsize > length)
438 break; /* don't parse partial options */
439
440 if (opcode == TCPOPT_SACK_PERM
441 && opsize == TCPOLEN_SACK_PERM)
442 state->flags |= IP_CT_TCP_FLAG_SACK_PERM;
443 else if (opcode == TCPOPT_WINDOW
444 && opsize == TCPOLEN_WINDOW) {
445 state->td_scale = *(u_int8_t *)ptr;
446
447 if (state->td_scale > 14) {
448 /* See RFC1323 */
449 state->td_scale = 14;
450 }
451 state->flags |=
452 IP_CT_TCP_FLAG_WINDOW_SCALE;
453 }
454 ptr += opsize - 2;
455 length -= opsize;
456 }
457 }
458}
459
460static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
461 struct tcphdr *tcph, __u32 *sack)
462{
463 unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
464 unsigned char *ptr;
465 int length = (tcph->doff*4) - sizeof(struct tcphdr);
466 __u32 tmp;
467
468 if (!length)
469 return;
470
471 ptr = skb_header_pointer(skb, dataoff + sizeof(struct tcphdr),
472 length, buff);
473 BUG_ON(ptr == NULL);
474
475 /* Fast path for timestamp-only option */
476 if (length == TCPOLEN_TSTAMP_ALIGNED*4
477 && *(__u32 *)ptr ==
478 __constant_ntohl((TCPOPT_NOP << 24)
479 | (TCPOPT_NOP << 16)
480 | (TCPOPT_TIMESTAMP << 8)
481 | TCPOLEN_TIMESTAMP))
482 return;
483
484 while (length > 0) {
485 int opcode = *ptr++;
486 int opsize, i;
487
488 switch (opcode) {
489 case TCPOPT_EOL:
490 return;
491 case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */
492 length--;
493 continue;
494 default:
495 opsize = *ptr++;
496 if (opsize < 2) /* "silly options" */
497 return;
498 if (opsize > length)
499 break; /* don't parse partial options */
500
501 if (opcode == TCPOPT_SACK
502 && opsize >= (TCPOLEN_SACK_BASE
503 + TCPOLEN_SACK_PERBLOCK)
504 && !((opsize - TCPOLEN_SACK_BASE)
505 % TCPOLEN_SACK_PERBLOCK)) {
506 for (i = 0;
507 i < (opsize - TCPOLEN_SACK_BASE);
508 i += TCPOLEN_SACK_PERBLOCK) {
509 memcpy(&tmp, (__u32 *)(ptr + i) + 1,
510 sizeof(__u32));
511 tmp = ntohl(tmp);
512
513 if (after(tmp, *sack))
514 *sack = tmp;
515 }
516 return;
517 }
518 ptr += opsize - 2;
519 length -= opsize;
520 }
521 }
522}
523
524static int tcp_in_window(struct ip_ct_tcp *state,
525 enum ip_conntrack_dir dir,
526 unsigned int index,
527 const struct sk_buff *skb,
528 unsigned int dataoff,
529 struct tcphdr *tcph,
530 int pf)
531{
532 struct ip_ct_tcp_state *sender = &state->seen[dir];
533 struct ip_ct_tcp_state *receiver = &state->seen[!dir];
534 __u32 seq, ack, sack, end, win, swin;
535 int res;
536
537 /*
538 * Get the required data from the packet.
539 */
540 seq = ntohl(tcph->seq);
541 ack = sack = ntohl(tcph->ack_seq);
542 win = ntohs(tcph->window);
543 end = segment_seq_plus_len(seq, skb->len, dataoff, tcph);
544
545 if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM)
546 tcp_sack(skb, dataoff, tcph, &sack);
547
548 DEBUGP("tcp_in_window: START\n");
549 DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
550 "seq=%u ack=%u sack=%u win=%u end=%u\n",
551 NIPQUAD(iph->saddr), ntohs(tcph->source),
552 NIPQUAD(iph->daddr), ntohs(tcph->dest),
553 seq, ack, sack, win, end);
554 DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
555 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
556 sender->td_end, sender->td_maxend, sender->td_maxwin,
557 sender->td_scale,
558 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
559 receiver->td_scale);
560
561 if (sender->td_end == 0) {
562 /*
563 * Initialize sender data.
564 */
565 if (tcph->syn && tcph->ack) {
566 /*
567 * Outgoing SYN-ACK in reply to a SYN.
568 */
569 sender->td_end =
570 sender->td_maxend = end;
571 sender->td_maxwin = (win == 0 ? 1 : win);
572
573 tcp_options(skb, dataoff, tcph, sender);
574 /*
575 * RFC 1323:
576 * Both sides must send the Window Scale option
577 * to enable window scaling in either direction.
578 */
579 if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE
580 && receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE))
581 sender->td_scale =
582 receiver->td_scale = 0;
583 } else {
584 /*
585 * We are in the middle of a connection,
586 * its history is lost for us.
587 * Let's try to use the data from the packet.
588 */
589 sender->td_end = end;
590 sender->td_maxwin = (win == 0 ? 1 : win);
591 sender->td_maxend = end + sender->td_maxwin;
592 }
593 } else if (((state->state == TCP_CONNTRACK_SYN_SENT
594 && dir == IP_CT_DIR_ORIGINAL)
595 || (state->state == TCP_CONNTRACK_SYN_RECV
596 && dir == IP_CT_DIR_REPLY))
597 && after(end, sender->td_end)) {
598 /*
599 * RFC 793: "if a TCP is reinitialized ... then it need
600 * not wait at all; it must only be sure to use sequence
601 * numbers larger than those recently used."
602 */
603 sender->td_end =
604 sender->td_maxend = end;
605 sender->td_maxwin = (win == 0 ? 1 : win);
606
607 tcp_options(skb, dataoff, tcph, sender);
608 }
609
610 if (!(tcph->ack)) {
611 /*
612 * If there is no ACK, just pretend it was set and OK.
613 */
614 ack = sack = receiver->td_end;
615 } else if (((tcp_flag_word(tcph) & (TCP_FLAG_ACK|TCP_FLAG_RST)) ==
616 (TCP_FLAG_ACK|TCP_FLAG_RST))
617 && (ack == 0)) {
618 /*
619 * Broken TCP stacks, that set ACK in RST packets as well
620 * with zero ack value.
621 */
622 ack = sack = receiver->td_end;
623 }
624
625 if (seq == end
626 && (!tcph->rst
627 || (seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT)))
628 /*
629 * Packets contains no data: we assume it is valid
630 * and check the ack value only.
631 * However RST segments are always validated by their
632 * SEQ number, except when seq == 0 (reset sent answering
633 * SYN.
634 */
635 seq = end = sender->td_end;
636
637 DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
638 "seq=%u ack=%u sack =%u win=%u end=%u\n",
639 NIPQUAD(iph->saddr), ntohs(tcph->source),
640 NIPQUAD(iph->daddr), ntohs(tcph->dest),
641 seq, ack, sack, win, end);
642 DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
643 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
644 sender->td_end, sender->td_maxend, sender->td_maxwin,
645 sender->td_scale,
646 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
647 receiver->td_scale);
648
649 DEBUGP("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
650 before(seq, sender->td_maxend + 1),
651 after(end, sender->td_end - receiver->td_maxwin - 1),
652 before(sack, receiver->td_end + 1),
653 after(ack, receiver->td_end - MAXACKWINDOW(sender)));
654
655 if (sender->loose || receiver->loose ||
656 (before(seq, sender->td_maxend + 1) &&
657 after(end, sender->td_end - receiver->td_maxwin - 1) &&
658 before(sack, receiver->td_end + 1) &&
659 after(ack, receiver->td_end - MAXACKWINDOW(sender)))) {
660 /*
661 * Take into account window scaling (RFC 1323).
662 */
663 if (!tcph->syn)
664 win <<= sender->td_scale;
665
666 /*
667 * Update sender data.
668 */
669 swin = win + (sack - ack);
670 if (sender->td_maxwin < swin)
671 sender->td_maxwin = swin;
672 if (after(end, sender->td_end))
673 sender->td_end = end;
674 /*
675 * Update receiver data.
676 */
677 if (after(end, sender->td_maxend))
678 receiver->td_maxwin += end - sender->td_maxend;
679 if (after(sack + win, receiver->td_maxend - 1)) {
680 receiver->td_maxend = sack + win;
681 if (win == 0)
682 receiver->td_maxend++;
683 }
684
685 /*
686 * Check retransmissions.
687 */
688 if (index == TCP_ACK_SET) {
689 if (state->last_dir == dir
690 && state->last_seq == seq
691 && state->last_ack == ack
692 && state->last_end == end)
693 state->retrans++;
694 else {
695 state->last_dir = dir;
696 state->last_seq = seq;
697 state->last_ack = ack;
698 state->last_end = end;
699 state->retrans = 0;
700 }
701 }
702 /*
703 * Close the window of disabled window tracking :-)
704 */
705 if (sender->loose)
706 sender->loose--;
707
708 res = 1;
709 } else {
710 if (LOG_INVALID(IPPROTO_TCP))
711 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
712 "nf_ct_tcp: %s ",
713 before(seq, sender->td_maxend + 1) ?
714 after(end, sender->td_end - receiver->td_maxwin - 1) ?
715 before(sack, receiver->td_end + 1) ?
716 after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG"
717 : "ACK is under the lower bound (possible overly delayed ACK)"
718 : "ACK is over the upper bound (ACKed data not seen yet)"
719 : "SEQ is under the lower bound (already ACKed data retransmitted)"
720 : "SEQ is over the upper bound (over the window of the receiver)");
721
722 res = nf_ct_tcp_be_liberal;
723 }
724
725 DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
726 "receiver end=%u maxend=%u maxwin=%u\n",
727 res, sender->td_end, sender->td_maxend, sender->td_maxwin,
728 receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
729
730 return res;
731}
732
733#ifdef CONFIG_IP_NF_NAT_NEEDED
734/* Update sender->td_end after NAT successfully mangled the packet */
735/* Caller must linearize skb at tcp header. */
736void nf_conntrack_tcp_update(struct sk_buff *skb,
737 unsigned int dataoff,
738 struct nf_conn *conntrack,
739 int dir)
740{
741 struct tcphdr *tcph = (void *)skb->data + dataoff;
742 __u32 end;
743#ifdef DEBUGP_VARS
744 struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[dir];
745 struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[!dir];
746#endif
747
748 end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
749
750 write_lock_bh(&tcp_lock);
751 /*
752 * We have to worry for the ack in the reply packet only...
753 */
754 if (after(end, conntrack->proto.tcp.seen[dir].td_end))
755 conntrack->proto.tcp.seen[dir].td_end = end;
756 conntrack->proto.tcp.last_end = end;
757 write_unlock_bh(&tcp_lock);
758 DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
759 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
760 sender->td_end, sender->td_maxend, sender->td_maxwin,
761 sender->td_scale,
762 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
763 receiver->td_scale);
764}
765
766#endif
767
768#define TH_FIN 0x01
769#define TH_SYN 0x02
770#define TH_RST 0x04
771#define TH_PUSH 0x08
772#define TH_ACK 0x10
773#define TH_URG 0x20
774#define TH_ECE 0x40
775#define TH_CWR 0x80
776
777/* table of valid flag combinations - ECE and CWR are always valid */
778static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
779{
780 [TH_SYN] = 1,
781 [TH_SYN|TH_ACK] = 1,
782 [TH_SYN|TH_ACK|TH_PUSH] = 1,
783 [TH_RST] = 1,
784 [TH_RST|TH_ACK] = 1,
785 [TH_RST|TH_ACK|TH_PUSH] = 1,
786 [TH_FIN|TH_ACK] = 1,
787 [TH_ACK] = 1,
788 [TH_ACK|TH_PUSH] = 1,
789 [TH_ACK|TH_URG] = 1,
790 [TH_ACK|TH_URG|TH_PUSH] = 1,
791 [TH_FIN|TH_ACK|TH_PUSH] = 1,
792 [TH_FIN|TH_ACK|TH_URG] = 1,
793 [TH_FIN|TH_ACK|TH_URG|TH_PUSH] = 1,
794};
795
796/* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */
797static int tcp_error(struct sk_buff *skb,
798 unsigned int dataoff,
799 enum ip_conntrack_info *ctinfo,
800 int pf,
801 unsigned int hooknum,
802 int(*csum)(const struct sk_buff *,unsigned int))
803{
804 struct tcphdr _tcph, *th;
805 unsigned int tcplen = skb->len - dataoff;
806 u_int8_t tcpflags;
807
808 /* Smaller that minimal TCP header? */
809 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
810 if (th == NULL) {
811 if (LOG_INVALID(IPPROTO_TCP))
812 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
813 "nf_ct_tcp: short packet ");
814 return -NF_ACCEPT;
815 }
816
817 /* Not whole TCP header or malformed packet */
818 if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) {
819 if (LOG_INVALID(IPPROTO_TCP))
820 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
821 "nf_ct_tcp: truncated/malformed packet ");
822 return -NF_ACCEPT;
823 }
824
825 /* Checksum invalid? Ignore.
826 * We skip checking packets on the outgoing path
827 * because the semantic of CHECKSUM_HW is different there
828 * and moreover root might send raw packets.
829 */
830 /* FIXME: Source route IP option packets --RR */
831 if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
832 (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING))
833 && skb->ip_summed != CHECKSUM_UNNECESSARY
834 && csum(skb, dataoff)) {
835 if (LOG_INVALID(IPPROTO_TCP))
836 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
837 "nf_ct_tcp: bad TCP checksum ");
838 return -NF_ACCEPT;
839 }
840
841 /* Check TCP flags. */
842 tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR));
843 if (!tcp_valid_flags[tcpflags]) {
844 if (LOG_INVALID(IPPROTO_TCP))
845 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
846 "nf_ct_tcp: invalid TCP flag combination ");
847 return -NF_ACCEPT;
848 }
849
850 return NF_ACCEPT;
851}
852
853static int csum4(const struct sk_buff *skb, unsigned int dataoff)
854{
855 return csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr,
856 skb->len - dataoff, IPPROTO_TCP,
857 skb->ip_summed == CHECKSUM_HW ? skb->csum
858 : skb_checksum(skb, dataoff,
859 skb->len - dataoff, 0));
860}
861
862static int csum6(const struct sk_buff *skb, unsigned int dataoff)
863{
864 return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
865 skb->len - dataoff, IPPROTO_TCP,
866 skb->ip_summed == CHECKSUM_HW ? skb->csum
867 : skb_checksum(skb, dataoff, skb->len - dataoff,
868 0));
869}
870
871static int tcp_error4(struct sk_buff *skb,
872 unsigned int dataoff,
873 enum ip_conntrack_info *ctinfo,
874 int pf,
875 unsigned int hooknum)
876{
877 return tcp_error(skb, dataoff, ctinfo, pf, hooknum, csum4);
878}
879
880static int tcp_error6(struct sk_buff *skb,
881 unsigned int dataoff,
882 enum ip_conntrack_info *ctinfo,
883 int pf,
884 unsigned int hooknum)
885{
886 return tcp_error(skb, dataoff, ctinfo, pf, hooknum, csum6);
887}
888
889/* Returns verdict for packet, or -1 for invalid. */
890static int tcp_packet(struct nf_conn *conntrack,
891 const struct sk_buff *skb,
892 unsigned int dataoff,
893 enum ip_conntrack_info ctinfo,
894 int pf,
895 unsigned int hooknum)
896{
897 enum tcp_conntrack new_state, old_state;
898 enum ip_conntrack_dir dir;
899 struct tcphdr *th, _tcph;
900 unsigned long timeout;
901 unsigned int index;
902
903 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
904 BUG_ON(th == NULL);
905
906 write_lock_bh(&tcp_lock);
907 old_state = conntrack->proto.tcp.state;
908 dir = CTINFO2DIR(ctinfo);
909 index = get_conntrack_index(th);
910 new_state = tcp_conntracks[dir][index][old_state];
911
912 switch (new_state) {
913 case TCP_CONNTRACK_IGNORE:
914 /* Either SYN in ORIGINAL
915 * or SYN/ACK in REPLY. */
916 if (index == TCP_SYNACK_SET
917 && conntrack->proto.tcp.last_index == TCP_SYN_SET
918 && conntrack->proto.tcp.last_dir != dir
919 && ntohl(th->ack_seq) ==
920 conntrack->proto.tcp.last_end) {
921 /* This SYN/ACK acknowledges a SYN that we earlier
922 * ignored as invalid. This means that the client and
923 * the server are both in sync, while the firewall is
924 * not. We kill this session and block the SYN/ACK so
925 * that the client cannot but retransmit its SYN and
926 * thus initiate a clean new session.
927 */
928 write_unlock_bh(&tcp_lock);
929 if (LOG_INVALID(IPPROTO_TCP))
930 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
931 "nf_ct_tcp: killing out of sync session ");
932 if (del_timer(&conntrack->timeout))
933 conntrack->timeout.function((unsigned long)
934 conntrack);
935 return -NF_DROP;
936 }
937 conntrack->proto.tcp.last_index = index;
938 conntrack->proto.tcp.last_dir = dir;
939 conntrack->proto.tcp.last_seq = ntohl(th->seq);
940 conntrack->proto.tcp.last_end =
941 segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
942
943 write_unlock_bh(&tcp_lock);
944 if (LOG_INVALID(IPPROTO_TCP))
945 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
946 "nf_ct_tcp: invalid packed ignored ");
947 return NF_ACCEPT;
948 case TCP_CONNTRACK_MAX:
949 /* Invalid packet */
950 DEBUGP("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
951 dir, get_conntrack_index(th),
952 old_state);
953 write_unlock_bh(&tcp_lock);
954 if (LOG_INVALID(IPPROTO_TCP))
955 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
956 "nf_ct_tcp: invalid state ");
957 return -NF_ACCEPT;
958 case TCP_CONNTRACK_SYN_SENT:
959 if (old_state < TCP_CONNTRACK_TIME_WAIT)
960 break;
961 if ((conntrack->proto.tcp.seen[dir].flags &
962 IP_CT_TCP_FLAG_CLOSE_INIT)
963 || after(ntohl(th->seq),
964 conntrack->proto.tcp.seen[dir].td_end)) {
965 /* Attempt to reopen a closed connection.
966 * Delete this connection and look up again. */
967 write_unlock_bh(&tcp_lock);
968 if (del_timer(&conntrack->timeout))
969 conntrack->timeout.function((unsigned long)
970 conntrack);
971 return -NF_REPEAT;
972 }
973 case TCP_CONNTRACK_CLOSE:
974 if (index == TCP_RST_SET
975 && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
976 && conntrack->proto.tcp.last_index == TCP_SYN_SET
977 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
978 /* RST sent to invalid SYN we had let trough
979 * SYN was in window then, tear down connection.
980 * We skip window checking, because packet might ACK
981 * segments we ignored in the SYN. */
982 goto in_window;
983 }
984 /* Just fall trough */
985 default:
986 /* Keep compilers happy. */
987 break;
988 }
989
990 if (!tcp_in_window(&conntrack->proto.tcp, dir, index,
991 skb, dataoff, th, pf)) {
992 write_unlock_bh(&tcp_lock);
993 return -NF_ACCEPT;
994 }
995 in_window:
996 /* From now on we have got in-window packets */
997 conntrack->proto.tcp.last_index = index;
998
999 DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
1000 "syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
1001 NIPQUAD(iph->saddr), ntohs(th->source),
1002 NIPQUAD(iph->daddr), ntohs(th->dest),
1003 (th->syn ? 1 : 0), (th->ack ? 1 : 0),
1004 (th->fin ? 1 : 0), (th->rst ? 1 : 0),
1005 old_state, new_state);
1006
1007 conntrack->proto.tcp.state = new_state;
1008 if (old_state != new_state
1009 && (new_state == TCP_CONNTRACK_FIN_WAIT
1010 || new_state == TCP_CONNTRACK_CLOSE))
1011 conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
1012 timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
1013 && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
1014 ? nf_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
1015 write_unlock_bh(&tcp_lock);
1016
1017 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
1018 if (new_state != old_state)
1019 nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
1020
1021 if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
1022 /* If only reply is a RST, we can consider ourselves not to
1023 have an established connection: this is a fairly common
1024 problem case, so we can delete the conntrack
1025 immediately. --RR */
1026 if (th->rst) {
1027 if (del_timer(&conntrack->timeout))
1028 conntrack->timeout.function((unsigned long)
1029 conntrack);
1030 return NF_ACCEPT;
1031 }
1032 } else if (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
1033 && (old_state == TCP_CONNTRACK_SYN_RECV
1034 || old_state == TCP_CONNTRACK_ESTABLISHED)
1035 && new_state == TCP_CONNTRACK_ESTABLISHED) {
1036 /* Set ASSURED if we see see valid ack in ESTABLISHED
1037 after SYN_RECV or a valid answer for a picked up
1038 connection. */
1039 set_bit(IPS_ASSURED_BIT, &conntrack->status);
1040 nf_conntrack_event_cache(IPCT_STATUS, skb);
1041 }
1042 nf_ct_refresh_acct(conntrack, ctinfo, skb, timeout);
1043
1044 return NF_ACCEPT;
1045}
1046
1047/* Called when a new connection for this protocol found. */
1048static int tcp_new(struct nf_conn *conntrack,
1049 const struct sk_buff *skb,
1050 unsigned int dataoff)
1051{
1052 enum tcp_conntrack new_state;
1053 struct tcphdr *th, _tcph;
1054#ifdef DEBUGP_VARS
1055 struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0];
1056 struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1];
1057#endif
1058
1059 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
1060 BUG_ON(th == NULL);
1061
1062 /* Don't need lock here: this conntrack not in circulation yet */
1063 new_state
1064 = tcp_conntracks[0][get_conntrack_index(th)]
1065 [TCP_CONNTRACK_NONE];
1066
1067 /* Invalid: delete conntrack */
1068 if (new_state >= TCP_CONNTRACK_MAX) {
1069 DEBUGP("nf_ct_tcp: invalid new deleting.\n");
1070 return 0;
1071 }
1072
1073 if (new_state == TCP_CONNTRACK_SYN_SENT) {
1074 /* SYN packet */
1075 conntrack->proto.tcp.seen[0].td_end =
1076 segment_seq_plus_len(ntohl(th->seq), skb->len,
1077 dataoff, th);
1078 conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
1079 if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
1080 conntrack->proto.tcp.seen[0].td_maxwin = 1;
1081 conntrack->proto.tcp.seen[0].td_maxend =
1082 conntrack->proto.tcp.seen[0].td_end;
1083
1084 tcp_options(skb, dataoff, th, &conntrack->proto.tcp.seen[0]);
1085 conntrack->proto.tcp.seen[1].flags = 0;
1086 conntrack->proto.tcp.seen[0].loose =
1087 conntrack->proto.tcp.seen[1].loose = 0;
1088 } else if (nf_ct_tcp_loose == 0) {
1089 /* Don't try to pick up connections. */
1090 return 0;
1091 } else {
1092 /*
1093 * We are in the middle of a connection,
1094 * its history is lost for us.
1095 * Let's try to use the data from the packet.
1096 */
1097 conntrack->proto.tcp.seen[0].td_end =
1098 segment_seq_plus_len(ntohl(th->seq), skb->len,
1099 dataoff, th);
1100 conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
1101 if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
1102 conntrack->proto.tcp.seen[0].td_maxwin = 1;
1103 conntrack->proto.tcp.seen[0].td_maxend =
1104 conntrack->proto.tcp.seen[0].td_end +
1105 conntrack->proto.tcp.seen[0].td_maxwin;
1106 conntrack->proto.tcp.seen[0].td_scale = 0;
1107
1108 /* We assume SACK. Should we assume window scaling too? */
1109 conntrack->proto.tcp.seen[0].flags =
1110 conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM;
1111 conntrack->proto.tcp.seen[0].loose =
1112 conntrack->proto.tcp.seen[1].loose = nf_ct_tcp_loose;
1113 }
1114
1115 conntrack->proto.tcp.seen[1].td_end = 0;
1116 conntrack->proto.tcp.seen[1].td_maxend = 0;
1117 conntrack->proto.tcp.seen[1].td_maxwin = 1;
1118 conntrack->proto.tcp.seen[1].td_scale = 0;
1119
1120 /* tcp_packet will set them */
1121 conntrack->proto.tcp.state = TCP_CONNTRACK_NONE;
1122 conntrack->proto.tcp.last_index = TCP_NONE_SET;
1123
1124 DEBUGP("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
1125 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
1126 sender->td_end, sender->td_maxend, sender->td_maxwin,
1127 sender->td_scale,
1128 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
1129 receiver->td_scale);
1130 return 1;
1131}
1132
1133struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 =
1134{
1135 .l3proto = PF_INET,
1136 .proto = IPPROTO_TCP,
1137 .name = "tcp",
1138 .pkt_to_tuple = tcp_pkt_to_tuple,
1139 .invert_tuple = tcp_invert_tuple,
1140 .print_tuple = tcp_print_tuple,
1141 .print_conntrack = tcp_print_conntrack,
1142 .packet = tcp_packet,
1143 .new = tcp_new,
1144 .error = tcp_error4,
1145};
1146
1147struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 =
1148{
1149 .l3proto = PF_INET6,
1150 .proto = IPPROTO_TCP,
1151 .name = "tcp",
1152 .pkt_to_tuple = tcp_pkt_to_tuple,
1153 .invert_tuple = tcp_invert_tuple,
1154 .print_tuple = tcp_print_tuple,
1155 .print_conntrack = tcp_print_conntrack,
1156 .packet = tcp_packet,
1157 .new = tcp_new,
1158 .error = tcp_error6,
1159};
1160
1161EXPORT_SYMBOL(nf_conntrack_protocol_tcp4);
1162EXPORT_SYMBOL(nf_conntrack_protocol_tcp6);
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
new file mode 100644
index 000000000000..3cae7ce420dd
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -0,0 +1,216 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
9 * - enable working with Layer 3 protocol independent connection tracking.
10 *
11 * Derived from net/ipv4/netfilter/ip_conntrack_proto_udp.c
12 */
13
14#include <linux/types.h>
15#include <linux/sched.h>
16#include <linux/timer.h>
17#include <linux/module.h>
18#include <linux/netfilter.h>
19#include <linux/udp.h>
20#include <linux/seq_file.h>
21#include <linux/skbuff.h>
22#include <linux/ipv6.h>
23#include <net/ip6_checksum.h>
24#include <net/checksum.h>
25#include <linux/netfilter.h>
26#include <linux/netfilter_ipv4.h>
27#include <linux/netfilter_ipv6.h>
28#include <net/netfilter/nf_conntrack_protocol.h>
29
30unsigned long nf_ct_udp_timeout = 30*HZ;
31unsigned long nf_ct_udp_timeout_stream = 180*HZ;
32
33static int udp_pkt_to_tuple(const struct sk_buff *skb,
34 unsigned int dataoff,
35 struct nf_conntrack_tuple *tuple)
36{
37 struct udphdr _hdr, *hp;
38
39 /* Actually only need first 8 bytes. */
40 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
41 if (hp == NULL)
42 return 0;
43
44 tuple->src.u.udp.port = hp->source;
45 tuple->dst.u.udp.port = hp->dest;
46
47 return 1;
48}
49
50static int udp_invert_tuple(struct nf_conntrack_tuple *tuple,
51 const struct nf_conntrack_tuple *orig)
52{
53 tuple->src.u.udp.port = orig->dst.u.udp.port;
54 tuple->dst.u.udp.port = orig->src.u.udp.port;
55 return 1;
56}
57
58/* Print out the per-protocol part of the tuple. */
59static int udp_print_tuple(struct seq_file *s,
60 const struct nf_conntrack_tuple *tuple)
61{
62 return seq_printf(s, "sport=%hu dport=%hu ",
63 ntohs(tuple->src.u.udp.port),
64 ntohs(tuple->dst.u.udp.port));
65}
66
67/* Print out the private part of the conntrack. */
68static int udp_print_conntrack(struct seq_file *s,
69 const struct nf_conn *conntrack)
70{
71 return 0;
72}
73
74/* Returns verdict for packet, and may modify conntracktype */
75static int udp_packet(struct nf_conn *conntrack,
76 const struct sk_buff *skb,
77 unsigned int dataoff,
78 enum ip_conntrack_info ctinfo,
79 int pf,
80 unsigned int hooknum)
81{
82 /* If we've seen traffic both ways, this is some kind of UDP
83 stream. Extend timeout. */
84 if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
85 nf_ct_refresh_acct(conntrack, ctinfo, skb,
86 nf_ct_udp_timeout_stream);
87 /* Also, more likely to be important, and not a probe */
88 if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
89 nf_conntrack_event_cache(IPCT_STATUS, skb);
90 } else
91 nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_udp_timeout);
92
93 return NF_ACCEPT;
94}
95
96/* Called when a new connection for this protocol found. */
97static int udp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
98 unsigned int dataoff)
99{
100 return 1;
101}
102
103static int udp_error(struct sk_buff *skb, unsigned int dataoff,
104 enum ip_conntrack_info *ctinfo,
105 int pf,
106 unsigned int hooknum,
107 int (*csum)(const struct sk_buff *, unsigned int))
108{
109 unsigned int udplen = skb->len - dataoff;
110 struct udphdr _hdr, *hdr;
111
112 /* Header is too small? */
113 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
114 if (hdr == NULL) {
115 if (LOG_INVALID(IPPROTO_UDP))
116 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
117 "nf_ct_udp: short packet ");
118 return -NF_ACCEPT;
119 }
120
121 /* Truncated/malformed packets */
122 if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) {
123 if (LOG_INVALID(IPPROTO_UDP))
124 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
125 "nf_ct_udp: truncated/malformed packet ");
126 return -NF_ACCEPT;
127 }
128
129 /* Packet with no checksum */
130 if (!hdr->check)
131 return NF_ACCEPT;
132
133 /* Checksum invalid? Ignore.
134 * We skip checking packets on the outgoing path
135 * because the semantic of CHECKSUM_HW is different there
136 * and moreover root might send raw packets.
137 * FIXME: Source route IP option packets --RR */
138 if (((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
139 (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING))
140 && skb->ip_summed != CHECKSUM_UNNECESSARY
141 && csum(skb, dataoff)) {
142 if (LOG_INVALID(IPPROTO_UDP))
143 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
144 "nf_ct_udp: bad UDP checksum ");
145 return -NF_ACCEPT;
146 }
147
148 return NF_ACCEPT;
149}
150
151static int csum4(const struct sk_buff *skb, unsigned int dataoff)
152{
153 return csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr,
154 skb->len - dataoff, IPPROTO_UDP,
155 skb->ip_summed == CHECKSUM_HW ? skb->csum
156 : skb_checksum(skb, dataoff,
157 skb->len - dataoff, 0));
158}
159
160static int csum6(const struct sk_buff *skb, unsigned int dataoff)
161{
162 return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
163 skb->len - dataoff, IPPROTO_UDP,
164 skb->ip_summed == CHECKSUM_HW ? skb->csum
165 : skb_checksum(skb, dataoff, skb->len - dataoff,
166 0));
167}
168
169static int udp_error4(struct sk_buff *skb,
170 unsigned int dataoff,
171 enum ip_conntrack_info *ctinfo,
172 int pf,
173 unsigned int hooknum)
174{
175 return udp_error(skb, dataoff, ctinfo, pf, hooknum, csum4);
176}
177
178static int udp_error6(struct sk_buff *skb,
179 unsigned int dataoff,
180 enum ip_conntrack_info *ctinfo,
181 int pf,
182 unsigned int hooknum)
183{
184 return udp_error(skb, dataoff, ctinfo, pf, hooknum, csum6);
185}
186
187struct nf_conntrack_protocol nf_conntrack_protocol_udp4 =
188{
189 .l3proto = PF_INET,
190 .proto = IPPROTO_UDP,
191 .name = "udp",
192 .pkt_to_tuple = udp_pkt_to_tuple,
193 .invert_tuple = udp_invert_tuple,
194 .print_tuple = udp_print_tuple,
195 .print_conntrack = udp_print_conntrack,
196 .packet = udp_packet,
197 .new = udp_new,
198 .error = udp_error4,
199};
200
201struct nf_conntrack_protocol nf_conntrack_protocol_udp6 =
202{
203 .l3proto = PF_INET6,
204 .proto = IPPROTO_UDP,
205 .name = "udp",
206 .pkt_to_tuple = udp_pkt_to_tuple,
207 .invert_tuple = udp_invert_tuple,
208 .print_tuple = udp_print_tuple,
209 .print_conntrack = udp_print_conntrack,
210 .packet = udp_packet,
211 .new = udp_new,
212 .error = udp_error6,
213};
214
215EXPORT_SYMBOL(nf_conntrack_protocol_udp4);
216EXPORT_SYMBOL(nf_conntrack_protocol_udp6);
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
new file mode 100644
index 000000000000..45224db4fe2f
--- /dev/null
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -0,0 +1,869 @@
1/* This file contains all the functions required for the standalone
2 nf_conntrack module.
3
4 These are not required by the compatibility layer.
5*/
6
7/* (C) 1999-2001 Paul `Rusty' Russell
8 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
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 version 2 as
12 * published by the Free Software Foundation.
13 *
14 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
15 * - generalize L3 protocol dependent part.
16 *
17 * Derived from net/ipv4/netfilter/ip_conntrack_standalone.c
18 */
19
20#include <linux/config.h>
21#include <linux/types.h>
22#include <linux/netfilter.h>
23#include <linux/module.h>
24#include <linux/skbuff.h>
25#include <linux/proc_fs.h>
26#include <linux/seq_file.h>
27#include <linux/percpu.h>
28#include <linux/netdevice.h>
29#ifdef CONFIG_SYSCTL
30#include <linux/sysctl.h>
31#endif
32
33#define ASSERT_READ_LOCK(x)
34#define ASSERT_WRITE_LOCK(x)
35
36#include <net/netfilter/nf_conntrack.h>
37#include <net/netfilter/nf_conntrack_l3proto.h>
38#include <net/netfilter/nf_conntrack_protocol.h>
39#include <net/netfilter/nf_conntrack_core.h>
40#include <net/netfilter/nf_conntrack_helper.h>
41#include <linux/netfilter_ipv4/listhelp.h>
42
43#if 0
44#define DEBUGP printk
45#else
46#define DEBUGP(format, args...)
47#endif
48
49MODULE_LICENSE("GPL");
50
51extern atomic_t nf_conntrack_count;
52DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
53
54static int kill_l3proto(struct nf_conn *i, void *data)
55{
56 return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
57 ((struct nf_conntrack_l3proto *)data)->l3proto);
58}
59
60static int kill_proto(struct nf_conn *i, void *data)
61{
62 struct nf_conntrack_protocol *proto;
63 proto = (struct nf_conntrack_protocol *)data;
64 return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
65 proto->proto) &&
66 (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
67 proto->l3proto);
68}
69
70#ifdef CONFIG_PROC_FS
71static int
72print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
73 struct nf_conntrack_l3proto *l3proto,
74 struct nf_conntrack_protocol *proto)
75{
76 return l3proto->print_tuple(s, tuple) || proto->print_tuple(s, tuple);
77}
78
79#ifdef CONFIG_NF_CT_ACCT
80static unsigned int
81seq_print_counters(struct seq_file *s,
82 const struct ip_conntrack_counter *counter)
83{
84 return seq_printf(s, "packets=%llu bytes=%llu ",
85 (unsigned long long)counter->packets,
86 (unsigned long long)counter->bytes);
87}
88#else
89#define seq_print_counters(x, y) 0
90#endif
91
92struct ct_iter_state {
93 unsigned int bucket;
94};
95
96static struct list_head *ct_get_first(struct seq_file *seq)
97{
98 struct ct_iter_state *st = seq->private;
99
100 for (st->bucket = 0;
101 st->bucket < nf_conntrack_htable_size;
102 st->bucket++) {
103 if (!list_empty(&nf_conntrack_hash[st->bucket]))
104 return nf_conntrack_hash[st->bucket].next;
105 }
106 return NULL;
107}
108
109static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head)
110{
111 struct ct_iter_state *st = seq->private;
112
113 head = head->next;
114 while (head == &nf_conntrack_hash[st->bucket]) {
115 if (++st->bucket >= nf_conntrack_htable_size)
116 return NULL;
117 head = nf_conntrack_hash[st->bucket].next;
118 }
119 return head;
120}
121
122static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos)
123{
124 struct list_head *head = ct_get_first(seq);
125
126 if (head)
127 while (pos && (head = ct_get_next(seq, head)))
128 pos--;
129 return pos ? NULL : head;
130}
131
132static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
133{
134 read_lock_bh(&nf_conntrack_lock);
135 return ct_get_idx(seq, *pos);
136}
137
138static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
139{
140 (*pos)++;
141 return ct_get_next(s, v);
142}
143
144static void ct_seq_stop(struct seq_file *s, void *v)
145{
146 read_unlock_bh(&nf_conntrack_lock);
147}
148
149/* return 0 on success, 1 in case of error */
150static int ct_seq_show(struct seq_file *s, void *v)
151{
152 const struct nf_conntrack_tuple_hash *hash = v;
153 const struct nf_conn *conntrack = nf_ct_tuplehash_to_ctrack(hash);
154 struct nf_conntrack_l3proto *l3proto;
155 struct nf_conntrack_protocol *proto;
156
157 ASSERT_READ_LOCK(&nf_conntrack_lock);
158 NF_CT_ASSERT(conntrack);
159
160 /* we only want to print DIR_ORIGINAL */
161 if (NF_CT_DIRECTION(hash))
162 return 0;
163
164 l3proto = nf_ct_find_l3proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
165 .tuple.src.l3num);
166
167 NF_CT_ASSERT(l3proto);
168 proto = nf_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
169 .tuple.src.l3num,
170 conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
171 .tuple.dst.protonum);
172 NF_CT_ASSERT(proto);
173
174 if (seq_printf(s, "%-8s %u %-8s %u %ld ",
175 l3proto->name,
176 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num,
177 proto->name,
178 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
179 timer_pending(&conntrack->timeout)
180 ? (long)(conntrack->timeout.expires - jiffies)/HZ : 0) != 0)
181 return -ENOSPC;
182
183 if (l3proto->print_conntrack(s, conntrack))
184 return -ENOSPC;
185
186 if (proto->print_conntrack(s, conntrack))
187 return -ENOSPC;
188
189 if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
190 l3proto, proto))
191 return -ENOSPC;
192
193 if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_ORIGINAL]))
194 return -ENOSPC;
195
196 if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
197 if (seq_printf(s, "[UNREPLIED] "))
198 return -ENOSPC;
199
200 if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
201 l3proto, proto))
202 return -ENOSPC;
203
204 if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_REPLY]))
205 return -ENOSPC;
206
207 if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
208 if (seq_printf(s, "[ASSURED] "))
209 return -ENOSPC;
210
211#if defined(CONFIG_NF_CONNTRACK_MARK)
212 if (seq_printf(s, "mark=%u ", conntrack->mark))
213 return -ENOSPC;
214#endif
215
216 if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use)))
217 return -ENOSPC;
218
219 return 0;
220}
221
222static struct seq_operations ct_seq_ops = {
223 .start = ct_seq_start,
224 .next = ct_seq_next,
225 .stop = ct_seq_stop,
226 .show = ct_seq_show
227};
228
229static int ct_open(struct inode *inode, struct file *file)
230{
231 struct seq_file *seq;
232 struct ct_iter_state *st;
233 int ret;
234
235 st = kmalloc(sizeof(struct ct_iter_state), GFP_KERNEL);
236 if (st == NULL)
237 return -ENOMEM;
238 ret = seq_open(file, &ct_seq_ops);
239 if (ret)
240 goto out_free;
241 seq = file->private_data;
242 seq->private = st;
243 memset(st, 0, sizeof(struct ct_iter_state));
244 return ret;
245out_free:
246 kfree(st);
247 return ret;
248}
249
250static struct file_operations ct_file_ops = {
251 .owner = THIS_MODULE,
252 .open = ct_open,
253 .read = seq_read,
254 .llseek = seq_lseek,
255 .release = seq_release_private,
256};
257
258/* expects */
259static void *exp_seq_start(struct seq_file *s, loff_t *pos)
260{
261 struct list_head *e = &nf_conntrack_expect_list;
262 loff_t i;
263
264 /* strange seq_file api calls stop even if we fail,
265 * thus we need to grab lock since stop unlocks */
266 read_lock_bh(&nf_conntrack_lock);
267
268 if (list_empty(e))
269 return NULL;
270
271 for (i = 0; i <= *pos; i++) {
272 e = e->next;
273 if (e == &nf_conntrack_expect_list)
274 return NULL;
275 }
276 return e;
277}
278
279static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
280{
281 struct list_head *e = v;
282
283 ++*pos;
284 e = e->next;
285
286 if (e == &nf_conntrack_expect_list)
287 return NULL;
288
289 return e;
290}
291
292static void exp_seq_stop(struct seq_file *s, void *v)
293{
294 read_unlock_bh(&nf_conntrack_lock);
295}
296
297static int exp_seq_show(struct seq_file *s, void *v)
298{
299 struct nf_conntrack_expect *expect = v;
300
301 if (expect->timeout.function)
302 seq_printf(s, "%ld ", timer_pending(&expect->timeout)
303 ? (long)(expect->timeout.expires - jiffies)/HZ : 0);
304 else
305 seq_printf(s, "- ");
306 seq_printf(s, "l3proto = %u proto=%u ",
307 expect->tuple.src.l3num,
308 expect->tuple.dst.protonum);
309 print_tuple(s, &expect->tuple,
310 nf_ct_find_l3proto(expect->tuple.src.l3num),
311 nf_ct_find_proto(expect->tuple.src.l3num,
312 expect->tuple.dst.protonum));
313 return seq_putc(s, '\n');
314}
315
316static struct seq_operations exp_seq_ops = {
317 .start = exp_seq_start,
318 .next = exp_seq_next,
319 .stop = exp_seq_stop,
320 .show = exp_seq_show
321};
322
323static int exp_open(struct inode *inode, struct file *file)
324{
325 return seq_open(file, &exp_seq_ops);
326}
327
328static struct file_operations exp_file_ops = {
329 .owner = THIS_MODULE,
330 .open = exp_open,
331 .read = seq_read,
332 .llseek = seq_lseek,
333 .release = seq_release
334};
335
336static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
337{
338 int cpu;
339
340 if (*pos == 0)
341 return SEQ_START_TOKEN;
342
343 for (cpu = *pos-1; cpu < NR_CPUS; ++cpu) {
344 if (!cpu_possible(cpu))
345 continue;
346 *pos = cpu + 1;
347 return &per_cpu(nf_conntrack_stat, cpu);
348 }
349
350 return NULL;
351}
352
353static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
354{
355 int cpu;
356
357 for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
358 if (!cpu_possible(cpu))
359 continue;
360 *pos = cpu + 1;
361 return &per_cpu(nf_conntrack_stat, cpu);
362 }
363
364 return NULL;
365}
366
367static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
368{
369}
370
371static int ct_cpu_seq_show(struct seq_file *seq, void *v)
372{
373 unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
374 struct ip_conntrack_stat *st = v;
375
376 if (v == SEQ_START_TOKEN) {
377 seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete\n");
378 return 0;
379 }
380
381 seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x "
382 "%08x %08x %08x %08x %08x %08x %08x %08x \n",
383 nr_conntracks,
384 st->searched,
385 st->found,
386 st->new,
387 st->invalid,
388 st->ignore,
389 st->delete,
390 st->delete_list,
391 st->insert,
392 st->insert_failed,
393 st->drop,
394 st->early_drop,
395 st->error,
396
397 st->expect_new,
398 st->expect_create,
399 st->expect_delete
400 );
401 return 0;
402}
403
404static struct seq_operations ct_cpu_seq_ops = {
405 .start = ct_cpu_seq_start,
406 .next = ct_cpu_seq_next,
407 .stop = ct_cpu_seq_stop,
408 .show = ct_cpu_seq_show,
409};
410
411static int ct_cpu_seq_open(struct inode *inode, struct file *file)
412{
413 return seq_open(file, &ct_cpu_seq_ops);
414}
415
416static struct file_operations ct_cpu_seq_fops = {
417 .owner = THIS_MODULE,
418 .open = ct_cpu_seq_open,
419 .read = seq_read,
420 .llseek = seq_lseek,
421 .release = seq_release_private,
422};
423#endif /* CONFIG_PROC_FS */
424
425/* Sysctl support */
426
427#ifdef CONFIG_SYSCTL
428
429/* From nf_conntrack_core.c */
430extern int nf_conntrack_max;
431extern unsigned int nf_conntrack_htable_size;
432
433/* From nf_conntrack_proto_tcp.c */
434extern unsigned long nf_ct_tcp_timeout_syn_sent;
435extern unsigned long nf_ct_tcp_timeout_syn_recv;
436extern unsigned long nf_ct_tcp_timeout_established;
437extern unsigned long nf_ct_tcp_timeout_fin_wait;
438extern unsigned long nf_ct_tcp_timeout_close_wait;
439extern unsigned long nf_ct_tcp_timeout_last_ack;
440extern unsigned long nf_ct_tcp_timeout_time_wait;
441extern unsigned long nf_ct_tcp_timeout_close;
442extern unsigned long nf_ct_tcp_timeout_max_retrans;
443extern int nf_ct_tcp_loose;
444extern int nf_ct_tcp_be_liberal;
445extern int nf_ct_tcp_max_retrans;
446
447/* From nf_conntrack_proto_udp.c */
448extern unsigned long nf_ct_udp_timeout;
449extern unsigned long nf_ct_udp_timeout_stream;
450
451/* From nf_conntrack_proto_generic.c */
452extern unsigned long nf_ct_generic_timeout;
453
454/* Log invalid packets of a given protocol */
455static int log_invalid_proto_min = 0;
456static int log_invalid_proto_max = 255;
457
458static struct ctl_table_header *nf_ct_sysctl_header;
459
460static ctl_table nf_ct_sysctl_table[] = {
461 {
462 .ctl_name = NET_NF_CONNTRACK_MAX,
463 .procname = "nf_conntrack_max",
464 .data = &nf_conntrack_max,
465 .maxlen = sizeof(int),
466 .mode = 0644,
467 .proc_handler = &proc_dointvec,
468 },
469 {
470 .ctl_name = NET_NF_CONNTRACK_COUNT,
471 .procname = "nf_conntrack_count",
472 .data = &nf_conntrack_count,
473 .maxlen = sizeof(int),
474 .mode = 0444,
475 .proc_handler = &proc_dointvec,
476 },
477 {
478 .ctl_name = NET_NF_CONNTRACK_BUCKETS,
479 .procname = "nf_conntrack_buckets",
480 .data = &nf_conntrack_htable_size,
481 .maxlen = sizeof(unsigned int),
482 .mode = 0444,
483 .proc_handler = &proc_dointvec,
484 },
485 {
486 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
487 .procname = "nf_conntrack_tcp_timeout_syn_sent",
488 .data = &nf_ct_tcp_timeout_syn_sent,
489 .maxlen = sizeof(unsigned int),
490 .mode = 0644,
491 .proc_handler = &proc_dointvec_jiffies,
492 },
493 {
494 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
495 .procname = "nf_conntrack_tcp_timeout_syn_recv",
496 .data = &nf_ct_tcp_timeout_syn_recv,
497 .maxlen = sizeof(unsigned int),
498 .mode = 0644,
499 .proc_handler = &proc_dointvec_jiffies,
500 },
501 {
502 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
503 .procname = "nf_conntrack_tcp_timeout_established",
504 .data = &nf_ct_tcp_timeout_established,
505 .maxlen = sizeof(unsigned int),
506 .mode = 0644,
507 .proc_handler = &proc_dointvec_jiffies,
508 },
509 {
510 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
511 .procname = "nf_conntrack_tcp_timeout_fin_wait",
512 .data = &nf_ct_tcp_timeout_fin_wait,
513 .maxlen = sizeof(unsigned int),
514 .mode = 0644,
515 .proc_handler = &proc_dointvec_jiffies,
516 },
517 {
518 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
519 .procname = "nf_conntrack_tcp_timeout_close_wait",
520 .data = &nf_ct_tcp_timeout_close_wait,
521 .maxlen = sizeof(unsigned int),
522 .mode = 0644,
523 .proc_handler = &proc_dointvec_jiffies,
524 },
525 {
526 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
527 .procname = "nf_conntrack_tcp_timeout_last_ack",
528 .data = &nf_ct_tcp_timeout_last_ack,
529 .maxlen = sizeof(unsigned int),
530 .mode = 0644,
531 .proc_handler = &proc_dointvec_jiffies,
532 },
533 {
534 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
535 .procname = "nf_conntrack_tcp_timeout_time_wait",
536 .data = &nf_ct_tcp_timeout_time_wait,
537 .maxlen = sizeof(unsigned int),
538 .mode = 0644,
539 .proc_handler = &proc_dointvec_jiffies,
540 },
541 {
542 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
543 .procname = "nf_conntrack_tcp_timeout_close",
544 .data = &nf_ct_tcp_timeout_close,
545 .maxlen = sizeof(unsigned int),
546 .mode = 0644,
547 .proc_handler = &proc_dointvec_jiffies,
548 },
549 {
550 .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT,
551 .procname = "nf_conntrack_udp_timeout",
552 .data = &nf_ct_udp_timeout,
553 .maxlen = sizeof(unsigned int),
554 .mode = 0644,
555 .proc_handler = &proc_dointvec_jiffies,
556 },
557 {
558 .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
559 .procname = "nf_conntrack_udp_timeout_stream",
560 .data = &nf_ct_udp_timeout_stream,
561 .maxlen = sizeof(unsigned int),
562 .mode = 0644,
563 .proc_handler = &proc_dointvec_jiffies,
564 },
565 {
566 .ctl_name = NET_NF_CONNTRACK_GENERIC_TIMEOUT,
567 .procname = "nf_conntrack_generic_timeout",
568 .data = &nf_ct_generic_timeout,
569 .maxlen = sizeof(unsigned int),
570 .mode = 0644,
571 .proc_handler = &proc_dointvec_jiffies,
572 },
573 {
574 .ctl_name = NET_NF_CONNTRACK_LOG_INVALID,
575 .procname = "nf_conntrack_log_invalid",
576 .data = &nf_ct_log_invalid,
577 .maxlen = sizeof(unsigned int),
578 .mode = 0644,
579 .proc_handler = &proc_dointvec_minmax,
580 .strategy = &sysctl_intvec,
581 .extra1 = &log_invalid_proto_min,
582 .extra2 = &log_invalid_proto_max,
583 },
584 {
585 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
586 .procname = "nf_conntrack_tcp_timeout_max_retrans",
587 .data = &nf_ct_tcp_timeout_max_retrans,
588 .maxlen = sizeof(unsigned int),
589 .mode = 0644,
590 .proc_handler = &proc_dointvec_jiffies,
591 },
592 {
593 .ctl_name = NET_NF_CONNTRACK_TCP_LOOSE,
594 .procname = "nf_conntrack_tcp_loose",
595 .data = &nf_ct_tcp_loose,
596 .maxlen = sizeof(unsigned int),
597 .mode = 0644,
598 .proc_handler = &proc_dointvec,
599 },
600 {
601 .ctl_name = NET_NF_CONNTRACK_TCP_BE_LIBERAL,
602 .procname = "nf_conntrack_tcp_be_liberal",
603 .data = &nf_ct_tcp_be_liberal,
604 .maxlen = sizeof(unsigned int),
605 .mode = 0644,
606 .proc_handler = &proc_dointvec,
607 },
608 {
609 .ctl_name = NET_NF_CONNTRACK_TCP_MAX_RETRANS,
610 .procname = "nf_conntrack_tcp_max_retrans",
611 .data = &nf_ct_tcp_max_retrans,
612 .maxlen = sizeof(unsigned int),
613 .mode = 0644,
614 .proc_handler = &proc_dointvec,
615 },
616
617 { .ctl_name = 0 }
618};
619
620#define NET_NF_CONNTRACK_MAX 2089
621
622static ctl_table nf_ct_netfilter_table[] = {
623 {
624 .ctl_name = NET_NETFILTER,
625 .procname = "netfilter",
626 .mode = 0555,
627 .child = nf_ct_sysctl_table,
628 },
629 {
630 .ctl_name = NET_NF_CONNTRACK_MAX,
631 .procname = "nf_conntrack_max",
632 .data = &nf_conntrack_max,
633 .maxlen = sizeof(int),
634 .mode = 0644,
635 .proc_handler = &proc_dointvec,
636 },
637 { .ctl_name = 0 }
638};
639
640static ctl_table nf_ct_net_table[] = {
641 {
642 .ctl_name = CTL_NET,
643 .procname = "net",
644 .mode = 0555,
645 .child = nf_ct_netfilter_table,
646 },
647 { .ctl_name = 0 }
648};
649EXPORT_SYMBOL(nf_ct_log_invalid);
650#endif /* CONFIG_SYSCTL */
651
652static int init_or_cleanup(int init)
653{
654#ifdef CONFIG_PROC_FS
655 struct proc_dir_entry *proc, *proc_exp, *proc_stat;
656#endif
657 int ret = 0;
658
659 if (!init) goto cleanup;
660
661 ret = nf_conntrack_init();
662 if (ret < 0)
663 goto cleanup_nothing;
664
665#ifdef CONFIG_PROC_FS
666 proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops);
667 if (!proc) goto cleanup_init;
668
669 proc_exp = proc_net_fops_create("nf_conntrack_expect", 0440,
670 &exp_file_ops);
671 if (!proc_exp) goto cleanup_proc;
672
673 proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat);
674 if (!proc_stat)
675 goto cleanup_proc_exp;
676
677 proc_stat->proc_fops = &ct_cpu_seq_fops;
678 proc_stat->owner = THIS_MODULE;
679#endif
680#ifdef CONFIG_SYSCTL
681 nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
682 if (nf_ct_sysctl_header == NULL) {
683 printk("nf_conntrack: can't register to sysctl.\n");
684 ret = -ENOMEM;
685 goto cleanup_proc_stat;
686 }
687#endif
688
689 return ret;
690
691 cleanup:
692#ifdef CONFIG_SYSCTL
693 unregister_sysctl_table(nf_ct_sysctl_header);
694 cleanup_proc_stat:
695#endif
696#ifdef CONFIG_PROC_FS
697 proc_net_remove("nf_conntrack_stat");
698 cleanup_proc_exp:
699 proc_net_remove("nf_conntrack_expect");
700 cleanup_proc:
701 proc_net_remove("nf_conntrack");
702 cleanup_init:
703#endif /* CNFIG_PROC_FS */
704 nf_conntrack_cleanup();
705 cleanup_nothing:
706 return ret;
707}
708
709int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
710{
711 int ret = 0;
712
713 write_lock_bh(&nf_conntrack_lock);
714 if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_generic_l3proto) {
715 ret = -EBUSY;
716 goto out;
717 }
718 nf_ct_l3protos[proto->l3proto] = proto;
719out:
720 write_unlock_bh(&nf_conntrack_lock);
721
722 return ret;
723}
724
725void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
726{
727 write_lock_bh(&nf_conntrack_lock);
728 nf_ct_l3protos[proto->l3proto] = &nf_conntrack_generic_l3proto;
729 write_unlock_bh(&nf_conntrack_lock);
730
731 /* Somebody could be still looking at the proto in bh. */
732 synchronize_net();
733
734 /* Remove all contrack entries for this protocol */
735 nf_ct_iterate_cleanup(kill_l3proto, proto);
736}
737
738/* FIXME: Allow NULL functions and sub in pointers to generic for
739 them. --RR */
740int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto)
741{
742 int ret = 0;
743
744retry:
745 write_lock_bh(&nf_conntrack_lock);
746 if (nf_ct_protos[proto->l3proto]) {
747 if (nf_ct_protos[proto->l3proto][proto->proto]
748 != &nf_conntrack_generic_protocol) {
749 ret = -EBUSY;
750 goto out_unlock;
751 }
752 } else {
753 /* l3proto may be loaded latter. */
754 struct nf_conntrack_protocol **proto_array;
755 int i;
756
757 write_unlock_bh(&nf_conntrack_lock);
758
759 proto_array = (struct nf_conntrack_protocol **)
760 kmalloc(MAX_NF_CT_PROTO *
761 sizeof(struct nf_conntrack_protocol *),
762 GFP_KERNEL);
763 if (proto_array == NULL) {
764 ret = -ENOMEM;
765 goto out;
766 }
767 for (i = 0; i < MAX_NF_CT_PROTO; i++)
768 proto_array[i] = &nf_conntrack_generic_protocol;
769
770 write_lock_bh(&nf_conntrack_lock);
771 if (nf_ct_protos[proto->l3proto]) {
772 /* bad timing, but no problem */
773 write_unlock_bh(&nf_conntrack_lock);
774 kfree(proto_array);
775 } else {
776 nf_ct_protos[proto->l3proto] = proto_array;
777 write_unlock_bh(&nf_conntrack_lock);
778 }
779
780 /*
781 * Just once because array is never freed until unloading
782 * nf_conntrack.ko
783 */
784 goto retry;
785 }
786
787 nf_ct_protos[proto->l3proto][proto->proto] = proto;
788
789out_unlock:
790 write_unlock_bh(&nf_conntrack_lock);
791out:
792 return ret;
793}
794
795void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto)
796{
797 write_lock_bh(&nf_conntrack_lock);
798 nf_ct_protos[proto->l3proto][proto->proto]
799 = &nf_conntrack_generic_protocol;
800 write_unlock_bh(&nf_conntrack_lock);
801
802 /* Somebody could be still looking at the proto in bh. */
803 synchronize_net();
804
805 /* Remove all contrack entries for this protocol */
806 nf_ct_iterate_cleanup(kill_proto, proto);
807}
808
809static int __init init(void)
810{
811 return init_or_cleanup(1);
812}
813
814static void __exit fini(void)
815{
816 init_or_cleanup(0);
817}
818
819module_init(init);
820module_exit(fini);
821
822/* Some modules need us, but don't depend directly on any symbol.
823 They should call this. */
824void need_nf_conntrack(void)
825{
826}
827
828#ifdef CONFIG_NF_CONNTRACK_EVENTS
829EXPORT_SYMBOL_GPL(nf_conntrack_chain);
830EXPORT_SYMBOL_GPL(nf_conntrack_expect_chain);
831EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
832EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
833EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init);
834EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
835EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
836#endif
837EXPORT_SYMBOL(nf_conntrack_l3proto_register);
838EXPORT_SYMBOL(nf_conntrack_l3proto_unregister);
839EXPORT_SYMBOL(nf_conntrack_protocol_register);
840EXPORT_SYMBOL(nf_conntrack_protocol_unregister);
841EXPORT_SYMBOL(nf_ct_invert_tuplepr);
842EXPORT_SYMBOL(nf_conntrack_alter_reply);
843EXPORT_SYMBOL(nf_conntrack_destroyed);
844EXPORT_SYMBOL(need_nf_conntrack);
845EXPORT_SYMBOL(nf_conntrack_helper_register);
846EXPORT_SYMBOL(nf_conntrack_helper_unregister);
847EXPORT_SYMBOL(nf_ct_iterate_cleanup);
848EXPORT_SYMBOL(__nf_ct_refresh_acct);
849EXPORT_SYMBOL(nf_ct_protos);
850EXPORT_SYMBOL(nf_ct_find_proto);
851EXPORT_SYMBOL(nf_ct_l3protos);
852EXPORT_SYMBOL(nf_conntrack_expect_alloc);
853EXPORT_SYMBOL(nf_conntrack_expect_put);
854EXPORT_SYMBOL(nf_conntrack_expect_related);
855EXPORT_SYMBOL(nf_conntrack_unexpect_related);
856EXPORT_SYMBOL(nf_conntrack_tuple_taken);
857EXPORT_SYMBOL(nf_conntrack_htable_size);
858EXPORT_SYMBOL(nf_conntrack_lock);
859EXPORT_SYMBOL(nf_conntrack_hash);
860EXPORT_SYMBOL(nf_conntrack_untracked);
861EXPORT_SYMBOL_GPL(nf_conntrack_find_get);
862#ifdef CONFIG_IP_NF_NAT_NEEDED
863EXPORT_SYMBOL(nf_conntrack_tcp_update);
864#endif
865EXPORT_SYMBOL(__nf_conntrack_confirm);
866EXPORT_SYMBOL(nf_ct_get_tuple);
867EXPORT_SYMBOL(nf_ct_invert_tuple);
868EXPORT_SYMBOL(nf_conntrack_in);
869EXPORT_SYMBOL(__nf_conntrack_attach);
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 4bc27a6334c1..83f4c53030fc 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -128,7 +128,7 @@ void __nfa_fill(struct sk_buff *skb, int attrtype, int attrlen,
128 memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size); 128 memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size);
129} 129}
130 130
131int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len) 131void nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
132{ 132{
133 memset(tb, 0, sizeof(struct nfattr *) * maxattr); 133 memset(tb, 0, sizeof(struct nfattr *) * maxattr);
134 134
@@ -138,8 +138,6 @@ int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
138 tb[flavor-1] = nfa; 138 tb[flavor-1] = nfa;
139 nfa = NFA_NEXT(nfa, len); 139 nfa = NFA_NEXT(nfa, len);
140 } 140 }
141
142 return 0;
143} 141}
144 142
145/** 143/**
@@ -242,15 +240,18 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
242 ss = nfnetlink_get_subsys(type); 240 ss = nfnetlink_get_subsys(type);
243 if (!ss) { 241 if (!ss) {
244#ifdef CONFIG_KMOD 242#ifdef CONFIG_KMOD
245 /* don't call nfnl_shunlock, since it would reenter 243 if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
246 * with further packet processing */ 244 /* don't call nfnl_shunlock, since it would reenter
247 up(&nfnl_sem); 245 * with further packet processing */
248 request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type)); 246 up(&nfnl_sem);
249 nfnl_shlock(); 247 request_module("nfnetlink-subsys-%d",
250 ss = nfnetlink_get_subsys(type); 248 NFNL_SUBSYS_ID(type));
249 nfnl_shlock();
250 ss = nfnetlink_get_subsys(type);
251 }
251 if (!ss) 252 if (!ss)
252#endif 253#endif
253 goto err_inval; 254 goto err_inval;
254 } 255 }
255 256
256 nc = nfnetlink_find_client(type, ss); 257 nc = nfnetlink_find_client(type, ss);
diff --git a/net/netlink/Makefile b/net/netlink/Makefile
index 39d9c2dcd03c..e3589c2de49e 100644
--- a/net/netlink/Makefile
+++ b/net/netlink/Makefile
@@ -2,4 +2,4 @@
2# Makefile for the netlink driver. 2# Makefile for the netlink driver.
3# 3#
4 4
5obj-y := af_netlink.o 5obj-y := af_netlink.o attr.o genetlink.o
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 5ca283537bc6..8c38ee6d255e 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -58,6 +58,7 @@
58 58
59#include <net/sock.h> 59#include <net/sock.h>
60#include <net/scm.h> 60#include <net/scm.h>
61#include <net/netlink.h>
61 62
62#define Nprintk(a...) 63#define Nprintk(a...)
63#define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) 64#define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8)
@@ -427,7 +428,8 @@ static int netlink_release(struct socket *sock)
427 428
428 spin_lock(&nlk->cb_lock); 429 spin_lock(&nlk->cb_lock);
429 if (nlk->cb) { 430 if (nlk->cb) {
430 nlk->cb->done(nlk->cb); 431 if (nlk->cb->done)
432 nlk->cb->done(nlk->cb);
431 netlink_destroy_callback(nlk->cb); 433 netlink_destroy_callback(nlk->cb);
432 nlk->cb = NULL; 434 nlk->cb = NULL;
433 } 435 }
@@ -1322,7 +1324,8 @@ static int netlink_dump(struct sock *sk)
1322 skb_queue_tail(&sk->sk_receive_queue, skb); 1324 skb_queue_tail(&sk->sk_receive_queue, skb);
1323 sk->sk_data_ready(sk, skb->len); 1325 sk->sk_data_ready(sk, skb->len);
1324 1326
1325 cb->done(cb); 1327 if (cb->done)
1328 cb->done(cb);
1326 nlk->cb = NULL; 1329 nlk->cb = NULL;
1327 spin_unlock(&nlk->cb_lock); 1330 spin_unlock(&nlk->cb_lock);
1328 1331
@@ -1409,6 +1412,94 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
1409 netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); 1412 netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
1410} 1413}
1411 1414
1415static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
1416 struct nlmsghdr *, int *))
1417{
1418 unsigned int total_len;
1419 struct nlmsghdr *nlh;
1420 int err;
1421
1422 while (skb->len >= nlmsg_total_size(0)) {
1423 nlh = (struct nlmsghdr *) skb->data;
1424
1425 if (skb->len < nlh->nlmsg_len)
1426 return 0;
1427
1428 total_len = min(NLMSG_ALIGN(nlh->nlmsg_len), skb->len);
1429
1430 if (cb(skb, nlh, &err) < 0) {
1431 /* Not an error, but we have to interrupt processing
1432 * here. Note: that in this case we do not pull
1433 * message from skb, it will be processed later.
1434 */
1435 if (err == 0)
1436 return -1;
1437 netlink_ack(skb, nlh, err);
1438 } else if (nlh->nlmsg_flags & NLM_F_ACK)
1439 netlink_ack(skb, nlh, 0);
1440
1441 skb_pull(skb, total_len);
1442 }
1443
1444 return 0;
1445}
1446
1447/**
1448 * nelink_run_queue - Process netlink receive queue.
1449 * @sk: Netlink socket containing the queue
1450 * @qlen: Place to store queue length upon entry
1451 * @cb: Callback function invoked for each netlink message found
1452 *
1453 * Processes as much as there was in the queue upon entry and invokes
1454 * a callback function for each netlink message found. The callback
1455 * function may refuse a message by returning a negative error code
1456 * but setting the error pointer to 0 in which case this function
1457 * returns with a qlen != 0.
1458 *
1459 * qlen must be initialized to 0 before the initial entry, afterwards
1460 * the function may be called repeatedly until qlen reaches 0.
1461 */
1462void netlink_run_queue(struct sock *sk, unsigned int *qlen,
1463 int (*cb)(struct sk_buff *, struct nlmsghdr *, int *))
1464{
1465 struct sk_buff *skb;
1466
1467 if (!*qlen || *qlen > skb_queue_len(&sk->sk_receive_queue))
1468 *qlen = skb_queue_len(&sk->sk_receive_queue);
1469
1470 for (; *qlen; (*qlen)--) {
1471 skb = skb_dequeue(&sk->sk_receive_queue);
1472 if (netlink_rcv_skb(skb, cb)) {
1473 if (skb->len)
1474 skb_queue_head(&sk->sk_receive_queue, skb);
1475 else {
1476 kfree_skb(skb);
1477 (*qlen)--;
1478 }
1479 break;
1480 }
1481
1482 kfree_skb(skb);
1483 }
1484}
1485
1486/**
1487 * netlink_queue_skip - Skip netlink message while processing queue.
1488 * @nlh: Netlink message to be skipped
1489 * @skb: Socket buffer containing the netlink messages.
1490 *
1491 * Pulls the given netlink message off the socket buffer so the next
1492 * call to netlink_queue_run() will not reconsider the message.
1493 */
1494void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb)
1495{
1496 int msglen = NLMSG_ALIGN(nlh->nlmsg_len);
1497
1498 if (msglen > skb->len)
1499 msglen = skb->len;
1500
1501 skb_pull(skb, msglen);
1502}
1412 1503
1413#ifdef CONFIG_PROC_FS 1504#ifdef CONFIG_PROC_FS
1414struct nl_seq_iter { 1505struct nl_seq_iter {
@@ -1657,6 +1748,8 @@ out:
1657core_initcall(netlink_proto_init); 1748core_initcall(netlink_proto_init);
1658 1749
1659EXPORT_SYMBOL(netlink_ack); 1750EXPORT_SYMBOL(netlink_ack);
1751EXPORT_SYMBOL(netlink_run_queue);
1752EXPORT_SYMBOL(netlink_queue_skip);
1660EXPORT_SYMBOL(netlink_broadcast); 1753EXPORT_SYMBOL(netlink_broadcast);
1661EXPORT_SYMBOL(netlink_dump_start); 1754EXPORT_SYMBOL(netlink_dump_start);
1662EXPORT_SYMBOL(netlink_kernel_create); 1755EXPORT_SYMBOL(netlink_kernel_create);
diff --git a/net/netlink/attr.c b/net/netlink/attr.c
new file mode 100644
index 000000000000..fffef4ab276f
--- /dev/null
+++ b/net/netlink/attr.c
@@ -0,0 +1,328 @@
1/*
2 * NETLINK Netlink attributes
3 *
4 * Authors: Thomas Graf <tgraf@suug.ch>
5 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
6 */
7
8#include <linux/config.h>
9#include <linux/module.h>
10#include <linux/kernel.h>
11#include <linux/errno.h>
12#include <linux/jiffies.h>
13#include <linux/netdevice.h>
14#include <linux/skbuff.h>
15#include <linux/string.h>
16#include <linux/types.h>
17#include <net/netlink.h>
18
19static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
20 [NLA_U8] = sizeof(u8),
21 [NLA_U16] = sizeof(u16),
22 [NLA_U32] = sizeof(u32),
23 [NLA_U64] = sizeof(u64),
24 [NLA_STRING] = 1,
25 [NLA_NESTED] = NLA_HDRLEN,
26};
27
28static int validate_nla(struct nlattr *nla, int maxtype,
29 struct nla_policy *policy)
30{
31 struct nla_policy *pt;
32 int minlen = 0;
33
34 if (nla->nla_type <= 0 || nla->nla_type > maxtype)
35 return 0;
36
37 pt = &policy[nla->nla_type];
38
39 BUG_ON(pt->type > NLA_TYPE_MAX);
40
41 if (pt->minlen)
42 minlen = pt->minlen;
43 else if (pt->type != NLA_UNSPEC)
44 minlen = nla_attr_minlen[pt->type];
45
46 if (pt->type == NLA_FLAG && nla_len(nla) > 0)
47 return -ERANGE;
48
49 if (nla_len(nla) < minlen)
50 return -ERANGE;
51
52 return 0;
53}
54
55/**
56 * nla_validate - Validate a stream of attributes
57 * @head: head of attribute stream
58 * @len: length of attribute stream
59 * @maxtype: maximum attribute type to be expected
60 * @policy: validation policy
61 *
62 * Validates all attributes in the specified attribute stream against the
63 * specified policy. Attributes with a type exceeding maxtype will be
64 * ignored. See documenation of struct nla_policy for more details.
65 *
66 * Returns 0 on success or a negative error code.
67 */
68int nla_validate(struct nlattr *head, int len, int maxtype,
69 struct nla_policy *policy)
70{
71 struct nlattr *nla;
72 int rem, err;
73
74 nla_for_each_attr(nla, head, len, rem) {
75 err = validate_nla(nla, maxtype, policy);
76 if (err < 0)
77 goto errout;
78 }
79
80 err = 0;
81errout:
82 return err;
83}
84
85/**
86 * nla_parse - Parse a stream of attributes into a tb buffer
87 * @tb: destination array with maxtype+1 elements
88 * @maxtype: maximum attribute type to be expected
89 * @head: head of attribute stream
90 * @len: length of attribute stream
91 *
92 * Parses a stream of attributes and stores a pointer to each attribute in
93 * the tb array accessable via the attribute type. Attributes with a type
94 * exceeding maxtype will be silently ignored for backwards compatibility
95 * reasons. policy may be set to NULL if no validation is required.
96 *
97 * Returns 0 on success or a negative error code.
98 */
99int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
100 struct nla_policy *policy)
101{
102 struct nlattr *nla;
103 int rem, err;
104
105 memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
106
107 nla_for_each_attr(nla, head, len, rem) {
108 u16 type = nla->nla_type;
109
110 if (type > 0 && type <= maxtype) {
111 if (policy) {
112 err = validate_nla(nla, maxtype, policy);
113 if (err < 0)
114 goto errout;
115 }
116
117 tb[type] = nla;
118 }
119 }
120
121 if (unlikely(rem > 0))
122 printk(KERN_WARNING "netlink: %d bytes leftover after parsing "
123 "attributes.\n", rem);
124
125 err = 0;
126errout:
127 return err;
128}
129
130/**
131 * nla_find - Find a specific attribute in a stream of attributes
132 * @head: head of attribute stream
133 * @len: length of attribute stream
134 * @attrtype: type of attribute to look for
135 *
136 * Returns the first attribute in the stream matching the specified type.
137 */
138struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
139{
140 struct nlattr *nla;
141 int rem;
142
143 nla_for_each_attr(nla, head, len, rem)
144 if (nla->nla_type == attrtype)
145 return nla;
146
147 return NULL;
148}
149
150/**
151 * nla_strlcpy - Copy string attribute payload into a sized buffer
152 * @dst: where to copy the string to
153 * @src: attribute to copy the string from
154 * @dstsize: size of destination buffer
155 *
156 * Copies at most dstsize - 1 bytes into the destination buffer.
157 * The result is always a valid NUL-terminated string. Unlike
158 * strlcpy the destination buffer is always padded out.
159 *
160 * Returns the length of the source buffer.
161 */
162size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
163{
164 size_t srclen = nla_len(nla);
165 char *src = nla_data(nla);
166
167 if (srclen > 0 && src[srclen - 1] == '\0')
168 srclen--;
169
170 if (dstsize > 0) {
171 size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
172
173 memset(dst, 0, dstsize);
174 memcpy(dst, src, len);
175 }
176
177 return srclen;
178}
179
180/**
181 * nla_memcpy - Copy a netlink attribute into another memory area
182 * @dest: where to copy to memcpy
183 * @src: netlink attribute to copy from
184 * @count: size of the destination area
185 *
186 * Note: The number of bytes copied is limited by the length of
187 * attribute's payload. memcpy
188 *
189 * Returns the number of bytes copied.
190 */
191int nla_memcpy(void *dest, struct nlattr *src, int count)
192{
193 int minlen = min_t(int, count, nla_len(src));
194
195 memcpy(dest, nla_data(src), minlen);
196
197 return minlen;
198}
199
200/**
201 * nla_memcmp - Compare an attribute with sized memory area
202 * @nla: netlink attribute
203 * @data: memory area
204 * @size: size of memory area
205 */
206int nla_memcmp(const struct nlattr *nla, const void *data,
207 size_t size)
208{
209 int d = nla_len(nla) - size;
210
211 if (d == 0)
212 d = memcmp(nla_data(nla), data, size);
213
214 return d;
215}
216
217/**
218 * nla_strcmp - Compare a string attribute against a string
219 * @nla: netlink string attribute
220 * @str: another string
221 */
222int nla_strcmp(const struct nlattr *nla, const char *str)
223{
224 int len = strlen(str) + 1;
225 int d = nla_len(nla) - len;
226
227 if (d == 0)
228 d = memcmp(nla_data(nla), str, len);
229
230 return d;
231}
232
233/**
234 * __nla_reserve - reserve room for attribute on the skb
235 * @skb: socket buffer to reserve room on
236 * @attrtype: attribute type
237 * @attrlen: length of attribute payload
238 *
239 * Adds a netlink attribute header to a socket buffer and reserves
240 * room for the payload but does not copy it.
241 *
242 * The caller is responsible to ensure that the skb provides enough
243 * tailroom for the attribute header and payload.
244 */
245struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
246{
247 struct nlattr *nla;
248
249 nla = (struct nlattr *) skb_put(skb, nla_total_size(attrlen));
250 nla->nla_type = attrtype;
251 nla->nla_len = nla_attr_size(attrlen);
252
253 memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
254
255 return nla;
256}
257
258/**
259 * nla_reserve - reserve room for attribute on the skb
260 * @skb: socket buffer to reserve room on
261 * @attrtype: attribute type
262 * @attrlen: length of attribute payload
263 *
264 * Adds a netlink attribute header to a socket buffer and reserves
265 * room for the payload but does not copy it.
266 *
267 * Returns NULL if the tailroom of the skb is insufficient to store
268 * the attribute header and payload.
269 */
270struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
271{
272 if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
273 return NULL;
274
275 return __nla_reserve(skb, attrtype, attrlen);
276}
277
278/**
279 * __nla_put - Add a netlink attribute to a socket buffer
280 * @skb: socket buffer to add attribute to
281 * @attrtype: attribute type
282 * @attrlen: length of attribute payload
283 * @data: head of attribute payload
284 *
285 * The caller is responsible to ensure that the skb provides enough
286 * tailroom for the attribute header and payload.
287 */
288void __nla_put(struct sk_buff *skb, int attrtype, int attrlen,
289 const void *data)
290{
291 struct nlattr *nla;
292
293 nla = __nla_reserve(skb, attrtype, attrlen);
294 memcpy(nla_data(nla), data, attrlen);
295}
296
297
298/**
299 * nla_put - Add a netlink attribute to a socket buffer
300 * @skb: socket buffer to add attribute to
301 * @attrtype: attribute type
302 * @attrlen: length of attribute payload
303 * @data: head of attribute payload
304 *
305 * Returns -1 if the tailroom of the skb is insufficient to store
306 * the attribute header and payload.
307 */
308int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
309{
310 if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
311 return -1;
312
313 __nla_put(skb, attrtype, attrlen, data);
314 return 0;
315}
316
317
318EXPORT_SYMBOL(nla_validate);
319EXPORT_SYMBOL(nla_parse);
320EXPORT_SYMBOL(nla_find);
321EXPORT_SYMBOL(nla_strlcpy);
322EXPORT_SYMBOL(__nla_reserve);
323EXPORT_SYMBOL(nla_reserve);
324EXPORT_SYMBOL(__nla_put);
325EXPORT_SYMBOL(nla_put);
326EXPORT_SYMBOL(nla_memcpy);
327EXPORT_SYMBOL(nla_memcmp);
328EXPORT_SYMBOL(nla_strcmp);
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
new file mode 100644
index 000000000000..287cfcc56951
--- /dev/null
+++ b/net/netlink/genetlink.c
@@ -0,0 +1,579 @@
1/*
2 * NETLINK Generic Netlink Family
3 *
4 * Authors: Jamal Hadi Salim
5 * Thomas Graf <tgraf@suug.ch>
6 */
7
8#include <linux/config.h>
9#include <linux/module.h>
10#include <linux/kernel.h>
11#include <linux/errno.h>
12#include <linux/types.h>
13#include <linux/socket.h>
14#include <linux/string.h>
15#include <linux/skbuff.h>
16#include <net/sock.h>
17#include <net/genetlink.h>
18
19struct sock *genl_sock = NULL;
20
21static DECLARE_MUTEX(genl_sem); /* serialization of message processing */
22
23static void genl_lock(void)
24{
25 down(&genl_sem);
26}
27
28static int genl_trylock(void)
29{
30 return down_trylock(&genl_sem);
31}
32
33static void genl_unlock(void)
34{
35 up(&genl_sem);
36
37 if (genl_sock && genl_sock->sk_receive_queue.qlen)
38 genl_sock->sk_data_ready(genl_sock, 0);
39}
40
41#define GENL_FAM_TAB_SIZE 16
42#define GENL_FAM_TAB_MASK (GENL_FAM_TAB_SIZE - 1)
43
44static struct list_head family_ht[GENL_FAM_TAB_SIZE];
45
46static int genl_ctrl_event(int event, void *data);
47
48static inline unsigned int genl_family_hash(unsigned int id)
49{
50 return id & GENL_FAM_TAB_MASK;
51}
52
53static inline struct list_head *genl_family_chain(unsigned int id)
54{
55 return &family_ht[genl_family_hash(id)];
56}
57
58static struct genl_family *genl_family_find_byid(unsigned int id)
59{
60 struct genl_family *f;
61
62 list_for_each_entry(f, genl_family_chain(id), family_list)
63 if (f->id == id)
64 return f;
65
66 return NULL;
67}
68
69static struct genl_family *genl_family_find_byname(char *name)
70{
71 struct genl_family *f;
72 int i;
73
74 for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
75 list_for_each_entry(f, genl_family_chain(i), family_list)
76 if (strcmp(f->name, name) == 0)
77 return f;
78
79 return NULL;
80}
81
82static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
83{
84 struct genl_ops *ops;
85
86 list_for_each_entry(ops, &family->ops_list, ops_list)
87 if (ops->cmd == cmd)
88 return ops;
89
90 return NULL;
91}
92
93/* Of course we are going to have problems once we hit
94 * 2^16 alive types, but that can only happen by year 2K
95*/
96static inline u16 genl_generate_id(void)
97{
98 static u16 id_gen_idx;
99 int overflowed = 0;
100
101 do {
102 if (id_gen_idx == 0)
103 id_gen_idx = GENL_MIN_ID;
104
105 if (++id_gen_idx > GENL_MAX_ID) {
106 if (!overflowed) {
107 overflowed = 1;
108 id_gen_idx = 0;
109 continue;
110 } else
111 return 0;
112 }
113
114 } while (genl_family_find_byid(id_gen_idx));
115
116 return id_gen_idx;
117}
118
119/**
120 * genl_register_ops - register generic netlink operations
121 * @family: generic netlink family
122 * @ops: operations to be registered
123 *
124 * Registers the specified operations and assigns them to the specified
125 * family. Either a doit or dumpit callback must be specified or the
126 * operation will fail. Only one operation structure per command
127 * identifier may be registered.
128 *
129 * See include/net/genetlink.h for more documenation on the operations
130 * structure.
131 *
132 * Returns 0 on success or a negative error code.
133 */
134int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
135{
136 int err = -EINVAL;
137
138 if (ops->dumpit == NULL && ops->doit == NULL)
139 goto errout;
140
141 if (genl_get_cmd(ops->cmd, family)) {
142 err = -EEXIST;
143 goto errout;
144 }
145
146 genl_lock();
147 list_add_tail(&ops->ops_list, &family->ops_list);
148 genl_unlock();
149
150 genl_ctrl_event(CTRL_CMD_NEWOPS, ops);
151 err = 0;
152errout:
153 return err;
154}
155
156/**
157 * genl_unregister_ops - unregister generic netlink operations
158 * @family: generic netlink family
159 * @ops: operations to be unregistered
160 *
161 * Unregisters the specified operations and unassigns them from the
162 * specified family. The operation blocks until the current message
163 * processing has finished and doesn't start again until the
164 * unregister process has finished.
165 *
166 * Note: It is not necessary to unregister all operations before
167 * unregistering the family, unregistering the family will cause
168 * all assigned operations to be unregistered automatically.
169 *
170 * Returns 0 on success or a negative error code.
171 */
172int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops)
173{
174 struct genl_ops *rc;
175
176 genl_lock();
177 list_for_each_entry(rc, &family->ops_list, ops_list) {
178 if (rc == ops) {
179 list_del(&ops->ops_list);
180 genl_unlock();
181 genl_ctrl_event(CTRL_CMD_DELOPS, ops);
182 return 0;
183 }
184 }
185 genl_unlock();
186
187 return -ENOENT;
188}
189
190/**
191 * genl_register_family - register a generic netlink family
192 * @family: generic netlink family
193 *
194 * Registers the specified family after validating it first. Only one
195 * family may be registered with the same family name or identifier.
196 * The family id may equal GENL_ID_GENERATE causing an unique id to
197 * be automatically generated and assigned.
198 *
199 * Return 0 on success or a negative error code.
200 */
201int genl_register_family(struct genl_family *family)
202{
203 int err = -EINVAL;
204
205 if (family->id && family->id < GENL_MIN_ID)
206 goto errout;
207
208 if (family->id > GENL_MAX_ID)
209 goto errout;
210
211 INIT_LIST_HEAD(&family->ops_list);
212
213 genl_lock();
214
215 if (genl_family_find_byname(family->name)) {
216 err = -EEXIST;
217 goto errout_locked;
218 }
219
220 if (genl_family_find_byid(family->id)) {
221 err = -EEXIST;
222 goto errout_locked;
223 }
224
225 if (!try_module_get(family->owner)) {
226 err = -EBUSY;
227 goto errout_locked;
228 }
229
230 if (family->id == GENL_ID_GENERATE) {
231 u16 newid = genl_generate_id();
232
233 if (!newid) {
234 err = -ENOMEM;
235 goto errout_locked;
236 }
237
238 family->id = newid;
239 }
240
241 if (family->maxattr) {
242 family->attrbuf = kmalloc((family->maxattr+1) *
243 sizeof(struct nlattr *), GFP_KERNEL);
244 if (family->attrbuf == NULL) {
245 err = -ENOMEM;
246 goto errout;
247 }
248 } else
249 family->attrbuf = NULL;
250
251 list_add_tail(&family->family_list, genl_family_chain(family->id));
252 genl_unlock();
253
254 genl_ctrl_event(CTRL_CMD_NEWFAMILY, family);
255
256 return 0;
257
258errout_locked:
259 genl_unlock();
260errout:
261 return err;
262}
263
264/**
265 * genl_unregister_family - unregister generic netlink family
266 * @family: generic netlink family
267 *
268 * Unregisters the specified family.
269 *
270 * Returns 0 on success or a negative error code.
271 */
272int genl_unregister_family(struct genl_family *family)
273{
274 struct genl_family *rc;
275
276 genl_lock();
277
278 list_for_each_entry(rc, genl_family_chain(family->id), family_list) {
279 if (family->id != rc->id || strcmp(rc->name, family->name))
280 continue;
281
282 list_del(&rc->family_list);
283 INIT_LIST_HEAD(&family->ops_list);
284 genl_unlock();
285
286 module_put(family->owner);
287 kfree(family->attrbuf);
288 genl_ctrl_event(CTRL_CMD_DELFAMILY, family);
289 return 0;
290 }
291
292 genl_unlock();
293
294 return -ENOENT;
295}
296
297static inline int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
298 int *errp)
299{
300 struct genl_ops *ops;
301 struct genl_family *family;
302 struct genl_info info;
303 struct genlmsghdr *hdr = nlmsg_data(nlh);
304 int hdrlen, err = -EINVAL;
305
306 if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
307 goto ignore;
308
309 if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
310 goto ignore;
311
312 family = genl_family_find_byid(nlh->nlmsg_type);
313 if (family == NULL) {
314 err = -ENOENT;
315 goto errout;
316 }
317
318 hdrlen = GENL_HDRLEN + family->hdrsize;
319 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
320 goto errout;
321
322 ops = genl_get_cmd(hdr->cmd, family);
323 if (ops == NULL) {
324 err = -EOPNOTSUPP;
325 goto errout;
326 }
327
328 if ((ops->flags & GENL_ADMIN_PERM) && security_netlink_recv(skb)) {
329 err = -EPERM;
330 goto errout;
331 }
332
333 if (nlh->nlmsg_flags & NLM_F_DUMP) {
334 if (ops->dumpit == NULL) {
335 err = -EOPNOTSUPP;
336 goto errout;
337 }
338
339 *errp = err = netlink_dump_start(genl_sock, skb, nlh,
340 ops->dumpit, NULL);
341 if (err == 0)
342 skb_pull(skb, min(NLMSG_ALIGN(nlh->nlmsg_len),
343 skb->len));
344 return -1;
345 }
346
347 if (ops->doit == NULL) {
348 err = -EOPNOTSUPP;
349 goto errout;
350 }
351
352 if (family->attrbuf) {
353 err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr,
354 ops->policy);
355 if (err < 0)
356 goto errout;
357 }
358
359 info.snd_seq = nlh->nlmsg_seq;
360 info.snd_pid = NETLINK_CB(skb).pid;
361 info.nlhdr = nlh;
362 info.genlhdr = nlmsg_data(nlh);
363 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
364 info.attrs = family->attrbuf;
365
366 *errp = err = ops->doit(skb, &info);
367 return err;
368
369ignore:
370 return 0;
371
372errout:
373 *errp = err;
374 return -1;
375}
376
377static void genl_rcv(struct sock *sk, int len)
378{
379 unsigned int qlen = 0;
380
381 do {
382 if (genl_trylock())
383 return;
384 netlink_run_queue(sk, &qlen, &genl_rcv_msg);
385 genl_unlock();
386 } while (qlen && genl_sock && genl_sock->sk_receive_queue.qlen);
387}
388
389/**************************************************************************
390 * Controller
391 **************************************************************************/
392
393static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
394 u32 flags, struct sk_buff *skb, u8 cmd)
395{
396 void *hdr;
397
398 hdr = genlmsg_put(skb, pid, seq, GENL_ID_CTRL, 0, flags, cmd,
399 family->version);
400 if (hdr == NULL)
401 return -1;
402
403 NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, family->name);
404 NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, family->id);
405
406 return genlmsg_end(skb, hdr);
407
408nla_put_failure:
409 return genlmsg_cancel(skb, hdr);
410}
411
412static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
413{
414
415 int i, n = 0;
416 struct genl_family *rt;
417 int chains_to_skip = cb->args[0];
418 int fams_to_skip = cb->args[1];
419
420 for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
421 if (i < chains_to_skip)
422 continue;
423 n = 0;
424 list_for_each_entry(rt, genl_family_chain(i), family_list) {
425 if (++n < fams_to_skip)
426 continue;
427 if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).pid,
428 cb->nlh->nlmsg_seq, NLM_F_MULTI,
429 skb, CTRL_CMD_NEWFAMILY) < 0)
430 goto errout;
431 }
432
433 fams_to_skip = 0;
434 }
435
436errout:
437 cb->args[0] = i;
438 cb->args[1] = n;
439
440 return skb->len;
441}
442
443static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
444 int seq, int cmd)
445{
446 struct sk_buff *skb;
447 int err;
448
449 skb = nlmsg_new(NLMSG_GOODSIZE);
450 if (skb == NULL)
451 return ERR_PTR(-ENOBUFS);
452
453 err = ctrl_fill_info(family, pid, seq, 0, skb, cmd);
454 if (err < 0) {
455 nlmsg_free(skb);
456 return ERR_PTR(err);
457 }
458
459 return skb;
460}
461
462static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = {
463 [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 },
464 [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_STRING },
465};
466
467static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
468{
469 struct sk_buff *msg;
470 struct genl_family *res = NULL;
471 int err = -EINVAL;
472
473 if (info->attrs[CTRL_ATTR_FAMILY_ID]) {
474 u16 id = nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]);
475 res = genl_family_find_byid(id);
476 }
477
478 if (info->attrs[CTRL_ATTR_FAMILY_NAME]) {
479 char name[GENL_NAMSIZ];
480
481 if (nla_strlcpy(name, info->attrs[CTRL_ATTR_FAMILY_NAME],
482 GENL_NAMSIZ) >= GENL_NAMSIZ)
483 goto errout;
484
485 res = genl_family_find_byname(name);
486 }
487
488 if (res == NULL) {
489 err = -ENOENT;
490 goto errout;
491 }
492
493 msg = ctrl_build_msg(res, info->snd_pid, info->snd_seq,
494 CTRL_CMD_NEWFAMILY);
495 if (IS_ERR(msg)) {
496 err = PTR_ERR(msg);
497 goto errout;
498 }
499
500 err = genlmsg_unicast(msg, info->snd_pid);
501errout:
502 return err;
503}
504
505static int genl_ctrl_event(int event, void *data)
506{
507 struct sk_buff *msg;
508
509 if (genl_sock == NULL)
510 return 0;
511
512 switch (event) {
513 case CTRL_CMD_NEWFAMILY:
514 case CTRL_CMD_DELFAMILY:
515 msg = ctrl_build_msg(data, 0, 0, event);
516 if (IS_ERR(msg))
517 return PTR_ERR(msg);
518
519 genlmsg_multicast(msg, 0, GENL_ID_CTRL);
520 break;
521 }
522
523 return 0;
524}
525
526static struct genl_ops genl_ctrl_ops = {
527 .cmd = CTRL_CMD_GETFAMILY,
528 .doit = ctrl_getfamily,
529 .dumpit = ctrl_dumpfamily,
530 .policy = ctrl_policy,
531};
532
533static struct genl_family genl_ctrl = {
534 .id = GENL_ID_CTRL,
535 .name = "nlctrl",
536 .version = 0x1,
537 .maxattr = CTRL_ATTR_MAX,
538 .owner = THIS_MODULE,
539};
540
541static int __init genl_init(void)
542{
543 int i, err;
544
545 for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
546 INIT_LIST_HEAD(&family_ht[i]);
547
548 err = genl_register_family(&genl_ctrl);
549 if (err < 0)
550 goto errout;
551
552 err = genl_register_ops(&genl_ctrl, &genl_ctrl_ops);
553 if (err < 0)
554 goto errout_register;
555
556 netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
557 genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID,
558 genl_rcv, THIS_MODULE);
559 if (genl_sock == NULL) {
560 panic("GENL: Cannot initialize generic netlink\n");
561 return -ENOMEM;
562 }
563
564 return 0;
565
566errout_register:
567 genl_unregister_family(&genl_ctrl);
568errout:
569 panic("GENL: Cannot register controller: %d\n", err);
570 return err;
571}
572
573subsys_initcall(genl_init);
574
575EXPORT_SYMBOL(genl_sock);
576EXPORT_SYMBOL(genl_register_ops);
577EXPORT_SYMBOL(genl_unregister_ops);
578EXPORT_SYMBOL(genl_register_family);
579EXPORT_SYMBOL(genl_unregister_family);
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index b18fe5043019..8631b65a7312 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -240,8 +240,7 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
240 if ((s = rose_neigh_list) == rose_neigh) { 240 if ((s = rose_neigh_list) == rose_neigh) {
241 rose_neigh_list = rose_neigh->next; 241 rose_neigh_list = rose_neigh->next;
242 spin_unlock_bh(&rose_neigh_list_lock); 242 spin_unlock_bh(&rose_neigh_list_lock);
243 if (rose_neigh->digipeat != NULL) 243 kfree(rose_neigh->digipeat);
244 kfree(rose_neigh->digipeat);
245 kfree(rose_neigh); 244 kfree(rose_neigh);
246 return; 245 return;
247 } 246 }
@@ -250,8 +249,7 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
250 if (s->next == rose_neigh) { 249 if (s->next == rose_neigh) {
251 s->next = rose_neigh->next; 250 s->next = rose_neigh->next;
252 spin_unlock_bh(&rose_neigh_list_lock); 251 spin_unlock_bh(&rose_neigh_list_lock);
253 if (rose_neigh->digipeat != NULL) 252 kfree(rose_neigh->digipeat);
254 kfree(rose_neigh->digipeat);
255 kfree(rose_neigh); 253 kfree(rose_neigh);
256 return; 254 return;
257 } 255 }
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 29d8b9a4d162..75470486e405 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -298,8 +298,7 @@ static int fw_change(struct tcf_proto *tp, unsigned long base,
298 return 0; 298 return 0;
299 299
300errout: 300errout:
301 if (f) 301 kfree(f);
302 kfree(f);
303 return err; 302 return err;
304} 303}
305 304
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 02996ac05c75..520ff716dab2 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -525,8 +525,7 @@ reinsert:
525 return 0; 525 return 0;
526 526
527errout: 527errout:
528 if (f) 528 kfree(f);
529 kfree(f);
530 return err; 529 return err;
531} 530}
532 531
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 006168d69376..572f06be3b02 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -555,8 +555,7 @@ insert:
555 goto insert; 555 goto insert;
556 556
557errout: 557errout:
558 if (f) 558 kfree(f);
559 kfree(f);
560errout2: 559errout2:
561 tcf_exts_destroy(tp, &e); 560 tcf_exts_destroy(tp, &e);
562 return err; 561 return err;
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 404d9d83a7fa..9f921174c8ab 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -194,8 +194,7 @@ found:
194 } 194 }
195 tcf_unbind_filter(tp, &r->res); 195 tcf_unbind_filter(tp, &r->res);
196 tcf_exts_destroy(tp, &r->exts); 196 tcf_exts_destroy(tp, &r->exts);
197 if (f) 197 kfree(f);
198 kfree(f);
199 return 0; 198 return 0;
200} 199}
201 200
@@ -442,10 +441,8 @@ static void tcindex_destroy(struct tcf_proto *tp)
442 walker.skip = 0; 441 walker.skip = 0;
443 walker.fn = &tcindex_destroy_element; 442 walker.fn = &tcindex_destroy_element;
444 tcindex_walk(tp,&walker); 443 tcindex_walk(tp,&walker);
445 if (p->perfect) 444 kfree(p->perfect);
446 kfree(p->perfect); 445 kfree(p->h);
447 if (p->h)
448 kfree(p->h);
449 kfree(p); 446 kfree(p);
450 tp->root = NULL; 447 tp->root = NULL;
451} 448}
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 364b87d86455..2b670479dde1 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -347,7 +347,7 @@ static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n)
347 if (n->ht_down) 347 if (n->ht_down)
348 n->ht_down->refcnt--; 348 n->ht_down->refcnt--;
349#ifdef CONFIG_CLS_U32_PERF 349#ifdef CONFIG_CLS_U32_PERF
350 if (n && (NULL != n->pf)) 350 if (n)
351 kfree(n->pf); 351 kfree(n->pf);
352#endif 352#endif
353 kfree(n); 353 kfree(n);
@@ -680,7 +680,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
680 return 0; 680 return 0;
681 } 681 }
682#ifdef CONFIG_CLS_U32_PERF 682#ifdef CONFIG_CLS_U32_PERF
683 if (n && (NULL != n->pf)) 683 if (n)
684 kfree(n->pf); 684 kfree(n->pf);
685#endif 685#endif
686 kfree(n); 686 kfree(n);
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index cf68a59fdc5a..700844d49d79 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -561,8 +561,7 @@ static int meta_var_change(struct meta_value *dst, struct rtattr *rta)
561 561
562static void meta_var_destroy(struct meta_value *v) 562static void meta_var_destroy(struct meta_value *v)
563{ 563{
564 if (v->val) 564 kfree((void *) v->val);
565 kfree((void *) v->val);
566} 565}
567 566
568static void meta_var_apply_extras(struct meta_value *v, 567static void meta_var_apply_extras(struct meta_value *v,
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index ebfe2e7d21bd..64b047c65568 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -298,6 +298,11 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta,
298 struct tcf_ematch_tree_hdr *tree_hdr; 298 struct tcf_ematch_tree_hdr *tree_hdr;
299 struct tcf_ematch *em; 299 struct tcf_ematch *em;
300 300
301 if (!rta) {
302 memset(tree, 0, sizeof(*tree));
303 return 0;
304 }
305
301 if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0) 306 if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0)
302 goto errout; 307 goto errout;
303 308
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 12b0f582a66b..8c8ddf7f9b61 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -344,9 +344,7 @@ void sctp_association_free(struct sctp_association *asoc)
344 } 344 }
345 345
346 /* Free peer's cached cookie. */ 346 /* Free peer's cached cookie. */
347 if (asoc->peer.cookie) { 347 kfree(asoc->peer.cookie);
348 kfree(asoc->peer.cookie);
349 }
350 348
351 /* Release the transport structures. */ 349 /* Release the transport structures. */
352 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { 350 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 660c61bdf164..f9573eba5c7a 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -254,8 +254,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
254 aiparam.adaption_ind = htonl(sp->adaption_ind); 254 aiparam.adaption_ind = htonl(sp->adaption_ind);
255 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam); 255 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
256nodata: 256nodata:
257 if (addrs.v) 257 kfree(addrs.v);
258 kfree(addrs.v);
259 return retval; 258 return retval;
260} 259}
261 260
@@ -347,8 +346,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
347nomem_chunk: 346nomem_chunk:
348 kfree(cookie); 347 kfree(cookie);
349nomem_cookie: 348nomem_cookie:
350 if (addrs.v) 349 kfree(addrs.v);
351 kfree(addrs.v);
352 return retval; 350 return retval;
353} 351}
354 352
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
index 13f8ae979454..d0dfdfd5e79e 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
@@ -143,6 +143,6 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
143 143
144 return ((ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE); 144 return ((ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE);
145out_err: 145out_err:
146 if (md5cksum.data) kfree(md5cksum.data); 146 kfree(md5cksum.data);
147 return GSS_S_FAILURE; 147 return GSS_S_FAILURE;
148} 148}
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
index 2030475d98ed..db055fd7d778 100644
--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
@@ -176,6 +176,6 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
176 176
177 ret = GSS_S_COMPLETE; 177 ret = GSS_S_COMPLETE;
178out: 178out:
179 if (md5cksum.data) kfree(md5cksum.data); 179 kfree(md5cksum.data);
180 return ret; 180 return ret;
181} 181}
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index b048bf672da2..f8bac6ccd524 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -60,8 +60,7 @@ gss_mech_free(struct gss_api_mech *gm)
60 60
61 for (i = 0; i < gm->gm_pf_num; i++) { 61 for (i = 0; i < gm->gm_pf_num; i++) {
62 pf = &gm->gm_pfs[i]; 62 pf = &gm->gm_pfs[i];
63 if (pf->auth_domain_name) 63 kfree(pf->auth_domain_name);
64 kfree(pf->auth_domain_name);
65 pf->auth_domain_name = NULL; 64 pf->auth_domain_name = NULL;
66 } 65 }
67} 66}
diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c
index 148201e929d0..d1e12b25d6e2 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_seal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_seal.c
@@ -122,8 +122,7 @@ spkm3_make_token(struct spkm3_ctx *ctx,
122 122
123 return GSS_S_COMPLETE; 123 return GSS_S_COMPLETE;
124out_err: 124out_err:
125 if (md5cksum.data) 125 kfree(md5cksum.data);
126 kfree(md5cksum.data);
127 token->data = NULL; 126 token->data = NULL;
128 token->len = 0; 127 token->len = 0;
129 return GSS_S_FAILURE; 128 return GSS_S_FAILURE;
diff --git a/net/sunrpc/auth_gss/gss_spkm3_token.c b/net/sunrpc/auth_gss/gss_spkm3_token.c
index 46c08a0710f6..1f824578d773 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_token.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_token.c
@@ -259,8 +259,7 @@ spkm3_verify_mic_token(unsigned char **tokp, int *mic_hdrlen, unsigned char **ck
259 259
260 ret = GSS_S_COMPLETE; 260 ret = GSS_S_COMPLETE;
261out: 261out:
262 if (spkm3_ctx_id.data) 262 kfree(spkm3_ctx_id.data);
263 kfree(spkm3_ctx_id.data);
264 return ret; 263 return ret;
265} 264}
266 265
diff --git a/net/sunrpc/auth_gss/gss_spkm3_unseal.c b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
index c3c0d9586103..241d5b30dfcb 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_unseal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
@@ -120,9 +120,7 @@ spkm3_read_token(struct spkm3_ctx *ctx,
120 /* XXX: need to add expiration and sequencing */ 120 /* XXX: need to add expiration and sequencing */
121 ret = GSS_S_COMPLETE; 121 ret = GSS_S_COMPLETE;
122out: 122out:
123 if (md5cksum.data) 123 kfree(md5cksum.data);
124 kfree(md5cksum.data); 124 kfree(wire_cksum.data);
125 if (wire_cksum.data)
126 kfree(wire_cksum.data);
127 return ret; 125 return ret;
128} 126}
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 702ede309b06..61c3abeaccae 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -55,6 +55,7 @@ static void call_bind(struct rpc_task *task);
55static void call_bind_status(struct rpc_task *task); 55static void call_bind_status(struct rpc_task *task);
56static void call_transmit(struct rpc_task *task); 56static void call_transmit(struct rpc_task *task);
57static void call_status(struct rpc_task *task); 57static void call_status(struct rpc_task *task);
58static void call_transmit_status(struct rpc_task *task);
58static void call_refresh(struct rpc_task *task); 59static void call_refresh(struct rpc_task *task);
59static void call_refreshresult(struct rpc_task *task); 60static void call_refreshresult(struct rpc_task *task);
60static void call_timeout(struct rpc_task *task); 61static void call_timeout(struct rpc_task *task);
@@ -672,6 +673,18 @@ call_allocate(struct rpc_task *task)
672 rpc_exit(task, -ERESTARTSYS); 673 rpc_exit(task, -ERESTARTSYS);
673} 674}
674 675
676static inline int
677rpc_task_need_encode(struct rpc_task *task)
678{
679 return task->tk_rqstp->rq_snd_buf.len == 0;
680}
681
682static inline void
683rpc_task_force_reencode(struct rpc_task *task)
684{
685 task->tk_rqstp->rq_snd_buf.len = 0;
686}
687
675/* 688/*
676 * 3. Encode arguments of an RPC call 689 * 3. Encode arguments of an RPC call
677 */ 690 */
@@ -867,12 +880,14 @@ call_transmit(struct rpc_task *task)
867 if (task->tk_status != 0) 880 if (task->tk_status != 0)
868 return; 881 return;
869 /* Encode here so that rpcsec_gss can use correct sequence number. */ 882 /* Encode here so that rpcsec_gss can use correct sequence number. */
870 if (task->tk_rqstp->rq_bytes_sent == 0) { 883 if (rpc_task_need_encode(task)) {
884 task->tk_rqstp->rq_bytes_sent = 0;
871 call_encode(task); 885 call_encode(task);
872 /* Did the encode result in an error condition? */ 886 /* Did the encode result in an error condition? */
873 if (task->tk_status != 0) 887 if (task->tk_status != 0)
874 goto out_nosend; 888 goto out_nosend;
875 } 889 }
890 task->tk_action = call_transmit_status;
876 xprt_transmit(task); 891 xprt_transmit(task);
877 if (task->tk_status < 0) 892 if (task->tk_status < 0)
878 return; 893 return;
@@ -884,6 +899,7 @@ call_transmit(struct rpc_task *task)
884out_nosend: 899out_nosend:
885 /* release socket write lock before attempting to handle error */ 900 /* release socket write lock before attempting to handle error */
886 xprt_abort_transmit(task); 901 xprt_abort_transmit(task);
902 rpc_task_force_reencode(task);
887} 903}
888 904
889/* 905/*
@@ -915,7 +931,6 @@ call_status(struct rpc_task *task)
915 break; 931 break;
916 case -ECONNREFUSED: 932 case -ECONNREFUSED:
917 case -ENOTCONN: 933 case -ENOTCONN:
918 req->rq_bytes_sent = 0;
919 if (clnt->cl_autobind) 934 if (clnt->cl_autobind)
920 clnt->cl_port = 0; 935 clnt->cl_port = 0;
921 task->tk_action = call_bind; 936 task->tk_action = call_bind;
@@ -937,7 +952,18 @@ call_status(struct rpc_task *task)
937} 952}
938 953
939/* 954/*
940 * 6a. Handle RPC timeout 955 * 6a. Handle transmission errors.
956 */
957static void
958call_transmit_status(struct rpc_task *task)
959{
960 if (task->tk_status != -EAGAIN)
961 rpc_task_force_reencode(task);
962 call_status(task);
963}
964
965/*
966 * 6b. Handle RPC timeout
941 * We do not release the request slot, so we keep using the 967 * We do not release the request slot, so we keep using the
942 * same XID for all retransmits. 968 * same XID for all retransmits.
943 */ 969 */
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 4f188d0a5d11..81e00a6c19de 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -603,7 +603,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
603 return ERR_PTR(error); 603 return ERR_PTR(error);
604 dir = nd->dentry->d_inode; 604 dir = nd->dentry->d_inode;
605 down(&dir->i_sem); 605 down(&dir->i_sem);
606 dentry = lookup_hash(&nd->last, nd->dentry); 606 dentry = lookup_hash(nd);
607 if (IS_ERR(dentry)) 607 if (IS_ERR(dentry))
608 goto out_err; 608 goto out_err;
609 if (dentry->d_inode) { 609 if (dentry->d_inode) {
@@ -665,7 +665,7 @@ rpc_rmdir(char *path)
665 return error; 665 return error;
666 dir = nd.dentry->d_inode; 666 dir = nd.dentry->d_inode;
667 down(&dir->i_sem); 667 down(&dir->i_sem);
668 dentry = lookup_hash(&nd.last, nd.dentry); 668 dentry = lookup_hash(&nd);
669 if (IS_ERR(dentry)) { 669 if (IS_ERR(dentry)) {
670 error = PTR_ERR(dentry); 670 error = PTR_ERR(dentry);
671 goto out_release; 671 goto out_release;
@@ -726,7 +726,7 @@ rpc_unlink(char *path)
726 return error; 726 return error;
727 dir = nd.dentry->d_inode; 727 dir = nd.dentry->d_inode;
728 down(&dir->i_sem); 728 down(&dir->i_sem);
729 dentry = lookup_hash(&nd.last, nd.dentry); 729 dentry = lookup_hash(&nd);
730 if (IS_ERR(dentry)) { 730 if (IS_ERR(dentry)) {
731 error = PTR_ERR(dentry); 731 error = PTR_ERR(dentry);
732 goto out_release; 732 goto out_release;
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 5a220b2bb376..e4296c8b861e 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -196,12 +196,9 @@ svc_exit_thread(struct svc_rqst *rqstp)
196 struct svc_serv *serv = rqstp->rq_server; 196 struct svc_serv *serv = rqstp->rq_server;
197 197
198 svc_release_buffer(rqstp); 198 svc_release_buffer(rqstp);
199 if (rqstp->rq_resp) 199 kfree(rqstp->rq_resp);
200 kfree(rqstp->rq_resp); 200 kfree(rqstp->rq_argp);
201 if (rqstp->rq_argp) 201 kfree(rqstp->rq_auth_data);
202 kfree(rqstp->rq_argp);
203 if (rqstp->rq_auth_data)
204 kfree(rqstp->rq_auth_data);
205 kfree(rqstp); 202 kfree(rqstp);
206 203
207 /* Release the server */ 204 /* Release the server */
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 32df43372ee9..aaf08cdd19f0 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -992,8 +992,7 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base,
992 err = 0; 992 err = 0;
993 993
994out: 994out:
995 if (elem) 995 kfree(elem);
996 kfree(elem);
997 if (ppages) 996 if (ppages)
998 kunmap(*ppages); 997 kunmap(*ppages);
999 return err; 998 return err;
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 41feca3bef86..acc73ba8bade 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -676,7 +676,7 @@ static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
676 err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd); 676 err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
677 if (err) 677 if (err)
678 goto fail; 678 goto fail;
679 err = permission(nd.dentry->d_inode,MAY_WRITE, &nd); 679 err = vfs_permission(&nd, MAY_WRITE);
680 if (err) 680 if (err)
681 goto put_fail; 681 goto put_fail;
682 682
diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
index 596cb96e5f47..59fec59b2132 100644
--- a/net/wanrouter/af_wanpipe.c
+++ b/net/wanrouter/af_wanpipe.c
@@ -1099,7 +1099,7 @@ static void release_driver(struct sock *sk)
1099 sock_reset_flag(sk, SOCK_ZAPPED); 1099 sock_reset_flag(sk, SOCK_ZAPPED);
1100 wp = wp_sk(sk); 1100 wp = wp_sk(sk);
1101 1101
1102 if (wp && wp->mbox) { 1102 if (wp) {
1103 kfree(wp->mbox); 1103 kfree(wp->mbox);
1104 wp->mbox = NULL; 1104 wp->mbox = NULL;
1105 } 1105 }
@@ -1186,10 +1186,8 @@ static void wanpipe_kill_sock_timer (unsigned long data)
1186 return; 1186 return;
1187 } 1187 }
1188 1188
1189 if (wp_sk(sk)) { 1189 kfree(wp_sk(sk));
1190 kfree(wp_sk(sk)); 1190 wp_sk(sk) = NULL;
1191 wp_sk(sk) = NULL;
1192 }
1193 1191
1194 if (atomic_read(&sk->sk_refcnt) != 1) { 1192 if (atomic_read(&sk->sk_refcnt) != 1) {
1195 atomic_set(&sk->sk_refcnt, 1); 1193 atomic_set(&sk->sk_refcnt, 1);
@@ -1219,10 +1217,8 @@ static void wanpipe_kill_sock_accept (struct sock *sk)
1219 sk->sk_socket = NULL; 1217 sk->sk_socket = NULL;
1220 1218
1221 1219
1222 if (wp_sk(sk)) { 1220 kfree(wp_sk(sk));
1223 kfree(wp_sk(sk)); 1221 wp_sk(sk) = NULL;
1224 wp_sk(sk) = NULL;
1225 }
1226 1222
1227 if (atomic_read(&sk->sk_refcnt) != 1) { 1223 if (atomic_read(&sk->sk_refcnt) != 1) {
1228 atomic_set(&sk->sk_refcnt, 1); 1224 atomic_set(&sk->sk_refcnt, 1);
@@ -1243,10 +1239,8 @@ static void wanpipe_kill_sock_irq (struct sock *sk)
1243 1239
1244 sk->sk_socket = NULL; 1240 sk->sk_socket = NULL;
1245 1241
1246 if (wp_sk(sk)) { 1242 kfree(wp_sk(sk));
1247 kfree(wp_sk(sk)); 1243 wp_sk(sk) = NULL;
1248 wp_sk(sk) = NULL;
1249 }
1250 1244
1251 if (atomic_read(&sk->sk_refcnt) != 1) { 1245 if (atomic_read(&sk->sk_refcnt) != 1) {
1252 atomic_set(&sk->sk_refcnt, 1); 1246 atomic_set(&sk->sk_refcnt, 1);
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
index 13b650ad22e2..bcf7b3faa76a 100644
--- a/net/wanrouter/wanmain.c
+++ b/net/wanrouter/wanmain.c
@@ -714,10 +714,8 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
714 } 714 }
715 715
716 /* This code has moved from del_if() function */ 716 /* This code has moved from del_if() function */
717 if (dev->priv) { 717 kfree(dev->priv);
718 kfree(dev->priv); 718 dev->priv = NULL;
719 dev->priv = NULL;
720 }
721 719
722#ifdef CONFIG_WANPIPE_MULTPPP 720#ifdef CONFIG_WANPIPE_MULTPPP
723 if (cnf->config_id == WANCONFIG_MPPP) 721 if (cnf->config_id == WANCONFIG_MPPP)
@@ -851,10 +849,8 @@ static int wanrouter_delete_interface(struct wan_device *wandev, char *name)
851 849
852 /* Due to new interface linking method using dev->priv, 850 /* Due to new interface linking method using dev->priv,
853 * this code has moved from del_if() function.*/ 851 * this code has moved from del_if() function.*/
854 if (dev->priv){ 852 kfree(dev->priv);
855 kfree(dev->priv); 853 dev->priv=NULL;
856 dev->priv=NULL;
857 }
858 854
859 unregister_netdev(dev); 855 unregister_netdev(dev);
860 856
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 8b9a4747417d..7cf48aa6c95b 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -62,14 +62,10 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
62{ 62{
63 if (del_timer(&x->timer)) 63 if (del_timer(&x->timer))
64 BUG(); 64 BUG();
65 if (x->aalg) 65 kfree(x->aalg);
66 kfree(x->aalg); 66 kfree(x->ealg);
67 if (x->ealg) 67 kfree(x->calg);
68 kfree(x->ealg); 68 kfree(x->encap);
69 if (x->calg)
70 kfree(x->calg);
71 if (x->encap)
72 kfree(x->encap);
73 if (x->type) { 69 if (x->type) {
74 x->type->destructor(x); 70 x->type->destructor(x);
75 xfrm_put_type(x->type); 71 xfrm_put_type(x->type);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index c35336a0f71b..0cdd9a07e043 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -18,7 +18,6 @@
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/net.h> 19#include <linux/net.h>
20#include <linux/skbuff.h> 20#include <linux/skbuff.h>
21#include <linux/netlink.h>
22#include <linux/rtnetlink.h> 21#include <linux/rtnetlink.h>
23#include <linux/pfkeyv2.h> 22#include <linux/pfkeyv2.h>
24#include <linux/ipsec.h> 23#include <linux/ipsec.h>
@@ -26,6 +25,7 @@
26#include <linux/security.h> 25#include <linux/security.h>
27#include <net/sock.h> 26#include <net/sock.h>
28#include <net/xfrm.h> 27#include <net/xfrm.h>
28#include <net/netlink.h>
29#include <asm/uaccess.h> 29#include <asm/uaccess.h>
30 30
31static struct sock *xfrm_nl; 31static struct sock *xfrm_nl;
@@ -948,11 +948,6 @@ static struct xfrm_link {
948 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, 948 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy },
949}; 949};
950 950
951static int xfrm_done(struct netlink_callback *cb)
952{
953 return 0;
954}
955
956static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) 951static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
957{ 952{
958 struct rtattr *xfrma[XFRMA_MAX]; 953 struct rtattr *xfrma[XFRMA_MAX];
@@ -984,20 +979,15 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err
984 if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || 979 if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
985 type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && 980 type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) &&
986 (nlh->nlmsg_flags & NLM_F_DUMP)) { 981 (nlh->nlmsg_flags & NLM_F_DUMP)) {
987 u32 rlen;
988
989 if (link->dump == NULL) 982 if (link->dump == NULL)
990 goto err_einval; 983 goto err_einval;
991 984
992 if ((*errp = netlink_dump_start(xfrm_nl, skb, nlh, 985 if ((*errp = netlink_dump_start(xfrm_nl, skb, nlh,
993 link->dump, 986 link->dump, NULL)) != 0) {
994 xfrm_done)) != 0) {
995 return -1; 987 return -1;
996 } 988 }
997 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 989
998 if (rlen > skb->len) 990 netlink_queue_skip(nlh, skb);
999 rlen = skb->len;
1000 skb_pull(skb, rlen);
1001 return -1; 991 return -1;
1002 } 992 }
1003 993
@@ -1032,60 +1022,13 @@ err_einval:
1032 return -1; 1022 return -1;
1033} 1023}
1034 1024
1035static int xfrm_user_rcv_skb(struct sk_buff *skb)
1036{
1037 int err;
1038 struct nlmsghdr *nlh;
1039
1040 while (skb->len >= NLMSG_SPACE(0)) {
1041 u32 rlen;
1042
1043 nlh = (struct nlmsghdr *) skb->data;
1044 if (nlh->nlmsg_len < sizeof(*nlh) ||
1045 skb->len < nlh->nlmsg_len)
1046 return 0;
1047 rlen = NLMSG_ALIGN(nlh->nlmsg_len);
1048 if (rlen > skb->len)
1049 rlen = skb->len;
1050 if (xfrm_user_rcv_msg(skb, nlh, &err) < 0) {
1051 if (err == 0)
1052 return -1;
1053 netlink_ack(skb, nlh, err);
1054 } else if (nlh->nlmsg_flags & NLM_F_ACK)
1055 netlink_ack(skb, nlh, 0);
1056 skb_pull(skb, rlen);
1057 }
1058
1059 return 0;
1060}
1061
1062static void xfrm_netlink_rcv(struct sock *sk, int len) 1025static void xfrm_netlink_rcv(struct sock *sk, int len)
1063{ 1026{
1064 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); 1027 unsigned int qlen = 0;
1065 1028
1066 do { 1029 do {
1067 struct sk_buff *skb;
1068
1069 down(&xfrm_cfg_sem); 1030 down(&xfrm_cfg_sem);
1070 1031 netlink_run_queue(sk, &qlen, &xfrm_user_rcv_msg);
1071 if (qlen > skb_queue_len(&sk->sk_receive_queue))
1072 qlen = skb_queue_len(&sk->sk_receive_queue);
1073
1074 for (; qlen; qlen--) {
1075 skb = skb_dequeue(&sk->sk_receive_queue);
1076 if (xfrm_user_rcv_skb(skb)) {
1077 if (skb->len)
1078 skb_queue_head(&sk->sk_receive_queue,
1079 skb);
1080 else {
1081 kfree_skb(skb);
1082 qlen--;
1083 }
1084 break;
1085 }
1086 kfree_skb(skb);
1087 }
1088
1089 up(&xfrm_cfg_sem); 1032 up(&xfrm_cfg_sem);
1090 1033
1091 } while (qlen); 1034 } while (qlen);
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index c65c435c4923..9d67782b812f 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -114,7 +114,7 @@ gconf-objs := gconf.o kconfig_load.o zconf.tab.o
114endif 114endif
115 115
116clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ 116clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
117 .tmp_gtkcheck zconf.tab.c zconf.tab.h lex.zconf.c 117 .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
118 118
119# Needed for systems without gettext 119# Needed for systems without gettext
120KBUILD_HAVE_NLS := $(shell \ 120KBUILD_HAVE_NLS := $(shell \
@@ -136,12 +136,6 @@ HOSTLOADLIBES_gconf = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
136HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \ 136HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \
137 -D LKC_DIRECT_LINK 137 -D LKC_DIRECT_LINK
138 138
139$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o $(obj)/kxgettext: $(obj)/zconf.tab.h
140
141$(obj)/zconf.tab.h: $(src)/zconf.tab.h_shipped
142$(obj)/zconf.tab.c: $(src)/zconf.tab.c_shipped
143$(obj)/lex.zconf.c: $(src)/lex.zconf.c_shipped
144
145$(obj)/qconf.o: $(obj)/.tmp_qtcheck 139$(obj)/qconf.o: $(obj)/.tmp_qtcheck
146 140
147ifeq ($(qconf-target),1) 141ifeq ($(qconf-target),1)
@@ -207,7 +201,7 @@ $(obj)/.tmp_gtkcheck:
207 fi 201 fi
208endif 202endif
209 203
210$(obj)/zconf.tab.o: $(obj)/lex.zconf.c 204$(obj)/zconf.tab.o: $(obj)/lex.zconf.c $(obj)/zconf.hash.c
211 205
212$(obj)/kconfig_load.o: $(obj)/lkc_defs.h 206$(obj)/kconfig_load.o: $(obj)/lkc_defs.h
213 207
@@ -223,20 +217,27 @@ $(obj)/lkc_defs.h: $(src)/lkc_proto.h
223 217
224 218
225### 219###
226# The following requires flex/bison 220# The following requires flex/bison/gperf
227# By default we use the _shipped versions, uncomment the following line if 221# By default we use the _shipped versions, uncomment the following line if
228# you are modifying the flex/bison src. 222# you are modifying the flex/bison src.
229# LKC_GENPARSER := 1 223# LKC_GENPARSER := 1
230 224
231ifdef LKC_GENPARSER 225ifdef LKC_GENPARSER
232 226
233$(obj)/zconf.tab.c: $(obj)/zconf.y 227$(obj)/zconf.tab.c: $(src)/zconf.y
234$(obj)/zconf.tab.h: $(obj)/zconf.tab.c 228$(obj)/lex.zconf.c: $(src)/zconf.l
229$(obj)/zconf.hash.c: $(src)/zconf.gperf
235 230
236%.tab.c: %.y 231%.tab.c: %.y
237 bison -t -d -v -b $* -p $(notdir $*) $< 232 bison -l -b $* -p $(notdir $*) $<
233 cp $@ $@_shipped
238 234
239lex.%.c: %.l 235lex.%.c: %.l
240 flex -P$(notdir $*) -o$@ $< 236 flex -L -P$(notdir $*) -o$@ $<
237 cp $@ $@_shipped
238
239%.hash.c: %.gperf
240 gperf < $< > $@
241 cp $@ $@_shipped
241 242
242endif 243endif
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index bc20cab9d0d6..8ba5d29d3d42 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -82,6 +82,15 @@ static void conf_askvalue(struct symbol *sym, const char *def)
82 } 82 }
83 83
84 switch (input_mode) { 84 switch (input_mode) {
85 case set_no:
86 case set_mod:
87 case set_yes:
88 case set_random:
89 if (sym_has_value(sym)) {
90 printf("%s\n", def);
91 return;
92 }
93 break;
85 case ask_new: 94 case ask_new:
86 case ask_silent: 95 case ask_silent:
87 if (sym_has_value(sym)) { 96 if (sym_has_value(sym)) {
@@ -467,15 +476,14 @@ static void check_conf(struct menu *menu)
467 return; 476 return;
468 477
469 sym = menu->sym; 478 sym = menu->sym;
470 if (sym) { 479 if (sym && !sym_has_value(sym)) {
471 if (sym_is_changable(sym) && !sym_has_value(sym)) { 480 if (sym_is_changable(sym) ||
481 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
472 if (!conf_cnt++) 482 if (!conf_cnt++)
473 printf(_("*\n* Restart config...\n*\n")); 483 printf(_("*\n* Restart config...\n*\n"));
474 rootEntry = menu_get_parent_menu(menu); 484 rootEntry = menu_get_parent_menu(menu);
475 conf(rootEntry); 485 conf(rootEntry);
476 } 486 }
477 if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
478 return;
479 } 487 }
480 488
481 for (child = menu->list; child; child = child->next) 489 for (child = menu->list; child; child = child->next)
@@ -559,6 +567,27 @@ int main(int ac, char **av)
559 case ask_new: 567 case ask_new:
560 conf_read(NULL); 568 conf_read(NULL);
561 break; 569 break;
570 case set_no:
571 case set_mod:
572 case set_yes:
573 case set_random:
574 name = getenv("KCONFIG_ALLCONFIG");
575 if (name && !stat(name, &tmpstat)) {
576 conf_read_simple(name);
577 break;
578 }
579 switch (input_mode) {
580 case set_no: name = "allno.config"; break;
581 case set_mod: name = "allmod.config"; break;
582 case set_yes: name = "allyes.config"; break;
583 case set_random: name = "allrandom.config"; break;
584 default: break;
585 }
586 if (!stat(name, &tmpstat))
587 conf_read_simple(name);
588 else if (!stat("all.config", &tmpstat))
589 conf_read_simple("all.config");
590 break;
562 default: 591 default:
563 break; 592 break;
564 } 593 }
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 02f670cc6bb9..ccd45130c482 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -14,6 +14,12 @@
14#define LKC_DIRECT_LINK 14#define LKC_DIRECT_LINK
15#include "lkc.h" 15#include "lkc.h"
16 16
17static void conf_warning(const char *fmt, ...)
18 __attribute__ ((format (printf, 1, 2)));
19
20static const char *conf_filename;
21static int conf_lineno, conf_warnings, conf_unsaved;
22
17const char conf_def_filename[] = ".config"; 23const char conf_def_filename[] = ".config";
18 24
19const char conf_defname[] = "arch/$ARCH/defconfig"; 25const char conf_defname[] = "arch/$ARCH/defconfig";
@@ -27,6 +33,17 @@ const char *conf_confnames[] = {
27 NULL, 33 NULL,
28}; 34};
29 35
36static void conf_warning(const char *fmt, ...)
37{
38 va_list ap;
39 va_start(ap, fmt);
40 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
41 vfprintf(stderr, fmt, ap);
42 fprintf(stderr, "\n");
43 va_end(ap);
44 conf_warnings++;
45}
46
30static char *conf_expand_value(const char *in) 47static char *conf_expand_value(const char *in)
31{ 48{
32 struct symbol *sym; 49 struct symbol *sym;
@@ -69,15 +86,12 @@ char *conf_get_default_confname(void)
69 return name; 86 return name;
70} 87}
71 88
72int conf_read(const char *name) 89int conf_read_simple(const char *name)
73{ 90{
74 FILE *in = NULL; 91 FILE *in = NULL;
75 char line[1024]; 92 char line[1024];
76 char *p, *p2; 93 char *p, *p2;
77 int lineno = 0;
78 struct symbol *sym; 94 struct symbol *sym;
79 struct property *prop;
80 struct expr *e;
81 int i; 95 int i;
82 96
83 if (name) { 97 if (name) {
@@ -95,12 +109,18 @@ int conf_read(const char *name)
95 } 109 }
96 } 110 }
97 } 111 }
98
99 if (!in) 112 if (!in)
100 return 1; 113 return 1;
101 114
115 conf_filename = name;
116 conf_lineno = 0;
117 conf_warnings = 0;
118 conf_unsaved = 0;
119
102 for_all_symbols(i, sym) { 120 for_all_symbols(i, sym) {
103 sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; 121 sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
122 if (sym_is_choice(sym))
123 sym->flags &= ~SYMBOL_NEW;
104 sym->flags &= ~SYMBOL_VALID; 124 sym->flags &= ~SYMBOL_VALID;
105 switch (sym->type) { 125 switch (sym->type) {
106 case S_INT: 126 case S_INT:
@@ -115,7 +135,7 @@ int conf_read(const char *name)
115 } 135 }
116 136
117 while (fgets(line, sizeof(line), in)) { 137 while (fgets(line, sizeof(line), in)) {
118 lineno++; 138 conf_lineno++;
119 sym = NULL; 139 sym = NULL;
120 switch (line[0]) { 140 switch (line[0]) {
121 case '#': 141 case '#':
@@ -129,7 +149,10 @@ int conf_read(const char *name)
129 continue; 149 continue;
130 sym = sym_find(line + 9); 150 sym = sym_find(line + 9);
131 if (!sym) { 151 if (!sym) {
132 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9); 152 conf_warning("trying to assign nonexistent symbol %s", line + 9);
153 break;
154 } else if (!(sym->flags & SYMBOL_NEW)) {
155 conf_warning("trying to reassign symbol %s", sym->name);
133 break; 156 break;
134 } 157 }
135 switch (sym->type) { 158 switch (sym->type) {
@@ -143,8 +166,10 @@ int conf_read(const char *name)
143 } 166 }
144 break; 167 break;
145 case 'C': 168 case 'C':
146 if (memcmp(line, "CONFIG_", 7)) 169 if (memcmp(line, "CONFIG_", 7)) {
170 conf_warning("unexpected data");
147 continue; 171 continue;
172 }
148 p = strchr(line + 7, '='); 173 p = strchr(line + 7, '=');
149 if (!p) 174 if (!p)
150 continue; 175 continue;
@@ -154,7 +179,10 @@ int conf_read(const char *name)
154 *p2 = 0; 179 *p2 = 0;
155 sym = sym_find(line + 7); 180 sym = sym_find(line + 7);
156 if (!sym) { 181 if (!sym) {
157 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7); 182 conf_warning("trying to assign nonexistent symbol %s", line + 7);
183 break;
184 } else if (!(sym->flags & SYMBOL_NEW)) {
185 conf_warning("trying to reassign symbol %s", sym->name);
158 break; 186 break;
159 } 187 }
160 switch (sym->type) { 188 switch (sym->type) {
@@ -175,6 +203,7 @@ int conf_read(const char *name)
175 sym->flags &= ~SYMBOL_NEW; 203 sym->flags &= ~SYMBOL_NEW;
176 break; 204 break;
177 } 205 }
206 conf_warning("symbol value '%s' invalid for %s", p, sym->name);
178 break; 207 break;
179 case S_STRING: 208 case S_STRING:
180 if (*p++ != '"') 209 if (*p++ != '"')
@@ -187,8 +216,8 @@ int conf_read(const char *name)
187 memmove(p2, p2 + 1, strlen(p2)); 216 memmove(p2, p2 + 1, strlen(p2));
188 } 217 }
189 if (!p2) { 218 if (!p2) {
190 fprintf(stderr, "%s:%d: invalid string found\n", name, lineno); 219 conf_warning("invalid string found");
191 exit(1); 220 continue;
192 } 221 }
193 case S_INT: 222 case S_INT:
194 case S_HEX: 223 case S_HEX:
@@ -196,8 +225,8 @@ int conf_read(const char *name)
196 sym->user.val = strdup(p); 225 sym->user.val = strdup(p);
197 sym->flags &= ~SYMBOL_NEW; 226 sym->flags &= ~SYMBOL_NEW;
198 } else { 227 } else {
199 fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); 228 conf_warning("symbol value '%s' invalid for %s", p, sym->name);
200 exit(1); 229 continue;
201 } 230 }
202 break; 231 break;
203 default: 232 default:
@@ -207,6 +236,7 @@ int conf_read(const char *name)
207 case '\n': 236 case '\n':
208 break; 237 break;
209 default: 238 default:
239 conf_warning("unexpected data");
210 continue; 240 continue;
211 } 241 }
212 if (sym && sym_is_choice_value(sym)) { 242 if (sym && sym_is_choice_value(sym)) {
@@ -215,25 +245,63 @@ int conf_read(const char *name)
215 case no: 245 case no:
216 break; 246 break;
217 case mod: 247 case mod:
218 if (cs->user.tri == yes) 248 if (cs->user.tri == yes) {
219 /* warn? */; 249 conf_warning("%s creates inconsistent choice state", sym->name);
250 cs->flags |= SYMBOL_NEW;
251 }
220 break; 252 break;
221 case yes: 253 case yes:
222 if (cs->user.tri != no) 254 if (cs->user.tri != no) {
223 /* warn? */; 255 conf_warning("%s creates inconsistent choice state", sym->name);
224 cs->user.val = sym; 256 cs->flags |= SYMBOL_NEW;
257 } else
258 cs->user.val = sym;
225 break; 259 break;
226 } 260 }
227 cs->user.tri = E_OR(cs->user.tri, sym->user.tri); 261 cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
228 cs->flags &= ~SYMBOL_NEW;
229 } 262 }
230 } 263 }
231 fclose(in); 264 fclose(in);
232 265
233 if (modules_sym) 266 if (modules_sym)
234 sym_calc_value(modules_sym); 267 sym_calc_value(modules_sym);
268 return 0;
269}
270
271int conf_read(const char *name)
272{
273 struct symbol *sym;
274 struct property *prop;
275 struct expr *e;
276 int i;
277
278 if (conf_read_simple(name))
279 return 1;
280
235 for_all_symbols(i, sym) { 281 for_all_symbols(i, sym) {
236 sym_calc_value(sym); 282 sym_calc_value(sym);
283 if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
284 goto sym_ok;
285 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
286 /* check that calculated value agrees with saved value */
287 switch (sym->type) {
288 case S_BOOLEAN:
289 case S_TRISTATE:
290 if (sym->user.tri != sym_get_tristate_value(sym))
291 break;
292 if (!sym_is_choice(sym))
293 goto sym_ok;
294 default:
295 if (!strcmp(sym->curr.val, sym->user.val))
296 goto sym_ok;
297 break;
298 }
299 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
300 /* no previous value and not saved */
301 goto sym_ok;
302 conf_unsaved++;
303 /* maybe print value in verbose mode... */
304 sym_ok:
237 if (sym_has_value(sym) && !sym_is_choice_value(sym)) { 305 if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
238 if (sym->visible == no) 306 if (sym->visible == no)
239 sym->flags |= SYMBOL_NEW; 307 sym->flags |= SYMBOL_NEW;
@@ -241,8 +309,10 @@ int conf_read(const char *name)
241 case S_STRING: 309 case S_STRING:
242 case S_INT: 310 case S_INT:
243 case S_HEX: 311 case S_HEX:
244 if (!sym_string_within_range(sym, sym->user.val)) 312 if (!sym_string_within_range(sym, sym->user.val)) {
245 sym->flags |= SYMBOL_NEW; 313 sym->flags |= SYMBOL_NEW;
314 sym->flags &= ~SYMBOL_VALID;
315 }
246 default: 316 default:
247 break; 317 break;
248 } 318 }
@@ -255,7 +325,7 @@ int conf_read(const char *name)
255 sym->flags |= e->right.sym->flags & SYMBOL_NEW; 325 sym->flags |= e->right.sym->flags & SYMBOL_NEW;
256 } 326 }
257 327
258 sym_change_count = 1; 328 sym_change_count = conf_warnings && conf_unsaved;
259 329
260 return 0; 330 return 0;
261} 331}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 7d39ff43e6e1..1b36ef18c48d 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -93,7 +93,6 @@ struct symbol {
93#define SYMBOL_NEW 0x0800 93#define SYMBOL_NEW 0x0800
94#define SYMBOL_AUTO 0x1000 94#define SYMBOL_AUTO 0x1000
95#define SYMBOL_CHECKED 0x2000 95#define SYMBOL_CHECKED 0x2000
96#define SYMBOL_CHECK_DONE 0x4000
97#define SYMBOL_WARNED 0x8000 96#define SYMBOL_WARNED 0x8000
98 97
99#define SYMBOL_MAXLENGTH 256 98#define SYMBOL_MAXLENGTH 256
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index 22dda11f758b..24e3c8cbb7ac 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -1,5 +1,5 @@
1 1
2#line 3 "lex.zconf.c" 2#line 3 "scripts/kconfig/lex.zconf.c"
3 3
4#define YY_INT_ALIGNED short int 4#define YY_INT_ALIGNED short int
5 5
@@ -323,7 +323,7 @@ void zconffree (void * );
323 323
324/* Begin user sect3 */ 324/* Begin user sect3 */
325 325
326#define zconfwrap(n) 1 326#define zconfwrap() 1
327#define YY_SKIP_YYWRAP 327#define YY_SKIP_YYWRAP
328 328
329typedef unsigned char YY_CHAR; 329typedef unsigned char YY_CHAR;
@@ -338,1567 +338,323 @@ int zconflineno = 1;
338 338
339extern char *zconftext; 339extern char *zconftext;
340#define yytext_ptr zconftext 340#define yytext_ptr zconftext
341static yyconst flex_int16_t yy_nxt[][38] = 341static yyconst flex_int16_t yy_nxt[][17] =
342 { 342 {
343 { 343 {
344 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
345 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 345 0, 0, 0, 0, 0, 0, 0
346 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
347 0, 0, 0, 0, 0, 0, 0, 0
348 }, 346 },
349 347
350 { 348 {
351 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, 349 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
352 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 350 12, 12, 12, 12, 12, 12, 12
353 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
354 12, 12, 12, 12, 12, 12, 12, 12
355 }, 351 },
356 352
357 { 353 {
358 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, 354 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
359 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 355 12, 12, 12, 12, 12, 12, 12
360
361 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
362 12, 12, 12, 12, 12, 12, 12, 12
363 }, 356 },
364 357
365 { 358 {
366 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, 359 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
367 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, 360 16, 16, 16, 18, 16, 16, 16
368 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
369 27, 18, 28, 29, 30, 18, 18, 16
370 }, 361 },
371 362
372 { 363 {
373 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, 364 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
374 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, 365 16, 16, 16, 18, 16, 16, 16
375 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
376 27, 18, 28, 29, 30, 18, 18, 16
377 366
378 }, 367 },
379 368
380 { 369 {
381 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, 370 11, 19, 20, 21, 19, 19, 19, 19, 19, 19,
382 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 371 19, 19, 19, 19, 19, 19, 19
383 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
384 31, 31, 31, 31, 31, 31, 31, 31
385 }, 372 },
386 373
387 { 374 {
388 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, 375 11, 19, 20, 21, 19, 19, 19, 19, 19, 19,
389 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 376 19, 19, 19, 19, 19, 19, 19
390 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
391 31, 31, 31, 31, 31, 31, 31, 31
392 }, 377 },
393 378
394 { 379 {
395 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, 380 11, 22, 22, 23, 22, 24, 22, 22, 24, 22,
396 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, 381 22, 22, 22, 22, 22, 25, 22
397
398 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
399 34, 34, 34, 34, 34, 34, 34, 34
400 }, 382 },
401 383
402 { 384 {
403 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, 385 11, 22, 22, 23, 22, 24, 22, 22, 24, 22,
404 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, 386 22, 22, 22, 22, 22, 25, 22
405 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
406 34, 34, 34, 34, 34, 34, 34, 34
407 }, 387 },
408 388
409 { 389 {
410 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, 390 11, 26, 26, 27, 28, 29, 30, 31, 29, 32,
411 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, 391 33, 34, 35, 35, 36, 37, 38
412 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
413 47, 47, 47, 47, 47, 47, 47, 52
414 392
415 }, 393 },
416 394
417 { 395 {
418 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, 396 11, 26, 26, 27, 28, 29, 30, 31, 29, 32,
419 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, 397 33, 34, 35, 35, 36, 37, 38
420 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
421 47, 47, 47, 47, 47, 47, 47, 52
422 }, 398 },
423 399
424 { 400 {
425 -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, 401 -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
426 -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, 402 -11, -11, -11, -11, -11, -11, -11
427 -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
428 -11, -11, -11, -11, -11, -11, -11, -11
429 }, 403 },
430 404
431 { 405 {
432 11, -12, -12, -12, -12, -12, -12, -12, -12, -12, 406 11, -12, -12, -12, -12, -12, -12, -12, -12, -12,
433 -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, 407 -12, -12, -12, -12, -12, -12, -12
434
435 -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
436 -12, -12, -12, -12, -12, -12, -12, -12
437 }, 408 },
438 409
439 { 410 {
440 11, -13, 53, 54, -13, -13, 55, -13, -13, -13, 411 11, -13, 39, 40, -13, -13, 41, -13, -13, -13,
441 -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, 412 -13, -13, -13, -13, -13, -13, -13
442 -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
443 -13, -13, -13, -13, -13, -13, -13, -13
444 }, 413 },
445 414
446 { 415 {
447 11, -14, -14, -14, -14, -14, -14, -14, -14, -14, 416 11, -14, -14, -14, -14, -14, -14, -14, -14, -14,
448 -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, 417 -14, -14, -14, -14, -14, -14, -14
449 -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
450 -14, -14, -14, -14, -14, -14, -14, -14
451 418
452 }, 419 },
453 420
454 { 421 {
455 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, 422 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
456 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 423 42, 42, 42, 42, 42, 42, 42
457 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
458 56, 56, 56, 56, 56, 56, 56, 56
459 }, 424 },
460 425
461 { 426 {
462 11, -16, -16, -16, -16, -16, -16, -16, -16, -16, 427 11, -16, -16, -16, -16, -16, -16, -16, -16, -16,
463 -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, 428 -16, -16, -16, -16, -16, -16, -16
464 -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
465 -16, -16, -16, -16, -16, -16, -16, -16
466 }, 429 },
467 430
468 { 431 {
469 11, -17, -17, -17, -17, -17, -17, -17, -17, -17, 432 11, -17, -17, -17, -17, -17, -17, -17, -17, -17,
470 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, 433 -17, -17, -17, -17, -17, -17, -17
471
472 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
473 -17, -17, -17, -17, -17, -17, -17, -17
474 }, 434 },
475 435
476 { 436 {
477 11, -18, -18, -18, -18, -18, -18, -18, -18, -18, 437 11, -18, -18, -18, -18, -18, -18, -18, -18, -18,
478 -18, -18, -18, 58, -18, -18, 58, 58, 58, 58, 438 -18, -18, -18, 44, -18, -18, -18
479 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
480 58, 58, 58, 58, 58, 58, 58, -18
481 }, 439 },
482 440
483 { 441 {
484 11, -19, -19, -19, -19, -19, -19, -19, -19, -19, 442 11, 45, 45, -19, 45, 45, 45, 45, 45, 45,
485 -19, -19, -19, 58, -19, -19, 58, 58, 58, 58, 443 45, 45, 45, 45, 45, 45, 45
486 58, 58, 58, 58, 58, 58, 58, 58, 58, 59,
487 58, 58, 58, 58, 58, 58, 58, -19
488 444
489 }, 445 },
490 446
491 { 447 {
492 11, -20, -20, -20, -20, -20, -20, -20, -20, -20, 448 11, -20, 46, 47, -20, -20, -20, -20, -20, -20,
493 -20, -20, -20, 58, -20, -20, 58, 58, 58, 58, 449 -20, -20, -20, -20, -20, -20, -20
494 58, 58, 58, 58, 60, 58, 58, 58, 58, 61,
495 58, 58, 58, 58, 58, 58, 58, -20
496 }, 450 },
497 451
498 { 452 {
499 11, -21, -21, -21, -21, -21, -21, -21, -21, -21, 453 11, 48, -21, -21, 48, 48, 48, 48, 48, 48,
500 -21, -21, -21, 58, -21, -21, 58, 58, 58, 58, 454 48, 48, 48, 48, 48, 48, 48
501 58, 62, 58, 58, 58, 58, 58, 58, 58, 58,
502 58, 58, 58, 58, 58, 58, 58, -21
503 }, 455 },
504 456
505 { 457 {
506 11, -22, -22, -22, -22, -22, -22, -22, -22, -22, 458 11, 49, 49, 50, 49, -22, 49, 49, -22, 49,
507 -22, -22, -22, 58, -22, -22, 58, 58, 58, 58, 459 49, 49, 49, 49, 49, -22, 49
508
509 58, 58, 58, 58, 58, 58, 58, 58, 63, 58,
510 58, 58, 58, 58, 58, 58, 58, -22
511 }, 460 },
512 461
513 { 462 {
514 11, -23, -23, -23, -23, -23, -23, -23, -23, -23, 463 11, -23, -23, -23, -23, -23, -23, -23, -23, -23,
515 -23, -23, -23, 58, -23, -23, 58, 58, 58, 58, 464 -23, -23, -23, -23, -23, -23, -23
516 58, 64, 58, 58, 58, 58, 58, 58, 58, 58,
517 58, 58, 58, 58, 58, 58, 58, -23
518 }, 465 },
519 466
520 { 467 {
521 11, -24, -24, -24, -24, -24, -24, -24, -24, -24, 468 11, -24, -24, -24, -24, -24, -24, -24, -24, -24,
522 -24, -24, -24, 58, -24, -24, 58, 58, 58, 58, 469 -24, -24, -24, -24, -24, -24, -24
523 58, 58, 65, 58, 58, 58, 58, 58, 66, 58,
524 58, 58, 58, 58, 58, 58, 58, -24
525 470
526 }, 471 },
527 472
528 { 473 {
529 11, -25, -25, -25, -25, -25, -25, -25, -25, -25, 474 11, 51, 51, 52, 51, 51, 51, 51, 51, 51,
530 -25, -25, -25, 58, -25, -25, 58, 67, 58, 58, 475 51, 51, 51, 51, 51, 51, 51
531 58, 68, 58, 58, 58, 58, 58, 58, 58, 58,
532 58, 58, 58, 58, 58, 58, 58, -25
533 }, 476 },
534 477
535 { 478 {
536 11, -26, -26, -26, -26, -26, -26, -26, -26, -26, 479 11, -26, -26, -26, -26, -26, -26, -26, -26, -26,
537 -26, -26, -26, 58, -26, -26, 58, 58, 58, 58, 480 -26, -26, -26, -26, -26, -26, -26
538 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
539 69, 58, 58, 58, 58, 58, 58, -26
540 }, 481 },
541 482
542 { 483 {
543 11, -27, -27, -27, -27, -27, -27, -27, -27, -27, 484 11, -27, -27, -27, -27, -27, -27, -27, -27, -27,
544 -27, -27, -27, 58, -27, -27, 58, 58, 58, 58, 485 -27, -27, -27, -27, -27, -27, -27
545
546 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
547 58, 58, 70, 58, 58, 58, 58, -27
548 }, 486 },
549 487
550 { 488 {
551 11, -28, -28, -28, -28, -28, -28, -28, -28, -28, 489 11, -28, -28, -28, -28, -28, -28, -28, -28, -28,
552 -28, -28, -28, 58, -28, -28, 58, 71, 58, 58, 490 -28, -28, -28, -28, 53, -28, -28
553 58, 72, 58, 58, 58, 58, 58, 58, 58, 58,
554 58, 58, 58, 58, 58, 58, 58, -28
555 }, 491 },
556 492
557 { 493 {
558 11, -29, -29, -29, -29, -29, -29, -29, -29, -29, 494 11, -29, -29, -29, -29, -29, -29, -29, -29, -29,
559 -29, -29, -29, 58, -29, -29, 58, 58, 58, 58, 495 -29, -29, -29, -29, -29, -29, -29
560 58, 73, 58, 58, 58, 58, 58, 58, 58, 74,
561 58, 58, 58, 58, 75, 58, 58, -29
562 496
563 }, 497 },
564 498
565 { 499 {
566 11, -30, -30, -30, -30, -30, -30, -30, -30, -30, 500 11, 54, 54, -30, 54, 54, 54, 54, 54, 54,
567 -30, -30, -30, 58, -30, -30, 58, 58, 58, 58, 501 54, 54, 54, 54, 54, 54, 54
568 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
569 58, 58, 76, 58, 58, 58, 58, -30
570 }, 502 },
571 503
572 { 504 {
573 11, 77, 77, -31, 77, 77, 77, 77, 77, 77, 505 11, -31, -31, -31, -31, -31, -31, 55, -31, -31,
574 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 506 -31, -31, -31, -31, -31, -31, -31
575 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
576 77, 77, 77, 77, 77, 77, 77, 77
577 }, 507 },
578 508
579 { 509 {
580 11, -32, 78, 79, -32, -32, -32, -32, -32, -32, 510 11, -32, -32, -32, -32, -32, -32, -32, -32, -32,
581 -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, 511 -32, -32, -32, -32, -32, -32, -32
582
583 -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
584 -32, -32, -32, -32, -32, -32, -32, -32
585 }, 512 },
586 513
587 { 514 {
588 11, 80, -33, -33, 80, 80, 80, 80, 80, 80, 515 11, -33, -33, -33, -33, -33, -33, -33, -33, -33,
589 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 516 -33, -33, -33, -33, -33, -33, -33
590 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
591 80, 80, 80, 80, 80, 80, 80, 80
592 }, 517 },
593 518
594 { 519 {
595 11, 81, 81, 82, 81, -34, 81, 81, -34, 81, 520 11, -34, -34, -34, -34, -34, -34, -34, -34, -34,
596 81, 81, 81, 81, 81, -34, 81, 81, 81, 81, 521 -34, 56, 57, 57, -34, -34, -34
597 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
598 81, 81, 81, 81, 81, 81, 81, 81
599 522
600 }, 523 },
601 524
602 { 525 {
603 11, -35, -35, -35, -35, -35, -35, -35, -35, -35, 526 11, -35, -35, -35, -35, -35, -35, -35, -35, -35,
604 -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, 527 -35, 57, 57, 57, -35, -35, -35
605 -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
606 -35, -35, -35, -35, -35, -35, -35, -35
607 }, 528 },
608 529
609 { 530 {
610 11, -36, -36, -36, -36, -36, -36, -36, -36, -36, 531 11, -36, -36, -36, -36, -36, -36, -36, -36, -36,
611 -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, 532 -36, -36, -36, -36, -36, -36, -36
612 -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
613 -36, -36, -36, -36, -36, -36, -36, -36
614 }, 533 },
615 534
616 { 535 {
617 11, 83, 83, 84, 83, 83, 83, 83, 83, 83, 536 11, -37, -37, 58, -37, -37, -37, -37, -37, -37,
618 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 537 -37, -37, -37, -37, -37, -37, -37
619
620 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
621 83, 83, 83, 83, 83, 83, 83, 83
622 }, 538 },
623 539
624 { 540 {
625 11, -38, -38, -38, -38, -38, -38, -38, -38, -38, 541 11, -38, -38, -38, -38, -38, -38, -38, -38, -38,
626 -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, 542 -38, -38, -38, -38, -38, -38, 59
627 -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
628 -38, -38, -38, -38, -38, -38, -38, -38
629 }, 543 },
630 544
631 { 545 {
632 11, -39, -39, -39, -39, -39, -39, -39, -39, -39, 546 11, -39, 39, 40, -39, -39, 41, -39, -39, -39,
633 -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, 547 -39, -39, -39, -39, -39, -39, -39
634 -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
635 -39, -39, -39, -39, -39, -39, -39, -39
636 548
637 }, 549 },
638 550
639 { 551 {
640 11, -40, -40, -40, -40, -40, -40, -40, -40, -40, 552 11, -40, -40, -40, -40, -40, -40, -40, -40, -40,
641 -40, -40, -40, -40, 85, -40, -40, -40, -40, -40, 553 -40, -40, -40, -40, -40, -40, -40
642 -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
643 -40, -40, -40, -40, -40, -40, -40, -40
644 }, 554 },
645 555
646 { 556 {
647 11, -41, -41, -41, -41, -41, -41, -41, -41, -41, 557 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
648 -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, 558 42, 42, 42, 42, 42, 42, 42
649 -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
650 -41, -41, -41, -41, -41, -41, -41, -41
651 }, 559 },
652 560
653 { 561 {
654 11, 86, 86, -42, 86, 86, 86, 86, 86, 86, 562 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
655 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 563 42, 42, 42, 42, 42, 42, 42
656
657 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
658 86, 86, 86, 86, 86, 86, 86, 86
659 }, 564 },
660 565
661 { 566 {
662 11, -43, -43, -43, -43, -43, -43, 87, -43, -43, 567 11, -43, -43, -43, -43, -43, -43, -43, -43, -43,
663 -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, 568 -43, -43, -43, -43, -43, -43, -43
664 -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
665 -43, -43, -43, -43, -43, -43, -43, -43
666 }, 569 },
667 570
668 { 571 {
669 11, -44, -44, -44, -44, -44, -44, -44, -44, -44, 572 11, -44, -44, -44, -44, -44, -44, -44, -44, -44,
670 -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, 573 -44, -44, -44, 44, -44, -44, -44
671 -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
672 -44, -44, -44, -44, -44, -44, -44, -44
673 574
674 }, 575 },
675 576
676 { 577 {
677 11, -45, -45, -45, -45, -45, -45, -45, -45, -45, 578 11, 45, 45, -45, 45, 45, 45, 45, 45, 45,
678 -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, 579 45, 45, 45, 45, 45, 45, 45
679 -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
680 -45, -45, -45, -45, -45, -45, -45, -45
681 }, 580 },
682 581
683 { 582 {
684 11, -46, -46, -46, -46, -46, -46, -46, -46, -46, 583 11, -46, 46, 47, -46, -46, -46, -46, -46, -46,
685 -46, 88, 89, 89, -46, -46, 89, 89, 89, 89, 584 -46, -46, -46, -46, -46, -46, -46
686 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
687 89, 89, 89, 89, 89, 89, 89, -46
688 }, 585 },
689 586
690 { 587 {
691 11, -47, -47, -47, -47, -47, -47, -47, -47, -47, 588 11, 48, -47, -47, 48, 48, 48, 48, 48, 48,
692 -47, 89, 89, 89, -47, -47, 89, 89, 89, 89, 589 48, 48, 48, 48, 48, 48, 48
693
694 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
695 89, 89, 89, 89, 89, 89, 89, -47
696 }, 590 },
697 591
698 { 592 {
699 11, -48, -48, -48, -48, -48, -48, -48, -48, -48, 593 11, -48, -48, -48, -48, -48, -48, -48, -48, -48,
700 -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, 594 -48, -48, -48, -48, -48, -48, -48
701 -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
702 -48, -48, -48, -48, -48, -48, -48, -48
703 }, 595 },
704 596
705 { 597 {
706 11, -49, -49, 90, -49, -49, -49, -49, -49, -49, 598 11, 49, 49, 50, 49, -49, 49, 49, -49, 49,
707 -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, 599 49, 49, 49, 49, 49, -49, 49
708 -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
709 -49, -49, -49, -49, -49, -49, -49, -49
710 600
711 }, 601 },
712 602
713 { 603 {
714 11, -50, -50, -50, -50, -50, -50, -50, -50, -50, 604 11, -50, -50, -50, -50, -50, -50, -50, -50, -50,
715 -50, 89, 89, 89, -50, -50, 89, 89, 89, 89, 605 -50, -50, -50, -50, -50, -50, -50
716 89, 89, 91, 89, 89, 89, 89, 89, 89, 89,
717 89, 89, 89, 89, 89, 89, 89, -50
718 }, 606 },
719 607
720 { 608 {
721 11, -51, -51, -51, -51, -51, -51, -51, -51, -51, 609 11, -51, -51, 52, -51, -51, -51, -51, -51, -51,
722 -51, 89, 89, 89, -51, -51, 89, 89, 89, 89, 610 -51, -51, -51, -51, -51, -51, -51
723 89, 89, 89, 89, 89, 89, 89, 89, 92, 89,
724 89, 89, 89, 89, 89, 89, 89, -51
725 }, 611 },
726 612
727 { 613 {
728 11, -52, -52, -52, -52, -52, -52, -52, -52, -52, 614 11, -52, -52, -52, -52, -52, -52, -52, -52, -52,
729 -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, 615 -52, -52, -52, -52, -52, -52, -52
730
731 -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
732 -52, -52, -52, -52, -52, -52, -52, 93
733 }, 616 },
734 617
735 { 618 {
736 11, -53, 53, 54, -53, -53, 55, -53, -53, -53, 619 11, -53, -53, -53, -53, -53, -53, -53, -53, -53,
737 -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, 620 -53, -53, -53, -53, -53, -53, -53
738 -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
739 -53, -53, -53, -53, -53, -53, -53, -53
740 }, 621 },
741 622
742 { 623 {
743 11, -54, -54, -54, -54, -54, -54, -54, -54, -54, 624 11, 54, 54, -54, 54, 54, 54, 54, 54, 54,
744 -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, 625 54, 54, 54, 54, 54, 54, 54
745 -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
746 -54, -54, -54, -54, -54, -54, -54, -54
747 626
748 }, 627 },
749 628
750 { 629 {
751 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, 630 11, -55, -55, -55, -55, -55, -55, -55, -55, -55,
752 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 631 -55, -55, -55, -55, -55, -55, -55
753 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
754 56, 56, 56, 56, 56, 56, 56, 56
755 }, 632 },
756 633
757 { 634 {
758 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, 635 11, -56, -56, -56, -56, -56, -56, -56, -56, -56,
759 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 636 -56, 60, 57, 57, -56, -56, -56
760 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
761 56, 56, 56, 56, 56, 56, 56, 56
762 }, 637 },
763 638
764 { 639 {
765 11, -57, -57, -57, -57, -57, -57, -57, -57, -57, 640 11, -57, -57, -57, -57, -57, -57, -57, -57, -57,
766 -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, 641 -57, 57, 57, 57, -57, -57, -57
767
768 -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
769 -57, -57, -57, -57, -57, -57, -57, -57
770 }, 642 },
771 643
772 { 644 {
773 11, -58, -58, -58, -58, -58, -58, -58, -58, -58, 645 11, -58, -58, -58, -58, -58, -58, -58, -58, -58,
774 -58, -58, -58, 58, -58, -58, 58, 58, 58, 58, 646 -58, -58, -58, -58, -58, -58, -58
775 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
776 58, 58, 58, 58, 58, 58, 58, -58
777 }, 647 },
778 648
779 { 649 {
780 11, -59, -59, -59, -59, -59, -59, -59, -59, -59, 650 11, -59, -59, -59, -59, -59, -59, -59, -59, -59,
781 -59, -59, -59, 58, -59, -59, 58, 58, 58, 58, 651 -59, -59, -59, -59, -59, -59, -59
782 58, 58, 58, 58, 58, 58, 58, 58, 58, 94,
783 58, 58, 58, 58, 58, 58, 58, -59
784 652
785 }, 653 },
786 654
787 { 655 {
788 11, -60, -60, -60, -60, -60, -60, -60, -60, -60, 656 11, -60, -60, -60, -60, -60, -60, -60, -60, -60,
789 -60, -60, -60, 58, -60, -60, 58, 58, 58, 58, 657 -60, 57, 57, 57, -60, -60, -60
790 58, 58, 58, 58, 58, 58, 58, 58, 58, 95,
791 58, 58, 58, 58, 58, 58, 58, -60
792 },
793
794 {
795 11, -61, -61, -61, -61, -61, -61, -61, -61, -61,
796 -61, -61, -61, 58, -61, -61, 58, 58, 58, 58,
797 58, 58, 58, 58, 58, 58, 58, 96, 97, 58,
798 58, 58, 58, 58, 58, 58, 58, -61
799 },
800
801 {
802 11, -62, -62, -62, -62, -62, -62, -62, -62, -62,
803 -62, -62, -62, 58, -62, -62, 58, 58, 58, 58,
804
805 58, 58, 98, 58, 58, 58, 58, 58, 58, 58,
806 99, 58, 58, 58, 58, 58, 58, -62
807 },
808
809 {
810 11, -63, -63, -63, -63, -63, -63, -63, -63, -63,
811 -63, -63, -63, 58, -63, -63, 58, 100, 58, 58,
812 101, 58, 58, 58, 58, 58, 58, 58, 58, 58,
813 58, 58, 58, 58, 58, 58, 58, -63
814 },
815
816 {
817 11, -64, -64, -64, -64, -64, -64, -64, -64, -64,
818 -64, -64, -64, 58, -64, -64, 58, 58, 58, 58,
819 58, 58, 58, 58, 58, 58, 102, 58, 58, 58,
820 58, 58, 58, 58, 58, 58, 103, -64
821
822 },
823
824 {
825 11, -65, -65, -65, -65, -65, -65, -65, -65, -65,
826 -65, -65, -65, 58, -65, -65, 58, 58, 58, 58,
827 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
828 58, 58, 58, 58, 58, 58, 58, -65
829 },
830
831 {
832 11, -66, -66, -66, -66, -66, -66, -66, -66, -66,
833 -66, -66, -66, 58, -66, -66, 58, 58, 58, 58,
834 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
835 58, 58, 58, 58, 104, 58, 58, -66
836 },
837
838 {
839 11, -67, -67, -67, -67, -67, -67, -67, -67, -67,
840 -67, -67, -67, 58, -67, -67, 58, 58, 58, 58,
841
842 58, 58, 58, 58, 58, 105, 58, 58, 58, 58,
843 58, 58, 58, 58, 58, 58, 58, -67
844 },
845
846 {
847 11, -68, -68, -68, -68, -68, -68, -68, -68, -68,
848 -68, -68, -68, 58, -68, -68, 58, 58, 58, 58,
849 58, 58, 58, 58, 58, 58, 58, 58, 106, 58,
850 58, 58, 58, 58, 58, 58, 58, -68
851 },
852
853 {
854 11, -69, -69, -69, -69, -69, -69, -69, -69, -69,
855 -69, -69, -69, 58, -69, -69, 58, 58, 58, 58,
856 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
857 58, 58, 58, 58, 107, 58, 58, -69
858
859 },
860
861 {
862 11, -70, -70, -70, -70, -70, -70, -70, -70, -70,
863 -70, -70, -70, 58, -70, -70, 58, 58, 58, 58,
864 58, 58, 58, 58, 58, 58, 58, 58, 58, 108,
865 58, 58, 58, 58, 58, 58, 58, -70
866 },
867
868 {
869 11, -71, -71, -71, -71, -71, -71, -71, -71, -71,
870 -71, -71, -71, 58, -71, -71, 58, 58, 58, 58,
871 58, 58, 58, 58, 58, 58, 58, 58, 109, 58,
872 58, 58, 58, 58, 58, 58, 58, -71
873 },
874
875 {
876 11, -72, -72, -72, -72, -72, -72, -72, -72, -72,
877 -72, -72, -72, 58, -72, -72, 58, 58, 58, 58,
878
879 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
880 58, 110, 58, 58, 58, 58, 58, -72
881 },
882
883 {
884 11, -73, -73, -73, -73, -73, -73, -73, -73, -73,
885 -73, -73, -73, 58, -73, -73, 58, 58, 58, 58,
886 58, 58, 58, 58, 58, 58, 111, 58, 58, 58,
887 58, 58, 58, 58, 58, 58, 58, -73
888 },
889
890 {
891 11, -74, -74, -74, -74, -74, -74, -74, -74, -74,
892 -74, -74, -74, 58, -74, -74, 58, 58, 58, 58,
893 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
894 58, 58, 58, 58, 58, 112, 58, -74
895
896 },
897
898 {
899 11, -75, -75, -75, -75, -75, -75, -75, -75, -75,
900 -75, -75, -75, 58, -75, -75, 58, 58, 58, 58,
901 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
902 58, 58, 113, 58, 58, 58, 58, -75
903 },
904
905 {
906 11, -76, -76, -76, -76, -76, -76, -76, -76, -76,
907 -76, -76, -76, 58, -76, -76, 58, 58, 58, 58,
908 58, 58, 58, 58, 58, 114, 58, 58, 58, 58,
909 58, 58, 58, 58, 58, 58, 58, -76
910 },
911
912 {
913 11, 77, 77, -77, 77, 77, 77, 77, 77, 77,
914 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
915
916 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
917 77, 77, 77, 77, 77, 77, 77, 77
918 },
919
920 {
921 11, -78, 78, 79, -78, -78, -78, -78, -78, -78,
922 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
923 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
924 -78, -78, -78, -78, -78, -78, -78, -78
925 },
926
927 {
928 11, 80, -79, -79, 80, 80, 80, 80, 80, 80,
929 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
930 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
931 80, 80, 80, 80, 80, 80, 80, 80
932
933 },
934
935 {
936 11, -80, -80, -80, -80, -80, -80, -80, -80, -80,
937 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
938 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
939 -80, -80, -80, -80, -80, -80, -80, -80
940 },
941
942 {
943 11, 81, 81, 82, 81, -81, 81, 81, -81, 81,
944 81, 81, 81, 81, 81, -81, 81, 81, 81, 81,
945 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
946 81, 81, 81, 81, 81, 81, 81, 81
947 },
948
949 {
950 11, -82, -82, -82, -82, -82, -82, -82, -82, -82,
951 -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
952
953 -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
954 -82, -82, -82, -82, -82, -82, -82, -82
955 },
956
957 {
958 11, -83, -83, 84, -83, -83, -83, -83, -83, -83,
959 -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
960 -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
961 -83, -83, -83, -83, -83, -83, -83, -83
962 },
963
964 {
965 11, -84, -84, -84, -84, -84, -84, -84, -84, -84,
966 -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
967 -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
968 -84, -84, -84, -84, -84, -84, -84, -84
969
970 },
971
972 {
973 11, -85, -85, -85, -85, -85, -85, -85, -85, -85,
974 -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
975 -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
976 -85, -85, -85, -85, -85, -85, -85, -85
977 },
978
979 {
980 11, 86, 86, -86, 86, 86, 86, 86, 86, 86,
981 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
982 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
983 86, 86, 86, 86, 86, 86, 86, 86
984 },
985
986 {
987 11, -87, -87, -87, -87, -87, -87, -87, -87, -87,
988 -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
989
990 -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
991 -87, -87, -87, -87, -87, -87, -87, -87
992 },
993
994 {
995 11, -88, -88, -88, -88, -88, -88, -88, -88, -88,
996 -88, 115, 89, 89, -88, -88, 89, 89, 89, 89,
997 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
998 89, 89, 89, 89, 89, 89, 89, -88
999 },
1000
1001 {
1002 11, -89, -89, -89, -89, -89, -89, -89, -89, -89,
1003 -89, 89, 89, 89, -89, -89, 89, 89, 89, 89,
1004 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1005 89, 89, 89, 89, 89, 89, 89, -89
1006
1007 },
1008
1009 {
1010 11, -90, -90, -90, -90, -90, -90, -90, -90, -90,
1011 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
1012 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
1013 -90, -90, -90, -90, -90, -90, -90, -90
1014 },
1015
1016 {
1017 11, -91, -91, -91, -91, -91, -91, -91, -91, -91,
1018 -91, 89, 89, 89, -91, -91, 89, 89, 89, 89,
1019 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1020 89, 89, 89, 89, 89, 89, 89, -91
1021 },
1022
1023 {
1024 11, -92, -92, -92, -92, -92, -92, -92, -92, -92,
1025 -92, 89, 89, 89, -92, -92, 89, 89, 89, 89,
1026
1027 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1028 89, 89, 89, 89, 89, 89, 89, -92
1029 },
1030
1031 {
1032 11, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1033 -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1034 -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1035 -93, -93, -93, -93, -93, -93, -93, -93
1036 },
1037
1038 {
1039 11, -94, -94, -94, -94, -94, -94, -94, -94, -94,
1040 -94, -94, -94, 58, -94, -94, 58, 58, 58, 58,
1041 58, 58, 58, 58, 58, 58, 116, 58, 58, 58,
1042 58, 58, 58, 58, 58, 58, 58, -94
1043
1044 },
1045
1046 {
1047 11, -95, -95, -95, -95, -95, -95, -95, -95, -95,
1048 -95, -95, -95, 58, -95, -95, 58, 58, 58, 58,
1049 58, 58, 58, 58, 58, 117, 58, 58, 58, 58,
1050 58, 58, 58, 58, 58, 58, 58, -95
1051 },
1052
1053 {
1054 11, -96, -96, -96, -96, -96, -96, -96, -96, -96,
1055 -96, -96, -96, 58, -96, -96, 58, 58, 58, 58,
1056 58, 58, 58, 58, 58, 58, 58, 118, 58, 58,
1057 58, 58, 58, 58, 58, 58, 58, -96
1058 },
1059
1060 {
1061 11, -97, -97, -97, -97, -97, -97, -97, -97, -97,
1062 -97, -97, -97, 58, -97, -97, 58, 58, 58, 58,
1063
1064 58, 58, 119, 58, 58, 58, 58, 58, 58, 58,
1065 58, 58, 58, 58, 58, 58, 58, -97
1066 },
1067
1068 {
1069 11, -98, -98, -98, -98, -98, -98, -98, -98, -98,
1070 -98, -98, -98, 58, -98, -98, 120, 121, 58, 58,
1071 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1072 58, 58, 58, 58, 58, 58, 58, -98
1073 },
1074
1075 {
1076 11, -99, -99, -99, -99, -99, -99, -99, -99, -99,
1077 -99, -99, -99, 58, -99, -99, 58, 58, 58, 58,
1078 58, 122, 58, 58, 58, 58, 58, 58, 58, 58,
1079 58, 58, 58, 58, 58, 58, 58, -99
1080
1081 },
1082
1083 {
1084 11, -100, -100, -100, -100, -100, -100, -100, -100, -100,
1085 -100, -100, -100, 58, -100, -100, 58, 58, 123, 58,
1086 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1087 58, 58, 58, 58, 58, 58, 58, -100
1088 },
1089
1090 {
1091 11, -101, -101, -101, -101, -101, -101, -101, -101, -101,
1092 -101, -101, -101, 58, -101, -101, 58, 58, 58, 124,
1093 58, 58, 58, 58, 58, 125, 58, 126, 58, 58,
1094 58, 58, 58, 58, 58, 58, 58, -101
1095 },
1096
1097 {
1098 11, -102, -102, -102, -102, -102, -102, -102, -102, -102,
1099 -102, -102, -102, 58, -102, -102, 58, 58, 58, 58,
1100
1101 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1102 127, 58, 58, 58, 58, 58, 58, -102
1103 },
1104
1105 {
1106 11, -103, -103, -103, -103, -103, -103, -103, -103, -103,
1107 -103, -103, -103, 58, -103, -103, 58, 58, 58, 58,
1108 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1109 58, 58, 58, 58, 58, 58, 58, -103
1110 },
1111
1112 {
1113 11, -104, -104, -104, -104, -104, -104, -104, -104, -104,
1114 -104, -104, -104, 58, -104, -104, 58, 58, 58, 58,
1115 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1116 58, 58, 58, 58, 58, 58, 58, -104
1117
1118 },
1119
1120 {
1121 11, -105, -105, -105, -105, -105, -105, -105, -105, -105,
1122 -105, -105, -105, 58, -105, -105, 58, 58, 58, 58,
1123 58, 58, 58, 58, 58, 58, 58, 58, 128, 58,
1124 58, 58, 58, 58, 58, 58, 58, -105
1125 },
1126
1127 {
1128 11, -106, -106, -106, -106, -106, -106, -106, -106, -106,
1129 -106, -106, -106, 58, -106, -106, 58, 58, 58, 58,
1130 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1131 58, 58, 58, 58, 58, 129, 58, -106
1132 },
1133
1134 {
1135 11, -107, -107, -107, -107, -107, -107, -107, -107, -107,
1136 -107, -107, -107, 58, -107, -107, 58, 58, 58, 58,
1137
1138 58, 58, 58, 58, 58, 130, 58, 58, 58, 58,
1139 58, 58, 58, 58, 58, 58, 58, -107
1140 },
1141
1142 {
1143 11, -108, -108, -108, -108, -108, -108, -108, -108, -108,
1144 -108, -108, -108, 58, -108, -108, 58, 58, 58, 58,
1145 58, 58, 58, 58, 58, 58, 58, 131, 58, 58,
1146 58, 58, 58, 58, 58, 58, 58, -108
1147 },
1148
1149 {
1150 11, -109, -109, -109, -109, -109, -109, -109, -109, -109,
1151 -109, -109, -109, 58, -109, -109, 58, 58, 58, 58,
1152 58, 58, 58, 132, 58, 58, 58, 58, 58, 58,
1153 58, 58, 58, 58, 58, 58, 58, -109
1154
1155 },
1156
1157 {
1158 11, -110, -110, -110, -110, -110, -110, -110, -110, -110,
1159 -110, -110, -110, 58, -110, -110, 58, 58, 58, 58,
1160 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1161 58, 58, 58, 58, 58, 133, 58, -110
1162 },
1163
1164 {
1165 11, -111, -111, -111, -111, -111, -111, -111, -111, -111,
1166 -111, -111, -111, 58, -111, -111, 58, 58, 58, 58,
1167 58, 134, 58, 58, 58, 58, 58, 58, 58, 58,
1168 58, 58, 58, 58, 58, 58, 58, -111
1169 },
1170
1171 {
1172 11, -112, -112, -112, -112, -112, -112, -112, -112, -112,
1173 -112, -112, -112, 58, -112, -112, 58, 58, 58, 58,
1174
1175 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1176 58, 58, 135, 58, 58, 58, 58, -112
1177 },
1178
1179 {
1180 11, -113, -113, -113, -113, -113, -113, -113, -113, -113,
1181 -113, -113, -113, 58, -113, -113, 58, 58, 58, 58,
1182 58, 58, 58, 58, 58, 136, 58, 58, 58, 58,
1183 58, 58, 58, 58, 58, 58, 58, -113
1184 },
1185
1186 {
1187 11, -114, -114, -114, -114, -114, -114, -114, -114, -114,
1188 -114, -114, -114, 58, -114, -114, 58, 58, 58, 58,
1189 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1190 58, 58, 58, 137, 58, 58, 58, -114
1191
1192 },
1193
1194 {
1195 11, -115, -115, -115, -115, -115, -115, -115, -115, -115,
1196 -115, 89, 89, 89, -115, -115, 89, 89, 89, 89,
1197 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1198 89, 89, 89, 89, 89, 89, 89, -115
1199 },
1200
1201 {
1202 11, -116, -116, -116, -116, -116, -116, -116, -116, -116,
1203 -116, -116, -116, 58, -116, -116, 58, 58, 58, 58,
1204 58, 138, 58, 58, 58, 58, 58, 58, 58, 58,
1205 58, 58, 58, 58, 58, 58, 58, -116
1206 },
1207
1208 {
1209 11, -117, -117, -117, -117, -117, -117, -117, -117, -117,
1210 -117, -117, -117, 58, -117, -117, 58, 58, 58, 139,
1211
1212 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1213 58, 58, 58, 58, 58, 58, 58, -117
1214 },
1215
1216 {
1217 11, -118, -118, -118, -118, -118, -118, -118, -118, -118,
1218 -118, -118, -118, 58, -118, -118, 58, 58, 58, 58,
1219 58, 140, 58, 58, 58, 58, 58, 58, 58, 58,
1220 58, 58, 58, 58, 58, 58, 58, -118
1221 },
1222
1223 {
1224 11, -119, -119, -119, -119, -119, -119, -119, -119, -119,
1225 -119, -119, -119, 58, -119, -119, 58, 58, 58, 58,
1226 58, 58, 58, 58, 58, 141, 58, 58, 58, 58,
1227 58, 58, 58, 58, 58, 58, 58, -119
1228
1229 },
1230
1231 {
1232 11, -120, -120, -120, -120, -120, -120, -120, -120, -120,
1233 -120, -120, -120, 58, -120, -120, 58, 58, 142, 58,
1234 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1235 58, 58, 58, 58, 143, 58, 58, -120
1236 },
1237
1238 {
1239 11, -121, -121, -121, -121, -121, -121, -121, -121, -121,
1240 -121, -121, -121, 58, -121, -121, 58, 58, 58, 58,
1241 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1242 58, 58, 58, 58, 58, 144, 58, -121
1243 },
1244
1245 {
1246 11, -122, -122, -122, -122, -122, -122, -122, -122, -122,
1247 -122, -122, -122, 58, -122, -122, 58, 58, 58, 58,
1248
1249 58, 58, 58, 58, 58, 58, 58, 58, 145, 58,
1250 58, 58, 58, 58, 58, 58, 58, -122
1251 },
1252
1253 {
1254 11, -123, -123, -123, -123, -123, -123, -123, -123, -123,
1255 -123, -123, -123, 58, -123, -123, 58, 58, 58, 58,
1256 58, 58, 58, 58, 58, 58, 146, 58, 58, 58,
1257 58, 58, 58, 58, 58, 58, 58, -123
1258 },
1259
1260 {
1261 11, -124, -124, -124, -124, -124, -124, -124, -124, -124,
1262 -124, -124, -124, 58, -124, -124, 58, 58, 58, 58,
1263 58, 58, 58, 58, 147, 58, 58, 58, 58, 58,
1264 58, 58, 58, 58, 58, 58, 58, -124
1265
1266 },
1267
1268 {
1269 11, -125, -125, -125, -125, -125, -125, -125, -125, -125,
1270 -125, -125, -125, 58, -125, -125, 58, 58, 58, 58,
1271 58, 58, 148, 58, 58, 58, 58, 58, 58, 58,
1272 58, 58, 58, 58, 58, 58, 58, -125
1273 },
1274
1275 {
1276 11, -126, -126, -126, -126, -126, -126, -126, -126, -126,
1277 -126, -126, -126, 58, -126, -126, 58, 58, 58, 58,
1278 58, 149, 58, 58, 58, 58, 58, 58, 58, 58,
1279 58, 58, 58, 58, 58, 58, 58, -126
1280 },
1281
1282 {
1283 11, -127, -127, -127, -127, -127, -127, -127, -127, -127,
1284 -127, -127, -127, 58, -127, -127, 58, 58, 58, 58,
1285
1286 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1287 58, 58, 58, 58, 58, 58, 58, -127
1288 },
1289
1290 {
1291 11, -128, -128, -128, -128, -128, -128, -128, -128, -128,
1292 -128, -128, -128, 58, -128, -128, 58, 58, 58, 58,
1293 58, 58, 58, 58, 58, 58, 58, 150, 58, 58,
1294 58, 58, 58, 58, 58, 58, 58, -128
1295 },
1296
1297 {
1298 11, -129, -129, -129, -129, -129, -129, -129, -129, -129,
1299 -129, -129, -129, 58, -129, -129, 58, 58, 58, 151,
1300 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1301 58, 58, 58, 58, 58, 58, 58, -129
1302
1303 },
1304
1305 {
1306 11, -130, -130, -130, -130, -130, -130, -130, -130, -130,
1307 -130, -130, -130, 58, -130, -130, 58, 58, 58, 58,
1308 58, 58, 58, 58, 58, 58, 58, 58, 58, 152,
1309 58, 58, 58, 58, 58, 58, 58, -130
1310 },
1311
1312 {
1313 11, -131, -131, -131, -131, -131, -131, -131, -131, -131,
1314 -131, -131, -131, 58, -131, -131, 58, 58, 58, 58,
1315 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1316 153, 58, 58, 58, 58, 58, 58, -131
1317 },
1318
1319 {
1320 11, -132, -132, -132, -132, -132, -132, -132, -132, -132,
1321 -132, -132, -132, 58, -132, -132, 58, 58, 58, 58,
1322
1323 58, 154, 58, 58, 58, 58, 58, 58, 58, 58,
1324 58, 58, 58, 58, 58, 58, 58, -132
1325 },
1326
1327 {
1328 11, -133, -133, -133, -133, -133, -133, -133, -133, -133,
1329 -133, -133, -133, 58, -133, -133, 58, 58, 58, 58,
1330 58, 58, 58, 58, 58, 155, 58, 58, 58, 58,
1331 58, 58, 58, 58, 58, 58, 58, -133
1332 },
1333
1334 {
1335 11, -134, -134, -134, -134, -134, -134, -134, -134, -134,
1336 -134, -134, -134, 58, -134, -134, 58, 58, 58, 156,
1337 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1338 58, 58, 58, 58, 58, 58, 58, -134
1339
1340 },
1341
1342 {
1343 11, -135, -135, -135, -135, -135, -135, -135, -135, -135,
1344 -135, -135, -135, 58, -135, -135, 58, 58, 58, 157,
1345 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1346 58, 58, 58, 58, 58, 58, 58, -135
1347 },
1348
1349 {
1350 11, -136, -136, -136, -136, -136, -136, -136, -136, -136,
1351 -136, -136, -136, 58, -136, -136, 58, 58, 58, 58,
1352 58, 58, 58, 58, 58, 58, 58, 58, 158, 58,
1353 58, 58, 58, 58, 58, 58, 58, -136
1354 },
1355
1356 {
1357 11, -137, -137, -137, -137, -137, -137, -137, -137, -137,
1358 -137, -137, -137, 58, -137, -137, 58, 58, 58, 58,
1359
1360 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1361 58, 58, 58, 58, 159, 58, 58, -137
1362 },
1363
1364 {
1365 11, -138, -138, -138, -138, -138, -138, -138, -138, -138,
1366 -138, -138, -138, 58, -138, -138, 58, 160, 58, 58,
1367 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1368 58, 58, 58, 58, 58, 58, 58, -138
1369 },
1370
1371 {
1372 11, -139, -139, -139, -139, -139, -139, -139, -139, -139,
1373 -139, -139, -139, 58, -139, -139, 58, 58, 58, 58,
1374 58, 161, 58, 58, 58, 58, 58, 58, 58, 58,
1375 58, 58, 58, 58, 58, 58, 58, -139
1376
1377 },
1378
1379 {
1380 11, -140, -140, -140, -140, -140, -140, -140, -140, -140,
1381 -140, -140, -140, 58, -140, -140, 58, 58, 58, 58,
1382 58, 58, 58, 58, 58, 58, 58, 58, 162, 58,
1383 58, 58, 58, 58, 58, 58, 58, -140
1384 },
1385
1386 {
1387 11, -141, -141, -141, -141, -141, -141, -141, -141, -141,
1388 -141, -141, -141, 58, -141, -141, 58, 58, 58, 58,
1389 58, 58, 58, 163, 58, 58, 58, 58, 58, 58,
1390 58, 58, 58, 58, 58, 58, 58, -141
1391 },
1392
1393 {
1394 11, -142, -142, -142, -142, -142, -142, -142, -142, -142,
1395 -142, -142, -142, 58, -142, -142, 58, 58, 58, 58,
1396
1397 58, 58, 58, 58, 58, 58, 58, 58, 58, 164,
1398 58, 58, 58, 58, 58, 58, 58, -142
1399 },
1400
1401 {
1402 11, -143, -143, -143, -143, -143, -143, -143, -143, -143,
1403 -143, -143, -143, 58, -143, -143, 58, 58, 58, 58,
1404 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1405 58, 58, 165, 58, 58, 58, 58, -143
1406 },
1407
1408 {
1409 11, -144, -144, -144, -144, -144, -144, -144, -144, -144,
1410 -144, -144, -144, 58, -144, -144, 58, 58, 58, 58,
1411 58, 58, 58, 58, 58, 58, 166, 58, 58, 58,
1412 58, 58, 58, 58, 58, 58, 58, -144
1413
1414 },
1415
1416 {
1417 11, -145, -145, -145, -145, -145, -145, -145, -145, -145,
1418 -145, -145, -145, 58, -145, -145, 58, 58, 58, 58,
1419 167, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1420 58, 58, 58, 58, 58, 58, 58, -145
1421 },
1422
1423 {
1424 11, -146, -146, -146, -146, -146, -146, -146, -146, -146,
1425 -146, -146, -146, 58, -146, -146, 58, 58, 58, 58,
1426 58, 168, 58, 58, 58, 58, 58, 58, 58, 58,
1427 58, 58, 58, 58, 58, 58, 58, -146
1428 },
1429
1430 {
1431 11, -147, -147, -147, -147, -147, -147, -147, -147, -147,
1432 -147, -147, -147, 58, -147, -147, 58, 58, 58, 58,
1433
1434 58, 58, 58, 58, 58, 58, 58, 58, 58, 169,
1435 58, 58, 58, 58, 58, 58, 58, -147
1436 },
1437
1438 {
1439 11, -148, -148, -148, -148, -148, -148, -148, -148, -148,
1440 -148, -148, -148, 58, -148, -148, 58, 58, 58, 58,
1441 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1442 58, 58, 58, 58, 58, 58, 58, -148
1443 },
1444
1445 {
1446 11, -149, -149, -149, -149, -149, -149, -149, -149, -149,
1447 -149, -149, -149, 58, -149, -149, 58, 58, 58, 58,
1448 58, 58, 58, 58, 58, 58, 58, 58, 170, 58,
1449 58, 58, 58, 58, 58, 58, 58, -149
1450
1451 },
1452
1453 {
1454 11, -150, -150, -150, -150, -150, -150, -150, -150, -150,
1455 -150, -150, -150, 58, -150, -150, 58, 58, 58, 58,
1456 58, 171, 58, 58, 58, 58, 58, 58, 58, 58,
1457 58, 58, 58, 58, 58, 58, 58, -150
1458 },
1459
1460 {
1461 11, -151, -151, -151, -151, -151, -151, -151, -151, -151,
1462 -151, -151, -151, 58, -151, -151, 58, 58, 58, 58,
1463 58, 58, 58, 58, 58, 58, 58, 58, 58, 172,
1464 58, 58, 58, 58, 58, 58, 58, -151
1465 },
1466
1467 {
1468 11, -152, -152, -152, -152, -152, -152, -152, -152, -152,
1469 -152, -152, -152, 58, -152, -152, 58, 58, 58, 58,
1470
1471 58, 58, 58, 58, 58, 58, 58, 58, 173, 58,
1472 58, 58, 58, 58, 58, 58, 58, -152
1473 },
1474
1475 {
1476 11, -153, -153, -153, -153, -153, -153, -153, -153, -153,
1477 -153, -153, -153, 58, -153, -153, 58, 58, 58, 58,
1478 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1479 58, 58, 58, 58, 174, 58, 58, -153
1480 },
1481
1482 {
1483 11, -154, -154, -154, -154, -154, -154, -154, -154, -154,
1484 -154, -154, -154, 58, -154, -154, 58, 58, 58, 58,
1485 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1486 58, 58, 58, 58, 58, 58, 58, -154
1487
1488 },
1489
1490 {
1491 11, -155, -155, -155, -155, -155, -155, -155, -155, -155,
1492 -155, -155, -155, 58, -155, -155, 58, 58, 58, 58,
1493 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1494 58, 58, 175, 58, 58, 58, 58, -155
1495 },
1496
1497 {
1498 11, -156, -156, -156, -156, -156, -156, -156, -156, -156,
1499 -156, -156, -156, 58, -156, -156, 58, 58, 58, 58,
1500 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1501 58, 58, 58, 58, 176, 58, 58, -156
1502 },
1503
1504 {
1505 11, -157, -157, -157, -157, -157, -157, -157, -157, -157,
1506 -157, -157, -157, 58, -157, -157, 58, 58, 58, 58,
1507
1508 58, 177, 58, 58, 58, 58, 58, 58, 58, 58,
1509 58, 58, 58, 58, 58, 58, 58, -157
1510 },
1511
1512 {
1513 11, -158, -158, -158, -158, -158, -158, -158, -158, -158,
1514 -158, -158, -158, 58, -158, -158, 58, 58, 58, 58,
1515 58, 58, 58, 178, 58, 58, 58, 58, 58, 58,
1516 58, 58, 58, 58, 58, 58, 58, -158
1517 },
1518
1519 {
1520 11, -159, -159, -159, -159, -159, -159, -159, -159, -159,
1521 -159, -159, -159, 58, -159, -159, 58, 179, 58, 58,
1522 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1523 58, 58, 58, 58, 58, 58, 58, -159
1524
1525 },
1526
1527 {
1528 11, -160, -160, -160, -160, -160, -160, -160, -160, -160,
1529 -160, -160, -160, 58, -160, -160, 58, 58, 58, 58,
1530 58, 58, 58, 58, 58, 58, 58, 58, 180, 58,
1531 58, 58, 58, 58, 58, 58, 58, -160
1532 },
1533
1534 {
1535 11, -161, -161, -161, -161, -161, -161, -161, -161, -161,
1536 -161, -161, -161, 58, -161, -161, 58, 58, 58, 58,
1537 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1538 58, 58, 58, 58, 58, 58, 58, -161
1539 },
1540
1541 {
1542 11, -162, -162, -162, -162, -162, -162, -162, -162, -162,
1543 -162, -162, -162, 58, -162, -162, 58, 58, 58, 58,
1544
1545 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1546 58, 58, 58, 58, 181, 58, 58, -162
1547 },
1548
1549 {
1550 11, -163, -163, -163, -163, -163, -163, -163, -163, -163,
1551 -163, -163, -163, 58, -163, -163, 58, 58, 58, 58,
1552 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1553 58, 58, 58, 58, 58, 58, 58, -163
1554 },
1555
1556 {
1557 11, -164, -164, -164, -164, -164, -164, -164, -164, -164,
1558 -164, -164, -164, 58, -164, -164, 58, 58, 58, 58,
1559 58, 58, 58, 58, 58, 58, 58, 58, 58, 182,
1560 58, 58, 58, 58, 58, 58, 58, -164
1561
1562 },
1563
1564 {
1565 11, -165, -165, -165, -165, -165, -165, -165, -165, -165,
1566 -165, -165, -165, 58, -165, -165, 58, 58, 58, 58,
1567 58, 58, 58, 58, 58, 183, 58, 58, 58, 58,
1568 58, 58, 58, 58, 58, 58, 58, -165
1569 },
1570
1571 {
1572 11, -166, -166, -166, -166, -166, -166, -166, -166, -166,
1573 -166, -166, -166, 58, -166, -166, 58, 58, 58, 58,
1574 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1575 58, 58, 58, 58, 184, 58, 58, -166
1576 },
1577
1578 {
1579 11, -167, -167, -167, -167, -167, -167, -167, -167, -167,
1580 -167, -167, -167, 58, -167, -167, 58, 58, 58, 58,
1581
1582 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1583 58, 58, 58, 185, 58, 58, 58, -167
1584 },
1585
1586 {
1587 11, -168, -168, -168, -168, -168, -168, -168, -168, -168,
1588 -168, -168, -168, 58, -168, -168, 58, 58, 58, 58,
1589 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1590 58, 58, 58, 58, 58, 58, 58, -168
1591 },
1592
1593 {
1594 11, -169, -169, -169, -169, -169, -169, -169, -169, -169,
1595 -169, -169, -169, 58, -169, -169, 58, 58, 58, 58,
1596 58, 58, 58, 58, 58, 186, 58, 58, 58, 58,
1597 58, 58, 58, 58, 58, 58, 58, -169
1598
1599 },
1600
1601 {
1602 11, -170, -170, -170, -170, -170, -170, -170, -170, -170,
1603 -170, -170, -170, 58, -170, -170, 58, 58, 58, 58,
1604 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1605 58, 58, 58, 58, 58, 187, 58, -170
1606 },
1607
1608 {
1609 11, -171, -171, -171, -171, -171, -171, -171, -171, -171,
1610 -171, -171, -171, 58, -171, -171, 58, 58, 58, 58,
1611 58, 58, 58, 58, 58, 58, 58, 58, 188, 58,
1612 58, 58, 58, 58, 58, 58, 58, -171
1613 },
1614
1615 {
1616 11, -172, -172, -172, -172, -172, -172, -172, -172, -172,
1617 -172, -172, -172, 58, -172, -172, 58, 58, 58, 58,
1618
1619 58, 58, 58, 58, 58, 58, 58, 58, 189, 58,
1620 58, 58, 58, 58, 58, 58, 58, -172
1621 },
1622
1623 {
1624 11, -173, -173, -173, -173, -173, -173, -173, -173, -173,
1625 -173, -173, -173, 58, -173, -173, 58, 190, 58, 58,
1626 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1627 58, 58, 58, 58, 58, 58, 58, -173
1628 },
1629
1630 {
1631 11, -174, -174, -174, -174, -174, -174, -174, -174, -174,
1632 -174, -174, -174, 58, -174, -174, 58, 58, 58, 58,
1633 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1634 58, 58, 58, 58, 58, 58, 58, -174
1635
1636 },
1637
1638 {
1639 11, -175, -175, -175, -175, -175, -175, -175, -175, -175,
1640 -175, -175, -175, 58, -175, -175, 58, 58, 58, 58,
1641 58, 191, 58, 58, 58, 58, 58, 58, 58, 58,
1642 58, 58, 58, 58, 58, 58, 58, -175
1643 },
1644
1645 {
1646 11, -176, -176, -176, -176, -176, -176, -176, -176, -176,
1647 -176, -176, -176, 58, -176, -176, 58, 58, 58, 58,
1648 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1649 58, 58, 58, 58, 58, 58, 58, -176
1650 },
1651
1652 {
1653 11, -177, -177, -177, -177, -177, -177, -177, -177, -177,
1654 -177, -177, -177, 58, -177, -177, 58, 58, 58, 58,
1655
1656 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1657 58, 58, 58, 58, 58, 58, 58, -177
1658 },
1659
1660 {
1661 11, -178, -178, -178, -178, -178, -178, -178, -178, -178,
1662 -178, -178, -178, 58, -178, -178, 58, 58, 58, 58,
1663 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1664 58, 58, 58, 58, 58, 58, 58, -178
1665 },
1666
1667 {
1668 11, -179, -179, -179, -179, -179, -179, -179, -179, -179,
1669 -179, -179, -179, 58, -179, -179, 58, 58, 58, 58,
1670 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1671 58, 58, 58, 58, 192, 58, 58, -179
1672
1673 },
1674
1675 {
1676 11, -180, -180, -180, -180, -180, -180, -180, -180, -180,
1677 -180, -180, -180, 58, -180, -180, 58, 58, 58, 58,
1678 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1679 58, 58, 58, 58, 58, 58, 58, -180
1680 },
1681
1682 {
1683 11, -181, -181, -181, -181, -181, -181, -181, -181, -181,
1684 -181, -181, -181, 58, -181, -181, 58, 58, 58, 58,
1685 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1686 58, 58, 58, 58, 58, 58, 58, -181
1687 },
1688
1689 {
1690 11, -182, -182, -182, -182, -182, -182, -182, -182, -182,
1691 -182, -182, -182, 58, -182, -182, 58, 58, 58, 58,
1692
1693 58, 58, 58, 58, 58, 58, 193, 58, 58, 58,
1694 58, 58, 58, 58, 58, 58, 58, -182
1695 },
1696
1697 {
1698 11, -183, -183, -183, -183, -183, -183, -183, -183, -183,
1699 -183, -183, -183, 58, -183, -183, 58, 58, 58, 58,
1700 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1701 58, 58, 58, 194, 58, 58, 58, -183
1702 },
1703
1704 {
1705 11, -184, -184, -184, -184, -184, -184, -184, -184, -184,
1706 -184, -184, -184, 58, -184, -184, 58, 58, 58, 58,
1707 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1708 58, 58, 58, 58, 58, 58, 58, -184
1709
1710 },
1711
1712 {
1713 11, -185, -185, -185, -185, -185, -185, -185, -185, -185,
1714 -185, -185, -185, 58, -185, -185, 58, 58, 58, 58,
1715 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1716 58, 58, 58, 58, 58, 58, 58, -185
1717 },
1718
1719 {
1720 11, -186, -186, -186, -186, -186, -186, -186, -186, -186,
1721 -186, -186, -186, 58, -186, -186, 58, 58, 58, 195,
1722 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1723 58, 58, 58, 58, 58, 58, 58, -186
1724 },
1725
1726 {
1727 11, -187, -187, -187, -187, -187, -187, -187, -187, -187,
1728 -187, -187, -187, 58, -187, -187, 58, 58, 58, 58,
1729
1730 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1731 58, 58, 58, 58, 58, 58, 58, -187
1732 },
1733
1734 {
1735 11, -188, -188, -188, -188, -188, -188, -188, -188, -188,
1736 -188, -188, -188, 58, -188, -188, 58, 58, 58, 58,
1737 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1738 58, 58, 58, 58, 58, 196, 58, -188
1739 },
1740
1741 {
1742 11, -189, -189, -189, -189, -189, -189, -189, -189, -189,
1743 -189, -189, -189, 58, -189, -189, 58, 58, 58, 58,
1744 58, 58, 197, 58, 58, 58, 58, 58, 58, 58,
1745 58, 58, 58, 58, 58, 58, 58, -189
1746
1747 },
1748
1749 {
1750 11, -190, -190, -190, -190, -190, -190, -190, -190, -190,
1751 -190, -190, -190, 58, -190, -190, 58, 58, 58, 58,
1752 58, 58, 58, 58, 58, 58, 198, 58, 58, 58,
1753 58, 58, 58, 58, 58, 58, 58, -190
1754 },
1755
1756 {
1757 11, -191, -191, -191, -191, -191, -191, -191, -191, -191,
1758 -191, -191, -191, 58, -191, -191, 58, 58, 58, 58,
1759 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1760 58, 58, 58, 199, 58, 58, 58, -191
1761 },
1762
1763 {
1764 11, -192, -192, -192, -192, -192, -192, -192, -192, -192,
1765 -192, -192, -192, 58, -192, -192, 58, 58, 58, 58,
1766
1767 58, 200, 58, 58, 58, 58, 58, 58, 58, 58,
1768 58, 58, 58, 58, 58, 58, 58, -192
1769 },
1770
1771 {
1772 11, -193, -193, -193, -193, -193, -193, -193, -193, -193,
1773 -193, -193, -193, 58, -193, -193, 58, 58, 58, 58,
1774 58, 201, 58, 58, 58, 58, 58, 58, 58, 58,
1775 58, 58, 58, 58, 58, 58, 58, -193
1776 },
1777
1778 {
1779 11, -194, -194, -194, -194, -194, -194, -194, -194, -194,
1780 -194, -194, -194, 58, -194, -194, 58, 58, 58, 58,
1781 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1782 58, 58, 58, 58, 202, 58, 58, -194
1783
1784 },
1785
1786 {
1787 11, -195, -195, -195, -195, -195, -195, -195, -195, -195,
1788 -195, -195, -195, 58, -195, -195, 58, 58, 58, 58,
1789 58, 203, 58, 58, 58, 58, 58, 58, 58, 58,
1790 58, 58, 58, 58, 58, 58, 58, -195
1791 },
1792
1793 {
1794 11, -196, -196, -196, -196, -196, -196, -196, -196, -196,
1795 -196, -196, -196, 58, -196, -196, 58, 58, 58, 58,
1796 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1797 58, 58, 58, 58, 58, 58, 58, -196
1798 },
1799
1800 {
1801 11, -197, -197, -197, -197, -197, -197, -197, -197, -197,
1802 -197, -197, -197, 58, -197, -197, 58, 58, 58, 58,
1803
1804 58, 58, 58, 58, 58, 204, 58, 58, 58, 58,
1805 58, 58, 58, 58, 58, 58, 58, -197
1806 },
1807
1808 {
1809 11, -198, -198, -198, -198, -198, -198, -198, -198, -198,
1810 -198, -198, -198, 58, -198, -198, 58, 58, 58, 58,
1811 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1812 58, 58, 58, 58, 58, 58, 58, -198
1813 },
1814
1815 {
1816 11, -199, -199, -199, -199, -199, -199, -199, -199, -199,
1817 -199, -199, -199, 58, -199, -199, 58, 58, 58, 58,
1818 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1819 58, 58, 58, 58, 58, 58, 58, -199
1820
1821 },
1822
1823 {
1824 11, -200, -200, -200, -200, -200, -200, -200, -200, -200,
1825 -200, -200, -200, 58, -200, -200, 58, 58, 58, 58,
1826 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1827 58, 58, 58, 58, 58, 58, 58, -200
1828 },
1829
1830 {
1831 11, -201, -201, -201, -201, -201, -201, -201, -201, -201,
1832 -201, -201, -201, 58, -201, -201, 58, 205, 58, 58,
1833 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1834 58, 58, 58, 58, 58, 58, 58, -201
1835 },
1836
1837 {
1838 11, -202, -202, -202, -202, -202, -202, -202, -202, -202,
1839 -202, -202, -202, 58, -202, -202, 58, 206, 58, 58,
1840
1841 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1842 58, 58, 58, 58, 58, 58, 58, -202
1843 },
1844
1845 {
1846 11, -203, -203, -203, -203, -203, -203, -203, -203, -203,
1847 -203, -203, -203, 58, -203, -203, 58, 58, 58, 58,
1848 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1849 58, 58, 58, 58, 58, 58, 58, -203
1850 },
1851
1852 {
1853 11, -204, -204, -204, -204, -204, -204, -204, -204, -204,
1854 -204, -204, -204, 58, -204, -204, 58, 58, 58, 58,
1855 58, 58, 58, 207, 58, 58, 58, 58, 58, 58,
1856 58, 58, 58, 58, 58, 58, 58, -204
1857
1858 },
1859
1860 {
1861 11, -205, -205, -205, -205, -205, -205, -205, -205, -205,
1862 -205, -205, -205, 58, -205, -205, 58, 58, 58, 58,
1863 58, 58, 58, 58, 58, 58, 58, 58, 208, 58,
1864 58, 58, 58, 58, 58, 58, 58, -205
1865 },
1866
1867 {
1868 11, -206, -206, -206, -206, -206, -206, -206, -206, -206,
1869 -206, -206, -206, 58, -206, -206, 58, 58, 58, 58,
1870 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1871 58, 58, 58, 58, 209, 58, 58, -206
1872 },
1873
1874 {
1875 11, -207, -207, -207, -207, -207, -207, -207, -207, -207,
1876 -207, -207, -207, 58, -207, -207, 58, 58, 58, 58,
1877
1878 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1879 58, 58, 58, 58, 58, 58, 58, -207
1880 },
1881
1882 {
1883 11, -208, -208, -208, -208, -208, -208, -208, -208, -208,
1884 -208, -208, -208, 58, -208, -208, 58, 58, 58, 58,
1885 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1886 58, 58, 58, 58, 58, 58, 58, -208
1887 },
1888
1889 {
1890 11, -209, -209, -209, -209, -209, -209, -209, -209, -209,
1891 -209, -209, -209, 58, -209, -209, 58, 58, 58, 58,
1892 58, 210, 58, 58, 58, 58, 58, 58, 58, 58,
1893 58, 58, 58, 58, 58, 58, 58, -209
1894
1895 },
1896
1897 {
1898 11, -210, -210, -210, -210, -210, -210, -210, -210, -210,
1899 -210, -210, -210, 58, -210, -210, 58, 58, 58, 58,
1900 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1901 58, 58, 58, 58, 58, 58, 58, -210
1902 }, 658 },
1903 659
1904 } ; 660 } ;
@@ -1918,8 +674,8 @@ static void yy_fatal_error (yyconst char msg[] );
1918 *yy_cp = '\0'; \ 674 *yy_cp = '\0'; \
1919 (yy_c_buf_p) = yy_cp; 675 (yy_c_buf_p) = yy_cp;
1920 676
1921#define YY_NUM_RULES 64 677#define YY_NUM_RULES 33
1922#define YY_END_OF_BUFFER 65 678#define YY_END_OF_BUFFER 34
1923/* This struct is not used in this scanner, 679/* This struct is not used in this scanner,
1924 but its presence is necessary. */ 680 but its presence is necessary. */
1925struct yy_trans_info 681struct yy_trans_info
@@ -1927,31 +683,14 @@ struct yy_trans_info
1927 flex_int32_t yy_verify; 683 flex_int32_t yy_verify;
1928 flex_int32_t yy_nxt; 684 flex_int32_t yy_nxt;
1929 }; 685 };
1930static yyconst flex_int16_t yy_accept[211] = 686static yyconst flex_int16_t yy_accept[61] =
1931 { 0, 687 { 0,
1932 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 688 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1933 65, 5, 4, 3, 2, 36, 37, 35, 35, 35, 689 34, 5, 4, 2, 3, 7, 8, 6, 32, 29,
1934 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 690 31, 24, 28, 27, 26, 22, 17, 13, 16, 20,
1935 63, 60, 62, 55, 59, 58, 57, 53, 48, 42, 691 22, 11, 12, 19, 19, 14, 22, 22, 4, 2,
1936 47, 51, 53, 40, 41, 50, 50, 43, 53, 50, 692 3, 3, 1, 6, 32, 29, 31, 30, 24, 23,
1937 50, 53, 4, 3, 2, 2, 1, 35, 35, 35, 693 26, 25, 15, 20, 9, 19, 19, 21, 10, 18
1938 35, 35, 35, 35, 16, 35, 35, 35, 35, 35,
1939 35, 35, 35, 35, 35, 35, 63, 60, 62, 61,
1940 55, 54, 57, 56, 44, 51, 38, 50, 50, 52,
1941 45, 46, 39, 35, 35, 35, 35, 35, 35, 35,
1942
1943 35, 35, 30, 29, 35, 35, 35, 35, 35, 35,
1944 35, 35, 35, 35, 49, 25, 35, 35, 35, 35,
1945 35, 35, 35, 35, 35, 35, 15, 35, 7, 35,
1946 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
1947 35, 35, 35, 35, 35, 35, 35, 17, 35, 35,
1948 35, 35, 35, 34, 35, 35, 35, 35, 35, 35,
1949 10, 35, 13, 35, 35, 35, 35, 33, 35, 35,
1950 35, 35, 35, 22, 35, 32, 9, 31, 35, 26,
1951 12, 35, 35, 21, 18, 35, 8, 35, 35, 35,
1952 35, 35, 27, 35, 35, 6, 35, 20, 19, 23,
1953
1954 35, 35, 11, 35, 35, 35, 14, 28, 35, 24
1955 } ; 694 } ;
1956 695
1957static yyconst flex_int32_t yy_ec[256] = 696static yyconst flex_int32_t yy_ec[256] =
@@ -1965,11 +704,11 @@ static yyconst flex_int32_t yy_ec[256] =
1965 14, 1, 1, 1, 13, 13, 13, 13, 13, 13, 704 14, 1, 1, 1, 13, 13, 13, 13, 13, 13,
1966 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 705 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1967 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 706 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1968 1, 15, 1, 1, 16, 1, 17, 18, 19, 20, 707 1, 15, 1, 1, 13, 1, 13, 13, 13, 13,
1969 708
1970 21, 22, 23, 24, 25, 13, 13, 26, 27, 28, 709 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1971 29, 30, 31, 32, 33, 34, 35, 13, 13, 36, 710 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1972 13, 13, 1, 37, 1, 1, 1, 1, 1, 1, 711 13, 13, 1, 16, 1, 1, 1, 1, 1, 1,
1973 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 712 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1974 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 713 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1975 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 714 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -2014,8 +753,12 @@ char *zconftext;
2014 753
2015#define START_STRSIZE 16 754#define START_STRSIZE 16
2016 755
2017char *text; 756static struct {
2018static char *text_ptr; 757 struct file *file;
758 int lineno;
759} current_pos;
760
761static char *text;
2019static int text_size, text_asize; 762static int text_size, text_asize;
2020 763
2021struct buffer { 764struct buffer {
@@ -2028,29 +771,28 @@ struct buffer *current_buf;
2028static int last_ts, first_ts; 771static int last_ts, first_ts;
2029 772
2030static void zconf_endhelp(void); 773static void zconf_endhelp(void);
2031static struct buffer *zconf_endfile(void); 774static void zconf_endfile(void);
2032 775
2033void new_string(void) 776void new_string(void)
2034{ 777{
2035 text = malloc(START_STRSIZE); 778 text = malloc(START_STRSIZE);
2036 text_asize = START_STRSIZE; 779 text_asize = START_STRSIZE;
2037 text_ptr = text;
2038 text_size = 0; 780 text_size = 0;
2039 *text_ptr = 0; 781 *text = 0;
2040} 782}
2041 783
2042void append_string(const char *str, int size) 784void append_string(const char *str, int size)
2043{ 785{
2044 int new_size = text_size + size + 1; 786 int new_size = text_size + size + 1;
2045 if (new_size > text_asize) { 787 if (new_size > text_asize) {
788 new_size += START_STRSIZE - 1;
789 new_size &= -START_STRSIZE;
2046 text = realloc(text, new_size); 790 text = realloc(text, new_size);
2047 text_asize = new_size; 791 text_asize = new_size;
2048 text_ptr = text + text_size;
2049 } 792 }
2050 memcpy(text_ptr, str, size); 793 memcpy(text + text_size, str, size);
2051 text_ptr += size;
2052 text_size += size; 794 text_size += size;
2053 *text_ptr = 0; 795 text[text_size] = 0;
2054} 796}
2055 797
2056void alloc_string(const char *str, int size) 798void alloc_string(const char *str, int size)
@@ -2066,11 +808,13 @@ void alloc_string(const char *str, int size)
2066#define STRING 3 808#define STRING 3
2067#define PARAM 4 809#define PARAM 4
2068 810
811#ifndef YY_NO_UNISTD_H
2069/* Special case for "unistd.h", since it is non-ANSI. We include it way 812/* Special case for "unistd.h", since it is non-ANSI. We include it way
2070 * down here because we want the user's section 1 to have been scanned first. 813 * down here because we want the user's section 1 to have been scanned first.
2071 * The user has a chance to override it with an option. 814 * The user has a chance to override it with an option.
2072 */ 815 */
2073#include <unistd.h> 816#include <unistd.h>
817#endif
2074 818
2075#ifndef YY_EXTRA_TYPE 819#ifndef YY_EXTRA_TYPE
2076#define YY_EXTRA_TYPE void * 820#define YY_EXTRA_TYPE void *
@@ -2254,17 +998,17 @@ do_action: /* This label is used only to access EOF actions. */
2254 { /* beginning of action switch */ 998 { /* beginning of action switch */
2255case 1: 999case 1:
2256/* rule 1 can match eol */ 1000/* rule 1 can match eol */
2257YY_RULE_SETUP
2258current_file->lineno++;
2259 YY_BREAK
2260case 2: 1001case 2:
1002/* rule 2 can match eol */
2261YY_RULE_SETUP 1003YY_RULE_SETUP
2262 1004{
1005 current_file->lineno++;
1006 return T_EOL;
1007}
2263 YY_BREAK 1008 YY_BREAK
2264case 3: 1009case 3:
2265/* rule 3 can match eol */
2266YY_RULE_SETUP 1010YY_RULE_SETUP
2267current_file->lineno++; return T_EOL; 1011
2268 YY_BREAK 1012 YY_BREAK
2269case 4: 1013case 4:
2270YY_RULE_SETUP 1014YY_RULE_SETUP
@@ -2282,175 +1026,63 @@ YY_RULE_SETUP
2282 1026
2283case 6: 1027case 6:
2284YY_RULE_SETUP 1028YY_RULE_SETUP
2285BEGIN(PARAM); return T_MAINMENU;
2286 YY_BREAK
2287case 7:
2288YY_RULE_SETUP
2289BEGIN(PARAM); return T_MENU;
2290 YY_BREAK
2291case 8:
2292YY_RULE_SETUP
2293BEGIN(PARAM); return T_ENDMENU;
2294 YY_BREAK
2295case 9:
2296YY_RULE_SETUP
2297BEGIN(PARAM); return T_SOURCE;
2298 YY_BREAK
2299case 10:
2300YY_RULE_SETUP
2301BEGIN(PARAM); return T_CHOICE;
2302 YY_BREAK
2303case 11:
2304YY_RULE_SETUP
2305BEGIN(PARAM); return T_ENDCHOICE;
2306 YY_BREAK
2307case 12:
2308YY_RULE_SETUP
2309BEGIN(PARAM); return T_COMMENT;
2310 YY_BREAK
2311case 13:
2312YY_RULE_SETUP
2313BEGIN(PARAM); return T_CONFIG;
2314 YY_BREAK
2315case 14:
2316YY_RULE_SETUP
2317BEGIN(PARAM); return T_MENUCONFIG;
2318 YY_BREAK
2319case 15:
2320YY_RULE_SETUP
2321BEGIN(PARAM); return T_HELP;
2322 YY_BREAK
2323case 16:
2324YY_RULE_SETUP
2325BEGIN(PARAM); return T_IF;
2326 YY_BREAK
2327case 17:
2328YY_RULE_SETUP
2329BEGIN(PARAM); return T_ENDIF;
2330 YY_BREAK
2331case 18:
2332YY_RULE_SETUP
2333BEGIN(PARAM); return T_DEPENDS;
2334 YY_BREAK
2335case 19:
2336YY_RULE_SETUP
2337BEGIN(PARAM); return T_REQUIRES;
2338 YY_BREAK
2339case 20:
2340YY_RULE_SETUP
2341BEGIN(PARAM); return T_OPTIONAL;
2342 YY_BREAK
2343case 21:
2344YY_RULE_SETUP
2345BEGIN(PARAM); return T_DEFAULT;
2346 YY_BREAK
2347case 22:
2348YY_RULE_SETUP
2349BEGIN(PARAM); return T_PROMPT;
2350 YY_BREAK
2351case 23:
2352YY_RULE_SETUP
2353BEGIN(PARAM); return T_TRISTATE;
2354 YY_BREAK
2355case 24:
2356YY_RULE_SETUP
2357BEGIN(PARAM); return T_DEF_TRISTATE;
2358 YY_BREAK
2359case 25:
2360YY_RULE_SETUP
2361BEGIN(PARAM); return T_BOOLEAN;
2362 YY_BREAK
2363case 26:
2364YY_RULE_SETUP
2365BEGIN(PARAM); return T_BOOLEAN;
2366 YY_BREAK
2367case 27:
2368YY_RULE_SETUP
2369BEGIN(PARAM); return T_DEF_BOOLEAN;
2370 YY_BREAK
2371case 28:
2372YY_RULE_SETUP
2373BEGIN(PARAM); return T_DEF_BOOLEAN;
2374 YY_BREAK
2375case 29:
2376YY_RULE_SETUP
2377BEGIN(PARAM); return T_INT;
2378 YY_BREAK
2379case 30:
2380YY_RULE_SETUP
2381BEGIN(PARAM); return T_HEX;
2382 YY_BREAK
2383case 31:
2384YY_RULE_SETUP
2385BEGIN(PARAM); return T_STRING;
2386 YY_BREAK
2387case 32:
2388YY_RULE_SETUP
2389BEGIN(PARAM); return T_SELECT;
2390 YY_BREAK
2391case 33:
2392YY_RULE_SETUP
2393BEGIN(PARAM); return T_SELECT;
2394 YY_BREAK
2395case 34:
2396YY_RULE_SETUP
2397BEGIN(PARAM); return T_RANGE;
2398 YY_BREAK
2399case 35:
2400YY_RULE_SETUP
2401{ 1029{
1030 struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
1031 BEGIN(PARAM);
1032 current_pos.file = current_file;
1033 current_pos.lineno = current_file->lineno;
1034 if (id && id->flags & TF_COMMAND) {
1035 zconflval.id = id;
1036 return id->token;
1037 }
2402 alloc_string(zconftext, zconfleng); 1038 alloc_string(zconftext, zconfleng);
2403 zconflval.string = text; 1039 zconflval.string = text;
2404 return T_WORD; 1040 return T_WORD;
2405 } 1041 }
2406 YY_BREAK 1042 YY_BREAK
2407case 36: 1043case 7:
2408YY_RULE_SETUP 1044YY_RULE_SETUP
2409 1045
2410 YY_BREAK 1046 YY_BREAK
2411case 37: 1047case 8:
2412/* rule 37 can match eol */ 1048/* rule 8 can match eol */
2413YY_RULE_SETUP 1049YY_RULE_SETUP
2414current_file->lineno++; BEGIN(INITIAL); 1050{
1051 BEGIN(INITIAL);
1052 current_file->lineno++;
1053 return T_EOL;
1054 }
2415 YY_BREAK 1055 YY_BREAK
2416 1056
2417case 38: 1057case 9:
2418YY_RULE_SETUP 1058YY_RULE_SETUP
2419return T_AND; 1059return T_AND;
2420 YY_BREAK 1060 YY_BREAK
2421case 39: 1061case 10:
2422YY_RULE_SETUP 1062YY_RULE_SETUP
2423return T_OR; 1063return T_OR;
2424 YY_BREAK 1064 YY_BREAK
2425case 40: 1065case 11:
2426YY_RULE_SETUP 1066YY_RULE_SETUP
2427return T_OPEN_PAREN; 1067return T_OPEN_PAREN;
2428 YY_BREAK 1068 YY_BREAK
2429case 41: 1069case 12:
2430YY_RULE_SETUP 1070YY_RULE_SETUP
2431return T_CLOSE_PAREN; 1071return T_CLOSE_PAREN;
2432 YY_BREAK 1072 YY_BREAK
2433case 42: 1073case 13:
2434YY_RULE_SETUP 1074YY_RULE_SETUP
2435return T_NOT; 1075return T_NOT;
2436 YY_BREAK 1076 YY_BREAK
2437case 43: 1077case 14:
2438YY_RULE_SETUP 1078YY_RULE_SETUP
2439return T_EQUAL; 1079return T_EQUAL;
2440 YY_BREAK 1080 YY_BREAK
2441case 44: 1081case 15:
2442YY_RULE_SETUP 1082YY_RULE_SETUP
2443return T_UNEQUAL; 1083return T_UNEQUAL;
2444 YY_BREAK 1084 YY_BREAK
2445case 45: 1085case 16:
2446YY_RULE_SETUP
2447return T_IF;
2448 YY_BREAK
2449case 46:
2450YY_RULE_SETUP
2451return T_ON;
2452 YY_BREAK
2453case 47:
2454YY_RULE_SETUP 1086YY_RULE_SETUP
2455{ 1087{
2456 str = zconftext[0]; 1088 str = zconftext[0];
@@ -2458,33 +1090,38 @@ YY_RULE_SETUP
2458 BEGIN(STRING); 1090 BEGIN(STRING);
2459 } 1091 }
2460 YY_BREAK 1092 YY_BREAK
2461case 48: 1093case 17:
2462/* rule 48 can match eol */ 1094/* rule 17 can match eol */
2463YY_RULE_SETUP 1095YY_RULE_SETUP
2464BEGIN(INITIAL); current_file->lineno++; return T_EOL; 1096BEGIN(INITIAL); current_file->lineno++; return T_EOL;
2465 YY_BREAK 1097 YY_BREAK
2466case 49: 1098case 18:
2467YY_RULE_SETUP 1099YY_RULE_SETUP
2468/* ignore */ 1100/* ignore */
2469 YY_BREAK 1101 YY_BREAK
2470case 50: 1102case 19:
2471YY_RULE_SETUP 1103YY_RULE_SETUP
2472{ 1104{
1105 struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
1106 if (id && id->flags & TF_PARAM) {
1107 zconflval.id = id;
1108 return id->token;
1109 }
2473 alloc_string(zconftext, zconfleng); 1110 alloc_string(zconftext, zconfleng);
2474 zconflval.string = text; 1111 zconflval.string = text;
2475 return T_WORD; 1112 return T_WORD;
2476 } 1113 }
2477 YY_BREAK 1114 YY_BREAK
2478case 51: 1115case 20:
2479YY_RULE_SETUP 1116YY_RULE_SETUP
2480/* comment */ 1117/* comment */
2481 YY_BREAK 1118 YY_BREAK
2482case 52: 1119case 21:
2483/* rule 52 can match eol */ 1120/* rule 21 can match eol */
2484YY_RULE_SETUP 1121YY_RULE_SETUP
2485current_file->lineno++; 1122current_file->lineno++;
2486 YY_BREAK 1123 YY_BREAK
2487case 53: 1124case 22:
2488YY_RULE_SETUP 1125YY_RULE_SETUP
2489 1126
2490 YY_BREAK 1127 YY_BREAK
@@ -2494,8 +1131,8 @@ case YY_STATE_EOF(PARAM):
2494 } 1131 }
2495 YY_BREAK 1132 YY_BREAK
2496 1133
2497case 54: 1134case 23:
2498/* rule 54 can match eol */ 1135/* rule 23 can match eol */
2499*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ 1136*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
2500(yy_c_buf_p) = yy_cp -= 1; 1137(yy_c_buf_p) = yy_cp -= 1;
2501YY_DO_BEFORE_ACTION; /* set up zconftext again */ 1138YY_DO_BEFORE_ACTION; /* set up zconftext again */
@@ -2506,14 +1143,14 @@ YY_RULE_SETUP
2506 return T_WORD_QUOTE; 1143 return T_WORD_QUOTE;
2507 } 1144 }
2508 YY_BREAK 1145 YY_BREAK
2509case 55: 1146case 24:
2510YY_RULE_SETUP 1147YY_RULE_SETUP
2511{ 1148{
2512 append_string(zconftext, zconfleng); 1149 append_string(zconftext, zconfleng);
2513 } 1150 }
2514 YY_BREAK 1151 YY_BREAK
2515case 56: 1152case 25:
2516/* rule 56 can match eol */ 1153/* rule 25 can match eol */
2517*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ 1154*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
2518(yy_c_buf_p) = yy_cp -= 1; 1155(yy_c_buf_p) = yy_cp -= 1;
2519YY_DO_BEFORE_ACTION; /* set up zconftext again */ 1156YY_DO_BEFORE_ACTION; /* set up zconftext again */
@@ -2524,13 +1161,13 @@ YY_RULE_SETUP
2524 return T_WORD_QUOTE; 1161 return T_WORD_QUOTE;
2525 } 1162 }
2526 YY_BREAK 1163 YY_BREAK
2527case 57: 1164case 26:
2528YY_RULE_SETUP 1165YY_RULE_SETUP
2529{ 1166{
2530 append_string(zconftext + 1, zconfleng - 1); 1167 append_string(zconftext + 1, zconfleng - 1);
2531 } 1168 }
2532 YY_BREAK 1169 YY_BREAK
2533case 58: 1170case 27:
2534YY_RULE_SETUP 1171YY_RULE_SETUP
2535{ 1172{
2536 if (str == zconftext[0]) { 1173 if (str == zconftext[0]) {
@@ -2541,8 +1178,8 @@ YY_RULE_SETUP
2541 append_string(zconftext, 1); 1178 append_string(zconftext, 1);
2542 } 1179 }
2543 YY_BREAK 1180 YY_BREAK
2544case 59: 1181case 28:
2545/* rule 59 can match eol */ 1182/* rule 28 can match eol */
2546YY_RULE_SETUP 1183YY_RULE_SETUP
2547{ 1184{
2548 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); 1185 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
@@ -2557,7 +1194,7 @@ case YY_STATE_EOF(STRING):
2557 } 1194 }
2558 YY_BREAK 1195 YY_BREAK
2559 1196
2560case 60: 1197case 29:
2561YY_RULE_SETUP 1198YY_RULE_SETUP
2562{ 1199{
2563 ts = 0; 1200 ts = 0;
@@ -2582,8 +1219,8 @@ YY_RULE_SETUP
2582 } 1219 }
2583 } 1220 }
2584 YY_BREAK 1221 YY_BREAK
2585case 61: 1222case 30:
2586/* rule 61 can match eol */ 1223/* rule 30 can match eol */
2587*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ 1224*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
2588(yy_c_buf_p) = yy_cp -= 1; 1225(yy_c_buf_p) = yy_cp -= 1;
2589YY_DO_BEFORE_ACTION; /* set up zconftext again */ 1226YY_DO_BEFORE_ACTION; /* set up zconftext again */
@@ -2594,15 +1231,15 @@ YY_RULE_SETUP
2594 return T_HELPTEXT; 1231 return T_HELPTEXT;
2595 } 1232 }
2596 YY_BREAK 1233 YY_BREAK
2597case 62: 1234case 31:
2598/* rule 62 can match eol */ 1235/* rule 31 can match eol */
2599YY_RULE_SETUP 1236YY_RULE_SETUP
2600{ 1237{
2601 current_file->lineno++; 1238 current_file->lineno++;
2602 append_string("\n", 1); 1239 append_string("\n", 1);
2603 } 1240 }
2604 YY_BREAK 1241 YY_BREAK
2605case 63: 1242case 32:
2606YY_RULE_SETUP 1243YY_RULE_SETUP
2607{ 1244{
2608 append_string(zconftext, zconfleng); 1245 append_string(zconftext, zconfleng);
@@ -2620,15 +1257,15 @@ case YY_STATE_EOF(HELP):
2620case YY_STATE_EOF(INITIAL): 1257case YY_STATE_EOF(INITIAL):
2621case YY_STATE_EOF(COMMAND): 1258case YY_STATE_EOF(COMMAND):
2622{ 1259{
2623 if (current_buf) { 1260 if (current_file) {
2624 zconf_endfile(); 1261 zconf_endfile();
2625 return T_EOF; 1262 return T_EOL;
2626 } 1263 }
2627 fclose(zconfin); 1264 fclose(zconfin);
2628 yyterminate(); 1265 yyterminate();
2629} 1266}
2630 YY_BREAK 1267 YY_BREAK
2631case 64: 1268case 33:
2632YY_RULE_SETUP 1269YY_RULE_SETUP
2633YY_FATAL_ERROR( "flex scanner jammed" ); 1270YY_FATAL_ERROR( "flex scanner jammed" );
2634 YY_BREAK 1271 YY_BREAK
@@ -3332,16 +1969,16 @@ YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
3332 1969
3333/** Setup the input buffer state to scan a string. The next call to zconflex() will 1970/** Setup the input buffer state to scan a string. The next call to zconflex() will
3334 * scan from a @e copy of @a str. 1971 * scan from a @e copy of @a str.
3335 * @param str a NUL-terminated string to scan 1972 * @param yy_str a NUL-terminated string to scan
3336 * 1973 *
3337 * @return the newly allocated buffer state object. 1974 * @return the newly allocated buffer state object.
3338 * @note If you want to scan bytes that may contain NUL values, then use 1975 * @note If you want to scan bytes that may contain NUL values, then use
3339 * zconf_scan_bytes() instead. 1976 * zconf_scan_bytes() instead.
3340 */ 1977 */
3341YY_BUFFER_STATE zconf_scan_string (yyconst char * str ) 1978YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str )
3342{ 1979{
3343 1980
3344 return zconf_scan_bytes(str,strlen(str) ); 1981 return zconf_scan_bytes(yy_str,strlen(yy_str) );
3345} 1982}
3346 1983
3347/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will 1984/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
@@ -3650,7 +2287,7 @@ void zconf_nextfile(const char *name)
3650 current_file = file; 2287 current_file = file;
3651} 2288}
3652 2289
3653static struct buffer *zconf_endfile(void) 2290static void zconf_endfile(void)
3654{ 2291{
3655 struct buffer *parent; 2292 struct buffer *parent;
3656 2293
@@ -3666,23 +2303,15 @@ static struct buffer *zconf_endfile(void)
3666 } 2303 }
3667 free(current_buf); 2304 free(current_buf);
3668 current_buf = parent; 2305 current_buf = parent;
3669
3670 return parent;
3671} 2306}
3672 2307
3673int zconf_lineno(void) 2308int zconf_lineno(void)
3674{ 2309{
3675 if (current_buf) 2310 return current_pos.lineno;
3676 return current_file->lineno - 1;
3677 else
3678 return 0;
3679} 2311}
3680 2312
3681char *zconf_curname(void) 2313char *zconf_curname(void)
3682{ 2314{
3683 if (current_buf) 2315 return current_pos.file ? current_pos.file->name : "<none>";
3684 return current_file->name;
3685 else
3686 return "<none>";
3687} 2316}
3688 2317
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 5fba1feff2a8..527f60c99c50 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -37,6 +37,17 @@ extern "C" {
37#define _(text) gettext(text) 37#define _(text) gettext(text)
38#define N_(text) (text) 38#define N_(text) (text)
39 39
40
41#define TF_COMMAND 0x0001
42#define TF_PARAM 0x0002
43
44struct kconf_id {
45 int name;
46 int token;
47 unsigned int flags;
48 enum symbol_type stype;
49};
50
40int zconfparse(void); 51int zconfparse(void);
41void zconfdump(FILE *out); 52void zconfdump(FILE *out);
42 53
@@ -50,7 +61,6 @@ char *zconf_curname(void);
50 61
51/* confdata.c */ 62/* confdata.c */
52extern const char conf_def_filename[]; 63extern const char conf_def_filename[];
53extern char conf_filename[];
54 64
55char *conf_get_default_confname(void); 65char *conf_get_default_confname(void);
56 66
@@ -59,7 +69,7 @@ void kconfig_load(void);
59 69
60/* menu.c */ 70/* menu.c */
61void menu_init(void); 71void menu_init(void);
62void menu_add_menu(void); 72struct menu *menu_add_menu(void);
63void menu_end_menu(void); 73void menu_end_menu(void);
64void menu_add_entry(struct symbol *sym); 74void menu_add_entry(struct symbol *sym);
65void menu_end_entry(void); 75void menu_end_entry(void);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 6dc6d0c48e7a..b6a389c5fcbd 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -2,6 +2,7 @@
2/* confdata.c */ 2/* confdata.c */
3P(conf_parse,void,(const char *name)); 3P(conf_parse,void,(const char *name));
4P(conf_read,int,(const char *name)); 4P(conf_read,int,(const char *name));
5P(conf_read_simple,int,(const char *name));
5P(conf_write,int,(const char *name)); 6P(conf_write,int,(const char *name));
6 7
7/* menu.c */ 8/* menu.c */
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 5cfa6c405cf0..0fce20cb7f3c 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -61,10 +61,11 @@ void menu_end_entry(void)
61{ 61{
62} 62}
63 63
64void menu_add_menu(void) 64struct menu *menu_add_menu(void)
65{ 65{
66 current_menu = current_entry; 66 menu_end_entry();
67 last_entry_ptr = &current_entry->list; 67 last_entry_ptr = &current_entry->list;
68 return current_menu = current_entry;
68} 69}
69 70
70void menu_end_menu(void) 71void menu_end_menu(void)
@@ -151,6 +152,12 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
151 menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); 152 menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
152} 153}
153 154
155static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2)
156{
157 return sym2->type == S_INT || sym2->type == S_HEX ||
158 (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
159}
160
154void sym_check_prop(struct symbol *sym) 161void sym_check_prop(struct symbol *sym)
155{ 162{
156 struct property *prop; 163 struct property *prop;
@@ -185,8 +192,8 @@ void sym_check_prop(struct symbol *sym)
185 if (sym->type != S_INT && sym->type != S_HEX) 192 if (sym->type != S_INT && sym->type != S_HEX)
186 prop_warn(prop, "range is only allowed " 193 prop_warn(prop, "range is only allowed "
187 "for int or hex symbols"); 194 "for int or hex symbols");
188 if (!sym_string_valid(sym, prop->expr->left.sym->name) || 195 if (!menu_range_valid_sym(sym, prop->expr->left.sym) ||
189 !sym_string_valid(sym, prop->expr->right.sym->name)) 196 !menu_range_valid_sym(sym, prop->expr->right.sym))
190 prop_warn(prop, "range is invalid"); 197 prop_warn(prop, "range is invalid");
191 break; 198 break;
192 default: 199 default:
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index affa52f5c651..69c2549c0baa 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -141,6 +141,55 @@ struct property *sym_get_range_prop(struct symbol *sym)
141 return NULL; 141 return NULL;
142} 142}
143 143
144static int sym_get_range_val(struct symbol *sym, int base)
145{
146 sym_calc_value(sym);
147 switch (sym->type) {
148 case S_INT:
149 base = 10;
150 break;
151 case S_HEX:
152 base = 16;
153 break;
154 default:
155 break;
156 }
157 return strtol(sym->curr.val, NULL, base);
158}
159
160static void sym_validate_range(struct symbol *sym)
161{
162 struct property *prop;
163 int base, val, val2;
164 char str[64];
165
166 switch (sym->type) {
167 case S_INT:
168 base = 10;
169 break;
170 case S_HEX:
171 base = 16;
172 break;
173 default:
174 return;
175 }
176 prop = sym_get_range_prop(sym);
177 if (!prop)
178 return;
179 val = strtol(sym->curr.val, NULL, base);
180 val2 = sym_get_range_val(prop->expr->left.sym, base);
181 if (val >= val2) {
182 val2 = sym_get_range_val(prop->expr->right.sym, base);
183 if (val <= val2)
184 return;
185 }
186 if (sym->type == S_INT)
187 sprintf(str, "%d", val2);
188 else
189 sprintf(str, "0x%x", val2);
190 sym->curr.val = strdup(str);
191}
192
144static void sym_calc_visibility(struct symbol *sym) 193static void sym_calc_visibility(struct symbol *sym)
145{ 194{
146 struct property *prop; 195 struct property *prop;
@@ -301,6 +350,7 @@ void sym_calc_value(struct symbol *sym)
301 sym->curr = newval; 350 sym->curr = newval;
302 if (sym_is_choice(sym) && newval.tri == yes) 351 if (sym_is_choice(sym) && newval.tri == yes)
303 sym->curr.val = sym_calc_choice(sym); 352 sym->curr.val = sym_calc_choice(sym);
353 sym_validate_range(sym);
304 354
305 if (memcmp(&oldval, &sym->curr, sizeof(oldval))) 355 if (memcmp(&oldval, &sym->curr, sizeof(oldval)))
306 sym_set_changed(sym); 356 sym_set_changed(sym);
@@ -380,11 +430,22 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
380 sym->flags &= ~SYMBOL_NEW; 430 sym->flags &= ~SYMBOL_NEW;
381 sym_set_changed(sym); 431 sym_set_changed(sym);
382 } 432 }
433 /*
434 * setting a choice value also resets the new flag of the choice
435 * symbol and all other choice values.
436 */
383 if (sym_is_choice_value(sym) && val == yes) { 437 if (sym_is_choice_value(sym) && val == yes) {
384 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 438 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
439 struct property *prop;
440 struct expr *e;
385 441
386 cs->user.val = sym; 442 cs->user.val = sym;
387 cs->flags &= ~SYMBOL_NEW; 443 cs->flags &= ~SYMBOL_NEW;
444 prop = sym_get_choice_prop(cs);
445 for (e = prop->expr; e; e = e->left.expr) {
446 if (e->right.sym->visible != no)
447 e->right.sym->flags &= ~SYMBOL_NEW;
448 }
388 } 449 }
389 450
390 sym->user.tri = val; 451 sym->user.tri = val;
@@ -478,8 +539,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
478 if (!prop) 539 if (!prop)
479 return true; 540 return true;
480 val = strtol(str, NULL, 10); 541 val = strtol(str, NULL, 10);
481 return val >= strtol(prop->expr->left.sym->name, NULL, 10) && 542 return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
482 val <= strtol(prop->expr->right.sym->name, NULL, 10); 543 val <= sym_get_range_val(prop->expr->right.sym, 10);
483 case S_HEX: 544 case S_HEX:
484 if (!sym_string_valid(sym, str)) 545 if (!sym_string_valid(sym, str))
485 return false; 546 return false;
@@ -487,8 +548,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
487 if (!prop) 548 if (!prop)
488 return true; 549 return true;
489 val = strtol(str, NULL, 16); 550 val = strtol(str, NULL, 16);
490 return val >= strtol(prop->expr->left.sym->name, NULL, 16) && 551 return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
491 val <= strtol(prop->expr->right.sym->name, NULL, 16); 552 val <= sym_get_range_val(prop->expr->right.sym, 16);
492 case S_BOOLEAN: 553 case S_BOOLEAN:
493 case S_TRISTATE: 554 case S_TRISTATE:
494 switch (str[0]) { 555 switch (str[0]) {
@@ -731,12 +792,12 @@ struct symbol *sym_check_deps(struct symbol *sym)
731 struct symbol *sym2; 792 struct symbol *sym2;
732 struct property *prop; 793 struct property *prop;
733 794
734 if (sym->flags & SYMBOL_CHECK_DONE)
735 return NULL;
736 if (sym->flags & SYMBOL_CHECK) { 795 if (sym->flags & SYMBOL_CHECK) {
737 printf("Warning! Found recursive dependency: %s", sym->name); 796 printf("Warning! Found recursive dependency: %s", sym->name);
738 return sym; 797 return sym;
739 } 798 }
799 if (sym->flags & SYMBOL_CHECKED)
800 return NULL;
740 801
741 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); 802 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
742 sym2 = sym_check_expr_deps(sym->rev_dep.expr); 803 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
@@ -756,8 +817,13 @@ struct symbol *sym_check_deps(struct symbol *sym)
756 goto out; 817 goto out;
757 } 818 }
758out: 819out:
759 if (sym2) 820 if (sym2) {
760 printf(" %s", sym->name); 821 printf(" %s", sym->name);
822 if (sym2 == sym) {
823 printf("\n");
824 sym2 = NULL;
825 }
826 }
761 sym->flags &= ~SYMBOL_CHECK; 827 sym->flags &= ~SYMBOL_CHECK;
762 return sym2; 828 return sym2;
763} 829}
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
new file mode 100644
index 000000000000..b03220600b3a
--- /dev/null
+++ b/scripts/kconfig/zconf.gperf
@@ -0,0 +1,43 @@
1%language=ANSI-C
2%define hash-function-name kconf_id_hash
3%define lookup-function-name kconf_id_lookup
4%define string-pool-name kconf_id_strings
5%compare-strncmp
6%enum
7%pic
8%struct-type
9
10struct kconf_id;
11
12%%
13mainmenu, T_MAINMENU, TF_COMMAND
14menu, T_MENU, TF_COMMAND
15endmenu, T_ENDMENU, TF_COMMAND
16source, T_SOURCE, TF_COMMAND
17choice, T_CHOICE, TF_COMMAND
18endchoice, T_ENDCHOICE, TF_COMMAND
19comment, T_COMMENT, TF_COMMAND
20config, T_CONFIG, TF_COMMAND
21menuconfig, T_MENUCONFIG, TF_COMMAND
22help, T_HELP, TF_COMMAND
23if, T_IF, TF_COMMAND|TF_PARAM
24endif, T_ENDIF, TF_COMMAND
25depends, T_DEPENDS, TF_COMMAND
26requires, T_REQUIRES, TF_COMMAND
27optional, T_OPTIONAL, TF_COMMAND
28default, T_DEFAULT, TF_COMMAND, S_UNKNOWN
29prompt, T_PROMPT, TF_COMMAND
30tristate, T_TYPE, TF_COMMAND, S_TRISTATE
31def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE
32bool, T_TYPE, TF_COMMAND, S_BOOLEAN
33boolean, T_TYPE, TF_COMMAND, S_BOOLEAN
34def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN
35def_boolean, T_DEFAULT, TF_COMMAND, S_BOOLEAN
36int, T_TYPE, TF_COMMAND, S_INT
37hex, T_TYPE, TF_COMMAND, S_HEX
38string, T_TYPE, TF_COMMAND, S_STRING
39select, T_SELECT, TF_COMMAND
40enable, T_SELECT, TF_COMMAND
41range, T_RANGE, TF_COMMAND
42on, T_ON, TF_PARAM
43%%
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
new file mode 100644
index 000000000000..345f0fc07ca3
--- /dev/null
+++ b/scripts/kconfig/zconf.hash.c_shipped
@@ -0,0 +1,231 @@
1/* ANSI-C code produced by gperf version 3.0.1 */
2/* Command-line: gperf */
3/* Computed positions: -k'1,3' */
4
5#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
6 && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
7 && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
8 && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
9 && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
10 && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
11 && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
12 && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
13 && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
14 && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
15 && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
16 && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
17 && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
18 && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
19 && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
20 && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
21 && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
22 && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
23 && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
24 && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
25 && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
26 && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
27 && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
28/* The character set is not based on ISO-646. */
29#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
30#endif
31
32struct kconf_id;
33/* maximum key range = 45, duplicates = 0 */
34
35#ifdef __GNUC__
36__inline
37#else
38#ifdef __cplusplus
39inline
40#endif
41#endif
42static unsigned int
43kconf_id_hash (register const char *str, register unsigned int len)
44{
45 static unsigned char asso_values[] =
46 {
47 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
48 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
49 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
50 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
51 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
52 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
53 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
54 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
55 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
56 47, 47, 47, 47, 47, 47, 47, 25, 10, 15,
57 0, 0, 5, 47, 0, 0, 47, 47, 0, 10,
58 0, 20, 20, 20, 5, 0, 0, 20, 47, 47,
59 20, 47, 47, 47, 47, 47, 47, 47, 47, 47,
60 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
61 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
62 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
63 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
64 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
65 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
66 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
67 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
68 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
69 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
70 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
71 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
72 47, 47, 47, 47, 47, 47
73 };
74 register int hval = len;
75
76 switch (hval)
77 {
78 default:
79 hval += asso_values[(unsigned char)str[2]];
80 /*FALLTHROUGH*/
81 case 2:
82 case 1:
83 hval += asso_values[(unsigned char)str[0]];
84 break;
85 }
86 return hval;
87}
88
89struct kconf_id_strings_t
90 {
91 char kconf_id_strings_str2[sizeof("if")];
92 char kconf_id_strings_str3[sizeof("int")];
93 char kconf_id_strings_str4[sizeof("help")];
94 char kconf_id_strings_str5[sizeof("endif")];
95 char kconf_id_strings_str6[sizeof("select")];
96 char kconf_id_strings_str7[sizeof("endmenu")];
97 char kconf_id_strings_str8[sizeof("tristate")];
98 char kconf_id_strings_str9[sizeof("endchoice")];
99 char kconf_id_strings_str10[sizeof("range")];
100 char kconf_id_strings_str11[sizeof("string")];
101 char kconf_id_strings_str12[sizeof("default")];
102 char kconf_id_strings_str13[sizeof("def_bool")];
103 char kconf_id_strings_str14[sizeof("menu")];
104 char kconf_id_strings_str16[sizeof("def_boolean")];
105 char kconf_id_strings_str17[sizeof("def_tristate")];
106 char kconf_id_strings_str18[sizeof("mainmenu")];
107 char kconf_id_strings_str20[sizeof("menuconfig")];
108 char kconf_id_strings_str21[sizeof("config")];
109 char kconf_id_strings_str22[sizeof("on")];
110 char kconf_id_strings_str23[sizeof("hex")];
111 char kconf_id_strings_str26[sizeof("source")];
112 char kconf_id_strings_str27[sizeof("depends")];
113 char kconf_id_strings_str28[sizeof("optional")];
114 char kconf_id_strings_str31[sizeof("enable")];
115 char kconf_id_strings_str32[sizeof("comment")];
116 char kconf_id_strings_str33[sizeof("requires")];
117 char kconf_id_strings_str34[sizeof("bool")];
118 char kconf_id_strings_str37[sizeof("boolean")];
119 char kconf_id_strings_str41[sizeof("choice")];
120 char kconf_id_strings_str46[sizeof("prompt")];
121 };
122static struct kconf_id_strings_t kconf_id_strings_contents =
123 {
124 "if",
125 "int",
126 "help",
127 "endif",
128 "select",
129 "endmenu",
130 "tristate",
131 "endchoice",
132 "range",
133 "string",
134 "default",
135 "def_bool",
136 "menu",
137 "def_boolean",
138 "def_tristate",
139 "mainmenu",
140 "menuconfig",
141 "config",
142 "on",
143 "hex",
144 "source",
145 "depends",
146 "optional",
147 "enable",
148 "comment",
149 "requires",
150 "bool",
151 "boolean",
152 "choice",
153 "prompt"
154 };
155#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
156#ifdef __GNUC__
157__inline
158#endif
159struct kconf_id *
160kconf_id_lookup (register const char *str, register unsigned int len)
161{
162 enum
163 {
164 TOTAL_KEYWORDS = 30,
165 MIN_WORD_LENGTH = 2,
166 MAX_WORD_LENGTH = 12,
167 MIN_HASH_VALUE = 2,
168 MAX_HASH_VALUE = 46
169 };
170
171 static struct kconf_id wordlist[] =
172 {
173 {-1}, {-1},
174 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_IF, TF_COMMAND|TF_PARAM},
175 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT},
176 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str4, T_HELP, TF_COMMAND},
177 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND},
178 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_SELECT, TF_COMMAND},
179 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND},
180 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE},
181 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND},
182 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND},
183 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_TYPE, TF_COMMAND, S_STRING},
184 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
185 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
186 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_MENU, TF_COMMAND},
187 {-1},
188 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
189 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE},
190 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_MAINMENU, TF_COMMAND},
191 {-1},
192 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_MENUCONFIG, TF_COMMAND},
193 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_CONFIG, TF_COMMAND},
194 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ON, TF_PARAM},
195 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_HEX},
196 {-1}, {-1},
197 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SOURCE, TF_COMMAND},
198 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_DEPENDS, TF_COMMAND},
199 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPTIONAL, TF_COMMAND},
200 {-1}, {-1},
201 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND},
202 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
203 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_REQUIRES, TF_COMMAND},
204 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34, T_TYPE, TF_COMMAND, S_BOOLEAN},
205 {-1}, {-1},
206 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_TYPE, TF_COMMAND, S_BOOLEAN},
207 {-1}, {-1}, {-1},
208 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_CHOICE, TF_COMMAND},
209 {-1}, {-1}, {-1}, {-1},
210 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_PROMPT, TF_COMMAND}
211 };
212
213 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
214 {
215 register int key = kconf_id_hash (str, len);
216
217 if (key <= MAX_HASH_VALUE && key >= 0)
218 {
219 register int o = wordlist[key].name;
220 if (o >= 0)
221 {
222 register const char *s = o + kconf_id_strings;
223
224 if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
225 return &wordlist[key];
226 }
227 }
228 }
229 return 0;
230}
231
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 55517b2877cd..cfa46077c6b4 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -18,8 +18,12 @@
18 18
19#define START_STRSIZE 16 19#define START_STRSIZE 16
20 20
21char *text; 21static struct {
22static char *text_ptr; 22 struct file *file;
23 int lineno;
24} current_pos;
25
26static char *text;
23static int text_size, text_asize; 27static int text_size, text_asize;
24 28
25struct buffer { 29struct buffer {
@@ -32,29 +36,28 @@ struct buffer *current_buf;
32static int last_ts, first_ts; 36static int last_ts, first_ts;
33 37
34static void zconf_endhelp(void); 38static void zconf_endhelp(void);
35static struct buffer *zconf_endfile(void); 39static void zconf_endfile(void);
36 40
37void new_string(void) 41void new_string(void)
38{ 42{
39 text = malloc(START_STRSIZE); 43 text = malloc(START_STRSIZE);
40 text_asize = START_STRSIZE; 44 text_asize = START_STRSIZE;
41 text_ptr = text;
42 text_size = 0; 45 text_size = 0;
43 *text_ptr = 0; 46 *text = 0;
44} 47}
45 48
46void append_string(const char *str, int size) 49void append_string(const char *str, int size)
47{ 50{
48 int new_size = text_size + size + 1; 51 int new_size = text_size + size + 1;
49 if (new_size > text_asize) { 52 if (new_size > text_asize) {
53 new_size += START_STRSIZE - 1;
54 new_size &= -START_STRSIZE;
50 text = realloc(text, new_size); 55 text = realloc(text, new_size);
51 text_asize = new_size; 56 text_asize = new_size;
52 text_ptr = text + text_size;
53 } 57 }
54 memcpy(text_ptr, str, size); 58 memcpy(text + text_size, str, size);
55 text_ptr += size;
56 text_size += size; 59 text_size += size;
57 *text_ptr = 0; 60 text[text_size] = 0;
58} 61}
59 62
60void alloc_string(const char *str, int size) 63void alloc_string(const char *str, int size)
@@ -72,10 +75,13 @@ n [A-Za-z0-9_]
72 int str = 0; 75 int str = 0;
73 int ts, i; 76 int ts, i;
74 77
75[ \t]*#.*\n current_file->lineno++; 78[ \t]*#.*\n |
79[ \t]*\n {
80 current_file->lineno++;
81 return T_EOL;
82}
76[ \t]*#.* 83[ \t]*#.*
77 84
78[ \t]*\n current_file->lineno++; return T_EOL;
79 85
80[ \t]+ { 86[ \t]+ {
81 BEGIN(COMMAND); 87 BEGIN(COMMAND);
@@ -88,42 +94,25 @@ n [A-Za-z0-9_]
88 94
89 95
90<COMMAND>{ 96<COMMAND>{
91 "mainmenu" BEGIN(PARAM); return T_MAINMENU;
92 "menu" BEGIN(PARAM); return T_MENU;
93 "endmenu" BEGIN(PARAM); return T_ENDMENU;
94 "source" BEGIN(PARAM); return T_SOURCE;
95 "choice" BEGIN(PARAM); return T_CHOICE;
96 "endchoice" BEGIN(PARAM); return T_ENDCHOICE;
97 "comment" BEGIN(PARAM); return T_COMMENT;
98 "config" BEGIN(PARAM); return T_CONFIG;
99 "menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
100 "help" BEGIN(PARAM); return T_HELP;
101 "if" BEGIN(PARAM); return T_IF;
102 "endif" BEGIN(PARAM); return T_ENDIF;
103 "depends" BEGIN(PARAM); return T_DEPENDS;
104 "requires" BEGIN(PARAM); return T_REQUIRES;
105 "optional" BEGIN(PARAM); return T_OPTIONAL;
106 "default" BEGIN(PARAM); return T_DEFAULT;
107 "prompt" BEGIN(PARAM); return T_PROMPT;
108 "tristate" BEGIN(PARAM); return T_TRISTATE;
109 "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
110 "bool" BEGIN(PARAM); return T_BOOLEAN;
111 "boolean" BEGIN(PARAM); return T_BOOLEAN;
112 "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN;
113 "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN;
114 "int" BEGIN(PARAM); return T_INT;
115 "hex" BEGIN(PARAM); return T_HEX;
116 "string" BEGIN(PARAM); return T_STRING;
117 "select" BEGIN(PARAM); return T_SELECT;
118 "enable" BEGIN(PARAM); return T_SELECT;
119 "range" BEGIN(PARAM); return T_RANGE;
120 {n}+ { 97 {n}+ {
98 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
99 BEGIN(PARAM);
100 current_pos.file = current_file;
101 current_pos.lineno = current_file->lineno;
102 if (id && id->flags & TF_COMMAND) {
103 zconflval.id = id;
104 return id->token;
105 }
121 alloc_string(yytext, yyleng); 106 alloc_string(yytext, yyleng);
122 zconflval.string = text; 107 zconflval.string = text;
123 return T_WORD; 108 return T_WORD;
124 } 109 }
125 . 110 .
126 \n current_file->lineno++; BEGIN(INITIAL); 111 \n {
112 BEGIN(INITIAL);
113 current_file->lineno++;
114 return T_EOL;
115 }
127} 116}
128 117
129<PARAM>{ 118<PARAM>{
@@ -134,8 +123,6 @@ n [A-Za-z0-9_]
134 "!" return T_NOT; 123 "!" return T_NOT;
135 "=" return T_EQUAL; 124 "=" return T_EQUAL;
136 "!=" return T_UNEQUAL; 125 "!=" return T_UNEQUAL;
137 "if" return T_IF;
138 "on" return T_ON;
139 \"|\' { 126 \"|\' {
140 str = yytext[0]; 127 str = yytext[0];
141 new_string(); 128 new_string();
@@ -144,6 +131,11 @@ n [A-Za-z0-9_]
144 \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; 131 \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
145 --- /* ignore */ 132 --- /* ignore */
146 ({n}|[-/.])+ { 133 ({n}|[-/.])+ {
134 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
135 if (id && id->flags & TF_PARAM) {
136 zconflval.id = id;
137 return id->token;
138 }
147 alloc_string(yytext, yyleng); 139 alloc_string(yytext, yyleng);
148 zconflval.string = text; 140 zconflval.string = text;
149 return T_WORD; 141 return T_WORD;
@@ -236,9 +228,9 @@ n [A-Za-z0-9_]
236} 228}
237 229
238<<EOF>> { 230<<EOF>> {
239 if (current_buf) { 231 if (current_file) {
240 zconf_endfile(); 232 zconf_endfile();
241 return T_EOF; 233 return T_EOL;
242 } 234 }
243 fclose(yyin); 235 fclose(yyin);
244 yyterminate(); 236 yyterminate();
@@ -329,7 +321,7 @@ void zconf_nextfile(const char *name)
329 current_file = file; 321 current_file = file;
330} 322}
331 323
332static struct buffer *zconf_endfile(void) 324static void zconf_endfile(void)
333{ 325{
334 struct buffer *parent; 326 struct buffer *parent;
335 327
@@ -345,22 +337,14 @@ static struct buffer *zconf_endfile(void)
345 } 337 }
346 free(current_buf); 338 free(current_buf);
347 current_buf = parent; 339 current_buf = parent;
348
349 return parent;
350} 340}
351 341
352int zconf_lineno(void) 342int zconf_lineno(void)
353{ 343{
354 if (current_buf) 344 return current_pos.lineno;
355 return current_file->lineno - 1;
356 else
357 return 0;
358} 345}
359 346
360char *zconf_curname(void) 347char *zconf_curname(void)
361{ 348{
362 if (current_buf) 349 return current_pos.file ? current_pos.file->name : "<none>";
363 return current_file->name;
364 else
365 return "<none>";
366} 350}
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index ff4fcc09720e..ea7755da82f5 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -1,7 +1,7 @@
1/* A Bison parser, made by GNU Bison 1.875a. */ 1/* A Bison parser, made by GNU Bison 2.0. */
2 2
3/* Skeleton parser for Yacc-like parsing with Bison, 3/* Skeleton parser for Yacc-like parsing with Bison,
4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5 5
6 This program is free software; you can redistribute it and/or modify 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 7 it under the terms of the GNU General Public License as published by
@@ -45,8 +45,7 @@
45/* Using locations. */ 45/* Using locations. */
46#define YYLSP_NEEDED 0 46#define YYLSP_NEEDED 0
47 47
48/* If NAME_PREFIX is specified substitute the variables and functions 48/* Substitute the variable and function names. */
49 names. */
50#define yyparse zconfparse 49#define yyparse zconfparse
51#define yylex zconflex 50#define yylex zconflex
52#define yyerror zconferror 51#define yyerror zconferror
@@ -79,28 +78,21 @@
79 T_REQUIRES = 272, 78 T_REQUIRES = 272,
80 T_OPTIONAL = 273, 79 T_OPTIONAL = 273,
81 T_PROMPT = 274, 80 T_PROMPT = 274,
82 T_DEFAULT = 275, 81 T_TYPE = 275,
83 T_TRISTATE = 276, 82 T_DEFAULT = 276,
84 T_DEF_TRISTATE = 277, 83 T_SELECT = 277,
85 T_BOOLEAN = 278, 84 T_RANGE = 278,
86 T_DEF_BOOLEAN = 279, 85 T_ON = 279,
87 T_STRING = 280, 86 T_WORD = 280,
88 T_INT = 281, 87 T_WORD_QUOTE = 281,
89 T_HEX = 282, 88 T_UNEQUAL = 282,
90 T_WORD = 283, 89 T_CLOSE_PAREN = 283,
91 T_WORD_QUOTE = 284, 90 T_OPEN_PAREN = 284,
92 T_UNEQUAL = 285, 91 T_EOL = 285,
93 T_EOF = 286, 92 T_OR = 286,
94 T_EOL = 287, 93 T_AND = 287,
95 T_CLOSE_PAREN = 288, 94 T_EQUAL = 288,
96 T_OPEN_PAREN = 289, 95 T_NOT = 289
97 T_ON = 290,
98 T_SELECT = 291,
99 T_RANGE = 292,
100 T_OR = 293,
101 T_AND = 294,
102 T_EQUAL = 295,
103 T_NOT = 296
104 }; 96 };
105#endif 97#endif
106#define T_MAINMENU 258 98#define T_MAINMENU 258
@@ -120,28 +112,21 @@
120#define T_REQUIRES 272 112#define T_REQUIRES 272
121#define T_OPTIONAL 273 113#define T_OPTIONAL 273
122#define T_PROMPT 274 114#define T_PROMPT 274
123#define T_DEFAULT 275 115#define T_TYPE 275
124#define T_TRISTATE 276 116#define T_DEFAULT 276
125#define T_DEF_TRISTATE 277 117#define T_SELECT 277
126#define T_BOOLEAN 278 118#define T_RANGE 278
127#define T_DEF_BOOLEAN 279 119#define T_ON 279
128#define T_STRING 280 120#define T_WORD 280
129#define T_INT 281 121#define T_WORD_QUOTE 281
130#define T_HEX 282 122#define T_UNEQUAL 282
131#define T_WORD 283 123#define T_CLOSE_PAREN 283
132#define T_WORD_QUOTE 284 124#define T_OPEN_PAREN 284
133#define T_UNEQUAL 285 125#define T_EOL 285
134#define T_EOF 286 126#define T_OR 286
135#define T_EOL 287 127#define T_AND 287
136#define T_CLOSE_PAREN 288 128#define T_EQUAL 288
137#define T_OPEN_PAREN 289 129#define T_NOT 289
138#define T_ON 290
139#define T_SELECT 291
140#define T_RANGE 292
141#define T_OR 293
142#define T_AND 294
143#define T_EQUAL 295
144#define T_NOT 296
145 130
146 131
147 132
@@ -161,6 +146,11 @@
161#include <string.h> 146#include <string.h>
162#include <stdbool.h> 147#include <stdbool.h>
163 148
149#define LKC_DIRECT_LINK
150#include "lkc.h"
151
152#include "zconf.hash.c"
153
164#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) 154#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
165 155
166#define PRINTD 0x0001 156#define PRINTD 0x0001
@@ -170,14 +160,18 @@ int cdebug = PRINTD;
170 160
171extern int zconflex(void); 161extern int zconflex(void);
172static void zconfprint(const char *err, ...); 162static void zconfprint(const char *err, ...);
163static void zconf_error(const char *err, ...);
173static void zconferror(const char *err); 164static void zconferror(const char *err);
174static bool zconf_endtoken(int token, int starttoken, int endtoken); 165static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
175 166
176struct symbol *symbol_hash[257]; 167struct symbol *symbol_hash[257];
177 168
178static struct menu *current_menu, *current_entry; 169static struct menu *current_menu, *current_entry;
179 170
171#define YYDEBUG 0
172#if YYDEBUG
180#define YYERROR_VERBOSE 173#define YYERROR_VERBOSE
174#endif
181 175
182 176
183/* Enabling traces. */ 177/* Enabling traces. */
@@ -196,13 +190,14 @@ static struct menu *current_menu, *current_entry;
196#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) 190#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
197 191
198typedef union YYSTYPE { 192typedef union YYSTYPE {
199 int token;
200 char *string; 193 char *string;
194 struct file *file;
201 struct symbol *symbol; 195 struct symbol *symbol;
202 struct expr *expr; 196 struct expr *expr;
203 struct menu *menu; 197 struct menu *menu;
198 struct kconf_id *id;
204} YYSTYPE; 199} YYSTYPE;
205/* Line 191 of yacc.c. */ 200/* Line 190 of yacc.c. */
206 201
207# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 202# define yystype YYSTYPE /* obsolescent; will be withdrawn */
208# define YYSTYPE_IS_DECLARED 1 203# define YYSTYPE_IS_DECLARED 1
@@ -214,27 +209,26 @@ typedef union YYSTYPE {
214/* Copy the second part of user declarations. */ 209/* Copy the second part of user declarations. */
215 210
216 211
217#define LKC_DIRECT_LINK 212/* Line 213 of yacc.c. */
218#include "lkc.h"
219
220
221/* Line 214 of yacc.c. */
222 213
223 214
224#if ! defined (yyoverflow) || YYERROR_VERBOSE 215#if ! defined (yyoverflow) || YYERROR_VERBOSE
225 216
217# ifndef YYFREE
218# define YYFREE free
219# endif
220# ifndef YYMALLOC
221# define YYMALLOC malloc
222# endif
223
226/* The parser invokes alloca or malloc; define the necessary symbols. */ 224/* The parser invokes alloca or malloc; define the necessary symbols. */
227 225
228# if YYSTACK_USE_ALLOCA 226# ifdef YYSTACK_USE_ALLOCA
229# define YYSTACK_ALLOC alloca 227# if YYSTACK_USE_ALLOCA
230# else 228# ifdef __GNUC__
231# ifndef YYSTACK_USE_ALLOCA 229# define YYSTACK_ALLOC __builtin_alloca
232# if defined (alloca) || defined (_ALLOCA_H)
233# define YYSTACK_ALLOC alloca
234# else 230# else
235# ifdef __GNUC__ 231# define YYSTACK_ALLOC alloca
236# define YYSTACK_ALLOC __builtin_alloca
237# endif
238# endif 232# endif
239# endif 233# endif
240# endif 234# endif
@@ -247,20 +241,20 @@ typedef union YYSTYPE {
247# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ 241# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
248# define YYSIZE_T size_t 242# define YYSIZE_T size_t
249# endif 243# endif
250# define YYSTACK_ALLOC malloc 244# define YYSTACK_ALLOC YYMALLOC
251# define YYSTACK_FREE free 245# define YYSTACK_FREE YYFREE
252# endif 246# endif
253#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ 247#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
254 248
255 249
256#if (! defined (yyoverflow) \ 250#if (! defined (yyoverflow) \
257 && (! defined (__cplusplus) \ 251 && (! defined (__cplusplus) \
258 || (YYSTYPE_IS_TRIVIAL))) 252 || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
259 253
260/* A type that is properly aligned for any stack member. */ 254/* A type that is properly aligned for any stack member. */
261union yyalloc 255union yyalloc
262{ 256{
263 short yyss; 257 short int yyss;
264 YYSTYPE yyvs; 258 YYSTYPE yyvs;
265 }; 259 };
266 260
@@ -270,13 +264,13 @@ union yyalloc
270/* The size of an array large to enough to hold all stacks, each with 264/* The size of an array large to enough to hold all stacks, each with
271 N elements. */ 265 N elements. */
272# define YYSTACK_BYTES(N) \ 266# define YYSTACK_BYTES(N) \
273 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ 267 ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
274 + YYSTACK_GAP_MAXIMUM) 268 + YYSTACK_GAP_MAXIMUM)
275 269
276/* Copy COUNT objects from FROM to TO. The source and destination do 270/* Copy COUNT objects from FROM to TO. The source and destination do
277 not overlap. */ 271 not overlap. */
278# ifndef YYCOPY 272# ifndef YYCOPY
279# if 1 < __GNUC__ 273# if defined (__GNUC__) && 1 < __GNUC__
280# define YYCOPY(To, From, Count) \ 274# define YYCOPY(To, From, Count) \
281 __builtin_memcpy (To, From, (Count) * sizeof (*(From))) 275 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
282# else 276# else
@@ -312,26 +306,26 @@ union yyalloc
312#if defined (__STDC__) || defined (__cplusplus) 306#if defined (__STDC__) || defined (__cplusplus)
313 typedef signed char yysigned_char; 307 typedef signed char yysigned_char;
314#else 308#else
315 typedef short yysigned_char; 309 typedef short int yysigned_char;
316#endif 310#endif
317 311
318/* YYFINAL -- State number of the termination state. */ 312/* YYFINAL -- State number of the termination state. */
319#define YYFINAL 2 313#define YYFINAL 3
320/* YYLAST -- Last index in YYTABLE. */ 314/* YYLAST -- Last index in YYTABLE. */
321#define YYLAST 201 315#define YYLAST 264
322 316
323/* YYNTOKENS -- Number of terminals. */ 317/* YYNTOKENS -- Number of terminals. */
324#define YYNTOKENS 42 318#define YYNTOKENS 35
325/* YYNNTS -- Number of nonterminals. */ 319/* YYNNTS -- Number of nonterminals. */
326#define YYNNTS 41 320#define YYNNTS 42
327/* YYNRULES -- Number of rules. */ 321/* YYNRULES -- Number of rules. */
328#define YYNRULES 104 322#define YYNRULES 104
329/* YYNRULES -- Number of states. */ 323/* YYNRULES -- Number of states. */
330#define YYNSTATES 182 324#define YYNSTATES 175
331 325
332/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ 326/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
333#define YYUNDEFTOK 2 327#define YYUNDEFTOK 2
334#define YYMAXUTOK 296 328#define YYMAXUTOK 289
335 329
336#define YYTRANSLATE(YYX) \ 330#define YYTRANSLATE(YYX) \
337 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) 331 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -367,79 +361,78 @@ static const unsigned char yytranslate[] =
367 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 361 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
368 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 362 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
369 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 363 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
370 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 364 25, 26, 27, 28, 29, 30, 31, 32, 33, 34
371 35, 36, 37, 38, 39, 40, 41
372}; 365};
373 366
374#if YYDEBUG 367#if YYDEBUG
375/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in 368/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
376 YYRHS. */ 369 YYRHS. */
377static const unsigned short yyprhs[] = 370static const unsigned short int yyprhs[] =
378{ 371{
379 0, 0, 3, 4, 7, 9, 11, 13, 17, 19, 372 0, 0, 3, 5, 6, 9, 12, 15, 20, 23,
380 21, 23, 26, 28, 30, 32, 34, 36, 38, 42, 373 28, 33, 37, 39, 41, 43, 45, 47, 49, 51,
381 45, 49, 52, 53, 56, 59, 62, 65, 69, 74, 374 53, 55, 57, 59, 61, 63, 67, 70, 74, 77,
382 78, 83, 87, 91, 95, 100, 105, 110, 116, 119, 375 81, 84, 85, 88, 91, 94, 97, 100, 104, 109,
383 122, 124, 128, 131, 132, 135, 138, 141, 144, 149, 376 114, 119, 125, 128, 131, 133, 137, 138, 141, 144,
384 153, 157, 160, 165, 166, 169, 173, 175, 179, 182, 377 147, 150, 153, 158, 162, 165, 170, 171, 174, 178,
385 183, 186, 189, 192, 196, 199, 201, 205, 208, 209, 378 180, 184, 185, 188, 191, 194, 198, 201, 203, 207,
386 212, 215, 218, 222, 226, 228, 232, 235, 238, 241, 379 208, 211, 214, 217, 221, 225, 228, 231, 234, 235,
387 242, 245, 248, 253, 257, 261, 262, 265, 267, 269, 380 238, 241, 244, 249, 253, 257, 258, 261, 263, 265,
388 272, 275, 278, 280, 282, 283, 286, 288, 292, 296, 381 268, 271, 274, 276, 279, 280, 283, 285, 289, 293,
389 300, 303, 307, 311, 313 382 297, 300, 304, 308, 310
390}; 383};
391 384
392/* YYRHS -- A `-1'-separated list of the rules' RHS. */ 385/* YYRHS -- A `-1'-separated list of the rules' RHS. */
393static const yysigned_char yyrhs[] = 386static const yysigned_char yyrhs[] =
394{ 387{
395 43, 0, -1, -1, 43, 44, -1, 45, -1, 55, 388 36, 0, -1, 37, -1, -1, 37, 39, -1, 37,
396 -1, 66, -1, 3, 77, 79, -1, 5, -1, 15, 389 50, -1, 37, 61, -1, 37, 3, 71, 73, -1,
397 -1, 8, -1, 1, 79, -1, 61, -1, 71, -1, 390 37, 72, -1, 37, 25, 1, 30, -1, 37, 38,
398 47, -1, 49, -1, 69, -1, 79, -1, 10, 28, 391 1, 30, -1, 37, 1, 30, -1, 16, -1, 19,
399 32, -1, 46, 50, -1, 11, 28, 32, -1, 48, 392 -1, 20, -1, 22, -1, 18, -1, 23, -1, 21,
400 50, -1, -1, 50, 51, -1, 50, 75, -1, 50, 393 -1, 30, -1, 56, -1, 65, -1, 42, -1, 44,
401 73, -1, 50, 32, -1, 21, 76, 32, -1, 22, 394 -1, 63, -1, 25, 1, 30, -1, 1, 30, -1,
402 81, 80, 32, -1, 23, 76, 32, -1, 24, 81, 395 10, 25, 30, -1, 41, 45, -1, 11, 25, 30,
403 80, 32, -1, 26, 76, 32, -1, 27, 76, 32, 396 -1, 43, 45, -1, -1, 45, 46, -1, 45, 69,
404 -1, 25, 76, 32, -1, 19, 77, 80, 32, -1, 397 -1, 45, 67, -1, 45, 40, -1, 45, 30, -1,
405 20, 81, 80, 32, -1, 36, 28, 80, 32, -1, 398 20, 70, 30, -1, 19, 71, 74, 30, -1, 21,
406 37, 82, 82, 80, 32, -1, 7, 32, -1, 52, 399 75, 74, 30, -1, 22, 25, 74, 30, -1, 23,
407 56, -1, 78, -1, 53, 58, 54, -1, 53, 58, 400 76, 76, 74, 30, -1, 7, 30, -1, 47, 51,
408 -1, -1, 56, 57, -1, 56, 75, -1, 56, 73, 401 -1, 72, -1, 48, 53, 49, -1, -1, 51, 52,
409 -1, 56, 32, -1, 19, 77, 80, 32, -1, 21, 402 -1, 51, 69, -1, 51, 67, -1, 51, 30, -1,
410 76, 32, -1, 23, 76, 32, -1, 18, 32, -1, 403 51, 40, -1, 19, 71, 74, 30, -1, 20, 70,
411 20, 28, 80, 32, -1, -1, 58, 45, -1, 14, 404 30, -1, 18, 30, -1, 21, 25, 74, 30, -1,
412 81, 32, -1, 78, -1, 59, 62, 60, -1, 59, 405 -1, 53, 39, -1, 14, 75, 73, -1, 72, -1,
413 62, -1, -1, 62, 45, -1, 62, 66, -1, 62, 406 54, 57, 55, -1, -1, 57, 39, -1, 57, 61,
414 55, -1, 4, 77, 32, -1, 63, 74, -1, 78, 407 -1, 57, 50, -1, 4, 71, 30, -1, 58, 68,
415 -1, 64, 67, 65, -1, 64, 67, -1, -1, 67, 408 -1, 72, -1, 59, 62, 60, -1, -1, 62, 39,
416 45, -1, 67, 66, -1, 67, 55, -1, 67, 1, 409 -1, 62, 61, -1, 62, 50, -1, 6, 71, 30,
417 32, -1, 6, 77, 32, -1, 68, -1, 9, 77, 410 -1, 9, 71, 30, -1, 64, 68, -1, 12, 30,
418 32, -1, 70, 74, -1, 12, 32, -1, 72, 13, 411 -1, 66, 13, -1, -1, 68, 69, -1, 68, 30,
419 -1, -1, 74, 75, -1, 74, 32, -1, 16, 35, 412 -1, 68, 40, -1, 16, 24, 75, 30, -1, 16,
420 81, 32, -1, 16, 81, 32, -1, 17, 81, 32, 413 75, 30, -1, 17, 75, 30, -1, -1, 71, 74,
421 -1, -1, 77, 80, -1, 28, -1, 29, -1, 5, 414 -1, 25, -1, 26, -1, 5, 30, -1, 8, 30,
422 79, -1, 8, 79, -1, 15, 79, -1, 32, -1, 415 -1, 15, 30, -1, 30, -1, 73, 30, -1, -1,
423 31, -1, -1, 14, 81, -1, 82, -1, 82, 40, 416 14, 75, -1, 76, -1, 76, 33, 76, -1, 76,
424 82, -1, 82, 30, 82, -1, 34, 81, 33, -1, 417 27, 76, -1, 29, 75, 28, -1, 34, 75, -1,
425 41, 81, -1, 81, 38, 81, -1, 81, 39, 81, 418 75, 31, 75, -1, 75, 32, 75, -1, 25, -1,
426 -1, 28, -1, 29, -1 419 26, -1
427}; 420};
428 421
429/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ 422/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
430static const unsigned short yyrline[] = 423static const unsigned short int yyrline[] =
431{ 424{
432 0, 94, 94, 95, 98, 99, 100, 101, 102, 103, 425 0, 103, 103, 105, 107, 108, 109, 110, 111, 112,
433 104, 105, 109, 110, 111, 112, 113, 114, 120, 128, 426 113, 117, 121, 121, 121, 121, 121, 121, 121, 125,
434 134, 142, 152, 154, 155, 156, 157, 160, 166, 173, 427 126, 127, 128, 129, 130, 134, 135, 141, 149, 155,
435 179, 186, 192, 198, 204, 210, 216, 222, 230, 239, 428 163, 173, 175, 176, 177, 178, 179, 182, 190, 196,
436 245, 254, 255, 261, 263, 264, 265, 266, 269, 275, 429 206, 212, 220, 229, 234, 242, 245, 247, 248, 249,
437 281, 287, 293, 299, 301, 306, 315, 324, 325, 331, 430 250, 251, 254, 260, 271, 277, 287, 289, 294, 302,
438 333, 334, 335, 340, 347, 353, 362, 363, 369, 371, 431 310, 313, 315, 316, 317, 322, 329, 334, 342, 345,
439 372, 373, 374, 377, 383, 390, 397, 404, 410, 417, 432 347, 348, 349, 352, 360, 367, 374, 380, 387, 389,
440 418, 419, 422, 427, 432, 440, 442, 447, 448, 451, 433 390, 391, 394, 399, 404, 412, 414, 419, 420, 423,
441 452, 453, 457, 457, 459, 460, 463, 464, 465, 466, 434 424, 425, 429, 430, 433, 434, 437, 438, 439, 440,
442 467, 468, 469, 472, 473 435 441, 442, 443, 446, 447
443}; 436};
444#endif 437#endif
445 438
@@ -448,67 +441,65 @@ static const unsigned short yyrline[] =
448 First, the terminals, then, starting at YYNTOKENS, nonterminals. */ 441 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
449static const char *const yytname[] = 442static const char *const yytname[] =
450{ 443{
451 "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU", 444 "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
452 "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", 445 "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
453 "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", 446 "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
454 "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_DEFAULT", "T_TRISTATE", 447 "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT",
455 "T_DEF_TRISTATE", "T_BOOLEAN", "T_DEF_BOOLEAN", "T_STRING", "T_INT", 448 "T_SELECT", "T_RANGE", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
456 "T_HEX", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_EOF", "T_EOL", 449 "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
457 "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_ON", "T_SELECT", "T_RANGE", "T_OR", 450 "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt",
458 "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "block", 451 "option_error", "config_entry_start", "config_stmt",
459 "common_block", "config_entry_start", "config_stmt", 452 "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
460 "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", 453 "config_option", "choice", "choice_entry", "choice_end", "choice_stmt",
461 "config_option", "choice", "choice_entry", "choice_end", "choice_stmt", 454 "choice_option_list", "choice_option", "choice_block", "if_entry",
462 "choice_option_list", "choice_option", "choice_block", "if", "if_end", 455 "if_end", "if_stmt", "if_block", "menu", "menu_entry", "menu_end",
463 "if_stmt", "if_block", "menu", "menu_entry", "menu_end", "menu_stmt", 456 "menu_stmt", "menu_block", "source_stmt", "comment", "comment_stmt",
464 "menu_block", "source", "source_stmt", "comment", "comment_stmt", 457 "help_start", "help", "depends_list", "depends", "prompt_stmt_opt",
465 "help_start", "help", "depends_list", "depends", "prompt_stmt_opt", 458 "prompt", "end", "nl", "if_expr", "expr", "symbol", 0
466 "prompt", "end", "nl_or_eof", "if_expr", "expr", "symbol", 0
467}; 459};
468#endif 460#endif
469 461
470# ifdef YYPRINT 462# ifdef YYPRINT
471/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to 463/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
472 token YYLEX-NUM. */ 464 token YYLEX-NUM. */
473static const unsigned short yytoknum[] = 465static const unsigned short int yytoknum[] =
474{ 466{
475 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 467 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
476 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 468 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
477 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 469 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
478 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 470 285, 286, 287, 288, 289
479 295, 296
480}; 471};
481# endif 472# endif
482 473
483/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ 474/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
484static const unsigned char yyr1[] = 475static const unsigned char yyr1[] =
485{ 476{
486 0, 42, 43, 43, 44, 44, 44, 44, 44, 44, 477 0, 35, 36, 37, 37, 37, 37, 37, 37, 37,
487 44, 44, 45, 45, 45, 45, 45, 45, 46, 47, 478 37, 37, 38, 38, 38, 38, 38, 38, 38, 39,
488 48, 49, 50, 50, 50, 50, 50, 51, 51, 51, 479 39, 39, 39, 39, 39, 40, 40, 41, 42, 43,
489 51, 51, 51, 51, 51, 51, 51, 51, 52, 53, 480 44, 45, 45, 45, 45, 45, 45, 46, 46, 46,
490 54, 55, 55, 56, 56, 56, 56, 56, 57, 57, 481 46, 46, 47, 48, 49, 50, 51, 51, 51, 51,
491 57, 57, 57, 58, 58, 59, 60, 61, 61, 62, 482 51, 51, 52, 52, 52, 52, 53, 53, 54, 55,
492 62, 62, 62, 63, 64, 65, 66, 66, 67, 67, 483 56, 57, 57, 57, 57, 58, 59, 60, 61, 62,
493 67, 67, 67, 68, 69, 70, 71, 72, 73, 74, 484 62, 62, 62, 63, 64, 65, 66, 67, 68, 68,
494 74, 74, 75, 75, 75, 76, 76, 77, 77, 78, 485 68, 68, 69, 69, 69, 70, 70, 71, 71, 72,
495 78, 78, 79, 79, 80, 80, 81, 81, 81, 81, 486 72, 72, 73, 73, 74, 74, 75, 75, 75, 75,
496 81, 81, 81, 82, 82 487 75, 75, 75, 76, 76
497}; 488};
498 489
499/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ 490/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
500static const unsigned char yyr2[] = 491static const unsigned char yyr2[] =
501{ 492{
502 0, 2, 0, 2, 1, 1, 1, 3, 1, 1, 493 0, 2, 1, 0, 2, 2, 2, 4, 2, 4,
503 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, 494 4, 3, 1, 1, 1, 1, 1, 1, 1, 1,
504 3, 2, 0, 2, 2, 2, 2, 3, 4, 3, 495 1, 1, 1, 1, 1, 3, 2, 3, 2, 3,
505 4, 3, 3, 3, 4, 4, 4, 5, 2, 2, 496 2, 0, 2, 2, 2, 2, 2, 3, 4, 4,
506 1, 3, 2, 0, 2, 2, 2, 2, 4, 3, 497 4, 5, 2, 2, 1, 3, 0, 2, 2, 2,
507 3, 2, 4, 0, 2, 3, 1, 3, 2, 0, 498 2, 2, 4, 3, 2, 4, 0, 2, 3, 1,
508 2, 2, 2, 3, 2, 1, 3, 2, 0, 2, 499 3, 0, 2, 2, 2, 3, 2, 1, 3, 0,
509 2, 2, 3, 3, 1, 3, 2, 2, 2, 0, 500 2, 2, 2, 3, 3, 2, 2, 2, 0, 2,
510 2, 2, 4, 3, 3, 0, 2, 1, 1, 2, 501 2, 2, 4, 3, 3, 0, 2, 1, 1, 2,
511 2, 2, 1, 1, 0, 2, 1, 3, 3, 3, 502 2, 2, 1, 2, 0, 2, 1, 3, 3, 3,
512 2, 3, 3, 1, 1 503 2, 3, 3, 1, 1
513}; 504};
514 505
@@ -517,151 +508,160 @@ static const unsigned char yyr2[] =
517 means the default is an error. */ 508 means the default is an error. */
518static const unsigned char yydefact[] = 509static const unsigned char yydefact[] =
519{ 510{
520 2, 0, 1, 0, 0, 0, 8, 0, 0, 10, 511 3, 0, 0, 1, 0, 0, 0, 0, 0, 0,
521 0, 0, 0, 0, 9, 93, 92, 3, 4, 22, 512 0, 0, 0, 0, 0, 0, 12, 16, 13, 14,
522 14, 22, 15, 43, 53, 5, 59, 12, 79, 68, 513 18, 15, 17, 0, 19, 0, 4, 31, 22, 31,
523 6, 74, 16, 79, 13, 17, 11, 87, 88, 0, 514 23, 46, 56, 5, 61, 20, 78, 69, 6, 24,
524 0, 0, 38, 0, 0, 0, 103, 104, 0, 0, 515 78, 21, 8, 11, 87, 88, 0, 0, 89, 0,
525 0, 96, 19, 21, 39, 42, 58, 64, 0, 76, 516 42, 90, 0, 0, 0, 103, 104, 0, 0, 0,
526 7, 63, 73, 75, 18, 20, 0, 100, 55, 0, 517 96, 91, 0, 0, 0, 0, 0, 0, 0, 0,
527 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 518 0, 0, 92, 7, 65, 73, 74, 27, 29, 0,
528 85, 0, 85, 85, 85, 26, 0, 0, 23, 0, 519 100, 0, 0, 58, 0, 0, 9, 10, 0, 0,
529 25, 24, 0, 0, 0, 85, 85, 47, 44, 46, 520 0, 0, 0, 85, 0, 0, 0, 0, 36, 35,
530 45, 0, 0, 0, 54, 41, 40, 60, 62, 57, 521 32, 0, 34, 33, 0, 0, 85, 0, 50, 51,
531 61, 56, 81, 80, 0, 69, 71, 66, 70, 65, 522 47, 49, 48, 57, 45, 44, 62, 64, 60, 63,
532 99, 101, 102, 98, 97, 77, 0, 0, 0, 94, 523 59, 80, 81, 79, 70, 72, 68, 71, 67, 93,
533 94, 0, 94, 94, 0, 94, 0, 0, 0, 94, 524 99, 101, 102, 98, 97, 26, 76, 0, 0, 0,
534 0, 78, 51, 94, 94, 0, 0, 89, 90, 91, 525 94, 0, 94, 94, 94, 0, 0, 77, 54, 94,
535 72, 0, 83, 84, 0, 0, 0, 27, 86, 0, 526 0, 94, 0, 83, 84, 0, 0, 37, 86, 0,
536 29, 0, 33, 31, 32, 0, 94, 0, 0, 49, 527 0, 94, 25, 0, 53, 0, 82, 95, 38, 39,
537 50, 82, 95, 34, 35, 28, 30, 36, 0, 48, 528 40, 0, 52, 55, 41
538 52, 37
539}; 529};
540 530
541/* YYDEFGOTO[NTERM-NUM]. */ 531/* YYDEFGOTO[NTERM-NUM]. */
542static const short yydefgoto[] = 532static const short int yydefgoto[] =
543{ 533{
544 -1, 1, 17, 18, 19, 20, 21, 22, 52, 88, 534 -1, 1, 2, 25, 26, 99, 27, 28, 29, 30,
545 23, 24, 105, 25, 54, 98, 55, 26, 109, 27, 535 64, 100, 31, 32, 114, 33, 66, 110, 67, 34,
546 56, 28, 29, 117, 30, 58, 31, 32, 33, 34, 536 118, 35, 68, 36, 37, 126, 38, 70, 39, 40,
547 89, 90, 57, 91, 131, 132, 106, 35, 155, 50, 537 41, 101, 102, 69, 103, 141, 142, 42, 73, 156,
548 51 538 59, 60
549}; 539};
550 540
551/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing 541/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
552 STATE-NUM. */ 542 STATE-NUM. */
553#define YYPACT_NINF -99 543#define YYPACT_NINF -78
554static const short yypact[] = 544static const short int yypact[] =
555{ 545{
556 -99, 48, -99, 38, 46, 46, -99, 46, -29, -99, 546 -78, 2, 159, -78, -21, 0, 0, -12, 0, 1,
557 46, -17, -3, -11, -99, -99, -99, -99, -99, -99, 547 4, 0, 27, 38, 60, 58, -78, -78, -78, -78,
558 -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, 548 -78, -78, -78, 100, -78, 104, -78, -78, -78, -78,
559 -99, -99, -99, -99, -99, -99, -99, -99, -99, 38, 549 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
560 12, 15, -99, 18, 51, 62, -99, -99, -11, -11, 550 -78, -78, -78, -78, -78, -78, 86, 113, -78, 114,
561 4, -24, 138, 138, 160, 121, 110, -4, 81, -4, 551 -78, -78, 125, 127, 128, -78, -78, 60, 60, 210,
562 -99, -99, -99, -99, -99, -99, -19, -99, -99, -11, 552 65, -78, 141, 142, 39, 103, 182, 200, 6, 66,
563 -11, 70, 70, 73, 32, -11, 46, -11, 46, -11, 553 6, 131, -78, 146, -78, -78, -78, -78, -78, 196,
564 46, -11, 46, 46, 46, -99, 36, 70, -99, 95, 554 -78, 60, 60, 146, 40, 40, -78, -78, 155, 156,
565 -99, -99, 96, 46, 106, 46, 46, -99, -99, -99, 555 -2, 60, 0, 0, 60, 105, 40, 194, -78, -78,
566 -99, 38, 38, 38, -99, -99, -99, -99, -99, -99, 556 -78, 206, -78, -78, 183, 0, 0, 195, -78, -78,
567 -99, -99, -99, -99, 112, -99, -99, -99, -99, -99, 557 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
568 -99, 117, -99, -99, -99, -99, -11, 33, 65, 131, 558 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
569 1, 119, 131, 1, 136, 1, 153, 154, 155, 131, 559 -78, 197, -78, -78, -78, -78, -78, 60, 213, 216,
570 70, -99, -99, 131, 131, 156, 157, -99, -99, -99, 560 212, 203, 212, 190, 212, 40, 208, -78, -78, 212,
571 -99, 101, -99, -99, -11, 158, 159, -99, -99, 161, 561 222, 212, 219, -78, -78, 60, 223, -78, -78, 224,
572 -99, 162, -99, -99, -99, 163, 131, 164, 165, -99, 562 225, 212, -78, 226, -78, 227, -78, 47, -78, -78,
573 -99, -99, 99, -99, -99, -99, -99, -99, 166, -99, 563 -78, 228, -78, -78, -78
574 -99, -99
575}; 564};
576 565
577/* YYPGOTO[NTERM-NUM]. */ 566/* YYPGOTO[NTERM-NUM]. */
578static const short yypgoto[] = 567static const short int yypgoto[] =
579{ 568{
580 -99, -99, -99, 111, -99, -99, -99, -99, 178, -99, 569 -78, -78, -78, -78, 164, -36, -78, -78, -78, -78,
581 -99, -99, -99, 91, -99, -99, -99, -99, -99, -99, 570 230, -78, -78, -78, -78, 29, -78, -78, -78, -78,
582 -99, -99, -99, -99, 115, -99, -99, -99, -99, -99, 571 -78, -78, -78, -78, -78, -78, 59, -78, -78, -78,
583 -99, 146, 168, 89, 27, 0, 126, -1, -98, -48, 572 -78, -78, 198, 220, 24, 157, -5, 169, 202, 74,
584 -63 573 -53, -77
585}; 574};
586 575
587/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If 576/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
588 positive, shift that token. If negative, reduce the rule which 577 positive, shift that token. If negative, reduce the rule which
589 number is the opposite. If zero, do what YYDEFACT says. 578 number is the opposite. If zero, do what YYDEFACT says.
590 If YYTABLE_NINF, syntax error. */ 579 If YYTABLE_NINF, syntax error. */
591#define YYTABLE_NINF -68 580#define YYTABLE_NINF -76
592static const short yytable[] = 581static const short int yytable[] =
593{ 582{
594 66, 67, 36, 42, 39, 40, 71, 41, 123, 124, 583 46, 47, 3, 49, 79, 80, 52, 133, 134, 43,
595 43, 44, 74, 75, 120, 154, 72, 46, 47, 69, 584 6, 7, 8, 9, 10, 11, 12, 13, 48, 145,
596 70, 121, 122, 48, 140, 45, 127, 128, 112, 130, 585 14, 15, 137, 55, 56, 44, 45, 57, 131, 132,
597 49, 133, 156, 135, 158, 159, 68, 161, 60, 69, 586 109, 50, 58, 122, 51, 122, 24, 138, 139, -28,
598 70, 165, 69, 70, 61, 167, 168, 62, 2, 3, 587 88, 143, -28, -28, -28, -28, -28, -28, -28, -28,
599 63, 4, 5, 6, 7, 8, 9, 10, 11, 12, 588 -28, 89, 53, -28, -28, 90, 91, -28, 92, 93,
600 46, 47, 13, 14, 139, 152, 48, 126, 178, 15, 589 94, 95, 96, 54, 97, 55, 56, 88, 161, 98,
601 16, 69, 70, 49, 37, 38, 129, 166, 151, 15, 590 -66, -66, -66, -66, -66, -66, -66, -66, 81, 82,
602 16, -67, 114, 64, -67, 5, 101, 7, 8, 102, 591 -66, -66, 90, 91, 152, 55, 56, 140, 61, 57,
603 10, 11, 12, 143, 65, 13, 103, 153, 46, 47, 592 112, 97, 84, 123, 58, 123, 121, 117, 85, 125,
604 147, 148, 149, 69, 70, 125, 172, 134, 141, 136, 593 149, 62, 167, -30, 88, 63, -30, -30, -30, -30,
605 137, 138, 15, 16, 5, 101, 7, 8, 102, 10, 594 -30, -30, -30, -30, -30, 89, 72, -30, -30, 90,
606 11, 12, 145, 146, 13, 103, 101, 7, 142, 102, 595 91, -30, 92, 93, 94, 95, 96, 119, 97, 127,
607 10, 11, 12, 171, 144, 13, 103, 69, 70, 69, 596 144, -75, 88, 98, -75, -75, -75, -75, -75, -75,
608 70, 15, 16, 100, 150, 154, 113, 108, 113, 116, 597 -75, -75, -75, 74, 75, -75, -75, 90, 91, -75,
609 73, 157, 15, 16, 74, 75, 70, 76, 77, 78, 598 -75, -75, -75, -75, -75, 76, 97, 77, 78, -2,
610 79, 80, 81, 82, 83, 84, 104, 107, 160, 115, 599 4, 121, 5, 6, 7, 8, 9, 10, 11, 12,
611 85, 110, 73, 118, 86, 87, 74, 75, 92, 93, 600 13, 86, 87, 14, 15, 16, 129, 17, 18, 19,
612 94, 95, 111, 96, 119, 162, 163, 164, 169, 170, 601 20, 21, 22, 88, 23, 135, 136, -43, -43, 24,
613 173, 174, 97, 175, 176, 177, 179, 180, 181, 53, 602 -43, -43, -43, -43, 89, 146, -43, -43, 90, 91,
614 99, 59 603 104, 105, 106, 107, 155, 7, 8, 97, 10, 11,
604 12, 13, 108, 148, 14, 15, 158, 159, 160, 147,
605 151, 81, 82, 163, 130, 165, 155, 81, 82, 82,
606 24, 113, 116, 157, 124, 171, 115, 120, 162, 128,
607 72, 81, 82, 153, 81, 82, 154, 81, 82, 166,
608 81, 82, 164, 168, 169, 170, 172, 173, 174, 65,
609 71, 83, 0, 150, 111
615}; 610};
616 611
617static const unsigned char yycheck[] = 612static const short int yycheck[] =
618{ 613{
619 48, 49, 3, 32, 4, 5, 30, 7, 71, 72, 614 5, 6, 0, 8, 57, 58, 11, 84, 85, 30,
620 10, 28, 16, 17, 33, 14, 40, 28, 29, 38, 615 4, 5, 6, 7, 8, 9, 10, 11, 30, 96,
621 39, 69, 70, 34, 87, 28, 74, 75, 32, 77, 616 14, 15, 24, 25, 26, 25, 26, 29, 81, 82,
622 41, 79, 130, 81, 132, 133, 32, 135, 39, 38, 617 66, 30, 34, 69, 30, 71, 30, 90, 91, 0,
623 39, 139, 38, 39, 32, 143, 144, 32, 0, 1, 618 1, 94, 3, 4, 5, 6, 7, 8, 9, 10,
624 32, 3, 4, 5, 6, 7, 8, 9, 10, 11, 619 11, 12, 25, 14, 15, 16, 17, 18, 19, 20,
625 28, 29, 14, 15, 28, 32, 34, 35, 166, 31, 620 21, 22, 23, 25, 25, 25, 26, 1, 145, 30,
626 32, 38, 39, 41, 28, 29, 76, 140, 126, 31, 621 4, 5, 6, 7, 8, 9, 10, 11, 31, 32,
627 32, 0, 1, 32, 3, 4, 5, 6, 7, 8, 622 14, 15, 16, 17, 137, 25, 26, 92, 30, 29,
628 9, 10, 11, 93, 32, 14, 15, 32, 28, 29, 623 66, 25, 27, 69, 34, 71, 30, 68, 33, 70,
629 101, 102, 103, 38, 39, 32, 154, 80, 13, 82, 624 105, 1, 155, 0, 1, 1, 3, 4, 5, 6,
630 83, 84, 31, 32, 4, 5, 6, 7, 8, 9, 625 7, 8, 9, 10, 11, 12, 30, 14, 15, 16,
631 10, 11, 95, 96, 14, 15, 5, 6, 32, 8, 626 17, 18, 19, 20, 21, 22, 23, 68, 25, 70,
632 9, 10, 11, 32, 28, 14, 15, 38, 39, 38, 627 25, 0, 1, 30, 3, 4, 5, 6, 7, 8,
633 39, 31, 32, 54, 32, 14, 57, 56, 59, 58, 628 9, 10, 11, 30, 30, 14, 15, 16, 17, 18,
634 12, 32, 31, 32, 16, 17, 39, 19, 20, 21, 629 19, 20, 21, 22, 23, 30, 25, 30, 30, 0,
635 22, 23, 24, 25, 26, 27, 55, 56, 32, 58, 630 1, 30, 3, 4, 5, 6, 7, 8, 9, 10,
636 32, 56, 12, 58, 36, 37, 16, 17, 18, 19, 631 11, 30, 30, 14, 15, 16, 30, 18, 19, 20,
637 20, 21, 56, 23, 58, 32, 32, 32, 32, 32, 632 21, 22, 23, 1, 25, 30, 30, 5, 6, 30,
638 32, 32, 32, 32, 32, 32, 32, 32, 32, 21, 633 8, 9, 10, 11, 12, 1, 14, 15, 16, 17,
639 54, 33 634 18, 19, 20, 21, 14, 5, 6, 25, 8, 9,
635 10, 11, 30, 30, 14, 15, 142, 143, 144, 13,
636 25, 31, 32, 149, 28, 151, 14, 31, 32, 32,
637 30, 67, 68, 30, 70, 161, 67, 68, 30, 70,
638 30, 31, 32, 30, 31, 32, 30, 31, 32, 30,
639 31, 32, 30, 30, 30, 30, 30, 30, 30, 29,
640 40, 59, -1, 106, 66
640}; 641};
641 642
642/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing 643/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
643 symbol of state STATE-NUM. */ 644 symbol of state STATE-NUM. */
644static const unsigned char yystos[] = 645static const unsigned char yystos[] =
645{ 646{
646 0, 43, 0, 1, 3, 4, 5, 6, 7, 8, 647 0, 36, 37, 0, 1, 3, 4, 5, 6, 7,
647 9, 10, 11, 14, 15, 31, 32, 44, 45, 46, 648 8, 9, 10, 11, 14, 15, 16, 18, 19, 20,
648 47, 48, 49, 52, 53, 55, 59, 61, 63, 64, 649 21, 22, 23, 25, 30, 38, 39, 41, 42, 43,
649 66, 68, 69, 70, 71, 79, 79, 28, 29, 77, 650 44, 47, 48, 50, 54, 56, 58, 59, 61, 63,
650 77, 77, 32, 77, 28, 28, 28, 29, 34, 41, 651 64, 65, 72, 30, 25, 26, 71, 71, 30, 71,
651 81, 82, 50, 50, 56, 58, 62, 74, 67, 74, 652 30, 30, 71, 25, 25, 25, 26, 29, 34, 75,
652 79, 32, 32, 32, 32, 32, 81, 81, 32, 38, 653 76, 30, 1, 1, 45, 45, 51, 53, 57, 68,
653 39, 30, 40, 12, 16, 17, 19, 20, 21, 22, 654 62, 68, 30, 73, 30, 30, 30, 30, 30, 75,
654 23, 24, 25, 26, 27, 32, 36, 37, 51, 72, 655 75, 31, 32, 73, 27, 33, 30, 30, 1, 12,
655 73, 75, 18, 19, 20, 21, 23, 32, 57, 73, 656 16, 17, 19, 20, 21, 22, 23, 25, 30, 40,
656 75, 5, 8, 15, 45, 54, 78, 45, 55, 60, 657 46, 66, 67, 69, 18, 19, 20, 21, 30, 40,
657 66, 78, 32, 75, 1, 45, 55, 65, 66, 78, 658 52, 67, 69, 39, 49, 72, 39, 50, 55, 61,
658 33, 81, 81, 82, 82, 32, 35, 81, 81, 77, 659 72, 30, 40, 69, 39, 50, 60, 61, 72, 30,
659 81, 76, 77, 81, 76, 81, 76, 76, 76, 28, 660 28, 75, 75, 76, 76, 30, 30, 24, 75, 75,
660 82, 13, 32, 77, 28, 76, 76, 79, 79, 79, 661 71, 70, 71, 75, 25, 76, 1, 13, 30, 71,
661 32, 81, 32, 32, 14, 80, 80, 32, 80, 80, 662 70, 25, 75, 30, 30, 14, 74, 30, 74, 74,
662 32, 80, 32, 32, 32, 80, 82, 80, 80, 32, 663 74, 76, 30, 74, 30, 74, 30, 75, 30, 30,
663 32, 32, 81, 32, 32, 32, 32, 32, 80, 32, 664 30, 74, 30, 30, 30
664 32, 32
665}; 665};
666 666
667#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) 667#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
@@ -687,7 +687,7 @@ static const unsigned char yystos[] =
687 687
688#define YYACCEPT goto yyacceptlab 688#define YYACCEPT goto yyacceptlab
689#define YYABORT goto yyabortlab 689#define YYABORT goto yyabortlab
690#define YYERROR goto yyerrlab1 690#define YYERROR goto yyerrorlab
691 691
692 692
693/* Like YYERROR except do call yyerror. This remains here temporarily 693/* Like YYERROR except do call yyerror. This remains here temporarily
@@ -715,20 +715,53 @@ do \
715 } \ 715 } \
716while (0) 716while (0)
717 717
718
718#define YYTERROR 1 719#define YYTERROR 1
719#define YYERRCODE 256 720#define YYERRCODE 256
720 721
721/* YYLLOC_DEFAULT -- Compute the default location (before the actions
722 are run). */
723 722
723/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
724 If N is 0, then set CURRENT to the empty location which ends
725 the previous symbol: RHS[0] (always defined). */
726
727#define YYRHSLOC(Rhs, K) ((Rhs)[K])
724#ifndef YYLLOC_DEFAULT 728#ifndef YYLLOC_DEFAULT
725# define YYLLOC_DEFAULT(Current, Rhs, N) \ 729# define YYLLOC_DEFAULT(Current, Rhs, N) \
726 Current.first_line = Rhs[1].first_line; \ 730 do \
727 Current.first_column = Rhs[1].first_column; \ 731 if (N) \
728 Current.last_line = Rhs[N].last_line; \ 732 { \
729 Current.last_column = Rhs[N].last_column; 733 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
734 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
735 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
736 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
737 } \
738 else \
739 { \
740 (Current).first_line = (Current).last_line = \
741 YYRHSLOC (Rhs, 0).last_line; \
742 (Current).first_column = (Current).last_column = \
743 YYRHSLOC (Rhs, 0).last_column; \
744 } \
745 while (0)
746#endif
747
748
749/* YY_LOCATION_PRINT -- Print the location on the stream.
750 This macro was not mandated originally: define only if we know
751 we won't break user code: when these are the locations we know. */
752
753#ifndef YY_LOCATION_PRINT
754# if YYLTYPE_IS_TRIVIAL
755# define YY_LOCATION_PRINT(File, Loc) \
756 fprintf (File, "%d.%d-%d.%d", \
757 (Loc).first_line, (Loc).first_column, \
758 (Loc).last_line, (Loc).last_column)
759# else
760# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
761# endif
730#endif 762#endif
731 763
764
732/* YYLEX -- calling `yylex' with the right arguments. */ 765/* YYLEX -- calling `yylex' with the right arguments. */
733 766
734#ifdef YYLEX_PARAM 767#ifdef YYLEX_PARAM
@@ -751,36 +784,30 @@ do { \
751 YYFPRINTF Args; \ 784 YYFPRINTF Args; \
752} while (0) 785} while (0)
753 786
754# define YYDSYMPRINT(Args) \ 787# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
755do { \
756 if (yydebug) \
757 yysymprint Args; \
758} while (0)
759
760# define YYDSYMPRINTF(Title, Token, Value, Location) \
761do { \ 788do { \
762 if (yydebug) \ 789 if (yydebug) \
763 { \ 790 { \
764 YYFPRINTF (stderr, "%s ", Title); \ 791 YYFPRINTF (stderr, "%s ", Title); \
765 yysymprint (stderr, \ 792 yysymprint (stderr, \
766 Token, Value); \ 793 Type, Value); \
767 YYFPRINTF (stderr, "\n"); \ 794 YYFPRINTF (stderr, "\n"); \
768 } \ 795 } \
769} while (0) 796} while (0)
770 797
771/*------------------------------------------------------------------. 798/*------------------------------------------------------------------.
772| yy_stack_print -- Print the state stack from its BOTTOM up to its | 799| yy_stack_print -- Print the state stack from its BOTTOM up to its |
773| TOP (cinluded). | 800| TOP (included). |
774`------------------------------------------------------------------*/ 801`------------------------------------------------------------------*/
775 802
776#if defined (__STDC__) || defined (__cplusplus) 803#if defined (__STDC__) || defined (__cplusplus)
777static void 804static void
778yy_stack_print (short *bottom, short *top) 805yy_stack_print (short int *bottom, short int *top)
779#else 806#else
780static void 807static void
781yy_stack_print (bottom, top) 808yy_stack_print (bottom, top)
782 short *bottom; 809 short int *bottom;
783 short *top; 810 short int *top;
784#endif 811#endif
785{ 812{
786 YYFPRINTF (stderr, "Stack now"); 813 YYFPRINTF (stderr, "Stack now");
@@ -810,9 +837,9 @@ yy_reduce_print (yyrule)
810#endif 837#endif
811{ 838{
812 int yyi; 839 int yyi;
813 unsigned int yylineno = yyrline[yyrule]; 840 unsigned int yylno = yyrline[yyrule];
814 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", 841 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
815 yyrule - 1, yylineno); 842 yyrule - 1, yylno);
816 /* Print the symbols being reduced, and their result. */ 843 /* Print the symbols being reduced, and their result. */
817 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) 844 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
818 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); 845 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
@@ -830,8 +857,7 @@ do { \
830int yydebug; 857int yydebug;
831#else /* !YYDEBUG */ 858#else /* !YYDEBUG */
832# define YYDPRINTF(Args) 859# define YYDPRINTF(Args)
833# define YYDSYMPRINT(Args) 860# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
834# define YYDSYMPRINTF(Title, Token, Value, Location)
835# define YY_STACK_PRINT(Bottom, Top) 861# define YY_STACK_PRINT(Bottom, Top)
836# define YY_REDUCE_PRINT(Rule) 862# define YY_REDUCE_PRINT(Rule)
837#endif /* !YYDEBUG */ 863#endif /* !YYDEBUG */
@@ -849,10 +875,6 @@ int yydebug;
849 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) 875 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
850 evaluated with infinite-precision integer arithmetic. */ 876 evaluated with infinite-precision integer arithmetic. */
851 877
852#if YYMAXDEPTH == 0
853# undef YYMAXDEPTH
854#endif
855
856#ifndef YYMAXDEPTH 878#ifndef YYMAXDEPTH
857# define YYMAXDEPTH 10000 879# define YYMAXDEPTH 10000
858#endif 880#endif
@@ -934,15 +956,15 @@ yysymprint (yyoutput, yytype, yyvaluep)
934 (void) yyvaluep; 956 (void) yyvaluep;
935 957
936 if (yytype < YYNTOKENS) 958 if (yytype < YYNTOKENS)
937 { 959 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
938 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
939# ifdef YYPRINT
940 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
941# endif
942 }
943 else 960 else
944 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); 961 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
945 962
963
964# ifdef YYPRINT
965 if (yytype < YYNTOKENS)
966 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
967# endif
946 switch (yytype) 968 switch (yytype)
947 { 969 {
948 default: 970 default:
@@ -958,10 +980,11 @@ yysymprint (yyoutput, yytype, yyvaluep)
958 980
959#if defined (__STDC__) || defined (__cplusplus) 981#if defined (__STDC__) || defined (__cplusplus)
960static void 982static void
961yydestruct (int yytype, YYSTYPE *yyvaluep) 983yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
962#else 984#else
963static void 985static void
964yydestruct (yytype, yyvaluep) 986yydestruct (yymsg, yytype, yyvaluep)
987 const char *yymsg;
965 int yytype; 988 int yytype;
966 YYSTYPE *yyvaluep; 989 YYSTYPE *yyvaluep;
967#endif 990#endif
@@ -969,8 +992,42 @@ yydestruct (yytype, yyvaluep)
969 /* Pacify ``unused variable'' warnings. */ 992 /* Pacify ``unused variable'' warnings. */
970 (void) yyvaluep; 993 (void) yyvaluep;
971 994
995 if (!yymsg)
996 yymsg = "Deleting";
997 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
998
972 switch (yytype) 999 switch (yytype)
973 { 1000 {
1001 case 48: /* choice_entry */
1002
1003 {
1004 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
1005 (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
1006 if (current_menu == (yyvaluep->menu))
1007 menu_end_menu();
1008};
1009
1010 break;
1011 case 54: /* if_entry */
1012
1013 {
1014 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
1015 (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
1016 if (current_menu == (yyvaluep->menu))
1017 menu_end_menu();
1018};
1019
1020 break;
1021 case 59: /* menu_entry */
1022
1023 {
1024 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
1025 (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
1026 if (current_menu == (yyvaluep->menu))
1027 menu_end_menu();
1028};
1029
1030 break;
974 1031
975 default: 1032 default:
976 break; 1033 break;
@@ -996,10 +1053,10 @@ int yyparse ();
996 1053
997 1054
998 1055
999/* The lookahead symbol. */ 1056/* The look-ahead symbol. */
1000int yychar; 1057int yychar;
1001 1058
1002/* The semantic value of the lookahead symbol. */ 1059/* The semantic value of the look-ahead symbol. */
1003YYSTYPE yylval; 1060YYSTYPE yylval;
1004 1061
1005/* Number of syntax errors so far. */ 1062/* Number of syntax errors so far. */
@@ -1035,7 +1092,7 @@ yyparse ()
1035 int yyresult; 1092 int yyresult;
1036 /* Number of tokens to shift before error messages enabled. */ 1093 /* Number of tokens to shift before error messages enabled. */
1037 int yyerrstatus; 1094 int yyerrstatus;
1038 /* Lookahead token as an internal (translated) token number. */ 1095 /* Look-ahead token as an internal (translated) token number. */
1039 int yytoken = 0; 1096 int yytoken = 0;
1040 1097
1041 /* Three stacks and their tools: 1098 /* Three stacks and their tools:
@@ -1047,9 +1104,9 @@ yyparse ()
1047 to reallocate them elsewhere. */ 1104 to reallocate them elsewhere. */
1048 1105
1049 /* The state stack. */ 1106 /* The state stack. */
1050 short yyssa[YYINITDEPTH]; 1107 short int yyssa[YYINITDEPTH];
1051 short *yyss = yyssa; 1108 short int *yyss = yyssa;
1052 register short *yyssp; 1109 register short int *yyssp;
1053 1110
1054 /* The semantic value stack. */ 1111 /* The semantic value stack. */
1055 YYSTYPE yyvsa[YYINITDEPTH]; 1112 YYSTYPE yyvsa[YYINITDEPTH];
@@ -1086,6 +1143,9 @@ yyparse ()
1086 yyssp = yyss; 1143 yyssp = yyss;
1087 yyvsp = yyvs; 1144 yyvsp = yyvs;
1088 1145
1146
1147 yyvsp[0] = yylval;
1148
1089 goto yysetstate; 1149 goto yysetstate;
1090 1150
1091/*------------------------------------------------------------. 1151/*------------------------------------------------------------.
@@ -1111,7 +1171,7 @@ yyparse ()
1111 these so that the &'s don't force the real ones into 1171 these so that the &'s don't force the real ones into
1112 memory. */ 1172 memory. */
1113 YYSTYPE *yyvs1 = yyvs; 1173 YYSTYPE *yyvs1 = yyvs;
1114 short *yyss1 = yyss; 1174 short int *yyss1 = yyss;
1115 1175
1116 1176
1117 /* Each stack pointer address is followed by the size of the 1177 /* Each stack pointer address is followed by the size of the
@@ -1139,7 +1199,7 @@ yyparse ()
1139 yystacksize = YYMAXDEPTH; 1199 yystacksize = YYMAXDEPTH;
1140 1200
1141 { 1201 {
1142 short *yyss1 = yyss; 1202 short int *yyss1 = yyss;
1143 union yyalloc *yyptr = 1203 union yyalloc *yyptr =
1144 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); 1204 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1145 if (! yyptr) 1205 if (! yyptr)
@@ -1175,18 +1235,18 @@ yyparse ()
1175yybackup: 1235yybackup:
1176 1236
1177/* Do appropriate processing given the current state. */ 1237/* Do appropriate processing given the current state. */
1178/* Read a lookahead token if we need one and don't already have one. */ 1238/* Read a look-ahead token if we need one and don't already have one. */
1179/* yyresume: */ 1239/* yyresume: */
1180 1240
1181 /* First try to decide what to do without reference to lookahead token. */ 1241 /* First try to decide what to do without reference to look-ahead token. */
1182 1242
1183 yyn = yypact[yystate]; 1243 yyn = yypact[yystate];
1184 if (yyn == YYPACT_NINF) 1244 if (yyn == YYPACT_NINF)
1185 goto yydefault; 1245 goto yydefault;
1186 1246
1187 /* Not known => get a lookahead token if don't already have one. */ 1247 /* Not known => get a look-ahead token if don't already have one. */
1188 1248
1189 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ 1249 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1190 if (yychar == YYEMPTY) 1250 if (yychar == YYEMPTY)
1191 { 1251 {
1192 YYDPRINTF ((stderr, "Reading a token: ")); 1252 YYDPRINTF ((stderr, "Reading a token: "));
@@ -1201,7 +1261,7 @@ yybackup:
1201 else 1261 else
1202 { 1262 {
1203 yytoken = YYTRANSLATE (yychar); 1263 yytoken = YYTRANSLATE (yychar);
1204 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); 1264 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1205 } 1265 }
1206 1266
1207 /* If the proper action on seeing token YYTOKEN is to reduce or to 1267 /* If the proper action on seeing token YYTOKEN is to reduce or to
@@ -1221,8 +1281,8 @@ yybackup:
1221 if (yyn == YYFINAL) 1281 if (yyn == YYFINAL)
1222 YYACCEPT; 1282 YYACCEPT;
1223 1283
1224 /* Shift the lookahead token. */ 1284 /* Shift the look-ahead token. */
1225 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); 1285 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1226 1286
1227 /* Discard the token being shifted unless it is eof. */ 1287 /* Discard the token being shifted unless it is eof. */
1228 if (yychar != YYEOF) 1288 if (yychar != YYEOF)
@@ -1273,155 +1333,123 @@ yyreduce:
1273 { 1333 {
1274 case 8: 1334 case 8:
1275 1335
1276 { zconfprint("unexpected 'endmenu' statement"); ;} 1336 { zconf_error("unexpected end statement"); ;}
1277 break; 1337 break;
1278 1338
1279 case 9: 1339 case 9:
1280 1340
1281 { zconfprint("unexpected 'endif' statement"); ;} 1341 { zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); ;}
1282 break; 1342 break;
1283 1343
1284 case 10: 1344 case 10:
1285 1345
1286 { zconfprint("unexpected 'endchoice' statement"); ;} 1346 {
1347 zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name);
1348;}
1287 break; 1349 break;
1288 1350
1289 case 11: 1351 case 11:
1290 1352
1291 { zconfprint("syntax error"); yyerrok; ;} 1353 { zconf_error("invalid statement"); ;}
1292 break; 1354 break;
1293 1355
1294 case 18: 1356 case 25:
1295 1357
1296 { 1358 { zconf_error("unknown option \"%s\"", (yyvsp[-2].string)); ;}
1297 struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
1298 sym->flags |= SYMBOL_OPTIONAL;
1299 menu_add_entry(sym);
1300 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
1301;}
1302 break; 1359 break;
1303 1360
1304 case 19: 1361 case 26:
1305 1362
1306 { 1363 { zconf_error("invalid option"); ;}
1307 menu_end_entry();
1308 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
1309;}
1310 break; 1364 break;
1311 1365
1312 case 20: 1366 case 27:
1313 1367
1314 { 1368 {
1315 struct symbol *sym = sym_lookup(yyvsp[-1].string, 0); 1369 struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
1316 sym->flags |= SYMBOL_OPTIONAL; 1370 sym->flags |= SYMBOL_OPTIONAL;
1317 menu_add_entry(sym); 1371 menu_add_entry(sym);
1318 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string); 1372 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
1319;} 1373;}
1320 break; 1374 break;
1321 1375
1322 case 21: 1376 case 28:
1323 1377
1324 { 1378 {
1325 if (current_entry->prompt)
1326 current_entry->prompt->type = P_MENU;
1327 else
1328 zconfprint("warning: menuconfig statement without prompt");
1329 menu_end_entry(); 1379 menu_end_entry();
1330 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); 1380 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
1331;} 1381;}
1332 break; 1382 break;
1333 1383
1334 case 27:
1335
1336 {
1337 menu_set_type(S_TRISTATE);
1338 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
1339;}
1340 break;
1341
1342 case 28:
1343
1344 {
1345 menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
1346 menu_set_type(S_TRISTATE);
1347 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
1348;}
1349 break;
1350
1351 case 29: 1384 case 29:
1352 1385
1353 { 1386 {
1354 menu_set_type(S_BOOLEAN); 1387 struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
1355 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); 1388 sym->flags |= SYMBOL_OPTIONAL;
1389 menu_add_entry(sym);
1390 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
1356;} 1391;}
1357 break; 1392 break;
1358 1393
1359 case 30: 1394 case 30:
1360 1395
1361 { 1396 {
1362 menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); 1397 if (current_entry->prompt)
1363 menu_set_type(S_BOOLEAN); 1398 current_entry->prompt->type = P_MENU;
1364 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); 1399 else
1365;} 1400 zconfprint("warning: menuconfig statement without prompt");
1366 break; 1401 menu_end_entry();
1367 1402 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
1368 case 31:
1369
1370 {
1371 menu_set_type(S_INT);
1372 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
1373;}
1374 break;
1375
1376 case 32:
1377
1378 {
1379 menu_set_type(S_HEX);
1380 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
1381;} 1403;}
1382 break; 1404 break;
1383 1405
1384 case 33: 1406 case 37:
1385 1407
1386 { 1408 {
1387 menu_set_type(S_STRING); 1409 menu_set_type((yyvsp[-2].id)->stype);
1388 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno()); 1410 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
1411 zconf_curname(), zconf_lineno(),
1412 (yyvsp[-2].id)->stype);
1389;} 1413;}
1390 break; 1414 break;
1391 1415
1392 case 34: 1416 case 38:
1393 1417
1394 { 1418 {
1395 menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr); 1419 menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
1396 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 1420 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
1397;} 1421;}
1398 break; 1422 break;
1399 1423
1400 case 35: 1424 case 39:
1401 1425
1402 { 1426 {
1403 menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); 1427 menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr));
1404 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 1428 if ((yyvsp[-3].id)->stype != S_UNKNOWN)
1429 menu_set_type((yyvsp[-3].id)->stype);
1430 printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
1431 zconf_curname(), zconf_lineno(),
1432 (yyvsp[-3].id)->stype);
1405;} 1433;}
1406 break; 1434 break;
1407 1435
1408 case 36: 1436 case 40:
1409 1437
1410 { 1438 {
1411 menu_add_symbol(P_SELECT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr); 1439 menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
1412 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); 1440 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
1413;} 1441;}
1414 break; 1442 break;
1415 1443
1416 case 37: 1444 case 41:
1417 1445
1418 { 1446 {
1419 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,yyvsp[-3].symbol, yyvsp[-2].symbol), yyvsp[-1].expr); 1447 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr));
1420 printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); 1448 printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
1421;} 1449;}
1422 break; 1450 break;
1423 1451
1424 case 38: 1452 case 42:
1425 1453
1426 { 1454 {
1427 struct symbol *sym = sym_lookup(NULL, 0); 1455 struct symbol *sym = sym_lookup(NULL, 0);
@@ -1432,57 +1460,45 @@ yyreduce:
1432;} 1460;}
1433 break; 1461 break;
1434 1462
1435 case 39: 1463 case 43:
1436 1464
1437 { 1465 {
1438 menu_end_entry(); 1466 (yyval.menu) = menu_add_menu();
1439 menu_add_menu();
1440;} 1467;}
1441 break; 1468 break;
1442 1469
1443 case 40: 1470 case 44:
1444 1471
1445 { 1472 {
1446 if (zconf_endtoken(yyvsp[0].token, T_CHOICE, T_ENDCHOICE)) { 1473 if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) {
1447 menu_end_menu(); 1474 menu_end_menu();
1448 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); 1475 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
1449 } 1476 }
1450;} 1477;}
1451 break; 1478 break;
1452 1479
1453 case 42: 1480 case 52:
1454
1455 {
1456 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
1457 zconfnerrs++;
1458;}
1459 break;
1460
1461 case 48:
1462 1481
1463 { 1482 {
1464 menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr); 1483 menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
1465 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 1484 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
1466;} 1485;}
1467 break; 1486 break;
1468 1487
1469 case 49: 1488 case 53:
1470 1489
1471 { 1490 {
1472 menu_set_type(S_TRISTATE); 1491 if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) {
1473 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); 1492 menu_set_type((yyvsp[-2].id)->stype);
1493 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
1494 zconf_curname(), zconf_lineno(),
1495 (yyvsp[-2].id)->stype);
1496 } else
1497 YYERROR;
1474;} 1498;}
1475 break; 1499 break;
1476 1500
1477 case 50: 1501 case 54:
1478
1479 {
1480 menu_set_type(S_BOOLEAN);
1481 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
1482;}
1483 break;
1484
1485 case 51:
1486 1502
1487 { 1503 {
1488 current_entry->sym->flags |= SYMBOL_OPTIONAL; 1504 current_entry->sym->flags |= SYMBOL_OPTIONAL;
@@ -1490,115 +1506,89 @@ yyreduce:
1490;} 1506;}
1491 break; 1507 break;
1492 1508
1493 case 52: 1509 case 55:
1494 1510
1495 { 1511 {
1496 menu_add_symbol(P_DEFAULT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr); 1512 if ((yyvsp[-3].id)->stype == S_UNKNOWN) {
1497 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 1513 menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
1514 printd(DEBUG_PARSE, "%s:%d:default\n",
1515 zconf_curname(), zconf_lineno());
1516 } else
1517 YYERROR;
1498;} 1518;}
1499 break; 1519 break;
1500 1520
1501 case 55: 1521 case 58:
1502 1522
1503 { 1523 {
1504 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 1524 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
1505 menu_add_entry(NULL); 1525 menu_add_entry(NULL);
1506 menu_add_dep(yyvsp[-1].expr); 1526 menu_add_dep((yyvsp[-1].expr));
1507 menu_end_entry(); 1527 (yyval.menu) = menu_add_menu();
1508 menu_add_menu();
1509;} 1528;}
1510 break; 1529 break;
1511 1530
1512 case 56: 1531 case 59:
1513 1532
1514 { 1533 {
1515 if (zconf_endtoken(yyvsp[0].token, T_IF, T_ENDIF)) { 1534 if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) {
1516 menu_end_menu(); 1535 menu_end_menu();
1517 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); 1536 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
1518 } 1537 }
1519;} 1538;}
1520 break; 1539 break;
1521 1540
1522 case 58: 1541 case 65:
1523
1524 {
1525 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
1526 zconfnerrs++;
1527;}
1528 break;
1529
1530 case 63:
1531 1542
1532 { 1543 {
1533 menu_add_entry(NULL); 1544 menu_add_entry(NULL);
1534 menu_add_prompt(P_MENU, yyvsp[-1].string, NULL); 1545 menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL);
1535 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); 1546 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
1536;} 1547;}
1537 break; 1548 break;
1538 1549
1539 case 64: 1550 case 66:
1540 1551
1541 { 1552 {
1542 menu_end_entry(); 1553 (yyval.menu) = menu_add_menu();
1543 menu_add_menu();
1544;} 1554;}
1545 break; 1555 break;
1546 1556
1547 case 65: 1557 case 67:
1548 1558
1549 { 1559 {
1550 if (zconf_endtoken(yyvsp[0].token, T_MENU, T_ENDMENU)) { 1560 if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) {
1551 menu_end_menu(); 1561 menu_end_menu();
1552 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); 1562 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
1553 } 1563 }
1554;} 1564;}
1555 break; 1565 break;
1556 1566
1557 case 67:
1558
1559 {
1560 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
1561 zconfnerrs++;
1562;}
1563 break;
1564
1565 case 72:
1566
1567 { zconfprint("invalid menu option"); yyerrok; ;}
1568 break;
1569
1570 case 73: 1567 case 73:
1571 1568
1572 { 1569 {
1573 yyval.string = yyvsp[-1].string; 1570 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
1574 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string); 1571 zconf_nextfile((yyvsp[-1].string));
1575;} 1572;}
1576 break; 1573 break;
1577 1574
1578 case 74: 1575 case 74:
1579 1576
1580 { 1577 {
1581 zconf_nextfile(yyvsp[0].string);
1582;}
1583 break;
1584
1585 case 75:
1586
1587 {
1588 menu_add_entry(NULL); 1578 menu_add_entry(NULL);
1589 menu_add_prompt(P_COMMENT, yyvsp[-1].string, NULL); 1579 menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL);
1590 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); 1580 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
1591;} 1581;}
1592 break; 1582 break;
1593 1583
1594 case 76: 1584 case 75:
1595 1585
1596 { 1586 {
1597 menu_end_entry(); 1587 menu_end_entry();
1598;} 1588;}
1599 break; 1589 break;
1600 1590
1601 case 77: 1591 case 76:
1602 1592
1603 { 1593 {
1604 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); 1594 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
@@ -1606,17 +1596,17 @@ yyreduce:
1606;} 1596;}
1607 break; 1597 break;
1608 1598
1609 case 78: 1599 case 77:
1610 1600
1611 { 1601 {
1612 current_entry->sym->help = yyvsp[0].string; 1602 current_entry->sym->help = (yyvsp[0].string);
1613;} 1603;}
1614 break; 1604 break;
1615 1605
1616 case 82: 1606 case 82:
1617 1607
1618 { 1608 {
1619 menu_add_dep(yyvsp[-1].expr); 1609 menu_add_dep((yyvsp[-1].expr));
1620 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); 1610 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
1621;} 1611;}
1622 break; 1612 break;
@@ -1624,7 +1614,7 @@ yyreduce:
1624 case 83: 1614 case 83:
1625 1615
1626 { 1616 {
1627 menu_add_dep(yyvsp[-1].expr); 1617 menu_add_dep((yyvsp[-1].expr));
1628 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); 1618 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
1629;} 1619;}
1630 break; 1620 break;
@@ -1632,7 +1622,7 @@ yyreduce:
1632 case 84: 1622 case 84:
1633 1623
1634 { 1624 {
1635 menu_add_dep(yyvsp[-1].expr); 1625 menu_add_dep((yyvsp[-1].expr));
1636 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); 1626 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
1637;} 1627;}
1638 break; 1628 break;
@@ -1640,84 +1630,84 @@ yyreduce:
1640 case 86: 1630 case 86:
1641 1631
1642 { 1632 {
1643 menu_add_prompt(P_PROMPT, yyvsp[-1].string, yyvsp[0].expr); 1633 menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr));
1644;} 1634;}
1645 break; 1635 break;
1646 1636
1647 case 89: 1637 case 89:
1648 1638
1649 { yyval.token = T_ENDMENU; ;} 1639 { (yyval.id) = (yyvsp[-1].id); ;}
1650 break; 1640 break;
1651 1641
1652 case 90: 1642 case 90:
1653 1643
1654 { yyval.token = T_ENDCHOICE; ;} 1644 { (yyval.id) = (yyvsp[-1].id); ;}
1655 break; 1645 break;
1656 1646
1657 case 91: 1647 case 91:
1658 1648
1659 { yyval.token = T_ENDIF; ;} 1649 { (yyval.id) = (yyvsp[-1].id); ;}
1660 break; 1650 break;
1661 1651
1662 case 94: 1652 case 94:
1663 1653
1664 { yyval.expr = NULL; ;} 1654 { (yyval.expr) = NULL; ;}
1665 break; 1655 break;
1666 1656
1667 case 95: 1657 case 95:
1668 1658
1669 { yyval.expr = yyvsp[0].expr; ;} 1659 { (yyval.expr) = (yyvsp[0].expr); ;}
1670 break; 1660 break;
1671 1661
1672 case 96: 1662 case 96:
1673 1663
1674 { yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;} 1664 { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;}
1675 break; 1665 break;
1676 1666
1677 case 97: 1667 case 97:
1678 1668
1679 { yyval.expr = expr_alloc_comp(E_EQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;} 1669 { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
1680 break; 1670 break;
1681 1671
1682 case 98: 1672 case 98:
1683 1673
1684 { yyval.expr = expr_alloc_comp(E_UNEQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;} 1674 { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
1685 break; 1675 break;
1686 1676
1687 case 99: 1677 case 99:
1688 1678
1689 { yyval.expr = yyvsp[-1].expr; ;} 1679 { (yyval.expr) = (yyvsp[-1].expr); ;}
1690 break; 1680 break;
1691 1681
1692 case 100: 1682 case 100:
1693 1683
1694 { yyval.expr = expr_alloc_one(E_NOT, yyvsp[0].expr); ;} 1684 { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); ;}
1695 break; 1685 break;
1696 1686
1697 case 101: 1687 case 101:
1698 1688
1699 { yyval.expr = expr_alloc_two(E_OR, yyvsp[-2].expr, yyvsp[0].expr); ;} 1689 { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
1700 break; 1690 break;
1701 1691
1702 case 102: 1692 case 102:
1703 1693
1704 { yyval.expr = expr_alloc_two(E_AND, yyvsp[-2].expr, yyvsp[0].expr); ;} 1694 { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
1705 break; 1695 break;
1706 1696
1707 case 103: 1697 case 103:
1708 1698
1709 { yyval.symbol = sym_lookup(yyvsp[0].string, 0); free(yyvsp[0].string); ;} 1699 { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); ;}
1710 break; 1700 break;
1711 1701
1712 case 104: 1702 case 104:
1713 1703
1714 { yyval.symbol = sym_lookup(yyvsp[0].string, 1); free(yyvsp[0].string); ;} 1704 { (yyval.symbol) = sym_lookup((yyvsp[0].string), 1); free((yyvsp[0].string)); ;}
1715 break; 1705 break;
1716 1706
1717 1707
1718 } 1708 }
1719 1709
1720/* Line 999 of yacc.c. */ 1710/* Line 1037 of yacc.c. */
1721 1711
1722 1712
1723 yyvsp -= yylen; 1713 yyvsp -= yylen;
@@ -1759,18 +1749,33 @@ yyerrlab:
1759 { 1749 {
1760 YYSIZE_T yysize = 0; 1750 YYSIZE_T yysize = 0;
1761 int yytype = YYTRANSLATE (yychar); 1751 int yytype = YYTRANSLATE (yychar);
1752 const char* yyprefix;
1762 char *yymsg; 1753 char *yymsg;
1763 int yyx, yycount; 1754 int yyx;
1764 1755
1765 yycount = 0;
1766 /* Start YYX at -YYN if negative to avoid negative indexes in 1756 /* Start YYX at -YYN if negative to avoid negative indexes in
1767 YYCHECK. */ 1757 YYCHECK. */
1768 for (yyx = yyn < 0 ? -yyn : 0; 1758 int yyxbegin = yyn < 0 ? -yyn : 0;
1769 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) 1759
1760 /* Stay within bounds of both yycheck and yytname. */
1761 int yychecklim = YYLAST - yyn;
1762 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1763 int yycount = 0;
1764
1765 yyprefix = ", expecting ";
1766 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1770 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) 1767 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1771 yysize += yystrlen (yytname[yyx]) + 15, yycount++; 1768 {
1772 yysize += yystrlen ("syntax error, unexpected ") + 1; 1769 yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
1773 yysize += yystrlen (yytname[yytype]); 1770 yycount += 1;
1771 if (yycount == 5)
1772 {
1773 yysize = 0;
1774 break;
1775 }
1776 }
1777 yysize += (sizeof ("syntax error, unexpected ")
1778 + yystrlen (yytname[yytype]));
1774 yymsg = (char *) YYSTACK_ALLOC (yysize); 1779 yymsg = (char *) YYSTACK_ALLOC (yysize);
1775 if (yymsg != 0) 1780 if (yymsg != 0)
1776 { 1781 {
@@ -1779,16 +1784,13 @@ yyerrlab:
1779 1784
1780 if (yycount < 5) 1785 if (yycount < 5)
1781 { 1786 {
1782 yycount = 0; 1787 yyprefix = ", expecting ";
1783 for (yyx = yyn < 0 ? -yyn : 0; 1788 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1784 yyx < (int) (sizeof (yytname) / sizeof (char *));
1785 yyx++)
1786 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) 1789 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1787 { 1790 {
1788 const char *yyq = ! yycount ? ", expecting " : " or "; 1791 yyp = yystpcpy (yyp, yyprefix);
1789 yyp = yystpcpy (yyp, yyq);
1790 yyp = yystpcpy (yyp, yytname[yyx]); 1792 yyp = yystpcpy (yyp, yytname[yyx]);
1791 yycount++; 1793 yyprefix = " or ";
1792 } 1794 }
1793 } 1795 }
1794 yyerror (yymsg); 1796 yyerror (yymsg);
@@ -1806,38 +1808,57 @@ yyerrlab:
1806 1808
1807 if (yyerrstatus == 3) 1809 if (yyerrstatus == 3)
1808 { 1810 {
1809 /* If just tried and failed to reuse lookahead token after an 1811 /* If just tried and failed to reuse look-ahead token after an
1810 error, discard it. */ 1812 error, discard it. */
1811 1813
1812 /* Return failure if at end of input. */ 1814 if (yychar <= YYEOF)
1813 if (yychar == YYEOF)
1814 { 1815 {
1815 /* Pop the error token. */ 1816 /* If at end of input, pop the error token,
1816 YYPOPSTACK; 1817 then the rest of the stack, then return failure. */
1817 /* Pop the rest of the stack. */ 1818 if (yychar == YYEOF)
1818 while (yyss < yyssp) 1819 for (;;)
1819 { 1820 {
1820 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); 1821
1821 yydestruct (yystos[*yyssp], yyvsp); 1822 YYPOPSTACK;
1822 YYPOPSTACK; 1823 if (yyssp == yyss)
1823 } 1824 YYABORT;
1824 YYABORT; 1825 yydestruct ("Error: popping",
1826 yystos[*yyssp], yyvsp);
1827 }
1825 } 1828 }
1826 1829 else
1827 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); 1830 {
1828 yydestruct (yytoken, &yylval); 1831 yydestruct ("Error: discarding", yytoken, &yylval);
1829 yychar = YYEMPTY; 1832 yychar = YYEMPTY;
1830 1833 }
1831 } 1834 }
1832 1835
1833 /* Else will try to reuse lookahead token after shifting the error 1836 /* Else will try to reuse look-ahead token after shifting the error
1834 token. */ 1837 token. */
1835 goto yyerrlab1; 1838 goto yyerrlab1;
1836 1839
1837 1840
1838/*----------------------------------------------------. 1841/*---------------------------------------------------.
1839| yyerrlab1 -- error raised explicitly by an action. | 1842| yyerrorlab -- error raised explicitly by YYERROR. |
1840`----------------------------------------------------*/ 1843`---------------------------------------------------*/
1844yyerrorlab:
1845
1846#ifdef __GNUC__
1847 /* Pacify GCC when the user code never invokes YYERROR and the label
1848 yyerrorlab therefore never appears in user code. */
1849 if (0)
1850 goto yyerrorlab;
1851#endif
1852
1853yyvsp -= yylen;
1854 yyssp -= yylen;
1855 yystate = *yyssp;
1856 goto yyerrlab1;
1857
1858
1859/*-------------------------------------------------------------.
1860| yyerrlab1 -- common code for both syntax error and YYERROR. |
1861`-------------------------------------------------------------*/
1841yyerrlab1: 1862yyerrlab1:
1842 yyerrstatus = 3; /* Each real token shifted decrements this. */ 1863 yyerrstatus = 3; /* Each real token shifted decrements this. */
1843 1864
@@ -1859,22 +1880,22 @@ yyerrlab1:
1859 if (yyssp == yyss) 1880 if (yyssp == yyss)
1860 YYABORT; 1881 YYABORT;
1861 1882
1862 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1863 yydestruct (yystos[yystate], yyvsp);
1864 yyvsp--;
1865 yystate = *--yyssp;
1866 1883
1884 yydestruct ("Error: popping", yystos[yystate], yyvsp);
1885 YYPOPSTACK;
1886 yystate = *yyssp;
1867 YY_STACK_PRINT (yyss, yyssp); 1887 YY_STACK_PRINT (yyss, yyssp);
1868 } 1888 }
1869 1889
1870 if (yyn == YYFINAL) 1890 if (yyn == YYFINAL)
1871 YYACCEPT; 1891 YYACCEPT;
1872 1892
1873 YYDPRINTF ((stderr, "Shifting error token, "));
1874
1875 *++yyvsp = yylval; 1893 *++yyvsp = yylval;
1876 1894
1877 1895
1896 /* Shift the error token. */
1897 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
1898
1878 yystate = yyn; 1899 yystate = yyn;
1879 goto yynewstate; 1900 goto yynewstate;
1880 1901
@@ -1890,6 +1911,9 @@ yyacceptlab:
1890| yyabortlab -- YYABORT comes here. | 1911| yyabortlab -- YYABORT comes here. |
1891`-----------------------------------*/ 1912`-----------------------------------*/
1892yyabortlab: 1913yyabortlab:
1914 yydestruct ("Error: discarding lookahead",
1915 yytoken, &yylval);
1916 yychar = YYEMPTY;
1893 yyresult = 1; 1917 yyresult = 1;
1894 goto yyreturn; 1918 goto yyreturn;
1895 1919
@@ -1927,16 +1951,16 @@ void conf_parse(const char *name)
1927 modules_sym = sym_lookup("MODULES", 0); 1951 modules_sym = sym_lookup("MODULES", 0);
1928 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); 1952 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
1929 1953
1930 //zconfdebug = 1; 1954#if YYDEBUG
1955 if (getenv("ZCONF_DEBUG"))
1956 zconfdebug = 1;
1957#endif
1931 zconfparse(); 1958 zconfparse();
1932 if (zconfnerrs) 1959 if (zconfnerrs)
1933 exit(1); 1960 exit(1);
1934 menu_finalize(&rootmenu); 1961 menu_finalize(&rootmenu);
1935 for_all_symbols(i, sym) { 1962 for_all_symbols(i, sym) {
1936 if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) 1963 sym_check_deps(sym);
1937 printf("\n");
1938 else
1939 sym->flags |= SYMBOL_CHECK_DONE;
1940 } 1964 }
1941 1965
1942 sym_change_count = 1; 1966 sym_change_count = 1;
@@ -1951,20 +1975,25 @@ const char *zconf_tokenname(int token)
1951 case T_ENDCHOICE: return "endchoice"; 1975 case T_ENDCHOICE: return "endchoice";
1952 case T_IF: return "if"; 1976 case T_IF: return "if";
1953 case T_ENDIF: return "endif"; 1977 case T_ENDIF: return "endif";
1978 case T_DEPENDS: return "depends";
1954 } 1979 }
1955 return "<token>"; 1980 return "<token>";
1956} 1981}
1957 1982
1958static bool zconf_endtoken(int token, int starttoken, int endtoken) 1983static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
1959{ 1984{
1960 if (token != endtoken) { 1985 if (id->token != endtoken) {
1961 zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); 1986 zconf_error("unexpected '%s' within %s block",
1987 kconf_id_strings + id->name, zconf_tokenname(starttoken));
1962 zconfnerrs++; 1988 zconfnerrs++;
1963 return false; 1989 return false;
1964 } 1990 }
1965 if (current_menu->file != current_file) { 1991 if (current_menu->file != current_file) {
1966 zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); 1992 zconf_error("'%s' in different file than '%s'",
1967 zconfprint("location of the '%s'", zconf_tokenname(starttoken)); 1993 kconf_id_strings + id->name, zconf_tokenname(starttoken));
1994 fprintf(stderr, "%s:%d: location of the '%s'\n",
1995 current_menu->file->name, current_menu->lineno,
1996 zconf_tokenname(starttoken));
1968 zconfnerrs++; 1997 zconfnerrs++;
1969 return false; 1998 return false;
1970 } 1999 }
@@ -1975,7 +2004,19 @@ static void zconfprint(const char *err, ...)
1975{ 2004{
1976 va_list ap; 2005 va_list ap;
1977 2006
1978 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); 2007 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
2008 va_start(ap, err);
2009 vfprintf(stderr, err, ap);
2010 va_end(ap);
2011 fprintf(stderr, "\n");
2012}
2013
2014static void zconf_error(const char *err, ...)
2015{
2016 va_list ap;
2017
2018 zconfnerrs++;
2019 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
1979 va_start(ap, err); 2020 va_start(ap, err);
1980 vfprintf(stderr, err, ap); 2021 vfprintf(stderr, err, ap);
1981 va_end(ap); 2022 va_end(ap);
@@ -1984,7 +2025,9 @@ static void zconfprint(const char *err, ...)
1984 2025
1985static void zconferror(const char *err) 2026static void zconferror(const char *err)
1986{ 2027{
2028#if YYDEBUG
1987 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); 2029 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
2030#endif
1988} 2031}
1989 2032
1990void print_quoted_string(FILE *out, const char *str) 2033void print_quoted_string(FILE *out, const char *str)
diff --git a/scripts/kconfig/zconf.tab.h_shipped b/scripts/kconfig/zconf.tab.h_shipped
deleted file mode 100644
index 3b191ef59985..000000000000
--- a/scripts/kconfig/zconf.tab.h_shipped
+++ /dev/null
@@ -1,125 +0,0 @@
1/* A Bison parser, made from zconf.y, by GNU bison 1.75. */
2
3/* Skeleton parser for Yacc-like parsing with Bison,
4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
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, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21/* As a special exception, when this file is copied by Bison into a
22 Bison output file, you may use that output file without restriction.
23 This special exception was added by the Free Software Foundation
24 in version 1.24 of Bison. */
25
26#ifndef BISON_ZCONF_TAB_H
27# define BISON_ZCONF_TAB_H
28
29/* Tokens. */
30#ifndef YYTOKENTYPE
31# define YYTOKENTYPE
32 /* Put the tokens into the symbol table, so that GDB and other debuggers
33 know about them. */
34 enum yytokentype {
35 T_MAINMENU = 258,
36 T_MENU = 259,
37 T_ENDMENU = 260,
38 T_SOURCE = 261,
39 T_CHOICE = 262,
40 T_ENDCHOICE = 263,
41 T_COMMENT = 264,
42 T_CONFIG = 265,
43 T_HELP = 266,
44 T_HELPTEXT = 267,
45 T_IF = 268,
46 T_ENDIF = 269,
47 T_DEPENDS = 270,
48 T_REQUIRES = 271,
49 T_OPTIONAL = 272,
50 T_PROMPT = 273,
51 T_DEFAULT = 274,
52 T_TRISTATE = 275,
53 T_BOOLEAN = 276,
54 T_INT = 277,
55 T_HEX = 278,
56 T_WORD = 279,
57 T_STRING = 280,
58 T_UNEQUAL = 281,
59 T_EOF = 282,
60 T_EOL = 283,
61 T_CLOSE_PAREN = 284,
62 T_OPEN_PAREN = 285,
63 T_ON = 286,
64 T_OR = 287,
65 T_AND = 288,
66 T_EQUAL = 289,
67 T_NOT = 290
68 };
69#endif
70#define T_MAINMENU 258
71#define T_MENU 259
72#define T_ENDMENU 260
73#define T_SOURCE 261
74#define T_CHOICE 262
75#define T_ENDCHOICE 263
76#define T_COMMENT 264
77#define T_CONFIG 265
78#define T_HELP 266
79#define T_HELPTEXT 267
80#define T_IF 268
81#define T_ENDIF 269
82#define T_DEPENDS 270
83#define T_REQUIRES 271
84#define T_OPTIONAL 272
85#define T_PROMPT 273
86#define T_DEFAULT 274
87#define T_TRISTATE 275
88#define T_BOOLEAN 276
89#define T_INT 277
90#define T_HEX 278
91#define T_WORD 279
92#define T_STRING 280
93#define T_UNEQUAL 281
94#define T_EOF 282
95#define T_EOL 283
96#define T_CLOSE_PAREN 284
97#define T_OPEN_PAREN 285
98#define T_ON 286
99#define T_OR 287
100#define T_AND 288
101#define T_EQUAL 289
102#define T_NOT 290
103
104
105
106
107#ifndef YYSTYPE
108#line 33 "zconf.y"
109typedef union {
110 int token;
111 char *string;
112 struct symbol *symbol;
113 struct expr *expr;
114 struct menu *menu;
115} yystype;
116/* Line 1281 of /usr/share/bison/yacc.c. */
117#line 118 "zconf.tab.h"
118# define YYSTYPE yystype
119#endif
120
121extern YYSTYPE zconflval;
122
123
124#endif /* not BISON_ZCONF_TAB_H */
125
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index e1a0f455d4a8..1f61fba6aa28 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -11,6 +11,11 @@
11#include <string.h> 11#include <string.h>
12#include <stdbool.h> 12#include <stdbool.h>
13 13
14#define LKC_DIRECT_LINK
15#include "lkc.h"
16
17#include "zconf.hash.c"
18
14#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) 19#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
15 20
16#define PRINTD 0x0001 21#define PRINTD 0x0001
@@ -20,61 +25,59 @@ int cdebug = PRINTD;
20 25
21extern int zconflex(void); 26extern int zconflex(void);
22static void zconfprint(const char *err, ...); 27static void zconfprint(const char *err, ...);
28static void zconf_error(const char *err, ...);
23static void zconferror(const char *err); 29static void zconferror(const char *err);
24static bool zconf_endtoken(int token, int starttoken, int endtoken); 30static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
25 31
26struct symbol *symbol_hash[257]; 32struct symbol *symbol_hash[257];
27 33
28static struct menu *current_menu, *current_entry; 34static struct menu *current_menu, *current_entry;
29 35
36#define YYDEBUG 0
37#if YYDEBUG
30#define YYERROR_VERBOSE 38#define YYERROR_VERBOSE
39#endif
31%} 40%}
32%expect 40 41%expect 26
33 42
34%union 43%union
35{ 44{
36 int token;
37 char *string; 45 char *string;
46 struct file *file;
38 struct symbol *symbol; 47 struct symbol *symbol;
39 struct expr *expr; 48 struct expr *expr;
40 struct menu *menu; 49 struct menu *menu;
50 struct kconf_id *id;
41} 51}
42 52
43%token T_MAINMENU 53%token <id>T_MAINMENU
44%token T_MENU 54%token <id>T_MENU
45%token T_ENDMENU 55%token <id>T_ENDMENU
46%token T_SOURCE 56%token <id>T_SOURCE
47%token T_CHOICE 57%token <id>T_CHOICE
48%token T_ENDCHOICE 58%token <id>T_ENDCHOICE
49%token T_COMMENT 59%token <id>T_COMMENT
50%token T_CONFIG 60%token <id>T_CONFIG
51%token T_MENUCONFIG 61%token <id>T_MENUCONFIG
52%token T_HELP 62%token <id>T_HELP
53%token <string> T_HELPTEXT 63%token <string> T_HELPTEXT
54%token T_IF 64%token <id>T_IF
55%token T_ENDIF 65%token <id>T_ENDIF
56%token T_DEPENDS 66%token <id>T_DEPENDS
57%token T_REQUIRES 67%token <id>T_REQUIRES
58%token T_OPTIONAL 68%token <id>T_OPTIONAL
59%token T_PROMPT 69%token <id>T_PROMPT
60%token T_DEFAULT 70%token <id>T_TYPE
61%token T_TRISTATE 71%token <id>T_DEFAULT
62%token T_DEF_TRISTATE 72%token <id>T_SELECT
63%token T_BOOLEAN 73%token <id>T_RANGE
64%token T_DEF_BOOLEAN 74%token <id>T_ON
65%token T_STRING
66%token T_INT
67%token T_HEX
68%token <string> T_WORD 75%token <string> T_WORD
69%token <string> T_WORD_QUOTE 76%token <string> T_WORD_QUOTE
70%token T_UNEQUAL 77%token T_UNEQUAL
71%token T_EOF
72%token T_EOL
73%token T_CLOSE_PAREN 78%token T_CLOSE_PAREN
74%token T_OPEN_PAREN 79%token T_OPEN_PAREN
75%token T_ON 80%token T_EOL
76%token T_SELECT
77%token T_RANGE
78 81
79%left T_OR 82%left T_OR
80%left T_AND 83%left T_AND
@@ -82,38 +85,54 @@ static struct menu *current_menu, *current_entry;
82%nonassoc T_NOT 85%nonassoc T_NOT
83 86
84%type <string> prompt 87%type <string> prompt
85%type <string> source
86%type <symbol> symbol 88%type <symbol> symbol
87%type <expr> expr 89%type <expr> expr
88%type <expr> if_expr 90%type <expr> if_expr
89%type <token> end 91%type <id> end
92%type <id> option_name
93%type <menu> if_entry menu_entry choice_entry
94
95%destructor {
96 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
97 $$->file->name, $$->lineno);
98 if (current_menu == $$)
99 menu_end_menu();
100} if_entry menu_entry choice_entry
90 101
91%{
92#define LKC_DIRECT_LINK
93#include "lkc.h"
94%}
95%% 102%%
96input: /* empty */ 103input: stmt_list;
97 | input block 104
105stmt_list:
106 /* empty */
107 | stmt_list common_stmt
108 | stmt_list choice_stmt
109 | stmt_list menu_stmt
110 | stmt_list T_MAINMENU prompt nl
111 | stmt_list end { zconf_error("unexpected end statement"); }
112 | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
113 | stmt_list option_name error T_EOL
114{
115 zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
116}
117 | stmt_list error T_EOL { zconf_error("invalid statement"); }
98; 118;
99 119
100block: common_block 120option_name:
101 | choice_stmt 121 T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
102 | menu_stmt
103 | T_MAINMENU prompt nl_or_eof
104 | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
105 | T_ENDIF { zconfprint("unexpected 'endif' statement"); }
106 | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
107 | error nl_or_eof { zconfprint("syntax error"); yyerrok; }
108; 122;
109 123
110common_block: 124common_stmt:
111 if_stmt 125 T_EOL
126 | if_stmt
112 | comment_stmt 127 | comment_stmt
113 | config_stmt 128 | config_stmt
114 | menuconfig_stmt 129 | menuconfig_stmt
115 | source_stmt 130 | source_stmt
116 | nl_or_eof 131;
132
133option_error:
134 T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); }
135 | error T_EOL { zconf_error("invalid option"); }
117; 136;
118 137
119 138
@@ -156,51 +175,16 @@ config_option_list:
156 | config_option_list config_option 175 | config_option_list config_option
157 | config_option_list depends 176 | config_option_list depends
158 | config_option_list help 177 | config_option_list help
178 | config_option_list option_error
159 | config_option_list T_EOL 179 | config_option_list T_EOL
160; 180;
161 181
162config_option: T_TRISTATE prompt_stmt_opt T_EOL 182config_option: T_TYPE prompt_stmt_opt T_EOL
163{ 183{
164 menu_set_type(S_TRISTATE); 184 menu_set_type($1->stype);
165 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); 185 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
166}; 186 zconf_curname(), zconf_lineno(),
167 187 $1->stype);
168config_option: T_DEF_TRISTATE expr if_expr T_EOL
169{
170 menu_add_expr(P_DEFAULT, $2, $3);
171 menu_set_type(S_TRISTATE);
172 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
173};
174
175config_option: T_BOOLEAN prompt_stmt_opt T_EOL
176{
177 menu_set_type(S_BOOLEAN);
178 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
179};
180
181config_option: T_DEF_BOOLEAN expr if_expr T_EOL
182{
183 menu_add_expr(P_DEFAULT, $2, $3);
184 menu_set_type(S_BOOLEAN);
185 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
186};
187
188config_option: T_INT prompt_stmt_opt T_EOL
189{
190 menu_set_type(S_INT);
191 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
192};
193
194config_option: T_HEX prompt_stmt_opt T_EOL
195{
196 menu_set_type(S_HEX);
197 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
198};
199
200config_option: T_STRING prompt_stmt_opt T_EOL
201{
202 menu_set_type(S_STRING);
203 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
204}; 188};
205 189
206config_option: T_PROMPT prompt if_expr T_EOL 190config_option: T_PROMPT prompt if_expr T_EOL
@@ -212,7 +196,11 @@ config_option: T_PROMPT prompt if_expr T_EOL
212config_option: T_DEFAULT expr if_expr T_EOL 196config_option: T_DEFAULT expr if_expr T_EOL
213{ 197{
214 menu_add_expr(P_DEFAULT, $2, $3); 198 menu_add_expr(P_DEFAULT, $2, $3);
215 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 199 if ($1->stype != S_UNKNOWN)
200 menu_set_type($1->stype);
201 printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
202 zconf_curname(), zconf_lineno(),
203 $1->stype);
216}; 204};
217 205
218config_option: T_SELECT T_WORD if_expr T_EOL 206config_option: T_SELECT T_WORD if_expr T_EOL
@@ -240,8 +228,7 @@ choice: T_CHOICE T_EOL
240 228
241choice_entry: choice choice_option_list 229choice_entry: choice choice_option_list
242{ 230{
243 menu_end_entry(); 231 $$ = menu_add_menu();
244 menu_add_menu();
245}; 232};
246 233
247choice_end: end 234choice_end: end
@@ -252,13 +239,8 @@ choice_end: end
252 } 239 }
253}; 240};
254 241
255choice_stmt: 242choice_stmt: choice_entry choice_block choice_end
256 choice_entry choice_block choice_end 243;
257 | choice_entry choice_block
258{
259 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
260 zconfnerrs++;
261};
262 244
263choice_option_list: 245choice_option_list:
264 /* empty */ 246 /* empty */
@@ -266,6 +248,7 @@ choice_option_list:
266 | choice_option_list depends 248 | choice_option_list depends
267 | choice_option_list help 249 | choice_option_list help
268 | choice_option_list T_EOL 250 | choice_option_list T_EOL
251 | choice_option_list option_error
269; 252;
270 253
271choice_option: T_PROMPT prompt if_expr T_EOL 254choice_option: T_PROMPT prompt if_expr T_EOL
@@ -274,16 +257,15 @@ choice_option: T_PROMPT prompt if_expr T_EOL
274 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 257 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
275}; 258};
276 259
277choice_option: T_TRISTATE prompt_stmt_opt T_EOL 260choice_option: T_TYPE prompt_stmt_opt T_EOL
278{
279 menu_set_type(S_TRISTATE);
280 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
281};
282
283choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
284{ 261{
285 menu_set_type(S_BOOLEAN); 262 if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) {
286 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); 263 menu_set_type($1->stype);
264 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
265 zconf_curname(), zconf_lineno(),
266 $1->stype);
267 } else
268 YYERROR;
287}; 269};
288 270
289choice_option: T_OPTIONAL T_EOL 271choice_option: T_OPTIONAL T_EOL
@@ -294,24 +276,27 @@ choice_option: T_OPTIONAL T_EOL
294 276
295choice_option: T_DEFAULT T_WORD if_expr T_EOL 277choice_option: T_DEFAULT T_WORD if_expr T_EOL
296{ 278{
297 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); 279 if ($1->stype == S_UNKNOWN) {
298 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 280 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
281 printd(DEBUG_PARSE, "%s:%d:default\n",
282 zconf_curname(), zconf_lineno());
283 } else
284 YYERROR;
299}; 285};
300 286
301choice_block: 287choice_block:
302 /* empty */ 288 /* empty */
303 | choice_block common_block 289 | choice_block common_stmt
304; 290;
305 291
306/* if entry */ 292/* if entry */
307 293
308if: T_IF expr T_EOL 294if_entry: T_IF expr nl
309{ 295{
310 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 296 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
311 menu_add_entry(NULL); 297 menu_add_entry(NULL);
312 menu_add_dep($2); 298 menu_add_dep($2);
313 menu_end_entry(); 299 $$ = menu_add_menu();
314 menu_add_menu();
315}; 300};
316 301
317if_end: end 302if_end: end
@@ -322,17 +307,12 @@ if_end: end
322 } 307 }
323}; 308};
324 309
325if_stmt: 310if_stmt: if_entry if_block if_end
326 if if_block if_end 311;
327 | if if_block
328{
329 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
330 zconfnerrs++;
331};
332 312
333if_block: 313if_block:
334 /* empty */ 314 /* empty */
335 | if_block common_block 315 | if_block common_stmt
336 | if_block menu_stmt 316 | if_block menu_stmt
337 | if_block choice_stmt 317 | if_block choice_stmt
338; 318;
@@ -348,8 +328,7 @@ menu: T_MENU prompt T_EOL
348 328
349menu_entry: menu depends_list 329menu_entry: menu depends_list
350{ 330{
351 menu_end_entry(); 331 $$ = menu_add_menu();
352 menu_add_menu();
353}; 332};
354 333
355menu_end: end 334menu_end: end
@@ -360,31 +339,20 @@ menu_end: end
360 } 339 }
361}; 340};
362 341
363menu_stmt: 342menu_stmt: menu_entry menu_block menu_end
364 menu_entry menu_block menu_end 343;
365 | menu_entry menu_block
366{
367 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
368 zconfnerrs++;
369};
370 344
371menu_block: 345menu_block:
372 /* empty */ 346 /* empty */
373 | menu_block common_block 347 | menu_block common_stmt
374 | menu_block menu_stmt 348 | menu_block menu_stmt
375 | menu_block choice_stmt 349 | menu_block choice_stmt
376 | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
377; 350;
378 351
379source: T_SOURCE prompt T_EOL 352source_stmt: T_SOURCE prompt T_EOL
380{ 353{
381 $$ = $2;
382 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); 354 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
383}; 355 zconf_nextfile($2);
384
385source_stmt: source
386{
387 zconf_nextfile($1);
388}; 356};
389 357
390/* comment entry */ 358/* comment entry */
@@ -416,9 +384,11 @@ help: help_start T_HELPTEXT
416 384
417/* depends option */ 385/* depends option */
418 386
419depends_list: /* empty */ 387depends_list:
420 | depends_list depends 388 /* empty */
421 | depends_list T_EOL 389 | depends_list depends
390 | depends_list T_EOL
391 | depends_list option_error
422; 392;
423 393
424depends: T_DEPENDS T_ON expr T_EOL 394depends: T_DEPENDS T_ON expr T_EOL
@@ -450,13 +420,15 @@ prompt: T_WORD
450 | T_WORD_QUOTE 420 | T_WORD_QUOTE
451; 421;
452 422
453end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; } 423end: T_ENDMENU T_EOL { $$ = $1; }
454 | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; } 424 | T_ENDCHOICE T_EOL { $$ = $1; }
455 | T_ENDIF nl_or_eof { $$ = T_ENDIF; } 425 | T_ENDIF T_EOL { $$ = $1; }
456; 426;
457 427
458nl_or_eof: 428nl:
459 T_EOL | T_EOF; 429 T_EOL
430 | nl T_EOL
431;
460 432
461if_expr: /* empty */ { $$ = NULL; } 433if_expr: /* empty */ { $$ = NULL; }
462 | T_IF expr { $$ = $2; } 434 | T_IF expr { $$ = $2; }
@@ -489,16 +461,16 @@ void conf_parse(const char *name)
489 modules_sym = sym_lookup("MODULES", 0); 461 modules_sym = sym_lookup("MODULES", 0);
490 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); 462 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
491 463
492 //zconfdebug = 1; 464#if YYDEBUG
465 if (getenv("ZCONF_DEBUG"))
466 zconfdebug = 1;
467#endif
493 zconfparse(); 468 zconfparse();
494 if (zconfnerrs) 469 if (zconfnerrs)
495 exit(1); 470 exit(1);
496 menu_finalize(&rootmenu); 471 menu_finalize(&rootmenu);
497 for_all_symbols(i, sym) { 472 for_all_symbols(i, sym) {
498 if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) 473 sym_check_deps(sym);
499 printf("\n");
500 else
501 sym->flags |= SYMBOL_CHECK_DONE;
502 } 474 }
503 475
504 sym_change_count = 1; 476 sym_change_count = 1;
@@ -513,20 +485,25 @@ const char *zconf_tokenname(int token)
513 case T_ENDCHOICE: return "endchoice"; 485 case T_ENDCHOICE: return "endchoice";
514 case T_IF: return "if"; 486 case T_IF: return "if";
515 case T_ENDIF: return "endif"; 487 case T_ENDIF: return "endif";
488 case T_DEPENDS: return "depends";
516 } 489 }
517 return "<token>"; 490 return "<token>";
518} 491}
519 492
520static bool zconf_endtoken(int token, int starttoken, int endtoken) 493static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
521{ 494{
522 if (token != endtoken) { 495 if (id->token != endtoken) {
523 zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); 496 zconf_error("unexpected '%s' within %s block",
497 kconf_id_strings + id->name, zconf_tokenname(starttoken));
524 zconfnerrs++; 498 zconfnerrs++;
525 return false; 499 return false;
526 } 500 }
527 if (current_menu->file != current_file) { 501 if (current_menu->file != current_file) {
528 zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); 502 zconf_error("'%s' in different file than '%s'",
529 zconfprint("location of the '%s'", zconf_tokenname(starttoken)); 503 kconf_id_strings + id->name, zconf_tokenname(starttoken));
504 fprintf(stderr, "%s:%d: location of the '%s'\n",
505 current_menu->file->name, current_menu->lineno,
506 zconf_tokenname(starttoken));
530 zconfnerrs++; 507 zconfnerrs++;
531 return false; 508 return false;
532 } 509 }
@@ -537,7 +514,19 @@ static void zconfprint(const char *err, ...)
537{ 514{
538 va_list ap; 515 va_list ap;
539 516
540 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); 517 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
518 va_start(ap, err);
519 vfprintf(stderr, err, ap);
520 va_end(ap);
521 fprintf(stderr, "\n");
522}
523
524static void zconf_error(const char *err, ...)
525{
526 va_list ap;
527
528 zconfnerrs++;
529 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
541 va_start(ap, err); 530 va_start(ap, err);
542 vfprintf(stderr, err, ap); 531 vfprintf(stderr, err, ap);
543 va_end(ap); 532 va_end(ap);
@@ -546,7 +535,9 @@ static void zconfprint(const char *err, ...)
546 535
547static void zconferror(const char *err) 536static void zconferror(const char *err)
548{ 537{
538#if YYDEBUG
549 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); 539 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
540#endif
550} 541}
551 542
552void print_quoted_string(FILE *out, const char *str) 543void print_quoted_string(FILE *out, const char *str)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 45c41490d521..fc774436a264 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1986,6 +1986,9 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
1986 1986
1987 inode_security_set_sid(inode, newsid); 1987 inode_security_set_sid(inode, newsid);
1988 1988
1989 if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
1990 return -EOPNOTSUPP;
1991
1989 if (name) { 1992 if (name) {
1990 namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL); 1993 namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
1991 if (!namep) 1994 if (!namep)
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index fdc382389720..0e1352a555c8 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -271,46 +271,38 @@ static struct file_operations sel_load_ops = {
271 .write = sel_write_load, 271 .write = sel_write_load,
272}; 272};
273 273
274 274static ssize_t sel_write_context(struct file * file, char *buf, size_t size)
275static ssize_t sel_write_context(struct file * file, const char __user * buf,
276 size_t count, loff_t *ppos)
277
278{ 275{
279 char *page; 276 char *canon;
280 u32 sid; 277 u32 sid, len;
281 ssize_t length; 278 ssize_t length;
282 279
283 length = task_has_security(current, SECURITY__CHECK_CONTEXT); 280 length = task_has_security(current, SECURITY__CHECK_CONTEXT);
284 if (length) 281 if (length)
285 return length; 282 return length;
286 283
287 if (count >= PAGE_SIZE) 284 length = security_context_to_sid(buf, size, &sid);
288 return -ENOMEM; 285 if (length < 0)
289 if (*ppos != 0) { 286 return length;
290 /* No partial writes. */
291 return -EINVAL;
292 }
293 page = (char*)get_zeroed_page(GFP_KERNEL);
294 if (!page)
295 return -ENOMEM;
296 length = -EFAULT;
297 if (copy_from_user(page, buf, count))
298 goto out;
299 287
300 length = security_context_to_sid(page, count, &sid); 288 length = security_sid_to_context(sid, &canon, &len);
301 if (length < 0) 289 if (length < 0)
290 return length;
291
292 if (len > SIMPLE_TRANSACTION_LIMIT) {
293 printk(KERN_ERR "%s: context size (%u) exceeds payload "
294 "max\n", __FUNCTION__, len);
295 length = -ERANGE;
302 goto out; 296 goto out;
297 }
303 298
304 length = count; 299 memcpy(buf, canon, len);
300 length = len;
305out: 301out:
306 free_page((unsigned long) page); 302 kfree(canon);
307 return length; 303 return length;
308} 304}
309 305
310static struct file_operations sel_context_ops = {
311 .write = sel_write_context,
312};
313
314static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf, 306static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
315 size_t count, loff_t *ppos) 307 size_t count, loff_t *ppos)
316{ 308{
@@ -375,6 +367,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
375 [SEL_RELABEL] = sel_write_relabel, 367 [SEL_RELABEL] = sel_write_relabel,
376 [SEL_USER] = sel_write_user, 368 [SEL_USER] = sel_write_user,
377 [SEL_MEMBER] = sel_write_member, 369 [SEL_MEMBER] = sel_write_member,
370 [SEL_CONTEXT] = sel_write_context,
378}; 371};
379 372
380static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) 373static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -1220,7 +1213,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1220 static struct tree_descr selinux_files[] = { 1213 static struct tree_descr selinux_files[] = {
1221 [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR}, 1214 [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
1222 [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR}, 1215 [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR},
1223 [SEL_CONTEXT] = {"context", &sel_context_ops, S_IRUGO|S_IWUGO}, 1216 [SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO},
1224 [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO}, 1217 [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO},
1225 [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO}, 1218 [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
1226 [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO}, 1219 [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index aaefac2921f1..640d0bfdbc68 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -262,8 +262,11 @@ int mls_context_to_sid(char oldc,
262 struct cat_datum *catdatum, *rngdatum; 262 struct cat_datum *catdatum, *rngdatum;
263 int l, rc = -EINVAL; 263 int l, rc = -EINVAL;
264 264
265 if (!selinux_mls_enabled) 265 if (!selinux_mls_enabled) {
266 if (def_sid != SECSID_NULL && oldc)
267 *scontext += strlen(*scontext);
266 return 0; 268 return 0;
269 }
267 270
268 /* 271 /*
269 * No MLS component to the security context, try and map to 272 * No MLS component to the security context, try and map to
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index 9a3dc3c3b3de..c4993b004c42 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -23,6 +23,7 @@
23#include <sound/driver.h> 23#include <sound/driver.h>
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/firmware.h> 25#include <linux/firmware.h>
26#include <linux/vmalloc.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/hwdep.h> 28#include <sound/hwdep.h>
28#include <sound/vx_core.h> 29#include <sound/vx_core.h>
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 953e5f3ea03d..88e52dc84c09 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -4,9 +4,24 @@
4# More hacking for modularisation. 4# More hacking for modularisation.
5# 5#
6# Prompt user for primary drivers. 6# Prompt user for primary drivers.
7
8config OBSOLETE_OSS_DRIVER
9 bool "Obsolete OSS drivers"
10 depends on SOUND_PRIME
11 help
12 This option enables support for obsolete OSS drivers that
13 are scheduled for removal in the near future since there
14 are ALSA drivers for the same hardware.
15
16 Please contact Adrian Bunk <bunk@stusta.de> if you had to
17 say Y here because your soundcard is not properly supported
18 by ALSA.
19
20 If unsure, say N.
21
7config SOUND_BT878 22config SOUND_BT878
8 tristate "BT878 audio dma" 23 tristate "BT878 audio dma"
9 depends on SOUND_PRIME && PCI 24 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
10 ---help--- 25 ---help---
11 Audio DMA support for bt878 based grabber boards. As you might have 26 Audio DMA support for bt878 based grabber boards. As you might have
12 already noticed, bt878 is listed with two functions in /proc/pci. 27 already noticed, bt878 is listed with two functions in /proc/pci.
@@ -22,7 +37,7 @@ config SOUND_BT878
22 37
23config SOUND_CMPCI 38config SOUND_CMPCI
24 tristate "C-Media PCI (CMI8338/8738)" 39 tristate "C-Media PCI (CMI8338/8738)"
25 depends on SOUND_PRIME && PCI 40 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
26 help 41 help
27 Say Y or M if you have a PCI sound card using the CMI8338 42 Say Y or M if you have a PCI sound card using the CMI8338
28 or the CMI8738 chipset. Data on these chips are available at 43 or the CMI8738 chipset. Data on these chips are available at
@@ -61,7 +76,7 @@ config SOUND_CMPCI_JOYSTICK
61 76
62config SOUND_EMU10K1 77config SOUND_EMU10K1
63 tristate "Creative SBLive! (EMU10K1)" 78 tristate "Creative SBLive! (EMU10K1)"
64 depends on SOUND_PRIME && PCI 79 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
65 ---help--- 80 ---help---
66 Say Y or M if you have a PCI sound card using the EMU10K1 chipset, 81 Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
67 such as the Creative SBLive!, SB PCI512 or Emu-APS. 82 such as the Creative SBLive!, SB PCI512 or Emu-APS.
@@ -95,7 +110,7 @@ config SOUND_FUSION
95 110
96config SOUND_CS4281 111config SOUND_CS4281
97 tristate "Crystal Sound CS4281" 112 tristate "Crystal Sound CS4281"
98 depends on SOUND_PRIME && PCI 113 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
99 help 114 help
100 Picture and feature list at 115 Picture and feature list at
101 <http://www.pcbroker.com/crystal4281.html>. 116 <http://www.pcbroker.com/crystal4281.html>.
@@ -112,7 +127,7 @@ config SOUND_BCM_CS4297A
112 127
113config SOUND_ES1370 128config SOUND_ES1370
114 tristate "Ensoniq AudioPCI (ES1370)" 129 tristate "Ensoniq AudioPCI (ES1370)"
115 depends on SOUND_PRIME && PCI 130 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
116 help 131 help
117 Say Y or M if you have a PCI sound card utilizing the Ensoniq 132 Say Y or M if you have a PCI sound card utilizing the Ensoniq
118 ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find 133 ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find
@@ -125,7 +140,7 @@ config SOUND_ES1370
125 140
126config SOUND_ES1371 141config SOUND_ES1371
127 tristate "Creative Ensoniq AudioPCI 97 (ES1371)" 142 tristate "Creative Ensoniq AudioPCI 97 (ES1371)"
128 depends on SOUND_PRIME && PCI 143 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
129 help 144 help
130 Say Y or M if you have a PCI sound card utilizing the Ensoniq 145 Say Y or M if you have a PCI sound card utilizing the Ensoniq
131 ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if 146 ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if
@@ -138,7 +153,7 @@ config SOUND_ES1371
138 153
139config SOUND_ESSSOLO1 154config SOUND_ESSSOLO1
140 tristate "ESS Technology Solo1" 155 tristate "ESS Technology Solo1"
141 depends on SOUND_PRIME && PCI 156 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
142 help 157 help
143 Say Y or M if you have a PCI sound card utilizing the ESS Technology 158 Say Y or M if you have a PCI sound card utilizing the ESS Technology
144 Solo1 chip. To find out if your sound card uses a 159 Solo1 chip. To find out if your sound card uses a
@@ -149,7 +164,7 @@ config SOUND_ESSSOLO1
149 164
150config SOUND_MAESTRO 165config SOUND_MAESTRO
151 tristate "ESS Maestro, Maestro2, Maestro2E driver" 166 tristate "ESS Maestro, Maestro2, Maestro2E driver"
152 depends on SOUND_PRIME && PCI 167 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
153 help 168 help
154 Say Y or M if you have a sound system driven by ESS's Maestro line 169 Say Y or M if you have a sound system driven by ESS's Maestro line
155 of PCI sound chips. These include the Maestro 1, Maestro 2, and 170 of PCI sound chips. These include the Maestro 1, Maestro 2, and
@@ -158,7 +173,7 @@ config SOUND_MAESTRO
158 173
159config SOUND_MAESTRO3 174config SOUND_MAESTRO3
160 tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)" 175 tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)"
161 depends on SOUND_PRIME && PCI && EXPERIMENTAL 176 depends on SOUND_PRIME && PCI && EXPERIMENTAL && OBSOLETE_OSS_DRIVER
162 help 177 help
163 Say Y or M if you have a sound system driven by ESS's Maestro 3 178 Say Y or M if you have a sound system driven by ESS's Maestro 3
164 PCI sound chip. 179 PCI sound chip.
@@ -172,14 +187,14 @@ config SOUND_ICH
172 187
173config SOUND_HARMONY 188config SOUND_HARMONY
174 tristate "PA Harmony audio driver" 189 tristate "PA Harmony audio driver"
175 depends on GSC_LASI && SOUND_PRIME 190 depends on GSC_LASI && SOUND_PRIME && OBSOLETE_OSS_DRIVER
176 help 191 help
177 Say 'Y' or 'M' to include support for Harmony soundchip 192 Say 'Y' or 'M' to include support for Harmony soundchip
178 on HP 712, 715/new and many other GSC based machines. 193 on HP 712, 715/new and many other GSC based machines.
179 194
180config SOUND_SONICVIBES 195config SOUND_SONICVIBES
181 tristate "S3 SonicVibes" 196 tristate "S3 SonicVibes"
182 depends on SOUND_PRIME && PCI 197 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
183 help 198 help
184 Say Y or M if you have a PCI sound card utilizing the S3 199 Say Y or M if you have a PCI sound card utilizing the S3
185 SonicVibes chipset. To find out if your sound card uses a 200 SonicVibes chipset. To find out if your sound card uses a
@@ -218,7 +233,7 @@ config SOUND_VRC5477
218 233
219config SOUND_AU1000 234config SOUND_AU1000
220 tristate "Au1000 Sound" 235 tristate "Au1000 Sound"
221 depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) 236 depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && OBSOLETE_OSS_DRIVER
222 237
223config SOUND_AU1550_AC97 238config SOUND_AU1550_AC97
224 tristate "Au1550 AC97 Sound" 239 tristate "Au1550 AC97 Sound"
@@ -492,7 +507,7 @@ config MSND_FIFOSIZE
492 507
493config SOUND_VIA82CXXX 508config SOUND_VIA82CXXX
494 tristate "VIA 82C686 Audio Codec" 509 tristate "VIA 82C686 Audio Codec"
495 depends on SOUND_PRIME && PCI 510 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
496 help 511 help
497 Say Y here to include support for the audio codec found on VIA 512 Say Y here to include support for the audio codec found on VIA
498 82Cxxx-based chips. Typically these are built into a motherboard. 513 82Cxxx-based chips. Typically these are built into a motherboard.
@@ -563,7 +578,7 @@ config SOUND_AD1889
563 578
564config SOUND_SGALAXY 579config SOUND_SGALAXY
565 tristate "Aztech Sound Galaxy (non-PnP) cards" 580 tristate "Aztech Sound Galaxy (non-PnP) cards"
566 depends on SOUND_OSS 581 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
567 help 582 help
568 This module initializes the older non Plug and Play sound galaxy 583 This module initializes the older non Plug and Play sound galaxy
569 cards from Aztech. It supports the Waverider Pro 32 - 3D and the 584 cards from Aztech. It supports the Waverider Pro 32 - 3D and the
@@ -599,7 +614,7 @@ config SOUND_ACI_MIXER
599 614
600config SOUND_CS4232 615config SOUND_CS4232
601 tristate "Crystal CS4232 based (PnP) cards" 616 tristate "Crystal CS4232 based (PnP) cards"
602 depends on SOUND_OSS 617 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
603 help 618 help
604 Say Y here if you have a card based on the Crystal CS4232 chip set, 619 Say Y here if you have a card based on the Crystal CS4232 chip set,
605 which uses its own Plug and Play protocol. 620 which uses its own Plug and Play protocol.
@@ -613,7 +628,7 @@ config SOUND_CS4232
613 628
614config SOUND_SSCAPE 629config SOUND_SSCAPE
615 tristate "Ensoniq SoundScape support" 630 tristate "Ensoniq SoundScape support"
616 depends on SOUND_OSS 631 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
617 help 632 help
618 Answer Y if you have a sound card based on the Ensoniq SoundScape 633 Answer Y if you have a sound card based on the Ensoniq SoundScape
619 chipset. Such cards are being manufactured at least by Ensoniq, Spea 634 chipset. Such cards are being manufactured at least by Ensoniq, Spea
@@ -625,7 +640,7 @@ config SOUND_SSCAPE
625 640
626config SOUND_GUS 641config SOUND_GUS
627 tristate "Gravis Ultrasound support" 642 tristate "Gravis Ultrasound support"
628 depends on SOUND_OSS 643 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
629 help 644 help
630 Say Y here for any type of Gravis Ultrasound card, including the GUS 645 Say Y here for any type of Gravis Ultrasound card, including the GUS
631 or GUS MAX. See also <file:Documentation/sound/oss/ultrasound> for more 646 or GUS MAX. See also <file:Documentation/sound/oss/ultrasound> for more
@@ -727,7 +742,7 @@ config SOUND_MPU401
727 742
728config SOUND_NM256 743config SOUND_NM256
729 tristate "NM256AV/NM256ZX audio support" 744 tristate "NM256AV/NM256ZX audio support"
730 depends on SOUND_OSS 745 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
731 help 746 help
732 Say M here to include audio support for the NeoMagic 256AV/256ZX 747 Say M here to include audio support for the NeoMagic 256AV/256ZX
733 chipsets. These are the audio chipsets found in the Sony 748 chipsets. These are the audio chipsets found in the Sony
@@ -739,7 +754,7 @@ config SOUND_NM256
739 754
740config SOUND_MAD16 755config SOUND_MAD16
741 tristate "OPTi MAD16 and/or Mozart based cards" 756 tristate "OPTi MAD16 and/or Mozart based cards"
742 depends on SOUND_OSS 757 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
743 ---help--- 758 ---help---
744 Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi 759 Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi
745 82C928 or 82C929 or 82C931) audio interface chip. These chips are 760 82C928 or 82C929 or 82C931) audio interface chip. These chips are
@@ -860,7 +875,7 @@ config SOUND_SB
860 875
861config SOUND_AWE32_SYNTH 876config SOUND_AWE32_SYNTH
862 tristate "AWE32 synth" 877 tristate "AWE32 synth"
863 depends on SOUND_OSS 878 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
864 help 879 help
865 Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or 880 Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or
866 similar sound card. See <file:Documentation/sound/oss/README.awe>, 881 similar sound card. See <file:Documentation/sound/oss/README.awe>,
@@ -870,7 +885,7 @@ config SOUND_AWE32_SYNTH
870 885
871config SOUND_WAVEFRONT 886config SOUND_WAVEFRONT
872 tristate "Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards" 887 tristate "Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards"
873 depends on SOUND_OSS && m 888 depends on SOUND_OSS && m && OBSOLETE_OSS_DRIVER
874 help 889 help
875 Answer Y or M if you have a Tropez Plus, Tropez or Maui sound card 890 Answer Y or M if you have a Tropez Plus, Tropez or Maui sound card
876 and read the files <file:Documentation/sound/oss/Wavefront> and 891 and read the files <file:Documentation/sound/oss/Wavefront> and
@@ -878,7 +893,7 @@ config SOUND_WAVEFRONT
878 893
879config SOUND_MAUI 894config SOUND_MAUI
880 tristate "Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers" 895 tristate "Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers"
881 depends on SOUND_OSS 896 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
882 help 897 help
883 Say Y here if you have a Turtle Beach Wave Front, Maui, or Tropez 898 Say Y here if you have a Turtle Beach Wave Front, Maui, or Tropez
884 sound card. 899 sound card.
@@ -904,7 +919,7 @@ config MAUI_BOOT_FILE
904 919
905config SOUND_YM3812 920config SOUND_YM3812
906 tristate "Yamaha FM synthesizer (YM3812/OPL-3) support" 921 tristate "Yamaha FM synthesizer (YM3812/OPL-3) support"
907 depends on SOUND_OSS 922 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
908 ---help--- 923 ---help---
909 Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). 924 Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4).
910 Answering Y is usually a safe and recommended choice, however some 925 Answering Y is usually a safe and recommended choice, however some
@@ -920,7 +935,7 @@ config SOUND_YM3812
920 935
921config SOUND_OPL3SA1 936config SOUND_OPL3SA1
922 tristate "Yamaha OPL3-SA1 audio controller" 937 tristate "Yamaha OPL3-SA1 audio controller"
923 depends on SOUND_OSS 938 depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
924 help 939 help
925 Say Y or M if you have a Yamaha OPL3-SA1 sound chip, which is 940 Say Y or M if you have a Yamaha OPL3-SA1 sound chip, which is
926 usually built into motherboards. Read 941 usually built into motherboards. Read
@@ -946,7 +961,7 @@ config SOUND_OPL3SA2
946 961
947config SOUND_YMFPCI 962config SOUND_YMFPCI
948 tristate "Yamaha YMF7xx PCI audio (native mode)" 963 tristate "Yamaha YMF7xx PCI audio (native mode)"
949 depends on SOUND_OSS && PCI 964 depends on SOUND_OSS && PCI && OBSOLETE_OSS_DRIVER
950 help 965 help
951 Support for Yamaha cards including the YMF711, YMF715, YMF718, 966 Support for Yamaha cards including the YMF711, YMF715, YMF718,
952 YMF719, YMF724, Waveforce 192XG, and Waveforce 192 Digital. 967 YMF719, YMF724, Waveforce 192XG, and Waveforce 192 Digital.
@@ -1088,11 +1103,11 @@ config SOUND_KAHLUA
1088 1103
1089config SOUND_ALI5455 1104config SOUND_ALI5455
1090 tristate "ALi5455 audio support" 1105 tristate "ALi5455 audio support"
1091 depends on SOUND_PRIME && PCI 1106 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
1092 1107
1093config SOUND_FORTE 1108config SOUND_FORTE
1094 tristate "ForteMedia FM801 driver" 1109 tristate "ForteMedia FM801 driver"
1095 depends on SOUND_PRIME && PCI 1110 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
1096 help 1111 help
1097 Say Y or M if you want driver support for the ForteMedia FM801 PCI 1112 Say Y or M if you want driver support for the ForteMedia FM801 PCI
1098 audio controller (Abit AU10, Genius Sound Maker, HP Workstation 1113 audio controller (Abit AU10, Genius Sound Maker, HP Workstation
@@ -1100,7 +1115,7 @@ config SOUND_FORTE
1100 1115
1101config SOUND_RME96XX 1116config SOUND_RME96XX
1102 tristate "RME Hammerfall (RME96XX) support" 1117 tristate "RME Hammerfall (RME96XX) support"
1103 depends on SOUND_PRIME && PCI 1118 depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
1104 help 1119 help
1105 Say Y or M if you have a Hammerfall or Hammerfall light 1120 Say Y or M if you have a Hammerfall or Hammerfall light
1106 multichannel card from RME. If you want to access advanced 1121 multichannel card from RME. If you want to access advanced
@@ -1108,7 +1123,7 @@ config SOUND_RME96XX
1108 1123
1109config SOUND_AD1980 1124config SOUND_AD1980
1110 tristate "AD1980 front/back switch plugin" 1125 tristate "AD1980 front/back switch plugin"
1111 depends on SOUND_PRIME 1126 depends on SOUND_PRIME && OBSOLETE_OSS_DRIVER
1112 1127
1113config SOUND_SH_DAC_AUDIO 1128config SOUND_SH_DAC_AUDIO
1114 tristate "SuperH DAC audio support" 1129 tristate "SuperH DAC audio support"
diff --git a/sound/oss/msnd.c b/sound/oss/msnd.c
index 4f1ff1bccdce..a7ad2b0a2ac0 100644
--- a/sound/oss/msnd.c
+++ b/sound/oss/msnd.c
@@ -24,7 +24,6 @@
24 * 24 *
25 ********************************************************************/ 25 ********************************************************************/
26 26
27#include <linux/version.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/kernel.h> 28#include <linux/kernel.h>
30#include <linux/slab.h> 29#include <linux/slab.h>
diff --git a/sound/oss/os.h b/sound/oss/os.h
index 80dce329cc3a..0490562c7f7f 100644
--- a/sound/oss/os.h
+++ b/sound/oss/os.h
@@ -5,10 +5,8 @@
5#undef DO_TIMINGS 5#undef DO_TIMINGS
6 6
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/version.h>
9 8
10#ifdef __KERNEL__ 9#ifdef __KERNEL__
11#include <linux/utsname.h>
12#include <linux/string.h> 10#include <linux/string.h>
13#include <linux/fs.h> 11#include <linux/fs.h>
14#include <asm/dma.h> 12#include <asm/dma.h>
diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
index 7609c68a89f4..318dc51009fe 100644
--- a/sound/oss/rme96xx.c
+++ b/sound/oss/rme96xx.c
@@ -44,7 +44,6 @@ TODO:
44#define RMEVERSION "0.8" 44#define RMEVERSION "0.8"
45#endif 45#endif
46 46
47#include <linux/version.h>
48#include <linux/module.h> 47#include <linux/module.h>
49#include <linux/string.h> 48#include <linux/string.h>
50#include <linux/sched.h> 49#include <linux/sched.h>
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index c09cdeedc191..8a9917c919c2 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -2,7 +2,6 @@
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/init.h> 3#include <linux/init.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/linkage.h> 5#include <linux/linkage.h>
7#include <linux/slab.h> 6#include <linux/slab.h>
8#include <linux/fs.h> 7#include <linux/fs.h>
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h
index ae3bb6c6edff..bfff788e9847 100644
--- a/sound/ppc/pmac.h
+++ b/sound/ppc/pmac.h
@@ -22,7 +22,6 @@
22#ifndef __PMAC_H 22#ifndef __PMAC_H
23#define __PMAC_H 23#define __PMAC_H
24 24
25#include <linux/version.h>
26#include <sound/control.h> 25#include <sound/control.h>
27#include <sound/pcm.h> 26#include <sound/pcm.h>
28#include "awacs.h" 27#include "awacs.h"