Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Tue, 21 Mar 2006 17:25:47 +0000 (09:25 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 21 Mar 2006 17:25:47 +0000 (09:25 -0800)
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (81 commits)
  [PATCH] USB: omninet: fix up debugging comments
  [PATCH] USB serial: add navman driver
  [PATCH] USB: Fix irda-usb use after use
  [PATCH] USB: rtl8150 small fix
  [PATCH] USB: ftdi_sio: add Icom ID1 USB product and vendor ids
  [PATCH] USB: cp2101: add new device IDs
  [PATCH] USB: fix check_ctrlrecip to allow control transfers in state ADDRESS
  [PATCH] USB: vicam.c: fix a NULL pointer dereference
  [PATCH] USB: ZC0301 driver bugfix
  [PATCH] USB: add support for Creativelabs Silvercrest USB keyboard
  [PATCH] USB: storage: new unusual_devs.h entry: Mitsumi 7in1 Card Reader
  [PATCH] USB: storage: unusual_devs.h entry 0420:0001
  [PATCH] USB: storage: another unusual_devs.h entry
  [PATCH] USB: storage: sandisk unusual_devices entry
  [PATCH] USB: fix initdata issue in isp116x-hcd
  [PATCH] USB: usbcore: usb_set_configuration oops (NULL ptr dereference)
  [PATCH] USB: usbcore: Don't assume a USB configuration includes any interfaces
  [PATCH] USB: ub 03 drop stall clearing
  [PATCH] USB: ub 02 remove diag
  [PATCH] USB: ub 01 remove first_open
  ...

430 files changed:
.gitignore
Documentation/Changes
Documentation/dvb/avermedia.txt
Documentation/dvb/bt8xx.txt
Documentation/dvb/get_dvb_firmware
Documentation/dvb/readme.txt
Documentation/feature-removal-schedule.txt
Documentation/video4linux/CARDLIST.cx88
Documentation/video4linux/CARDLIST.em28xx
Documentation/video4linux/CARDLIST.saa7134
Documentation/video4linux/CARDLIST.tuner
Documentation/video4linux/README.cpia2 [new file with mode: 0644]
Documentation/video4linux/cpia2_overview.txt [new file with mode: 0644]
MAINTAINERS
README
arch/arm/common/locomo.c
arch/arm/common/sa1111.c
arch/arm/mach-realview/core.c
arch/i386/defconfig
arch/m68knommu/kernel/vmlinux.lds.S
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/au1000/common/dbdma.c
arch/mips/au1000/common/dma.c
arch/mips/au1000/common/platform.c
arch/mips/au1000/common/setup.c
arch/mips/au1000/common/time.c
arch/mips/cobalt/Kconfig [new file with mode: 0644]
arch/mips/cobalt/Makefile
arch/mips/cobalt/console.c [new file with mode: 0644]
arch/mips/cobalt/setup.c
arch/mips/configs/atlas_defconfig
arch/mips/configs/bigsur_defconfig
arch/mips/configs/capcella_defconfig
arch/mips/configs/cobalt_defconfig
arch/mips/configs/db1000_defconfig
arch/mips/configs/db1100_defconfig
arch/mips/configs/db1200_defconfig
arch/mips/configs/db1500_defconfig
arch/mips/configs/db1550_defconfig
arch/mips/configs/ddb5476_defconfig
arch/mips/configs/ddb5477_defconfig
arch/mips/configs/decstation_defconfig
arch/mips/configs/e55_defconfig
arch/mips/configs/ev64120_defconfig
arch/mips/configs/ev96100_defconfig
arch/mips/configs/ip22_defconfig
arch/mips/configs/ip27_defconfig
arch/mips/configs/ip32_defconfig
arch/mips/configs/it8172_defconfig
arch/mips/configs/ivr_defconfig
arch/mips/configs/jaguar-atx_defconfig
arch/mips/configs/jmr3927_defconfig
arch/mips/configs/lasat200_defconfig
arch/mips/configs/malta_defconfig
arch/mips/configs/mipssim_defconfig
arch/mips/configs/mpc30x_defconfig
arch/mips/configs/ocelot_3_defconfig
arch/mips/configs/ocelot_c_defconfig
arch/mips/configs/ocelot_defconfig
arch/mips/configs/ocelot_g_defconfig
arch/mips/configs/pb1100_defconfig
arch/mips/configs/pb1500_defconfig
arch/mips/configs/pb1550_defconfig
arch/mips/configs/pnx8550-jbs_defconfig
arch/mips/configs/pnx8550-v2pci_defconfig
arch/mips/configs/qemu_defconfig
arch/mips/configs/rbhma4500_defconfig
arch/mips/configs/rm200_defconfig
arch/mips/configs/sb1250-swarm_defconfig
arch/mips/configs/sead_defconfig
arch/mips/configs/tb0226_defconfig
arch/mips/configs/tb0229_defconfig
arch/mips/configs/tb0287_defconfig [deleted file]
arch/mips/configs/workpad_defconfig
arch/mips/configs/yosemite_defconfig
arch/mips/dec/prom/memory.c
arch/mips/defconfig
arch/mips/jazz/int-handler.S
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/gdb-low.S
arch/mips/kernel/linux32.c
arch/mips/kernel/proc.c
arch/mips/kernel/process.c
arch/mips/kernel/setup.c
arch/mips/kernel/signal-common.h
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/mips/kernel/syscall.c
arch/mips/kernel/traps.c
arch/mips/lasat/image/romscript.normal
arch/mips/mips-boards/generic/mipsIRQ.S
arch/mips/mips-boards/sim/sim_IRQ.c
arch/mips/mips-boards/sim/sim_irq.S
arch/mips/mips-boards/sim/sim_smp.c
arch/mips/mm/Makefile
arch/mips/mm/c-r3k.c
arch/mips/mm/c-r4k.c
arch/mips/mm/pg-r4k.c
arch/mips/mm/sc-rm7k.c
arch/mips/mm/tlb-andes.c [deleted file]
arch/mips/mm/tlb-r4k.c
arch/mips/mm/tlbex.c
arch/mips/momentum/jaguar_atx/reset.c
arch/mips/momentum/jaguar_atx/setup.c
arch/mips/momentum/ocelot_3/reset.c
arch/mips/momentum/ocelot_c/reset.c
arch/mips/pci/fixup-vr4133.c
arch/mips/pci/ops-ddb5477.c
arch/mips/pci/ops-tx4938.c
arch/mips/pci/pci-bcm1480.c
arch/mips/pci/pci-bcm1480ht.c
arch/mips/pci/pci-ip27.c
arch/mips/philips/pnx8550/common/int.c
arch/mips/qemu/Makefile
arch/mips/qemu/q-smp.c [new file with mode: 0644]
arch/mips/sgi-ip27/ip27-memory.c
arch/mips/sgi-ip32/ip32-setup.c
arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c
arch/mips/tx4938/toshiba_rbtx4938/setup.c
arch/mips/vr41xx/common/bcu.c
arch/v850/kernel/vmlinux.lds.S
block/genhd.c
drivers/base/cpu.c
drivers/base/firmware_class.c
drivers/base/map.c
drivers/base/platform.c
drivers/char/Makefile
drivers/char/drm/Kconfig
drivers/char/ip2.c [deleted file]
drivers/char/ip2/Makefile [new file with mode: 0644]
drivers/char/ip2/ip2base.c [new file with mode: 0644]
drivers/char/ip2/ip2main.c [new file with mode: 0644]
drivers/char/ip2main.c [deleted file]
drivers/char/s3c2410-rtc.c
drivers/char/watchdog/mpcore_wdt.c
drivers/i2c/busses/i2c-iop3xx.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/ide/mips/au1xxx-ide.c
drivers/infiniband/core/agent.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/fmr_pool.c
drivers/infiniband/core/mad.c
drivers/infiniband/core/mad_priv.h
drivers/infiniband/core/mad_rmpp.c
drivers/infiniband/core/smi.h
drivers/infiniband/core/sysfs.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/core/uverbs.h
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/mthca/mthca_av.c
drivers/infiniband/hw/mthca/mthca_cmd.c
drivers/infiniband/hw/mthca/mthca_cmd.h
drivers/infiniband/hw/mthca/mthca_cq.c
drivers/infiniband/hw/mthca/mthca_dev.h
drivers/infiniband/hw/mthca/mthca_eq.c
drivers/infiniband/hw/mthca/mthca_mad.c
drivers/infiniband/hw/mthca/mthca_main.c
drivers/infiniband/hw/mthca/mthca_mcg.c
drivers/infiniband/hw/mthca/mthca_memfree.c
drivers/infiniband/hw/mthca/mthca_memfree.h
drivers/infiniband/hw/mthca/mthca_mr.c
drivers/infiniband/hw/mthca/mthca_pd.c
drivers/infiniband/hw/mthca/mthca_profile.c
drivers/infiniband/hw/mthca/mthca_provider.c
drivers/infiniband/hw/mthca/mthca_provider.h
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/mthca/mthca_srq.c
drivers/infiniband/hw/mthca/mthca_user.h
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/infiniband/ulp/ipoib/ipoib_verbs.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/media/common/Makefile
drivers/media/common/ir-common.c [deleted file]
drivers/media/common/ir-functions.c [new file with mode: 0644]
drivers/media/common/ir-keymaps.c [new file with mode: 0644]
drivers/media/common/saa7146_core.c
drivers/media/common/saa7146_fops.c
drivers/media/common/saa7146_i2c.c
drivers/media/common/saa7146_vbi.c
drivers/media/common/saa7146_video.c
drivers/media/dvb/b2c2/flexcop-common.h
drivers/media/dvb/b2c2/flexcop-i2c.c
drivers/media/dvb/bt8xx/Makefile
drivers/media/dvb/bt8xx/bt878.c
drivers/media/dvb/bt8xx/bt878.h
drivers/media/dvb/bt8xx/dst.c
drivers/media/dvb/bt8xx/dst_ca.c
drivers/media/dvb/bt8xx/dst_common.h
drivers/media/dvb/bt8xx/dvb-bt8xx.c
drivers/media/dvb/bt8xx/dvb-bt8xx.h
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/dvb/dvb-core/dmxdev.c
drivers/media/dvb/dvb-core/dmxdev.h
drivers/media/dvb/dvb-core/dvb_demux.c
drivers/media/dvb/dvb-core/dvb_demux.h
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-core/dvb_frontend.h
drivers/media/dvb/dvb-core/dvb_net.c
drivers/media/dvb/dvb-core/dvb_ringbuffer.c
drivers/media/dvb/dvb-core/dvb_ringbuffer.h
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/dvb-usb/dibusb-common.c
drivers/media/dvb/dvb-usb/digitv.c
drivers/media/dvb/dvb-usb/dvb-usb-init.c
drivers/media/dvb/dvb-usb/dvb-usb-urb.c
drivers/media/dvb/dvb-usb/dvb-usb.h
drivers/media/dvb/dvb-usb/vp702x.c
drivers/media/dvb/dvb-usb/vp7045.c
drivers/media/dvb/frontends/Kconfig
drivers/media/dvb/frontends/Makefile
drivers/media/dvb/frontends/bcm3510.c
drivers/media/dvb/frontends/bsbe1.h [new file with mode: 0644]
drivers/media/dvb/frontends/bsru6.h [new file with mode: 0644]
drivers/media/dvb/frontends/cx24110.c
drivers/media/dvb/frontends/cx24110.h
drivers/media/dvb/frontends/dvb-pll.c
drivers/media/dvb/frontends/dvb-pll.h
drivers/media/dvb/frontends/lnbp21.h [new file with mode: 0644]
drivers/media/dvb/frontends/tda1004x.c
drivers/media/dvb/frontends/tda1004x.h
drivers/media/dvb/frontends/zl10353.c [new file with mode: 0644]
drivers/media/dvb/frontends/zl10353.h [new file with mode: 0644]
drivers/media/dvb/frontends/zl10353_priv.h [new file with mode: 0644]
drivers/media/dvb/ttpci/av7110.c
drivers/media/dvb/ttpci/av7110.h
drivers/media/dvb/ttpci/av7110_hw.c
drivers/media/dvb/ttpci/av7110_v4l.c
drivers/media/dvb/ttpci/budget-av.c
drivers/media/dvb/ttpci/budget-ci.c
drivers/media/dvb/ttpci/budget-patch.c
drivers/media/dvb/ttpci/budget.c
drivers/media/dvb/ttpci/budget.h
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/dvb/ttusb-dec/ttusb_dec.c
drivers/media/radio/miropcm20-rds-core.c
drivers/media/radio/radio-aimslab.c
drivers/media/radio/radio-aztech.c
drivers/media/radio/radio-maestro.c
drivers/media/radio/radio-maxiradio.c
drivers/media/radio/radio-sf16fmi.c
drivers/media/radio/radio-sf16fmr2.c
drivers/media/radio/radio-typhoon.c
drivers/media/radio/radio-zoltrix.c
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/arv.c
drivers/media/video/bttv-cards.c
drivers/media/video/bttv-driver.c
drivers/media/video/bttv-input.c
drivers/media/video/bttv-risc.c
drivers/media/video/bw-qcam.c
drivers/media/video/bw-qcam.h
drivers/media/video/c-qcam.c
drivers/media/video/cpia.c
drivers/media/video/cpia.h
drivers/media/video/cpia2/Kconfig [new file with mode: 0644]
drivers/media/video/cpia2/Makefile [new file with mode: 0644]
drivers/media/video/cpia2/cpia2.h [new file with mode: 0644]
drivers/media/video/cpia2/cpia2_core.c [new file with mode: 0644]
drivers/media/video/cpia2/cpia2_registers.h [new file with mode: 0644]
drivers/media/video/cpia2/cpia2_usb.c [new file with mode: 0644]
drivers/media/video/cpia2/cpia2_v4l.c [new file with mode: 0644]
drivers/media/video/cpia2/cpia2dev.h [new file with mode: 0644]
drivers/media/video/cpia2/cpia2patch.h [new file with mode: 0644]
drivers/media/video/cx25840/Kconfig [new file with mode: 0644]
drivers/media/video/cx25840/Makefile
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx25840/cx25840-vbi.c
drivers/media/video/cx25840/cx25840.h
drivers/media/video/cx88/Kconfig
drivers/media/video/cx88/Makefile
drivers/media/video/cx88/cx88-alsa.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-core.c
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/cx88/cx88-input.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/cx88/cx88.h
drivers/media/video/dpc7146.c
drivers/media/video/em28xx/Kconfig
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/em28xx/em28xx-i2c.c
drivers/media/video/em28xx/em28xx-input.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/em28xx/em28xx.h
drivers/media/video/hexium_gemini.c
drivers/media/video/hexium_orion.c
drivers/media/video/ir-kbd-i2c.c
drivers/media/video/meye.c
drivers/media/video/meye.h
drivers/media/video/msp3400-driver.c
drivers/media/video/msp3400-kthreads.c
drivers/media/video/msp3400.h
drivers/media/video/mxb.c
drivers/media/video/mxb.h
drivers/media/video/planb.c
drivers/media/video/planb.h
drivers/media/video/pms.c
drivers/media/video/saa5246a.c
drivers/media/video/saa5249.c
drivers/media/video/saa7115.c
drivers/media/video/saa7134/saa7134-alsa.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/saa7134/saa7134-oss.c
drivers/media/video/saa7134/saa7134-tvaudio.c
drivers/media/video/saa7134/saa7134-video.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/tda8290.c
drivers/media/video/tda9840.c
drivers/media/video/tea6415c.c
drivers/media/video/tea6420.c
drivers/media/video/tuner-core.c
drivers/media/video/tuner-simple.c
drivers/media/video/tuner-types.c
drivers/media/video/tvaudio.c
drivers/media/video/tvp5150.c
drivers/media/video/tvp5150_reg.h
drivers/media/video/v4l2-common.c
drivers/media/video/video-buf-dvb.c
drivers/media/video/video-buf.c
drivers/media/video/videodev.c
drivers/media/video/vino.c
drivers/mmc/pxamci.c
drivers/net/arm/am79c961a.c
drivers/net/fs_enet/mac-fcc.c
drivers/net/fs_enet/mac-fec.c
drivers/net/fs_enet/mac-scc.c
drivers/net/gianfar.c
drivers/net/smc91x.c
drivers/pcmcia/omap_cf.c
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/ahci.c
drivers/scsi/ata_piix.c
drivers/scsi/libata-bmdma.c [new file with mode: 0644]
drivers/scsi/libata-core.c
drivers/scsi/libata-scsi.c
drivers/scsi/libata.h
drivers/scsi/pdc_adma.c
drivers/scsi/sata_mv.c
drivers/scsi/sata_nv.c
drivers/scsi/sata_promise.c
drivers/scsi/sata_qstor.c
drivers/scsi/sata_sil.c
drivers/scsi/sata_sil24.c
drivers/scsi/sata_sis.c
drivers/scsi/sata_svw.c
drivers/scsi/sata_sx4.c
drivers/scsi/sata_uli.c
drivers/scsi/sata_via.c
drivers/scsi/sata_vsc.c
drivers/scsi/scsi_error.c
drivers/serial/s3c2410.c
drivers/usb/core/driver.c
drivers/usb/host/ohci-omap.c
drivers/video/Kconfig
drivers/video/epson1355fb.c
drivers/video/sa1100fb.c
drivers/video/vfb.c
fs/char_dev.c
fs/debugfs/file.c
fs/sysfs/dir.c
fs/sysfs/file.c
fs/sysfs/inode.c
fs/sysfs/symlink.c
fs/sysfs/sysfs.h
include/asm-arm/irq.h
include/asm-generic/vmlinux.lds.h
include/asm-mips/byteorder.h
include/asm-mips/compat.h
include/asm-mips/io.h
include/asm-mips/mach-cobalt/cobalt.h
include/asm-mips/mach-generic/mangle-port.h
include/asm-mips/mach-ip27/mangle-port.h
include/asm-mips/mach-ip32/mangle-port.h
include/asm-mips/mmu_context.h
include/asm-mips/pgtable-32.h
include/asm-mips/r4kcache.h
include/asm-mips/signal.h
include/asm-mips/sn/klconfig.h
include/asm-mips/sn/mapped_kernel.h
include/asm-mips/sn/sn0/hubio.h
include/asm-mips/stackframe.h
include/asm-mips/system.h
include/asm-mips/thread_info.h
include/linux/amba/clcd.h
include/linux/ata.h
include/linux/cpu.h
include/linux/debugfs.h
include/linux/device.h
include/linux/dvb/audio.h
include/linux/dvb/video.h
include/linux/kobj_map.h
include/linux/kobject.h
include/linux/libata.h
include/linux/module.h
include/linux/videodev2.h
include/media/ir-common.h
include/media/saa7146.h
include/media/tuner-types.h
include/media/tuner.h
include/media/v4l2-common.h
include/media/video-buf-dvb.h
include/media/video-buf.h
include/rdma/ib_fmr_pool.h
include/rdma/ib_mad.h
include/rdma/ib_user_verbs.h
include/rdma/ib_verbs.h
include/scsi/scsi_eh.h
kernel/ksysfs.c
kernel/module.c
kernel/params.c
kernel/rcupdate.c
lib/kobject.c
lib/kobject_uevent.c
lib/kref.c
scripts/genksyms/keywords.c_shipped
scripts/genksyms/keywords.gperf

index 3f8fb686b59ce6d3c9439232d9ade24f108ea65d..53e53f2791f882d2c3f2ec58ca472573eeda14f3 100644 (file)
@@ -30,3 +30,5 @@ include/linux/autoconf.h
 include/linux/compile.h
 include/linux/version.h
 
+# stgit generated dirs
+patches-*
index fe5ae0f550202f1692ab9dc1e45ba5735e867b1d..b02f476c297302bced86ee62fe89afe2066d3c70 100644 (file)
@@ -15,24 +15,6 @@ and therefore owes credit to the same people as that file (Jared Mauch,
 Axel Boldt, Alessandro Sigala, and countless other users all over the
 'net).
 
-The latest revision of this document, in various formats, can always
-be found at <http://cyberbuzz.gatech.edu/kaboom/linux/Changes-2.4/>.
-
-Feel free to translate this document.  If you do so, please send me a
-URL to your translation for inclusion in future revisions of this
-document.
-
-Smotrite file <http://oblom.rnc.ru/linux/kernel/Changes.ru>, yavlyaushisya
-russkim perevodom dannogo documenta.
-
-Visite <http://www2.adi.uam.es/~ender/tecnico/> para obtener la traducción
-al español de este documento en varios formatos.
-
-Eine deutsche Version dieser Datei finden Sie unter
-<http://www.stefan-winter.de/Changes-2.4.0.txt>.
-
-Chris Ricker (kaboom@gatech.edu or chris.ricker@genetics.utah.edu).
-
 Current Minimal Requirements
 ============================
 
index 068070ff13cd0a4673d9333341b39ea5b77daf41..8bab8461a4af177d6548858f87f3b79aa8807267 100644 (file)
@@ -1,4 +1,3 @@
-
 HOWTO: Get An Avermedia DVB-T working under Linux
           ______________________________________________
 
@@ -137,11 +136,8 @@ Getting the card going
    To  power  up  the  card,  load  the  following modules in the
    following order:
 
-     * insmod dvb-core.o
-     * modprobe bttv.o
-     * insmod bt878.o
-     * insmod dvb-bt8xx.o
-     * insmod sp887x.o
+     * modprobe bttv (normally loaded automatically)
+     * modprobe dvb-bt8xx (or place dvb-bt8xx in /etc/modules)
 
    Insertion  of  these  modules  into  the  running  kernel will
    activate the appropriate DVB device nodes. It is then possible
@@ -302,4 +298,4 @@ Further Update
    Many  thanks to Nigel Pearson for the updates to this document
    since the recent revision of the driver.
 
-   January 29th 2004
+   February 14th 2006
index 52ed462061dfdfc1ada13c2708f718755b07aeef..4e7614e606c5675e241bae76e9523534072ae133 100644 (file)
-How to get the Nebula, PCTV, FusionHDTV Lite and Twinhan DST cards working
-==========================================================================
+How to get the bt8xx cards working
+==================================
 
-This class of cards has a bt878a as the PCI interface, and
-require the bttv driver.
+1) General information
+======================
 
-Please pay close attention to the warning about the bttv module
-options below for the DST card.
+This class of cards has a bt878a as the PCI interface, and require the bttv driver
+for accessing the i2c bus and the gpio pins of the bt8xx chipset.
+Please see Documentation/dvb/cards.txt => o Cards based on the Conexant Bt8xx PCI bridge:
 
-1) General informations
-=======================
-
-These drivers require the bttv driver to provide the means to access
-the i2c bus and the gpio pins of the bt8xx chipset.
-
-Because of this, you need to enable
-"Device drivers" => "Multimedia devices"
-  => "Video For Linux" => "BT848 Video For Linux"
-
-Furthermore you need to enable
-"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
-  => "DVB for Linux" "DVB Core Support" "BT8xx based PCI cards"
+Compiling kernel please enable:
+a.)"Device drivers" => "Multimedia devices" => "Video For Linux" => "BT848 Video For Linux"
+b.)"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
+ => "DVB for Linux" "DVB Core Support" "Bt8xx based PCI Cards"
 
 2) Loading Modules
 ==================
 
-In general you need to load the bttv driver, which will handle the gpio and
-i2c communication for us, plus the common dvb-bt8xx device driver.
-The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110), TwinHan (dst),
-FusionHDTV DVB-T Lite (mt352) and FusionHDTV5 Lite (lgdt330x) are loaded
-automatically by the dvb-bt8xx device driver.
-
-3a) Nebula / Pinnacle PCTV / FusionHDTV Lite
----------------------------------------------
-
-   $ modprobe bttv (normally bttv is being loaded automatically by kmod)
-   $ modprobe dvb-bt8xx
-
-(or just place dvb-bt8xx in /etc/modules for automatic loading)
-
-
-3b) TwinHan and Clones
---------------------------
+In default cases bttv is loaded automatically.
+To load the backend either place dvb-bt8xx in etc/modules, or apply manually:
 
-   $ modprobe bttv card=0x71
-   $ modprobe dvb-bt8xx
-   $ modprobe dst
+       $ modprobe dvb-bt8xx
 
-The value 0x71 will override the PCI type detection for dvb-bt8xx,
-which  is necessary for TwinHan cards. Omission of this parameter might result
-in a system lockup.
+All frontends will be loaded automatically.
+People running udev please see Documentation/dvb/udev.txt.
 
-If you're having an older card (blue color PCB) and card=0x71 locks up
-your machine, try using 0x68, too. If that does not work, ask on the
-mailing list.
+In the following cases overriding the PCI type detection for dvb-bt8xx might be necessary:
 
-The DST module takes a couple of useful parameters.
+2a) Running TwinHan and Clones
+------------------------------
 
-verbose takes values 0 to 4. These values control the verbosity level,
-and can be used to debug also.
+       $ modprobe bttv card=113
+       $ modprobe dvb-bt8xx
+       $ modprobe dst
 
-verbose=0 means complete disabling of messages
-       1 only error messages are displayed
-       2 notifications are also displayed
-       3 informational messages are also displayed
-       4 debug setting
+Useful parameters for verbosity level and debugging the dst module:
 
-dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
-0x20 means it has a Conditional Access slot.
+verbose=0:             messages are disabled
+       1:              only error messages are displayed
+       2:              notifications are displayed
+       3:              other useful messages are displayed
+       4:              debug setting
+dst_addons=0:          card is a free to air (FTA) card only
+          0x20:        card has a conditional access slot for scrambled channels
 
-The autodetected values are determined by the cards 'response string'
-which you can see in your logs e.g.
+The autodetected values are determined by the cards' "response string".
+In your logs see f. ex.: dst_get_device_id: Recognize [DSTMCI].
+For bug reports please send in a complete log with verbose=4 activated.
+Please also see Documentation/dvb/ci.txt.
 
-dst_get_device_id: Recognise [DSTMCI]
-
-If you need to sent in bug reports on the dst, please do send in a complete
-log with the verbose=4 module parameter. For general usage, the default setting
-of verbose=1 is ideal.
-
-
-4) Multiple cards
+2b) Running multiple cards
 --------------------------
 
-If you happen to be running multiple cards, it would be advisable to load
-the bttv module with the card id. This would help to solve any module loading
-problems that you might face.
-
-For example, if you have a Twinhan and Clones card along with a FusionHDTV5 Lite
+Examples of card ID's:
 
-       $ modprobe bttv card=0x71 card=0x87
-
-Here the order of the card id is important and should be the same as that of the
-physical order of the cards. Here card=0x71 represents the Twinhan and clones
-and card=0x87 represents Fusion HDTV5 Lite. These arguments can also be
-specified in decimal, rather than hex:
+Pinnacle PCTV Sat:              94
+Nebula Electronics Digi TV:    104
+pcHDTV HD-2000 TV:             112
+Twinhan DST and clones:                113
+Avermedia AverTV DVB-T 771:    123
+Avermedia AverTV DVB-T 761:    124
+DViCO FusionHDTV DVB-T Lite:   128
+DViCO FusionHDTV 5 Lite:       135
 
+Notice: The order of the card ID should be uprising:
+Example:
        $ modprobe bttv card=113 card=135
+       $ modprobe dvb-bt8xx
 
-Some examples of card-id's
-
-Pinnacle Sat           0x5e  (94)
-Nebula Digi TV         0x68  (104)
-PC HDTV                        0x70  (112)
-Twinhan                        0x71  (113)
-FusionHDTV DVB-T Lite  0x80  (128)
-FusionHDTV5 Lite       0x87  (135)
-
-For a full list of card-id's, see the V4L Documentation within the kernel
-source:  linux/Documentation/video4linux/CARDLIST.bttv
-
-If you have problems with this please do ask on the mailing list.
+For a full list of card ID's please see Documentation/video4linux/CARDLIST.bttv.
+In case of further problems send questions to the mailing list: www.linuxdvb.org.
 
---
 Authors: Richard Walker,
         Jamie Honan,
         Michael Hunold,
         Manu Abraham,
+        Uwe Bugla,
         Michael Krufky
index 75c28a174092f5236e9dddc98444fff4b84e9183..bb55f49f2745e6f556d6aa6e24c80e6648e67e03 100644 (file)
@@ -21,8 +21,9 @@
 use File::Temp qw/ tempdir /;
 use IO::Handle;
 
-@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
-               "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
+@components = ( "sp8870", "sp887x", "tda10045", "tda10046",
+               "tda10046lifeview", "av7110", "dec2000t", "dec2540t",
+               "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
                "or51211", "or51132_qam", "or51132_vsb", "bluebird");
 
 # Check args
@@ -126,6 +127,24 @@ sub tda10046 {
     $outfile;
 }
 
+sub tda10046lifeview {
+    my $sourcefile = "Drv_2.11.02.zip";
+    my $url = "http://www.lifeview.com.tw/drivers/pci_card/FlyDVB-T/$sourcefile";
+    my $hash = "1ea24dee4eea8fe971686981f34fd2e0";
+    my $outfile = "dvb-fe-tda10046.fw";
+    my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+
+    checkstandard();
+
+    wgetfile($sourcefile, $url);
+    unzip($sourcefile, $tmpdir);
+    extract("$tmpdir/LVHybrid.sys", 0x8b088, 24602, "$tmpdir/fwtmp");
+    verify("$tmpdir/fwtmp", $hash);
+    copy("$tmpdir/fwtmp", $outfile);
+
+    $outfile;
+}
+
 sub av7110 {
     my $sourcefile = "dvb-ttpci-01.fw-261d";
     my $url = "http://www.linuxtv.org/downloads/firmware/$sourcefile";
index f5c50b22de3b89e09bb8553854cc8452d76bc110..0b0380c919902c012d1450f7202280fb8a5aefd6 100644 (file)
@@ -20,11 +20,23 @@ http://linuxtv.org/downloads/
 
 What's inside this directory:
 
+"avermedia.txt"
+contains detailed information about the
+Avermedia DVB-T cards. See also "bt8xx.txt".
+
+"bt8xx.txt"
+contains detailed information about the
+various bt8xx based "budget" DVB cards.
+
 "cards.txt"
 contains a list of supported hardware.
 
+"ci.txt"
+contains detailed information about the
+CI module as part from TwinHan cards and Clones.
+
 "contributors.txt"
-is the who-is-who of DVB development
+is the who-is-who of DVB development.
 
 "faq.txt"
 contains frequently asked questions and their answers.
@@ -34,19 +46,17 @@ script to download and extract firmware for those devices
 that require it.
 
 "ttusb-dec.txt"
-contains detailed informations about the
+contains detailed information about the
 TT DEC2000/DEC3000 USB DVB hardware.
 
-"bt8xx.txt"
-contains detailed installation instructions for the
-various bt8xx based "budget" DVB cards
-(Nebula, Pinnacle PCTV, Twinhan DST)
-
-"README.dibusb"
-contains detailed information about adapters
-based on DiBcom reference design.
-
 "udev.txt"
 how to get DVB and udev up and running.
 
+"README.dvb-usb"
+contains detailed information about the DVB USB cards.
+
+"README.flexcop"
+contains detailed information about the
+Technisat- and Flexcop B2C2 drivers.
+
 Good luck and have fun!
index 28a31c5e2289aa554f389f4fcb67c1a63fa2dbe8..afeaf6218ea2808adca3e28a5228924294d824b3 100644 (file)
@@ -196,3 +196,21 @@ Why:       Board specific code doesn't build anymore since ~2.6.0 and no
        users have complained indicating there is no more need for these
        boards.  This should really be considered a last call.
 Who:   Ralf Baechle <ralf@linux-mips.org>
+
+---------------------------
+
+What:  USB driver API moves to EXPORT_SYMBOL_GPL
+When:  Febuary 2008
+Files: include/linux/usb.h, drivers/usb/core/driver.c
+Why:   The USB subsystem has changed a lot over time, and it has been
+       possible to create userspace USB drivers using usbfs/libusb/gadgetfs
+       that operate as fast as the USB bus allows.  Because of this, the USB
+       subsystem will not be allowing closed source kernel drivers to
+       register with it, after this grace period is over.  If anyone needs
+       any help in converting their closed source drivers over to use the
+       userspace filesystems, please contact the
+       linux-usb-devel@lists.sourceforge.net mailing list, and the developers
+       there will be glad to help you out.
+Who:   Greg Kroah-Hartman <gregkh@suse.de>
+
+---------------------------
index 8bea3fbd0548297dcc73193c0d2ed485eda350c4..3b39a91b24bd98d48189d862660e81a27ce09005 100644 (file)
@@ -43,3 +43,5 @@
  42 -> digitalnow DNTV Live! DVB-T Pro                     [1822:0025]
  43 -> KWorld/VStream XPert DVB-T with cx22702             [17de:08a1]
  44 -> DViCO FusionHDTV DVB-T Dual Digital                 [18ac:db50,18ac:db54]
+ 45 -> KWorld HardwareMpegTV XPert                         [17de:0840]
+ 46 -> DViCO FusionHDTV DVB-T Hybrid                       [18ac:db40,18ac:db44]
index a0c7cad20971f5b8fa5d2d0280ae83d9d761bad0..a3026689bbe6b62b60878c89c16355dd5c8ace8a 100644 (file)
@@ -8,3 +8,4 @@
   7 -> Leadtek Winfast USB II                   (em2800)
   8 -> Kworld USB2800                           (em2800)
   9 -> Pinnacle Dazzle DVC 90                   (em2820/em2840) [2304:0207]
+ 12 -> Kworld PVR TV 2800 RF                    (em2820/em2840)
index da4fb890165f9de33e0d61e57acdbd1779db6230..8c71954559633218b813322eb87afaa2578dc17a 100644 (file)
  82 -> MSI TV@Anywhere plus                     [1462:6231]
  83 -> Terratec Cinergy 250 PCI TV              [153b:1160]
  84 -> LifeView FlyDVB Trio                     [5168:0319]
+ 85 -> AverTV DVB-T 777                         [1461:2c05]
+ 86 -> LifeView FlyDVB-T                        [5168:0301]
+ 87 -> ADS Instant TV Duo Cardbus PTV331        [0331:1421]
+ 88 -> Tevion/KWorld DVB-T 220RF                [17de:7201]
+ 89 -> ELSA EX-VISION 700TV                     [1048:226c]
+ 90 -> Kworld ATSC110                           [17de:7350]
+ 91 -> AVerMedia A169 B                         [1461:7360]
+ 92 -> AVerMedia A169 B1                        [1461:6360]
+ 93 -> Medion 7134 Bridge #2                    [16be:0005]
index f6d0cf7b792239985a4d1e40132c4e56ffbc4775..1bcdac67dd8c140e94dd00e1f0fa856b5a75f86e 100644 (file)
@@ -64,8 +64,10 @@ tuner=62 - Philips TEA5767HN FM Radio
 tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner
 tuner=64 - LG TDVS-H062F/TUA6034
 tuner=65 - Ymec TVF66T5-B/DFF
-tuner=66 - LG NTSC (TALN mini series)
+tuner=66 - LG TALN series
 tuner=67 - Philips TD1316 Hybrid Tuner
 tuner=68 - Philips TUV1236D ATSC/NTSC dual in
-tuner=69 - Tena TNF 5335 MF
+tuner=69 - Tena TNF 5335 and similar models
 tuner=70 - Samsung TCPN 2121P30A
+tuner=71 - Xceive xc3028
+tuner=72 - Thomson FE6600
diff --git a/Documentation/video4linux/README.cpia2 b/Documentation/video4linux/README.cpia2
new file mode 100644 (file)
index 0000000..ce8213d
--- /dev/null
@@ -0,0 +1,130 @@
+$Id: README,v 1.7 2005/08/29 23:39:57 sbertin Exp $
+
+1. Introduction
+
+       This is a driver for STMicroelectronics's CPiA2 (second generation
+Colour Processor Interface ASIC) based cameras. This camera outputs an MJPEG
+stream at up to vga size. It implements the Video4Linux interface as much as
+possible.  Since the V4L interface does not support compressed formats, only
+an mjpeg enabled application can be used with the camera. We have modified the
+gqcam application to view this stream.
+
+       The driver is implemented as two kernel modules. The cpia2 module
+contains the camera functions and the V4L interface.  The cpia2_usb module
+contains usb specific functions.  The main reason for this was the size of the
+module was getting out of hand, so I separted them.  It is not likely that
+there will be a parallel port version.
+
+FEATURES:
+   - Supports cameras with the Vision stv6410 (CIF) and stv6500 (VGA) cmos
+     sensors. I only have the vga sensor, so can't test the other.
+   - Image formats: VGA, QVGA, CIF, QCIF, and a number of sizes in between.
+     VGA and QVGA are the native image sizes for the VGA camera. CIF is done
+     in the coprocessor by scaling QVGA.  All other sizes are done by clipping.
+   - Palette: YCrCb, compressed with MJPEG.
+   - Some compression parameters are settable.
+   - Sensor framerate is adjustable (up to 30 fps CIF, 15 fps VGA).
+   - Adjust brightness, color, contrast while streaming.
+   - Flicker control settable for 50 or 60 Hz mains frequency.
+
+2. Making and installing the stv672 driver modules:
+
+       Requirements:
+       -------------
+       This should work with 2.4 (2.4.23 and later) and 2.6 kernels, but has
+only been tested on 2.6.  Video4Linux must be either compiled into the kernel or
+available as a module.  Video4Linux2 is automatically detected and made
+available at compile time.
+
+       Compiling:
+       ----------
+       As root, do a make install.  This will compile and install the modules
+into the media/video directory in the module tree. For 2.4 kernels, use
+Makefile_2.4 (aka do make -f Makefile_2.4 install).
+
+       Setup:
+       ------
+       Use 'modprobe cpia2' to load and 'modprobe -r cpia2' to unload. This
+may be done automatically by your distribution.
+
+3. Driver options
+
+       Option          Description
+       ------          -----------
+       video_nr        video device to register (0=/dev/video0, etc)
+                       range -1 to 64.  default is -1 (first available)
+                       If you have more than 1 camera, this MUST be -1.
+       buffer_size     Size for each frame buffer in bytes (default 68k)
+       num_buffers     Number of frame buffers (1-32, default 3)
+       alternate       USB Alternate (2-7, default 7)
+       flicker_freq    Frequency for flicker reduction(50 or 60, default 60)
+       flicker_mode    0 to disable, or 1 to enable flicker reduction.
+                       (default 0). This is only effective if the camera
+                       uses a stv0672 coprocessor.
+
+       Setting the options:
+       --------------------
+       If you are using modules, edit /etc/modules.conf and add an options
+line like this:
+       options cpia2 num_buffers=3 buffer_size=65535
+
+       If the driver is compiled into the kernel, at boot time specify them
+like this:
+       cpia2.num_buffers=3 cpia2.buffer_size=65535
+
+       What buffer size should I use?
+       ------------------------------
+       The maximum image size depends on the alternate you choose, and the
+frame rate achieved by the camera.  If the compression engine is able to
+keep up with the frame rate, the maximum image size is given by the table
+below.
+       The compression engine starts out at maximum compression, and will
+increase image quality until it is close to the size in the table.  As long
+as the compression engine can keep up with the frame rate, after a short time
+the images will all be about the size in the table, regardless of resolution.
+       At low alternate settings, the compression engine may not be able to
+compress the image enough and will reduce the frame rate by producing larger
+images.
+       The default of 68k should be good for most users.  This will handle
+any alternate at frame rates down to 15fps.  For lower frame rates, it may
+be necessary to increase the buffer size to avoid having frames dropped due
+to insufficient space.
+
+                            Image size(bytes)
+       Alternate  bytes/ms   15fps    30fps
+           2         128      8533     4267
+           3         384     25600    12800
+           4         640     42667    21333
+           5         768     51200    25600
+           6         896     59733    29867
+           7        1023     68200    34100
+
+       How many buffers should I use?
+       ------------------------------
+       For normal streaming, 3 should give the best results.  With only 2,
+it is possible for the camera to finish sending one image just after a
+program has started reading the other.  If this happens, the driver must drop
+a frame.  The exception to this is if you have a heavily loaded machine.  In
+this case use 2 buffers.  You are probably not reading at the full frame rate.
+If the camera can send multiple images before a read finishes, it could
+overwrite the third buffer before the read finishes, leading to a corrupt
+image.  Single and double buffering have extra checks to avoid overwriting.
+
+4. Using the camera
+
+       We are providing a modified gqcam application to view the output. In
+order to avoid confusion, here it is called mview.  There is also the qx5view
+program which can also control the lights on the qx5 microscope. MJPEG Tools
+(http://mjpeg.sourceforge.net) can also be used to record from the camera.
+
+5. Notes to developers:
+
+   - This is a driver version stripped of the 2.4 back compatibility
+     and old MJPEG ioctl API. See cpia2.sf.net for 2.4 support.
+
+6. Thanks:
+
+   - Peter Pregler <Peter_Pregler@email.com>,
+     Scott J. Bertin <scottbertin@yahoo.com>, and
+     Jarl Totland <Jarl.Totland@bdc.no> for the original cpia driver, which
+     this one was modelled from.
diff --git a/Documentation/video4linux/cpia2_overview.txt b/Documentation/video4linux/cpia2_overview.txt
new file mode 100644 (file)
index 0000000..a6e5366
--- /dev/null
@@ -0,0 +1,38 @@
+                       Programmer's View of Cpia2
+
+Cpia2 is the second generation video coprocessor from VLSI Vision Ltd (now a
+division of ST Microelectronics).  There are two versions.  The first is the
+STV0672, which is capable of up to 30 frames per second (fps) in frame sizes
+up to CIF, and 15 fps for VGA frames.  The STV0676 is an improved version,
+which can handle up to 30 fps VGA.  Both coprocessors can be attached to two
+CMOS sensors - the vvl6410 CIF sensor and the vvl6500 VGA sensor.  These will
+be referred to as the 410 and the 500 sensors, or the CIF and VGA sensors.
+
+The two chipsets operate almost identically.  The core is an 8051 processor,
+running two different versions of firmware.  The 672 runs the VP4 video
+processor code, the 676 runs VP5.  There are a few differences in register
+mappings for the two chips.  In these cases, the symbols defined in the
+header files are marked with VP4 or VP5 as part of the symbol name.
+
+The cameras appear externally as three sets of registers. Setting register
+values is the only way to control the camera.  Some settings are
+interdependant, such as the sequence required to power up the camera. I will
+try to make note of all of these cases.
+
+The register sets are called blocks.  Block 0 is the system block.  This
+section is always powered on when the camera is plugged in.  It contains
+registers that control housekeeping functions such as powering up the video
+processor.  The video processor is the VP block.  These registers control
+how the video from the sensor is processed.  Examples are timing registers,
+user mode (vga, qvga), scaling, cropping, framerates, and so on.  The last
+block is the video compressor (VC).  The video stream sent from the camera is
+compressed as Motion JPEG (JPEGA).  The VC controls all of the compression
+parameters.  Looking at the file cpia2_registers.h, you can get a full view
+of these registers and the possible values for most of them.
+
+One or more registers can be set or read by sending a usb control message to
+the camera.  There are three modes for this.  Block mode requests a number
+of contiguous registers.  Random mode reads or writes random registers with
+a tuple structure containing address/value pairs.  The repeat mode is only
+used by VP4 to load a firmware patch.  It contains a starting address and
+a sequence of bytes to be written into a gpio port.
\ No newline at end of file
index ad0d77cbfbc39df4a961c1e2fa56e90c4c3790bf..7a1cbda8a2fe1f41e8affe1e88f4c138069ab6f3 100644 (file)
@@ -1524,12 +1524,6 @@ M:       davem@davemloft.net
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
-LANMEDIA WAN CARD DRIVER
-P:     Andrew Stanley-Jones
-M:     asj@lanmedia.com
-W:     http://www.lanmedia.com/
-S:     Supported
 LAPB module
 P:     Henner Eisen
 M:     eis@baty.hanse.de
diff --git a/README b/README
index 0d318abaf7fd15f5cf2df2a01c9549262ebfa0fc..05e055530bbb687599dd732d6753c77ffa281ae5 100644 (file)
--- a/README
+++ b/README
@@ -74,7 +74,7 @@ INSTALLING the kernel:
    whatever the kernel-du-jour happens to be.
 
  - You can also upgrade between 2.6.xx releases by patching.  Patches are
-   distributed in the traditional gzip and the new bzip2 format.  To
+   distributed in the traditional gzip and the newer bzip2 format.  To
    install by patching, get all the newer patch files, enter the
    top level directory of the kernel source (linux-2.6.xx) and execute:
 
index d31b1cb7eea0d83ed2cb632ed07b42d593aad3c7..23609400a8e2f2ca9a1253dce10ff20a1a391d1f 100644 (file)
@@ -788,6 +788,8 @@ static int locomo_probe(struct platform_device *dev)
        if (!mem)
                return -EINVAL;
        irq = platform_get_irq(dev, 0);
+       if (irq < 0)
+               return -ENXIO;
 
        return __locomo_probe(&dev->dev, mem, irq);
 }
index 1475089f9b4265f7b2c9dc86696dea0a4970c027..93352f6097c1b387d799b025653147994fbdbbda 100644 (file)
@@ -943,6 +943,8 @@ static int sa1111_probe(struct platform_device *pdev)
        if (!mem)
                return -EINVAL;
        irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return -ENXIO;
 
        return __sa1111_probe(&pdev->dev, mem, irq);
 }
index 4303d988c4bf3fa621d070718bf591766c686595..d13270c5d7cdef5d41ee39287eadda3c7f1def36 100644 (file)
@@ -202,11 +202,6 @@ struct clk realview_clcd_clk = {
 /*
  * CLCD support.
  */
-#define SYS_CLCD_MODE_MASK     (3 << 0)
-#define SYS_CLCD_MODE_888      (0 << 0)
-#define SYS_CLCD_MODE_5551     (1 << 0)
-#define SYS_CLCD_MODE_565_RLSB (2 << 0)
-#define SYS_CLCD_MODE_565_BLSB (3 << 0)
 #define SYS_CLCD_NLCDIOON      (1 << 2)
 #define SYS_CLCD_VDDPOSSWITCH  (1 << 3)
 #define SYS_CLCD_PWR3V5SWITCH  (1 << 4)
@@ -360,29 +355,10 @@ static void realview_clcd_enable(struct clcd_fb *fb)
        void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
        u32 val;
 
-       val = readl(sys_clcd);
-       val &= ~SYS_CLCD_MODE_MASK;
-
-       switch (fb->fb.var.green.length) {
-       case 5:
-               val |= SYS_CLCD_MODE_5551;
-               break;
-       case 6:
-               val |= SYS_CLCD_MODE_565_RLSB;
-               break;
-       case 8:
-               val |= SYS_CLCD_MODE_888;
-               break;
-       }
-
-       /*
-        * Set the MUX
-        */
-       writel(val, sys_clcd);
-
        /*
-        * And now enable the PSUs
+        * Enable the PSUs
         */
+       val = readl(sys_clcd);
        val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
        writel(val, sys_clcd);
 }
index 3cbe6e9cb9fcb3799f573fb8799d1f0380fe6155..1629c3ac9bee6bb2a0ee1853036da45df84cee2b 100644 (file)
@@ -1,49 +1,87 @@
 #
 # Automatically generated make config: don't edit
 #
+CONFIG_X86_32=y
+CONFIG_SEMAPHORE_SLEEPERS=y
 CONFIG_X86=y
 CONFIG_MMU=y
-CONFIG_UID16=y
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
+# CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_AUDIT=y
-CONFIG_AUDITSYSCALL=y
-CONFIG_LOG_BUF_SHIFT=15
-CONFIG_HOTPLUG=y
-# CONFIG_IKCONFIG is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_VM86=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
 
 #
 # Processor type and features
@@ -66,43 +104,50 @@ CONFIG_X86_PC=y
 # CONFIG_MPENTIUMII is not set
 # CONFIG_MPENTIUMIII is not set
 # CONFIG_MPENTIUMM is not set
-CONFIG_MPENTIUM4=y
+# CONFIG_MPENTIUM4 is not set
 # CONFIG_MK6 is not set
-# CONFIG_MK7 is not set
+CONFIG_MK7=y
 # CONFIG_MK8 is not set
 # CONFIG_MCRUSOE is not set
 # CONFIG_MEFFICEON is not set
 # CONFIG_MWINCHIPC6 is not set
 # CONFIG_MWINCHIP2 is not set
 # CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
 # CONFIG_MCYRIXIII is not set
 # CONFIG_MVIAC3_2 is not set
 # CONFIG_X86_GENERIC is not set
 CONFIG_X86_CMPXCHG=y
 CONFIG_X86_XADD=y
-CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_X86_L1_CACHE_SHIFT=6
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_X86_WP_WORKS_OK=y
 CONFIG_X86_INVLPG=y
 CONFIG_X86_BSWAP=y
 CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
 CONFIG_X86_GOOD_APIC=y
 CONFIG_X86_INTEL_USERCOPY=y
 CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_USE_3DNOW=y
+CONFIG_X86_TSC=y
 # CONFIG_HPET_TIMER is not set
-# CONFIG_HPET_EMULATE_RTC is not set
-CONFIG_SMP=y
-CONFIG_NR_CPUS=8
-CONFIG_SCHED_SMT=y
-CONFIG_PREEMPT=y
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_X86_UP_APIC=y
+CONFIG_X86_UP_IOAPIC=y
 CONFIG_X86_LOCAL_APIC=y
 CONFIG_X86_IO_APIC=y
-CONFIG_X86_TSC=y
 CONFIG_X86_MCE=y
 CONFIG_X86_MCE_NONFATAL=y
-CONFIG_X86_MCE_P4THERMAL=y
+# CONFIG_X86_MCE_P4THERMAL is not set
 # CONFIG_TOSHIBA is not set
 # CONFIG_I8K is not set
+# CONFIG_X86_REBOOTFIXUPS is not set
 # CONFIG_MICROCODE is not set
 # CONFIG_X86_MSR is not set
 # CONFIG_X86_CPUID is not set
@@ -111,41 +156,71 @@ CONFIG_X86_MCE_P4THERMAL=y
 # Firmware Drivers
 #
 # CONFIG_EDD is not set
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
 CONFIG_NOHIGHMEM=y
 # CONFIG_HIGHMEM4G is not set
 # CONFIG_HIGHMEM64G is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_3G_OPT is not set
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_MATH_EMULATION is not set
 CONFIG_MTRR=y
 # CONFIG_EFI is not set
-CONFIG_IRQBALANCE=y
-CONFIG_HAVE_DEC_LOCK=y
-# CONFIG_REGPARM is not set
+CONFIG_REGPARM=y
+# CONFIG_SECCOMP is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+# CONFIG_KEXEC is not set
+CONFIG_PHYSICAL_START=0x100000
+CONFIG_DOUBLEFAULT=y
 
 #
 # Power management options (ACPI, APM)
 #
 CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
 CONFIG_SOFTWARE_SUSPEND=y
+CONFIG_PM_STD_PARTITION="/dev/hda2"
 
 #
 # ACPI (Advanced Configuration and Power Interface) Support
 #
 CONFIG_ACPI=y
-CONFIG_ACPI_SLEEP=y
-CONFIG_ACPI_SLEEP_PROC_FS=y
-CONFIG_ACPI_AC=y
-CONFIG_ACPI_BATTERY=y
-CONFIG_ACPI_BUTTON=y
-CONFIG_ACPI_FAN=y
-CONFIG_ACPI_PROCESSOR=y
-CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_SLEEP is not set
+# CONFIG_ACPI_AC is not set
+# CONFIG_ACPI_BATTERY is not set
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_VIDEO is not set
+# CONFIG_ACPI_HOTKEY is not set
+# CONFIG_ACPI_FAN is not set
+# CONFIG_ACPI_PROCESSOR is not set
 # CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_IBM is not set
 # CONFIG_ACPI_TOSHIBA is not set
+CONFIG_ACPI_BLACKLIST_YEAR=0
 # CONFIG_ACPI_DEBUG is not set
 CONFIG_ACPI_EC=y
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_SYSTEM=y
 # CONFIG_X86_PM_TIMER is not set
+# CONFIG_ACPI_CONTAINER is not set
 
 #
 # APM (Advanced Power Management) BIOS Support
@@ -168,19 +243,18 @@ CONFIG_PCI_GOANY=y
 CONFIG_PCI_BIOS=y
 CONFIG_PCI_DIRECT=y
 CONFIG_PCI_MMCONFIG=y
-# CONFIG_PCI_USE_VECTOR is not set
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
-CONFIG_ISA=y
-# CONFIG_EISA is not set
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_MSI is not set
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_ISA_DMA_API=y
+# CONFIG_ISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SCx200 is not set
 
 #
-# PCMCIA/CardBus support
+# PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCMCIA is not set
-CONFIG_PCMCIA_PROBE=y
+# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
@@ -191,8 +265,147 @@ CONFIG_PCMCIA_PROBE=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_MISC=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+CONFIG_NETFILTER_XTABLES=y
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+# CONFIG_IP_NF_CT_PROTO_SCTP is not set
+CONFIG_IP_NF_FTP=y
+# CONFIG_IP_NF_IRC is not set
+# CONFIG_IP_NF_NETBIOS_NS is not set
+# CONFIG_IP_NF_TFTP is not set
+# CONFIG_IP_NF_AMANDA is not set
+# CONFIG_IP_NF_PPTP is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+# CONFIG_IP_NF_MATCH_IPRANGE is not set
+# CONFIG_IP_NF_MATCH_MULTIPORT is not set
+# CONFIG_IP_NF_MATCH_TOS is not set
+# CONFIG_IP_NF_MATCH_RECENT is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_DSCP is not set
+# CONFIG_IP_NF_MATCH_AH_ESP is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
+CONFIG_IP_NF_FILTER=y
+# CONFIG_IP_NF_TARGET_REJECT is not set
+CONFIG_IP_NF_TARGET_LOG=y
+# CONFIG_IP_NF_TARGET_ULOG is not set
+# CONFIG_IP_NF_TARGET_TCPMSS is not set
+# CONFIG_IP_NF_NAT is not set
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -201,7 +414,14 @@ CONFIG_BINFMT_MISC=y
 #
 # Generic Driver Options
 #
-CONFIG_FW_LOADER=m
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -213,40 +433,36 @@ CONFIG_FW_LOADER=m
 #
 CONFIG_PARPORT=y
 CONFIG_PARPORT_PC=y
-CONFIG_PARPORT_PC_CML1=y
 # CONFIG_PARPORT_SERIAL is not set
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
-# CONFIG_PARPORT_1284 is not set
+# CONFIG_PARPORT_GSC is not set
+CONFIG_PARPORT_1284=y
 
 #
 # Plug and Play support
 #
-CONFIG_PNP=y
-# CONFIG_PNP_DEBUG is not set
-
-#
-# Protocols
-#
-# CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
+# CONFIG_PNP is not set
 
 #
 # Block devices
 #
-CONFIG_BLK_DEV_FD=y
-# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_FD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
-CONFIG_LBD=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -257,34 +473,31 @@ CONFIG_BLK_DEV_IDE=y
 #
 # Please see Documentation/ide.txt for help/info on IDE drives
 #
+# CONFIG_BLK_DEV_IDE_SATA is not set
 # CONFIG_BLK_DEV_HD_IDE is not set
 CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
-CONFIG_IDE_TASKFILE_IO=y
 
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_CMD640=y
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_CMD640 is not set
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_RZ1000=y
+# CONFIG_BLK_DEV_RZ1000 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
@@ -294,10 +507,12 @@ CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_CS5535 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
-CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -306,9 +521,8 @@ CONFIG_BLK_DEV_PIIX=y
 # CONFIG_BLK_DEV_SIS5513 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
 # CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
 CONFIG_IDEDMA_AUTO=y
@@ -317,8 +531,9 @@ CONFIG_IDEDMA_AUTO=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
+# CONFIG_SCSI_PROC_FS is not set
 
 #
 # SCSI support type (disk, tape, CD-ROM)
@@ -327,7 +542,8 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
-CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -341,78 +557,46 @@ CONFIG_CHR_DEV_SG=y
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
-CONFIG_SCSI_DPT_I2O=m
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_MEGARAID is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_SVW is not set
-CONFIG_SCSI_ATA_PIIX=y
-# CONFIG_SCSI_SATA_PROMISE is not set
-CONFIG_SCSI_SATA_SX4=m
-# CONFIG_SCSI_SATA_SIL is not set
-CONFIG_SCSI_SATA_SIS=m
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
 # CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_PPA is not set
 # CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-CONFIG_SCSI_IPR=m
-# CONFIG_SCSI_IPR_TRACE is not set
-# CONFIG_SCSI_IPR_DUMP is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
-# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
 #
 # Multi-device support (RAID and LVM)
 #
@@ -422,37 +606,14 @@ CONFIG_SCSI_QLA2XXX=y
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-CONFIG_IEEE1394=y
-
-#
-# Subsystem Options
-#
-# CONFIG_IEEE1394_VERBOSEDEBUG is not set
-# CONFIG_IEEE1394_OUI_DB is not set
-# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set
-
-#
-# Device Drivers
-#
-
-#
-# Texas Instruments PCILynx requires I2C
-#
-CONFIG_IEEE1394_OHCI1394=y
-
-#
-# Protocol Drivers
-#
-# CONFIG_IEEE1394_VIDEO1394 is not set
-# CONFIG_IEEE1394_SBP2 is not set
-# CONFIG_IEEE1394_ETH1394 is not set
-# CONFIG_IEEE1394_DV1394 is not set
-CONFIG_IEEE1394_RAWIO=y
-# CONFIG_IEEE1394_CMP is not set
+# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
@@ -460,136 +621,24 @@ CONFIG_IEEE1394_RAWIO=y
 # CONFIG_I2O is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
+# Network device support
 #
-CONFIG_IP_NF_CONNTRACK=y
-# CONFIG_IP_NF_FTP is not set
-# CONFIG_IP_NF_IRC is not set
-# CONFIG_IP_NF_TFTP is not set
-# CONFIG_IP_NF_AMANDA is not set
-CONFIG_IP_NF_QUEUE=y
-CONFIG_IP_NF_IPTABLES=y
-CONFIG_IP_NF_MATCH_LIMIT=y
-CONFIG_IP_NF_MATCH_IPRANGE=y
-CONFIG_IP_NF_MATCH_MAC=y
-CONFIG_IP_NF_MATCH_PKTTYPE=y
-CONFIG_IP_NF_MATCH_MARK=y
-CONFIG_IP_NF_MATCH_MULTIPORT=y
-CONFIG_IP_NF_MATCH_TOS=y
-CONFIG_IP_NF_MATCH_RECENT=y
-CONFIG_IP_NF_MATCH_ECN=y
-CONFIG_IP_NF_MATCH_DSCP=y
-CONFIG_IP_NF_MATCH_AH_ESP=y
-CONFIG_IP_NF_MATCH_LENGTH=y
-CONFIG_IP_NF_MATCH_TTL=y
-CONFIG_IP_NF_MATCH_TCPMSS=y
-CONFIG_IP_NF_MATCH_HELPER=y
-CONFIG_IP_NF_MATCH_STATE=y
-CONFIG_IP_NF_MATCH_CONNTRACK=y
-CONFIG_IP_NF_MATCH_OWNER=y
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_NAT=y
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=y
-CONFIG_IP_NF_TARGET_REDIRECT=y
-CONFIG_IP_NF_TARGET_NETMAP=y
-CONFIG_IP_NF_TARGET_SAME=y
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_MANGLE=y
-CONFIG_IP_NF_TARGET_TOS=y
-CONFIG_IP_NF_TARGET_ECN=y
-CONFIG_IP_NF_TARGET_DSCP=y
-CONFIG_IP_NF_TARGET_MARK=y
-CONFIG_IP_NF_TARGET_CLASSIFY=y
-CONFIG_IP_NF_TARGET_LOG=y
-CONFIG_IP_NF_TARGET_ULOG=y
-CONFIG_IP_NF_TARGET_TCPMSS=y
-CONFIG_IP_NF_ARPTABLES=y
-CONFIG_IP_NF_ARPFILTER=y
-CONFIG_IP_NF_ARP_MANGLE=y
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_RAW=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
+# CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
 
 #
 # ARCnet devices
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -597,40 +646,28 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
 
 #
 # Tulip family network device support
 #
 # CONFIG_NET_TULIP is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_CS89x0 is not set
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
+CONFIG_E100=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
 # CONFIG_8139CP is not set
-CONFIG_8139TOO=y
-CONFIG_8139TOO_PIO=y
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_8139TOO is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -644,21 +681,24 @@ CONFIG_8139TOO_PIO=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
-# CONFIG_E1000_NAPI is not set
-# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
-CONFIG_S2IO=m
-# CONFIG_S2IO_NAPI is not set
+# CONFIG_S2IO is not set
 
 #
 # Token Ring devices
@@ -682,6 +722,8 @@ CONFIG_S2IO=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -703,25 +745,13 @@ CONFIG_INPUT=y
 #
 CONFIG_INPUT_MOUSEDEV=y
 CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1024
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-
 #
 # Input Device Drivers
 #
@@ -734,14 +764,24 @@ CONFIG_KEYBOARD_ATKBD=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
 #
 # Character devices
 #
@@ -757,12 +797,14 @@ CONFIG_SERIAL_8250=y
 # CONFIG_SERIAL_8250_CONSOLE is not set
 # CONFIG_SERIAL_8250_ACPI is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_CORE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -770,7 +812,6 @@ CONFIG_PRINTER=y
 # CONFIG_LP_CONSOLE is not set
 # CONFIG_PPDEV is not set
 # CONFIG_TIPAR is not set
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -782,9 +823,8 @@ CONFIG_PRINTER=y
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
+CONFIG_NVRAM=y
+CONFIG_RTC=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -793,62 +833,268 @@ CONFIG_PRINTER=y
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_FTAPE is not set
 CONFIG_AGP=y
 # CONFIG_AGP_ALI is not set
 # CONFIG_AGP_ATI is not set
 # CONFIG_AGP_AMD is not set
 # CONFIG_AGP_AMD64 is not set
-CONFIG_AGP_INTEL=y
+# CONFIG_AGP_INTEL is not set
 # CONFIG_AGP_NVIDIA is not set
 # CONFIG_AGP_SIS is not set
 # CONFIG_AGP_SWORKS is not set
-# CONFIG_AGP_VIA is not set
+CONFIG_AGP_VIA=y
 # CONFIG_AGP_EFFICEON is not set
 CONFIG_DRM=y
 # CONFIG_DRM_TDFX is not set
-# CONFIG_DRM_GAMMA is not set
 # CONFIG_DRM_R128 is not set
-# CONFIG_DRM_RADEON is not set
-# CONFIG_DRM_I810 is not set
-CONFIG_DRM_I830=y
+CONFIG_DRM_RADEON=y
 # CONFIG_DRM_MGA is not set
 # CONFIG_DRM_SIS is not set
+# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
 # CONFIG_MWAVE is not set
+# CONFIG_CS5535_GPIO is not set
 # CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
 # CONFIG_HANGCHECK_TIMER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_ISA=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+CONFIG_I2C_VIAPRO=y
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=y
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+CONFIG_SENSORS_IT87=y
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_HDAPS is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
 #
 # CONFIG_IBM_ASM is not set
 
+#
+# Multimedia Capabilities Port drivers
+#
+
 #
 # Multimedia devices
 #
-# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_DEV=y
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_BWQCAM is not set
+# CONFIG_VIDEO_CQCAM is not set
+# CONFIG_VIDEO_W9966 is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+CONFIG_VIDEO_SAA7134=y
+# CONFIG_VIDEO_SAA7134_ALSA is not set
+# CONFIG_VIDEO_MXB is not set
+# CONFIG_VIDEO_DPC is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_VIDEO_AUDIO_DECODER is not set
+# CONFIG_VIDEO_DECODER is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
 
 #
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+CONFIG_VIDEO_TUNER=y
+CONFIG_VIDEO_BUF=y
+CONFIG_VIDEO_IR=y
 
 #
 # Graphics support
 #
-# CONFIG_FB is not set
-# CONFIG_VIDEO_SELECT is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_VESA is not set
+CONFIG_VIDEO_SELECT=y
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_I810 is not set
+# CONFIG_FB_INTEL is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_CYBLA is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_VIRTUAL is not set
 
 #
 # Console display driver support
 #
 CONFIG_VGA_CONSOLE=y
-# CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -864,10 +1110,13 @@ CONFIG_SND_PCM=y
 CONFIG_SND_RAWMIDI=y
 CONFIG_SND_SEQUENCER=y
 # CONFIG_SND_SEQ_DUMMY is not set
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_SEQUENCER_OSS is not set
+CONFIG_SND_RTCTIMER=y
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -875,81 +1124,66 @@ CONFIG_SND_SEQUENCER_OSS=y
 # Generic devices
 #
 CONFIG_SND_MPU401_UART=y
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_AC97_BUS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_VIRMIDI is not set
 # CONFIG_SND_MTPAV is not set
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
 
-#
-# ISA devices
-#
-# CONFIG_SND_AD1848 is not set
-# CONFIG_SND_CS4231 is not set
-# CONFIG_SND_CS4232 is not set
-# CONFIG_SND_CS4236 is not set
-# CONFIG_SND_ES1688 is not set
-# CONFIG_SND_ES18XX is not set
-# CONFIG_SND_GUSCLASSIC is not set
-# CONFIG_SND_GUSEXTREME is not set
-# CONFIG_SND_GUSMAX is not set
-# CONFIG_SND_INTERWAVE is not set
-# CONFIG_SND_INTERWAVE_STB is not set
-# CONFIG_SND_OPTI92X_AD1848 is not set
-# CONFIG_SND_OPTI92X_CS4231 is not set
-# CONFIG_SND_OPTI93X is not set
-# CONFIG_SND_SB8 is not set
-# CONFIG_SND_SB16 is not set
-# CONFIG_SND_SBAWE is not set
-# CONFIG_SND_WAVEFRONT is not set
-# CONFIG_SND_CMI8330 is not set
-# CONFIG_SND_OPL3SA2 is not set
-# CONFIG_SND_SGALAXY is not set
-# CONFIG_SND_SSCAPE is not set
-
 #
 # PCI devices
 #
-CONFIG_SND_AC97_CODEC=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS4000 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
 # CONFIG_SND_AU8810 is not set
 # CONFIG_SND_AU8820 is not set
 # CONFIG_SND_AU8830 is not set
 # CONFIG_SND_AZT3328 is not set
 # CONFIG_SND_BT87X is not set
-# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5535AUDIO is not set
 # CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_EMU10K1X is not set
 # CONFIG_SND_ENS1370 is not set
 # CONFIG_SND_ENS1371 is not set
 # CONFIG_SND_ES1938 is not set
 # CONFIG_SND_ES1968 is not set
-# CONFIG_SND_MAESTRO3 is not set
 # CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
 # CONFIG_SND_ICE1712 is not set
 # CONFIG_SND_ICE1724 is not set
-CONFIG_SND_INTEL8X0=y
+# CONFIG_SND_INTEL8X0 is not set
 # CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
 # CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_TRIDENT is not set
+CONFIG_SND_VIA82XX=y
+# CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
 
 #
-# ALSA USB devices
+# USB devices
 #
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
 
 #
 # Open Sound System
@@ -959,6 +1193,8 @@ CONFIG_SND_INTEL8X0=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -968,6 +1204,8 @@ CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
 
 #
 # USB Host Controller Drivers
@@ -975,68 +1213,93 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_OHCI_HCD is not set
 CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
 #
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_MIDI is not set
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
 # CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=y
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
 # CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
-# USB Human Interface Devices (HID)
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
 #
-CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
-CONFIG_USB_EGALAX=m
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
 
 #
 # USB Imaging devices
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
 #
 # CONFIG_USB_DABUSB is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_PWC is not set
 
 #
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -1053,56 +1316,85 @@ CONFIG_USB_EGALAX=m
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
-CONFIG_USB_CYTHERM=m
-CONFIG_USB_PHIDGETSERVO=m
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
 
+#
+# USB DSL modem support
+#
+
 #
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
 
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# EDAC - error detection and reporting (RAS)
+#
+# CONFIG_EDAC is not set
+
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+# CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=y
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+# CONFIG_UDF_FS is not set
 
 #
 # DOS/FAT/NT Filesystems
 #
 CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
+# CONFIG_MSDOS_FS is not set
 CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -1111,12 +1403,12 @@ CONFIG_VFAT_FS=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1138,38 +1430,48 @@ CONFIG_RAMFS=y
 #
 # Network File Systems
 #
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=y
-# CONFIG_NFSD_V3 is not set
-CONFIG_NFSD_TCP=y
-CONFIG_LOCKD=y
-CONFIG_EXPORTFS=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
+CONFIG_CIFS=y
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
 #
-# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
 CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 
 #
 # Native Language Support
 #
 CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+# CONFIG_NLS_CODEPAGE_437 is not set
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
+CONFIG_NLS_CODEPAGE_850=y
 # CONFIG_NLS_CODEPAGE_852 is not set
 # CONFIG_NLS_CODEPAGE_855 is not set
 # CONFIG_NLS_CODEPAGE_857 is not set
@@ -1189,6 +1491,7 @@ CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_ISO8859_8 is not set
 # CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
 CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
@@ -1199,31 +1502,33 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_ISO8859_9 is not set
 # CONFIG_NLS_ISO8859_13 is not set
 # CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
+CONFIG_NLS_ISO8859_15=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
+CONFIG_NLS_UTF8=y
 
 #
-# Profiling support
+# Instrumentation Support
 #
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
 
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_EARLY_PRINTK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-# CONFIG_FRAME_POINTER is not set
-CONFIG_4KSTACKS=y
 CONFIG_X86_FIND_SMP_CONFIG=y
 CONFIG_X86_MPPARSE=y
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
@@ -1231,14 +1536,19 @@ CONFIG_X86_MPPARSE=y
 #
 # CONFIG_CRYPTO is not set
 
+#
+# Hardware crypto devices
+#
+
 #
 # Library routines
 #
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
-CONFIG_LIBCRC32C=m
-CONFIG_X86_SMP=y
-CONFIG_X86_HT=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_X86_BIOS_REBOOT=y
-CONFIG_X86_TRAMPOLINE=y
-CONFIG_X86_STD_RESOURCES=y
-CONFIG_PC=y
+CONFIG_KTIME_SCALAR=y
index ac9de2661c0b98e43c62c80610dfb7771c230b9b..a331cc90797c2c959dcf50876aa738915886e46c 100644 (file)
@@ -269,6 +269,11 @@ SECTIONS {
                *(__ksymtab_gpl)
                __stop___ksymtab_gpl = .;
 
+               /* Kernel symbol table: GPL-future symbols */
+               __start___ksymtab_gpl_future = .;
+               *(__ksymtab_gpl_future)
+               __stop___ksymtab_gpl_future = .;
+
                /* Kernel symbol table: Normal symbols */
                __start___kcrctab = .;
                *(__kcrctab)
@@ -279,6 +284,11 @@ SECTIONS {
                *(__kcrctab_gpl)
                __stop___kcrctab_gpl = .;
 
+               /* Kernel symbol table: GPL-future symbols */
+               __start___kcrctab_gpl_future = .;
+               *(__kcrctab_gpl_future)
+               __stop___kcrctab_gpl_future = .;
+
                /* Kernel symbol table: strings */
                *(__ksymtab_strings)
 
index 3a0f89d2c8dc91586e6e189cf9d0eaa2082e916e..ac2012f033d611863c31812d04fb3417276e58a7 100644 (file)
@@ -602,7 +602,7 @@ config SGI_IP32
          If you want this kernel to run on SGI O2 workstation, say Y here.
 
 config SIBYTE_BIGSUR
-       bool "Support for Sibyte BigSur"
+       bool "Support for Sibyte BCM91480B-BigSur"
        select BOOT_ELF32
        select DMA_COHERENT
        select PCI_DOMAINS
@@ -790,6 +790,7 @@ source "arch/mips/tx4927/Kconfig"
 source "arch/mips/tx4938/Kconfig"
 source "arch/mips/vr41xx/Kconfig"
 source "arch/mips/philips/pnx8550/common/Kconfig"
+source "arch/mips/cobalt/Kconfig"
 
 endmenu
 
@@ -1159,6 +1160,7 @@ config CPU_R4X00
 config CPU_TX49XX
        bool "R49XX"
        depends on SYS_HAS_CPU_TX49XX
+       select CPU_HAS_PREFETCH
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_64BIT_KERNEL
 
@@ -1581,7 +1583,7 @@ source "mm/Kconfig"
 
 config SMP
        bool "Multi-Processing support"
-       depends on CPU_RM9000 || ((SIBYTE_BCM1x80 || SIBYTE_BCM1x55 || SIBYTE_SB1250) && !SIBYTE_STANDALONE) || SGI_IP27 || MIPS_MT_SMP
+       depends on CPU_RM9000 || ((SIBYTE_BCM1x80 || SIBYTE_BCM1x55 || SIBYTE_SB1250 || QEMU) && !SIBYTE_STANDALONE) || SGI_IP27 || MIPS_MT_SMP
        ---help---
          This enables support for systems with more than one CPU. If you have
          a system with only one CPU, like most personal computers, say N. If
index 3d8dac681c6352de5aab10e7a19deff067ae24c3..9a69e0f0ab765db60737334d34e3793c03ffb441 100644 (file)
 # for "archclean" cleaning up for this architecture.
 #
 
-as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \
-            -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \
-            else echo "$(2)"; fi ;)
-
 cflags-y :=
 
 #
@@ -38,12 +34,10 @@ else
 endif
 
 ifdef CONFIG_32BIT
-gcc-abi                        = 32
 tool-prefix            = $(32bit-tool-prefix)
 UTS_MACHINE            := mips
 endif
 ifdef CONFIG_64BIT
-gcc-abi                        = 64
 tool-prefix            = $(64bit-tool-prefix)
 UTS_MACHINE            := mips64
 endif
@@ -52,37 +46,27 @@ ifdef CONFIG_CROSSCOMPILE
 CROSS_COMPILE          := $(tool-prefix)
 endif
 
-CHECKFLAGS-y                           += -D__linux__ -D__mips__ \
-                                          -D_MIPS_SZINT=32 \
-                                          -D_ABIO32=1 \
-                                          -D_ABIN32=2 \
-                                          -D_ABI64=3
-CHECKFLAGS-$(CONFIG_32BIT)             += -D_MIPS_SIM=_ABIO32 \
-                                          -D_MIPS_SZLONG=32 \
-                                          -D_MIPS_SZPTR=32 \
-                                          -D__PTRDIFF_TYPE__=int
-CHECKFLAGS-$(CONFIG_64BIT)             += -m64 -D_MIPS_SIM=_ABI64 \
-                                          -D_MIPS_SZLONG=64 \
-                                          -D_MIPS_SZPTR=64 \
-                                          -D__PTRDIFF_TYPE__="long int"
-CHECKFLAGS-$(CONFIG_CPU_BIG_ENDIAN)    += -D__MIPSEB__
-CHECKFLAGS-$(CONFIG_CPU_LITTLE_ENDIAN) += -D__MIPSEL__
-
-CHECKFLAGS                             = $(CHECKFLAGS-y)
+ifdef CONFIG_32BIT
+ld-emul                        = $(32bit-emul)
+vmlinux-32             = vmlinux
+vmlinux-64             = vmlinux.64
+
+cflags-y               += -mabi=32
+endif
 
-ifdef CONFIG_BUILD_ELF64
-gas-abi                        = 64
+ifdef CONFIG_64BIT
 ld-emul                        = $(64bit-emul)
 vmlinux-32             = vmlinux.32
 vmlinux-64             = vmlinux
-else
-gas-abi                        = 32
-ld-emul                        = $(32bit-emul)
-vmlinux-32             = vmlinux
-vmlinux-64             = vmlinux.64
 
-cflags-$(CONFIG_64BIT) += $(call cc-option,-mno-explicit-relocs)
+cflags-y               += -mabi=64
+ifdef CONFIG_BUILD_ELF64
+cflags-y               += $(call cc-option,-mno-explicit-relocs)
+else
+cflags-y               += $(call cc-option,-msym32)
 endif
+endif
+
 
 #
 # GCC uses -G 0 -mabicalls -fpic as default.  We don't want PIC in the kernel
@@ -105,162 +89,44 @@ MODFLAGS                  += -mlong-calls
 # carefully avoid to add it redundantly because gcc 3.3/3.4 complains
 # when fed the toolchain default!
 #
-cflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB)
-cflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL)
+cflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB -D__MIPSEB__)
+cflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL -D__MIPSEL__)
 
 cflags-$(CONFIG_SB1XXX_CORELIS)        += $(call cc-option,-mno-sched-prolog) \
                                   -fno-omit-frame-pointer
 
-#
-# Use: $(call set_gccflags,<cpu0>,<isa0>,<cpu1>,<isa1>,<isa2>)
-#
-# <cpu0>,<isa0> -- preferred CPU and ISA designations (may require
-#                  recent tools)
-# <cpu1>,<isa1> -- fallback CPU and ISA designations (have to work
-#                  with up to the oldest supported tools)
-# <isa2>        -- an ISA designation used as an ABI selector for
-#                  gcc versions that do not support "-mabi=32"
-#                  (depending on the CPU type, either "mips1" or
-#                  "mips2")
-#
-set_gccflags = $(shell \
-while :; do \
-       cpu=$(1); isa=-$(2); \
-       for gcc_opt in -march= -mcpu=; do \
-               $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \
-                       -xc /dev/null > /dev/null 2>&1 && \
-                       break 2; \
-       done; \
-       cpu=$(3); isa=-$(4); \
-       for gcc_opt in -march= -mcpu=; do \
-               $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \
-                       -xc /dev/null > /dev/null 2>&1 && \
-                       break 2; \
-       done; \
-       break; \
-done; \
-gcc_abi=-mabi=$(gcc-abi); gcc_cpu=$$cpu; \
-if $(CC) $$gcc_abi -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then \
-       gcc_isa=$$isa; \
-else \
-       gcc_abi=; gcc_isa=-$(5); \
-fi; \
-gas_abi=-Wa,-$(gcc-abi); gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \
-while :; do \
-       for gas_opt in -Wa,-march= -Wa,-mcpu=; do \
-               $(CC) $$gas_abi $$gas_opt$$cpu $$gas_isa -Wa,-Z -c \
-                       -o /dev/null -xassembler /dev/null > /dev/null 2>&1 && \
-                       break 2; \
-       done; \
-       gas_abi=; gas_opt=; gas_cpu=; gas_isa=; \
-       break; \
-done; \
-if test "$(gcc-abi)" != "$(gas-abi)"; then \
-       gas_abi="-Wa,-$(gas-abi) -Wa,-mgp$(gcc-abi)"; \
-fi; \
-if test "$$gcc_opt" = -march= && test -n "$$gcc_abi"; then \
-       $(CC) $$gcc_abi $$gcc_opt$$gcc_cpu -S -o /dev/null \
-               -xc /dev/null > /dev/null 2>&1 && \
-               gcc_isa=; \
-fi; \
-echo $$gcc_abi $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_abi $$gas_opt$$gas_cpu $$gas_isa)
-
 #
 # CPU-dependent compiler/assembler options for optimization.
 #
-cflags-$(CONFIG_CPU_R3000)     += \
-                       $(call set_gccflags,r3000,mips1,r3000,mips1,mips1)
-CHECKFLAGS-$(CONFIG_CPU_R3000) += -D_MIPS_ISA=_MIPS_ISA_MIPS1
-
-cflags-$(CONFIG_CPU_TX39XX)    += \
-                       $(call set_gccflags,r3900,mips1,r3000,mips1,mips1)
-CHECKFLAGS-$(CONFIG_CPU_TX39XX)        += -D_MIPS_ISA=_MIPS_ISA_MIPS1
-
-cflags-$(CONFIG_CPU_R6000)     += \
-                       $(call set_gccflags,r6000,mips2,r6000,mips2,mips2) \
-                       -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_R6000) += -D_MIPS_ISA=_MIPS_ISA_MIPS2
-
-cflags-$(CONFIG_CPU_R4300)     += \
-                       $(call set_gccflags,r4300,mips3,r4300,mips3,mips2) \
-                       -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_R4300) += -D_MIPS_ISA=_MIPS_ISA_MIPS3
-
-cflags-$(CONFIG_CPU_VR41XX)    += \
-                       $(call set_gccflags,r4100,mips3,r4600,mips3,mips2) \
-                       -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_VR41XX)        += -D_MIPS_ISA=_MIPS_ISA_MIPS3
-
-cflags-$(CONFIG_CPU_R4X00)     += \
-                       $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \
-                       -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_R4X00) += -D_MIPS_ISA=_MIPS_ISA_MIPS3
-
-cflags-$(CONFIG_CPU_TX49XX)    += \
-                       $(call set_gccflags,r4600,mips3,r4600,mips3,mips2)  \
+cflags-$(CONFIG_CPU_R3000)     += -march=r3000
+cflags-$(CONFIG_CPU_TX39XX)    += -march=r3900
+cflags-$(CONFIG_CPU_R6000)     += -march=r6000 -Wa,--trap
+cflags-$(CONFIG_CPU_R4300)     += -march=r4300 -Wa,--trap
+cflags-$(CONFIG_CPU_VR41XX)    += -march=r4100 -Wa,--trap
+cflags-$(CONFIG_CPU_R4X00)     += -march=r4600 -Wa,--trap
+cflags-$(CONFIG_CPU_TX49XX)    += -march=r4600 -Wa,--trap
+cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips2 -mtune=r4600) \
+                       -Wa,-mips32 -Wa,--trap
+cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips2 -mtune=r4600) \
+                       -Wa,-mips32r2 -Wa,--trap
+cflags-$(CONFIG_CPU_MIPS64_R1) += $(call cc-option,-march=mips64,-mips2 -mtune=r4600) \
+                       -Wa,-mips64 -Wa,--trap
+cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips2 -mtune=r4600 ) \
+                       -Wa,-mips64r2 -Wa,--trap
+cflags-$(CONFIG_CPU_R5000)     += -march=r5000 -Wa,--trap
+cflags-$(CONFIG_CPU_R5432)     += $(call cc-options,-march=r5400,-march=r5000) \
                        -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_TX49XX)        += -D_MIPS_ISA=_MIPS_ISA_MIPS3
-
-cflags-$(CONFIG_CPU_MIPS32_R1) += \
-                       $(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
-                       -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_MIPS32_R1)     += -D_MIPS_ISA=_MIPS_ISA_MIPS32
-
-cflags-$(CONFIG_CPU_MIPS32_R2) += \
-                       $(call set_gccflags,mips32r2,mips32r2,r4600,mips3,mips2) \
+cflags-$(CONFIG_CPU_NEVADA)    += $(call cc-options,-march=rm5200,-march=r5000) \
                        -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_MIPS32_R2)     += -D_MIPS_ISA=_MIPS_ISA_MIPS32
-
-cflags-$(CONFIG_CPU_MIPS64_R1) += \
-                       $(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
+cflags-$(CONFIG_CPU_RM7000)    += $(call cc-option,-march=rm7000,-march=r5000) \
                        -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_MIPS64_R1)     += -D_MIPS_ISA=_MIPS_ISA_MIPS64
-
-cflags-$(CONFIG_CPU_MIPS64_R2) += \
-                       $(call set_gccflags,mips64r2,mips64r2,r4600,mips3,mips2) \
+cflags-$(CONFIG_CPU_RM9000)    += $(call cc-option,-march=rm9000,-march=r5000) \
                        -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_MIPS64_R2)     += -D_MIPS_ISA=_MIPS_ISA_MIPS64
-
-cflags-$(CONFIG_CPU_R5000)     += \
-                       $(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \
+cflags-$(CONFIG_CPU_SB1)       += $(call cc-option,-march=sb1,-march=r5000) \
                        -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_R5000) += -D_MIPS_ISA=_MIPS_ISA_MIPS4
-
-cflags-$(CONFIG_CPU_R5432)     += \
-                       $(call set_gccflags,r5400,mips4,r5000,mips4,mips2) \
+cflags-$(CONFIG_CPU_R8000)     += -march=r8000 -Wa,--trap
+cflags-$(CONFIG_CPU_R10000)    += $(call cc-option,-march=r10000,-march=r8000) \
                        -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_R5432) += -D_MIPS_ISA=_MIPS_ISA_MIPS4
-
-cflags-$(CONFIG_CPU_NEVADA)    += \
-                       $(call set_gccflags,rm5200,mips4,r5000,mips4,mips2) \
-                       -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_NEVADA)        += -D_MIPS_ISA=_MIPS_ISA_MIPS4
-
-cflags-$(CONFIG_CPU_RM7000)    += \
-                       $(call set_gccflags,rm7000,mips4,r5000,mips4,mips2) \
-                       -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_RM7000)        += -D_MIPS_ISA=_MIPS_ISA_MIPS4
-
-cflags-$(CONFIG_CPU_RM9000)    += \
-                       $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \
-                       -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_RM9000)        += -D_MIPS_ISA=_MIPS_ISA_MIPS4
-
-
-cflags-$(CONFIG_CPU_SB1)       += \
-                       $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \
-                       -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_SB1)   += -D_MIPS_ISA=_MIPS_ISA_MIPS64
-
-cflags-$(CONFIG_CPU_R8000)     += \
-                       $(call set_gccflags,r8000,mips4,r8000,mips4,mips2) \
-                       -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_R8000) += -D_MIPS_ISA=_MIPS_ISA_MIPS4
-
-cflags-$(CONFIG_CPU_R10000)    += \
-                       $(call set_gccflags,r10000,mips4,r8000,mips4,mips2) \
-                       -Wa,--trap
-CHECKFLAGS-$(CONFIG_CPU_R10000)        += -D_MIPS_ISA=_MIPS_ISA_MIPS4
 
 ifdef CONFIG_CPU_SB1
 ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
@@ -630,7 +496,6 @@ endif
 ifdef CONFIG_SGI_IP27
 core-$(CONFIG_SGI_IP27)                += arch/mips/sgi-ip27/
 cflags-$(CONFIG_SGI_IP27)      += -Iinclude/asm-mips/mach-ip27
-ifdef CONFIG_BUILD_ELF64
 ifdef CONFIG_MAPPED_KERNEL
 load-$(CONFIG_SGI_IP27)                += 0xc00000004001c000
 OBJCOPYFLAGS                   := --change-addresses=0x3fffffff80000000
@@ -639,16 +504,6 @@ else
 load-$(CONFIG_SGI_IP27)                += 0xa80000000001c000
 OBJCOPYFLAGS                   := --change-addresses=0x57ffffff80000000
 endif
-else
-ifdef CONFIG_MAPPED_KERNEL
-load-$(CONFIG_SGI_IP27)                += 0xffffffffc001c000
-OBJCOPYFLAGS                   := --change-addresses=0xc000000080000000
-dataoffset-$(CONFIG_SGI_IP27)  += 0x01000000
-else
-load-$(CONFIG_SGI_IP27)                += 0xffffffff8001c000
-OBJCOPYFLAGS                   := --change-addresses=0xa800000080000000
-endif
-endif
 endif
 
 #
@@ -757,6 +612,12 @@ CFLAGS             += $(cflags-y)
 
 LDFLAGS                        += -m $(ld-emul)
 
+ifdef CONFIG_MIPS
+CHECKFLAGS += $(shell $(CC) $(CFLAGS) -dM -E -xc /dev/null | \
+       egrep -vw '__GNUC_(MAJOR|MINOR|PATCHLEVEL)__' | \
+       sed -e 's/^\#define /-D/' -e 's/ /="/' -e 's/$$/"/')
+endif
+
 OBJCOPYFLAGS           += --remove-section=.reginfo
 
 #
index d00e8247d6c2ea7bbe67f765b1f19282bef51806..6ee090bd86c9a78bf215179033f5a195e3542d91 100644 (file)
@@ -214,7 +214,7 @@ au1xxx_ddma_add_device(dbdev_tab_t *dev)
        if ( NULL != p )
        {
                memcpy(p, dev, sizeof(dbdev_tab_t));
-               p->dev_id = DSCR_DEV2CUSTOM_ID(new_id,dev->dev_id);
+               p->dev_id = DSCR_DEV2CUSTOM_ID(new_id,dev->dev_id);
                ret = p->dev_id;
                new_id++;
 #if 0
@@ -260,7 +260,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
        spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
        if (!(stp->dev_flags & DEV_FLAGS_INUSE) ||
             (stp->dev_flags & DEV_FLAGS_ANYUSE)) {
-               /* Got source */
+               /* Got source */
                stp->dev_flags |= DEV_FLAGS_INUSE;
                if (!(dtp->dev_flags & DEV_FLAGS_INUSE) ||
                     (dtp->dev_flags & DEV_FLAGS_ANYUSE)) {
index 1905c6b104f23fd7c7e3c054c373373bb3420905..1d82f2277517e23511c48659c2ca649cd1c4cfa3 100644 (file)
@@ -174,7 +174,7 @@ int request_au1000_dma(int dev_id, const char *dev_str,
                return -EINVAL;
 #else
        if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
-               return -EINVAL;
+               return -EINVAL;
 #endif
 
        for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
index dbb4ee7ed42dc8d81cb7a84873be31ee2b521089..32702e5fbf6761600bc09ec3cf4e392425c8d3fd 100644 (file)
@@ -264,7 +264,7 @@ static struct resource smc91x_resources[] = {
 
 static struct platform_device smc91x_device = {
        .name           = "smc91x",
-       .id             = -1,
+       .id             = -1,
        .num_resources  = ARRAY_SIZE(smc91x_resources),
        .resource       = smc91x_resources,
 };
@@ -286,7 +286,7 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
        &au1xxx_mmc_device,
 #endif
 #ifdef CONFIG_MIPS_DB1200
-       &smc91x_device,
+       &smc91x_device,
 #endif
 };
 
index eb155c071aa61c372f5455a0525f2f347cf18832..1080558c8100e70200d07a011945eae7ea3634a9 100644 (file)
@@ -90,7 +90,7 @@ void __init plat_setup(void)
        else {
                /* Clear to obtain best system bus performance */
                clear_c0_config(1<<19); /* Clear Config[OD] */
-       }
+       }
 
        argptr = prom_getcmdline();
 
index 883d3f3d8c5369d10117bc7e16764c58c13c23a0..f85f1524b36639a1c9c2e9bf0e7ef8673afb4c97 100644 (file)
@@ -359,7 +359,7 @@ static unsigned long do_fast_cp0_gettimeoffset(void)
                : "hi", "lo", GCC_REG_ACCUM);
 
        /*
-        * Due to possible jiffies inconsistencies, we need to check
+        * Due to possible jiffies inconsistencies, we need to check
         * the result so that we'll get a timer that is monotonic.
         */
        if (res >= USECS_PER_JIFFY)
diff --git a/arch/mips/cobalt/Kconfig b/arch/mips/cobalt/Kconfig
new file mode 100644 (file)
index 0000000..7c42b08
--- /dev/null
@@ -0,0 +1,7 @@
+config EARLY_PRINTK
+       bool "Early console support"
+       depends on MIPS_COBALT
+       help
+         Provide early console support by direct access to the
+         on board UART. The UART must have been previously
+         initialised by the boot loader.
index 3b6b7579d1dee8e36b86189069cecffba594f218..720e757b2b6413cded55f094fc802bd565671412 100644 (file)
@@ -4,4 +4,6 @@
 
 obj-y   := irq.o int-handler.o reset.o setup.o
 
+obj-$(CONFIG_EARLY_PRINTK)     += console.o
+
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/cobalt/console.c b/arch/mips/cobalt/console.c
new file mode 100644 (file)
index 0000000..45c2d27
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * (C) P. Horton 2006
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/serial_reg.h>
+#include <asm/addrspace.h>
+#include <asm/mach-cobalt/cobalt.h>
+
+static void putchar(int c)
+{
+       if(c == '\n')
+               putchar('\r');
+
+       while(!(COBALT_UART[UART_LSR] & UART_LSR_THRE))
+               ;
+
+       COBALT_UART[UART_TX] = c;
+}
+
+static void cons_write(struct console *c, const char *s, unsigned n)
+{
+       while(n-- && *s)
+               putchar(*s++);
+}
+
+static struct console cons_info =
+{
+       .name   = "uart",
+       .write  = cons_write,
+       .flags  = CON_PRINTBUFFER | CON_BOOT,
+       .index  = -1,
+};
+
+void __init cobalt_early_console(void)
+{
+       register_console(&cons_info);
+
+       printk("Cobalt: early console registered\n");
+}
index b9713a7230536aeaf098d82538c092f34d26ae8c..4f9ea121002389cdbd5ce874017efbc0e40d12af 100644 (file)
@@ -31,6 +31,7 @@
 extern void cobalt_machine_restart(char *command);
 extern void cobalt_machine_halt(void);
 extern void cobalt_machine_power_off(void);
+extern void cobalt_early_console(void);
 
 int cobalt_board_id;
 
@@ -109,14 +110,6 @@ void __init plat_setup(void)
        /* I/O port resource must include UART and LCD/buttons */
        ioport_resource.end = 0x0fffffff;
 
-       /*
-        * This is a prom style console. We just poke at the
-        *  UART to make it talk.
-        * Only use this console if you really screw up and can't
-        *  get to the stage of setting up a real serial console.
-        */
-       /*ns16550_setup_console();*/
-
        /* request I/O space for devices used on all i[345]86 PCs */
        for (i = 0; i < COBALT_IO_RESOURCES; i++)
                request_resource(&ioport_resource, cobalt_io_resources + i);
@@ -136,6 +129,10 @@ void __init plat_setup(void)
 #ifdef CONFIG_SERIAL_8250
        if (cobalt_board_id > COBALT_BRD_ID_RAQ1) {
 
+#ifdef CONFIG_EARLY_PRINTK
+               cobalt_early_console();
+#endif
+
                uart.line       = 0;
                uart.type       = PORT_UNKNOWN;
                uart.uartclk    = 18432000;
index 89c21572a59cf94a480167466d615b6f453d2eb1..9e1ae953e966f000f56a936871cd3e20f9439abc 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:05:52 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:39:52 2006
 #
 CONFIG_MIPS=y
 
@@ -164,26 +164,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -335,6 +337,29 @@ CONFIG_BRIDGE_NETFILTER=y
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -353,47 +378,30 @@ CONFIG_IP_NF_AMANDA=m
 CONFIG_IP_NF_PPTP=m
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
 CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_PHYSDEV=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_DCCP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_CONNBYTES=m
 CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_MATCH_STRING=m
+CONFIG_IP_NF_MATCH_POLICY=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_TARGET_NFQUEUE=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
 CONFIG_IP_NF_NAT_IRC=m
 CONFIG_IP_NF_NAT_FTP=m
 CONFIG_IP_NF_NAT_TFTP=m
@@ -403,13 +411,9 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
 CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
 CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
 CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
@@ -419,26 +423,20 @@ CONFIG_IP_NF_ARP_MANGLE=m
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_FRAG=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_MULTIPORT=m
 CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_MATCH_PHYSDEV=m
+CONFIG_IP6_NF_MATCH_POLICY=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_TARGET_NFQUEUE=m
 CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
 CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 
@@ -494,6 +492,11 @@ CONFIG_IPDDP_ENCAP=y
 CONFIG_IPDDP_DECAP=y
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 CONFIG_NET_DIVERT=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -553,7 +556,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -663,7 +665,7 @@ CONFIG_SCSI_LOGGING=y
 # SCSI Transport Attributes
 #
 CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
 
@@ -696,13 +698,7 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -785,6 +781,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -824,6 +821,7 @@ CONFIG_LAN_SAA9730=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -845,8 +843,6 @@ CONFIG_LAN_SAA9730=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -926,6 +922,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -933,7 +930,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -970,6 +966,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -1076,6 +1078,7 @@ CONFIG_XFS_QUOTA=y
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=m
 CONFIG_ROMFS_FS=m
 CONFIG_INOTIFY=y
@@ -1118,6 +1121,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1225,6 +1229,7 @@ CONFIG_NLS_UTF8=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 6fd353779813835a5da72a7f101f2e535c118413..32984100a75e559a91db2bbca1b5da3a86b541fa 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:05:54 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:39:53 2006
 #
 CONFIG_MIPS=y
 
@@ -169,29 +169,31 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -247,7 +249,6 @@ CONFIG_MMU=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-CONFIG_BUILD_ELF64=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_MIPS32_O32=y
@@ -309,6 +310,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -457,6 +463,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -478,6 +485,7 @@ CONFIG_MII=y
 CONFIG_NET_SB1250_MAC=y
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -543,12 +551,15 @@ CONFIG_SERIO_RAW=m
 #
 # CONFIG_VT is not set
 CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
 # CONFIG_ROCKETPORT is not set
 # CONFIG_CYCLADES is not set
 # CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
+# CONFIG_SYNCLINK_GT is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_SPECIALIX is not set
 # CONFIG_SX is not set
@@ -564,7 +575,6 @@ CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -654,6 +664,12 @@ CONFIG_I2C_DEBUG_ALGO=y
 CONFIG_I2C_DEBUG_BUS=y
 CONFIG_I2C_DEBUG_CHIP=y
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -732,12 +748,12 @@ CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -770,6 +786,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -831,18 +848,20 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
index 5261e29ccf3794ae69c64d70c9c028887b19f584..6c2961affbd6d90cc159a76613ac3cdb0cb7bc98 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:05:55 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:39:54 2006
 #
 CONFIG_MIPS=y
 
@@ -63,9 +63,9 @@ CONFIG_MACH_VR41XX=y
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_CASIO_E55 is not set
 # CONFIG_IBM_WORKPAD is not set
+# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_TANBAC_TB022X is not set
 # CONFIG_VICTOR_MPC30X is not set
 CONFIG_ZAO_CAPCELLA=y
@@ -90,7 +90,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_MIPS64_R2 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
@@ -103,23 +103,18 @@ CONFIG_CPU_VR41XX=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_VR41XX=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
 #
 # Kernel type
 #
-CONFIG_32BIT=y
+# CONFIG_32BIT is not set
 # CONFIG_64BIT is not set
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_MIPS_MT is not set
-# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -155,26 +150,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -190,7 +187,6 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
-# CONFIG_LBD is not set
 
 #
 # IO Schedulers
@@ -228,7 +224,6 @@ CONFIG_MMU=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
 
 #
 # Networking
@@ -286,6 +281,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -306,7 +306,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -444,6 +443,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -487,6 +487,7 @@ CONFIG_8139TOO_PIO=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -508,8 +509,6 @@ CONFIG_8139TOO_PIO=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -579,11 +578,6 @@ CONFIG_HW_CONSOLE=y
 #
 # Non-8250 serial port support
 #
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_VR41XX=y
-CONFIG_SERIAL_VR41XX_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -599,7 +593,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
 # CONFIG_GEN_RTC is not set
-# CONFIG_RTC_VR41XX is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -608,7 +601,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Ftape, the floppy tape device driver
 #
 # CONFIG_DRM is not set
-CONFIG_GPIO_VR41XX=y
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -622,6 +614,12 @@ CONFIG_GPIO_VR41XX=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -704,11 +702,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -741,6 +739,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -803,6 +802,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 1d3ee18ea8bbbcb5fd57105211d90f90ebdca138..8336b21d3db289ffce3bb41c08d49bea78ba8668 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:05:57 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:39:55 2006
 #
 CONFIG_MIPS=y
 
@@ -150,26 +150,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -271,6 +273,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -291,7 +298,6 @@ CONFIG_IEEE80211=y
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=y
 CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_CRYPT_TKIP=y
 
 #
 # Device Drivers
@@ -364,9 +370,38 @@ CONFIG_BLK_DEV_IDEDISK=y
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_IDEPCI is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
 # CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_HD is not set
 
@@ -433,11 +468,21 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
 #
-# CONFIG_NET_TULIP is not set
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=y
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_TULIP_NAPI is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
 # CONFIG_HP100 is not set
 # CONFIG_NET_PCI is not set
 
@@ -453,6 +498,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -473,8 +519,6 @@ CONFIG_NET_ETHERNET=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=y
 
 #
 # Wan interfaces
@@ -550,6 +594,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -557,7 +602,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -594,6 +638,12 @@ CONFIG_COBALT_LCD=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -678,12 +728,12 @@ CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -716,6 +766,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -774,6 +825,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 18ac7926c05895a8b2541d505755d5c8994c5426..7f071403c8e335fedf9bc3f79fba8c802cb513f4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:05:59 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:39:56 2006
 #
 CONFIG_MIPS=y
 
@@ -151,26 +151,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -285,6 +288,21 @@ CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -312,6 +330,11 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -320,6 +343,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -332,7 +356,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -395,6 +418,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -512,6 +536,7 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -625,13 +650,13 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_CS=m
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 CONFIG_SERIAL_8250_AU1X00=y
 
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_AU1X00 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
@@ -675,6 +700,12 @@ CONFIG_SYNCLINK_CS=m
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -773,6 +804,7 @@ CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -805,6 +837,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -909,6 +942,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -963,3 +997,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index 4f55f7414c9cd32af09763edc982459c89a312f2..98590cac1ec56435efb8775c862da60f91f22815 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:00 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:39:57 2006
 #
 CONFIG_MIPS=y
 
@@ -151,26 +151,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -274,6 +277,21 @@ CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -301,6 +319,11 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -309,6 +332,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -321,7 +345,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -384,6 +407,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -501,6 +525,7 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -600,13 +625,13 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 CONFIG_SERIAL_8250_AU1X00=y
 
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_AU1X00 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
@@ -643,6 +668,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -772,6 +803,7 @@ CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -804,6 +836,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -908,6 +941,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -962,3 +996,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index 0e5de7d05f23c538b12ea088cf6c22c94df6c629..92888472dca09a6c8deb42fccbb3df5db8020735 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:03 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:39:58 2006
 #
 CONFIG_MIPS=y
 
@@ -151,27 +151,30 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -279,6 +282,21 @@ CONFIG_NETFILTER=y
 #
 # CONFIG_NETFILTER_NETLINK is not set
 # CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -306,6 +324,11 @@ CONFIG_NETFILTER=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -314,6 +337,7 @@ CONFIG_NETFILTER=y
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -385,6 +409,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -568,6 +593,7 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 # CONFIG_MIPS_AU1X00_ENET is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -665,13 +691,13 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 CONFIG_SERIAL_8250_AU1X00=y
 
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_AU1X00 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
@@ -715,6 +741,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -842,6 +874,7 @@ CONFIG_JFS_FS=y
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -881,6 +914,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -990,6 +1024,7 @@ CONFIG_NLS_UTF8=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -1020,3 +1055,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index 86e7be8412f3dc2566b04d2d97e9204c2ce810b6..5a415b1d4af0163de68fc0b7580965cbe0f90b1a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:05 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:39:59 2006
 #
 CONFIG_MIPS=y
 
@@ -153,26 +153,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -293,6 +296,21 @@ CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -320,6 +338,11 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -328,6 +351,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -340,7 +364,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -403,6 +426,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -561,6 +585,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -581,6 +606,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -601,8 +627,6 @@ CONFIG_MIPS_AU1X00_ENET=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # PCMCIA network device support
@@ -692,16 +716,15 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 CONFIG_SERIAL_8250_AU1X00=y
 
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_AU1X00 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -745,6 +768,12 @@ CONFIG_SYNCLINK_CS=m
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -788,8 +817,6 @@ CONFIG_SOUND=y
 # Advanced Linux Sound Architecture
 #
 CONFIG_SND=m
-CONFIG_SND_AC97_CODEC=m
-CONFIG_SND_AC97_BUS=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
 CONFIG_SND_RAWMIDI=m
@@ -799,13 +826,16 @@ CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-CONFIG_SND_GENERIC_DRIVER=y
 
 #
 # Generic devices
 #
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
 # CONFIG_SND_DUMMY is not set
 CONFIG_SND_VIRMIDI=m
 CONFIG_SND_MTPAV=m
@@ -815,6 +845,7 @@ CONFIG_SND_MTPAV=m
 #
 # PCI devices
 #
+# CONFIG_SND_AD1889 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
 # CONFIG_SND_ATIIXP_MODEM is not set
@@ -823,38 +854,38 @@ CONFIG_SND_MTPAV=m
 # CONFIG_SND_AU8830 is not set
 # CONFIG_SND_AZT3328 is not set
 # CONFIG_SND_BT87X is not set
-# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_ENS1370 is not set
 # CONFIG_SND_ENS1371 is not set
 # CONFIG_SND_ES1938 is not set
 # CONFIG_SND_ES1968 is not set
-# CONFIG_SND_MAESTRO3 is not set
 # CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
 # CONFIG_SND_ICE1712 is not set
 # CONFIG_SND_ICE1724 is not set
 # CONFIG_SND_INTEL8X0 is not set
 # CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
 # CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
 # CONFIG_SND_VIA82XX is not set
 # CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
-# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_YMFPCI is not set
 
 #
 # ALSA MIPS devices
@@ -939,12 +970,14 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # may also be needed; see USB_STORAGE Help for more information
 #
 # CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 # CONFIG_USB_HIDDEV is not set
 # CONFIG_USB_AIPTEK is not set
@@ -958,6 +991,7 @@ CONFIG_USB_HIDINPUT=y
 CONFIG_USB_YEALINK=m
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
 
@@ -1057,6 +1091,7 @@ CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -1089,6 +1124,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1193,6 +1229,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -1247,3 +1284,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index ea5ab0ca5774f7d31b69df26f67833a6ac912c40..8dc1f18badfe259b2611ae74b01c65cc4afa03e8 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:07 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:00 2006
 #
 CONFIG_MIPS=y
 
@@ -152,26 +152,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -292,6 +295,21 @@ CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -319,6 +337,11 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -327,6 +350,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -339,7 +363,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -402,6 +425,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -593,6 +617,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -613,6 +638,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -633,8 +659,6 @@ CONFIG_MIPS_AU1X00_ENET=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # PCMCIA network device support
@@ -732,16 +756,15 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 CONFIG_SERIAL_8250_AU1X00=y
 
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_AU1X00 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -785,6 +808,12 @@ CONFIG_SYNCLINK_CS=m
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -878,6 +907,7 @@ CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -910,6 +940,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1014,6 +1045,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -1068,3 +1100,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index a81e2de6947f0db01e5eac4ffb090622e54d304c..8fae63e47e5ecda5449adb057365f68ad111cc14 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:09 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:02 2006
 #
 CONFIG_MIPS=y
 
@@ -151,26 +151,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -276,6 +278,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -296,7 +303,6 @@ CONFIG_IEEE80211=y
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=y
 CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_CRYPT_TKIP=y
 
 #
 # Device Drivers
@@ -445,6 +451,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_DM9000 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 
 #
@@ -469,6 +476,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -489,8 +497,6 @@ CONFIG_NET_ETHERNET=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=y
 
 #
 # Wan interfaces
@@ -566,6 +572,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -573,7 +580,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -610,6 +616,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -669,7 +681,6 @@ CONFIG_FB=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_SMIVGX is not set
-# CONFIG_FB_CYBLA is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 
@@ -729,11 +740,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -766,6 +777,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -825,6 +837,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index f1c27c2fb03326b896856da651c89b68d001d635..a0fcd44e770944d1ce26f89c2a55db6ff1d123db 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:11 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:02 2006
 #
 CONFIG_MIPS=y
 
@@ -151,26 +151,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -275,6 +277,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -295,7 +302,6 @@ CONFIG_IEEE80211=y
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=y
 CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_CRYPT_TKIP=y
 
 #
 # Device Drivers
@@ -414,6 +420,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -453,6 +460,7 @@ CONFIG_PCNET32=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -474,8 +482,6 @@ CONFIG_PCNET32=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=y
 
 #
 # Wan interfaces
@@ -551,6 +557,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -558,7 +565,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -595,6 +601,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -677,11 +689,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -714,6 +726,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -776,6 +789,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 08a4de6ec4a69056a7ecfe21a08c59d5d9f84ecf..5a181eadd437e98a195d2c08004e171570a2b37a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:13 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:03 2006
 #
 CONFIG_MIPS=y
 
@@ -150,27 +150,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -278,6 +280,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -298,7 +305,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -436,6 +442,7 @@ CONFIG_CICADA_PHY=m
 #
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_DM9000 is not set
 CONFIG_DECLANCE=y
 
 #
@@ -538,6 +545,12 @@ CONFIG_RTC=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -636,12 +649,12 @@ CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -674,6 +687,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -734,6 +748,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SGI_PARTITION is not set
 CONFIG_ULTRIX_PARTITION=y
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -750,18 +765,20 @@ CONFIG_ULTRIX_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
index c9070cef08b1b9db010adcdbbd4b59416eb43403..8fbfc06a6a2ae0b5edfb678688bd66e882c0a624 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:14 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:04 2006
 #
 CONFIG_MIPS=y
 
@@ -63,9 +63,9 @@ CONFIG_MACH_VR41XX=y
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_NEC_CMBVR4133 is not set
 CONFIG_CASIO_E55=y
 # CONFIG_IBM_WORKPAD is not set
+# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_TANBAC_TB022X is not set
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
@@ -88,7 +88,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_MIPS64_R2 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
@@ -101,23 +101,18 @@ CONFIG_CPU_VR41XX=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_VR41XX=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
 #
 # Kernel type
 #
-CONFIG_32BIT=y
+# CONFIG_32BIT is not set
 # CONFIG_64BIT is not set
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_MIPS_MT is not set
-# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -153,26 +148,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -188,7 +185,6 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
-# CONFIG_LBD is not set
 
 #
 # IO Schedulers
@@ -223,7 +219,6 @@ CONFIG_MMU=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
 
 #
 # Networking
@@ -278,6 +273,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -298,7 +298,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -433,6 +432,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_DM9000 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_AT1700 is not set
 # CONFIG_DEPCA is not set
@@ -531,10 +531,6 @@ CONFIG_HW_CONSOLE=y
 #
 # Non-8250 serial port support
 #
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_VR41XX=y
-CONFIG_SERIAL_VR41XX_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -563,14 +559,12 @@ CONFIG_WATCHDOG=y
 # CONFIG_WDT is not set
 # CONFIG_RTC is not set
 # CONFIG_GEN_RTC is not set
-# CONFIG_RTC_VR41XX is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
 #
 # Ftape, the floppy tape device driver
 #
-CONFIG_GPIO_VR41XX=y
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -584,6 +578,12 @@ CONFIG_GPIO_VR41XX=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -665,11 +665,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -702,6 +702,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -763,6 +764,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index aa24d85ea94d12c687f1a031520baa45d76bb62e..f2d43be69007dffc1561150ac36582d01e17f129 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:16 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:05 2006
 #
 CONFIG_MIPS=y
 
@@ -153,26 +153,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -282,6 +284,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -302,7 +309,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -420,6 +426,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -440,6 +447,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -460,8 +468,6 @@ CONFIG_NET_ETHERNET=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -545,6 +551,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -552,7 +559,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -589,6 +595,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -671,11 +683,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -708,6 +720,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -767,6 +780,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index eeed0e5ad260a9aabf34994e619215824b32d58f..ac5841c4b698700b2bd146d4ff569eefdbcfead3 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:18 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:06 2006
 #
 CONFIG_MIPS=y
 
@@ -157,26 +157,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -284,6 +286,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -304,7 +311,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -407,6 +413,7 @@ CONFIG_CICADA_PHY=m
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_MIPS_GT96100ETH=y
+# CONFIG_DM9000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -496,6 +503,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -537,6 +545,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -617,11 +631,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -654,6 +668,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -713,6 +728,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index e56351abf87a403fdbd712d3df7a1602bf4f7bee..42d5cd7927cbf26f1e824b0c105e8b7e43b57469 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:20 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:39:51 2006
 #
 CONFIG_MIPS=y
 
@@ -158,27 +158,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -317,6 +319,28 @@ CONFIG_NETFILTER=y
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -335,39 +359,23 @@ CONFIG_IP_NF_AMANDA=m
 CONFIG_IP_NF_PPTP=m
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
 CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_OWNER=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_DCCP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_CONNBYTES=m
 CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_MATCH_STRING=m
+CONFIG_IP_NF_MATCH_POLICY=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_TARGET_NFQUEUE=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -384,13 +392,9 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
 CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
 CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
@@ -400,25 +404,20 @@ CONFIG_IP_NF_ARP_MANGLE=m
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_FRAG=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_MULTIPORT=m
 CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_POLICY=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_TARGET_NFQUEUE=m
 CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
 CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 
@@ -445,6 +444,11 @@ CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 CONFIG_NET_DIVERT=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -504,7 +508,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -641,6 +644,7 @@ CONFIG_CICADA_PHY=m
 #
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_DM9000 is not set
 CONFIG_SGISEEQ=y
 
 #
@@ -786,6 +790,12 @@ CONFIG_MAX_RAW_DEVS=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -892,6 +902,7 @@ CONFIG_XFS_QUOTA=y
 CONFIG_XFS_SECURITY=y
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=m
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -934,6 +945,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1007,6 +1019,7 @@ CONFIG_MSDOS_PARTITION=y
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -1062,6 +1075,7 @@ CONFIG_NLS_UTF8=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 58c22cd344d3570ee8efea3f7b4b49d8b12d041d..8c40590737e1c1419a398a7aeb74e86a7c8d1590 100644 (file)
@@ -132,6 +132,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=64
 CONFIG_PREEMPT_NONE=y
@@ -158,28 +159,30 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CPUSETS=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -234,7 +237,6 @@ CONFIG_MMU=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-CONFIG_BUILD_ELF64=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_MIPS32_O32=y
@@ -290,6 +292,10 @@ CONFIG_TCP_CONG_BIC=y
 #
 # CONFIG_IP_SCTP is not set
 
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -357,7 +363,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -368,7 +373,7 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -442,7 +447,7 @@ CONFIG_SCSI_LOGGING=y
 # SCSI Transport Attributes
 #
 CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
 
@@ -470,13 +475,7 @@ CONFIG_SCSI_SAS_ATTRS=m
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 CONFIG_SCSI_QLOGIC_1280=y
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -561,6 +560,7 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -581,6 +581,7 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -601,8 +602,6 @@ CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -656,6 +655,7 @@ CONFIG_SERIO_RAW=m
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -705,6 +705,12 @@ CONFIG_SGI_IP27_RTC=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -801,6 +807,7 @@ CONFIG_XFS_QUOTA=y
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -834,6 +841,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -894,6 +902,7 @@ CONFIG_MSDOS_PARTITION=y
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -910,6 +919,7 @@ CONFIG_SGI_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=15
 CONFIG_CROSSCOMPILE=y
index a34db6e82b27c07cd123bba3a86b11882f281f18..7fdcaf51face58f31976fb05babb581e208d6113 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:24 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:09 2006
 #
 CONFIG_MIPS=y
 
@@ -158,26 +158,28 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -224,7 +226,6 @@ CONFIG_MMU=y
 #
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
-# CONFIG_BUILD_ELF64 is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_MIPS32_O32=y
@@ -286,6 +287,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -306,7 +312,6 @@ CONFIG_IEEE80211=y
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=y
 CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_CRYPT_TKIP=y
 
 #
 # Device Drivers
@@ -392,7 +397,7 @@ CONFIG_SCSI_LOGGING=y
 # SCSI Transport Attributes
 #
 CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 CONFIG_SCSI_SAS_ATTRS=y
 
@@ -425,13 +430,7 @@ CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -498,6 +497,7 @@ CONFIG_SGI_O2MACE_ETH=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -518,6 +518,7 @@ CONFIG_SGI_O2MACE_ETH=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -538,8 +539,6 @@ CONFIG_SGI_O2MACE_ETH=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=y
 
 #
 # Wan interfaces
@@ -617,6 +616,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -624,7 +624,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -661,6 +660,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -743,11 +748,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -780,6 +785,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -835,6 +841,7 @@ CONFIG_PARTITION_ADVANCED=y
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -851,6 +858,7 @@ CONFIG_SGI_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index b5fa9639db6f35d6f6c8457864a1a7494e0bc5ff..c716996d9eca8152cd6c35145b6e72e62cd17c4b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:26 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:10 2006
 #
 CONFIG_MIPS=y
 
@@ -153,26 +153,29 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -281,6 +284,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -301,7 +309,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -362,6 +369,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -500,6 +508,7 @@ CONFIG_CICADA_PHY=m
 #
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_DM9000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -593,6 +602,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -634,6 +644,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -728,11 +744,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -765,6 +781,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -826,6 +843,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 71386938d47f155dc9f0c6e52ade74159df35ad1..a8376d125e11e438e813ffb5f25e2172a980c3ae 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:27 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:11 2006
 #
 CONFIG_MIPS=y
 
@@ -150,26 +150,28 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -280,6 +282,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -300,7 +307,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -440,6 +446,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -460,6 +467,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -480,8 +488,6 @@ CONFIG_NET_ETHERNET=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -560,6 +566,7 @@ CONFIG_IT8172_SCR1=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -567,7 +574,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -603,6 +609,12 @@ CONFIG_RTC=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -685,11 +697,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -722,6 +734,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -781,6 +794,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 14fb46886708429e9d13ce9e73d4c85efdb4dd38..316015379dbc7458b3e14d623a42138ce731553e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:29 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:12 2006
 #
 CONFIG_MIPS=y
 
@@ -158,27 +158,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -186,6 +187,7 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
 
@@ -294,7 +296,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -411,6 +412,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -469,8 +471,6 @@ CONFIG_MV643XX_ETH_2=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -515,6 +515,7 @@ CONFIG_IPW2200=m
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -522,7 +523,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -557,6 +557,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -631,7 +637,6 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -710,6 +715,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index a8ded3d74152dd7bff901867d9d7d4e763e6498e..53fbef1ac25d3d27063483ee188b0c4c80e9b9fc 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:31 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:13 2006
 #
 CONFIG_MIPS=y
 
@@ -148,26 +148,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -272,6 +274,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -292,7 +299,6 @@ CONFIG_IEEE80211=y
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=y
 CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_CRYPT_TKIP=y
 
 #
 # Device Drivers
@@ -411,6 +417,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -431,6 +438,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -451,8 +459,6 @@ CONFIG_NET_ETHERNET=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=y
 
 #
 # Wan interfaces
@@ -529,6 +535,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
+# CONFIG_SYNCLINK_GT is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -545,7 +552,6 @@ CONFIG_SERIAL_NONSTANDARD=y
 # Non-8250 serial port support
 #
 CONFIG_HAS_TXX9_SERIAL=y
-# CONFIG_SERIAL_JSM is not set
 # CONFIG_UNIX98_PTYS is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -582,6 +588,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -641,7 +653,6 @@ CONFIG_FB=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_SMIVGX is not set
-# CONFIG_FB_CYBLA is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 
@@ -698,11 +709,11 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -735,6 +746,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -794,6 +806,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 6c5df76d48d966f3c917e9bfd206d5d639718f61..ef0fa9fc79d6fc8cf9dd29c03579c52c4c73bb92 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:33 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:14 2006
 #
 CONFIG_MIPS=y
 
@@ -156,26 +156,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -282,6 +285,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -302,7 +310,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -365,6 +372,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -548,6 +556,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -568,6 +577,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -588,8 +598,6 @@ CONFIG_NET_ETHERNET=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -665,6 +673,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -672,7 +681,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -709,6 +717,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -801,6 +815,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -833,6 +848,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -895,6 +911,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index da0677a03c1d5b60ce081dcd617696faebb7a358..367d279efdd9a73923bc89009b000c315e0074f9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc5
-# Fri Dec 23 02:21:03 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:15 2006
 #
 CONFIG_MIPS=y
 
@@ -170,26 +170,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -341,6 +343,29 @@ CONFIG_BRIDGE_NETFILTER=y
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -359,40 +384,23 @@ CONFIG_IP_NF_AMANDA=m
 CONFIG_IP_NF_PPTP=m
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
 CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_PHYSDEV=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_DCCP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_CONNBYTES=m
 CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_MATCH_STRING=m
+CONFIG_IP_NF_MATCH_POLICY=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_TARGET_NFQUEUE=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -409,13 +417,9 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
 CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
 CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
@@ -425,26 +429,20 @@ CONFIG_IP_NF_ARP_MANGLE=m
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_FRAG=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_MULTIPORT=m
 CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_MATCH_PHYSDEV=m
+CONFIG_IP6_NF_MATCH_POLICY=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_TARGET_NFQUEUE=m
 CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
 CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 
@@ -500,6 +498,11 @@ CONFIG_IPDDP_ENCAP=y
 CONFIG_IPDDP_DECAP=y
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 CONFIG_NET_DIVERT=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -559,7 +562,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -734,13 +736,7 @@ CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -823,6 +819,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -862,6 +859,7 @@ CONFIG_PCNET32=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -883,8 +881,6 @@ CONFIG_PCNET32=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -961,6 +957,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -968,7 +965,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -1004,6 +1000,12 @@ CONFIG_RTC=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -1110,6 +1112,7 @@ CONFIG_XFS_QUOTA=y
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=m
 CONFIG_ROMFS_FS=m
 CONFIG_INOTIFY=y
@@ -1152,6 +1155,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1259,6 +1263,7 @@ CONFIG_NLS_UTF8=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index ac39ab7feeb78d774ebd7154671927e9813e4785..fe78961762b865b54bee4600e5e7b1e69238b545 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:37 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:16 2006
 #
 CONFIG_MIPS=y
 
@@ -156,27 +156,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -297,6 +299,11 @@ CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 CONFIG_NET_DIVERT=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -525,6 +532,7 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -566,6 +574,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -640,11 +654,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
 # CONFIG_INOTIFY is not set
@@ -677,6 +691,7 @@ CONFIG_PROC_FS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -738,17 +753,19 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
 # CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DETECT_SOFTLOCKUP is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
index 2b5ea37484e449dcf9b3fa005a908d68d12fc5bd..e4620e7f0a5e00082767c3b0f22be81432c277a0 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:39 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:17 2006
 #
 CONFIG_MIPS=y
 
@@ -63,9 +63,9 @@ CONFIG_MACH_VR41XX=y
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_CASIO_E55 is not set
 # CONFIG_IBM_WORKPAD is not set
+# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_TANBAC_TB022X is not set
 CONFIG_VICTOR_MPC30X=y
 # CONFIG_ZAO_CAPCELLA is not set
@@ -90,7 +90,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_MIPS64_R2 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
@@ -103,23 +103,18 @@ CONFIG_CPU_VR41XX=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_VR41XX=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
 #
 # Kernel type
 #
-CONFIG_32BIT=y
+# CONFIG_32BIT is not set
 # CONFIG_64BIT is not set
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_MIPS_MT is not set
-# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -155,26 +150,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -190,7 +187,6 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
-# CONFIG_LBD is not set
 
 #
 # IO Schedulers
@@ -229,7 +225,6 @@ CONFIG_PCMCIA_IOCTL=y
 # CONFIG_YENTA is not set
 # CONFIG_PD6729 is not set
 # CONFIG_I82092 is not set
-CONFIG_PCMCIA_VRC4173=y
 
 #
 # PCI Hotplug Support
@@ -241,7 +236,6 @@ CONFIG_PCMCIA_VRC4173=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
 
 #
 # Networking
@@ -296,6 +290,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -455,6 +454,7 @@ CONFIG_MII=m
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -604,11 +604,6 @@ CONFIG_HW_CONSOLE=y
 #
 # Non-8250 serial port support
 #
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_VR41XX=y
-CONFIG_SERIAL_VR41XX_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -624,7 +619,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
 # CONFIG_GEN_RTC is not set
-# CONFIG_RTC_VR41XX is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -640,7 +634,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_SYNCLINK_CS is not set
 # CONFIG_CARDMAN_4000 is not set
 # CONFIG_CARDMAN_4040 is not set
-CONFIG_GPIO_VR41XX=y
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -654,6 +647,12 @@ CONFIG_GPIO_VR41XX=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -740,6 +739,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # may also be needed; see USB_STORAGE Help for more information
 #
 # CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
@@ -762,6 +762,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
 
@@ -846,11 +847,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -883,6 +884,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -941,6 +943,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 7ad8718c1b69a13ddebad0222a7c989f2f7074a5..925d8adef88dc5e462c0c941829d954d4bf34d99 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:41 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:18 2006
 #
 CONFIG_MIPS=y
 
@@ -159,27 +159,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -291,6 +293,21 @@ CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -324,6 +341,11 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -332,6 +354,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -344,7 +367,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -426,7 +448,7 @@ CONFIG_SCSI_PROC_FS=y
 # SCSI Transport Attributes
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_FC_ATTRS=m
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
 
@@ -455,13 +477,7 @@ CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -528,6 +544,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -567,6 +584,7 @@ CONFIG_E100=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -592,8 +610,6 @@ CONFIG_MV643XX_ETH_2=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -675,6 +691,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -682,7 +699,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -718,6 +734,12 @@ CONFIG_RTC=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -777,7 +799,6 @@ CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_SMIVGX is not set
-# CONFIG_FB_CYBLA is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 
@@ -861,6 +882,7 @@ CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -893,6 +915,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -999,6 +1022,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -1052,3 +1076,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index e8d6bb3551a2d2003c881545683a60cd5eef7677..ee1cf9b9eb9a213ded75c9ac602aa4d70df58310 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:43 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:19 2006
 #
 CONFIG_MIPS=y
 
@@ -154,26 +154,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -220,7 +222,6 @@ CONFIG_MMU=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_BUILD_ELF64 is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_MIPS32_O32=y
@@ -281,6 +282,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -301,7 +307,6 @@ CONFIG_IEEE80211=y
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=y
 CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_CRYPT_TKIP=y
 
 #
 # Device Drivers
@@ -420,6 +425,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -440,6 +446,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -461,8 +468,6 @@ CONFIG_NET_ETHERNET=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=y
 
 #
 # Wan interfaces
@@ -538,6 +543,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -545,7 +551,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -582,6 +587,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -664,11 +675,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -701,6 +712,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -763,6 +775,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index f3787b68bdd145774bbea53e1e8996bb3f55d82d..d80ff278f2af3fd2e2ac63028f33673677ecd395 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:44 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:20 2006
 #
 CONFIG_MIPS=y
 
@@ -159,26 +159,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -280,6 +282,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -300,7 +307,6 @@ CONFIG_IEEE80211=y
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=y
 CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_CRYPT_TKIP=y
 
 #
 # Device Drivers
@@ -403,6 +409,7 @@ CONFIG_CICADA_PHY=y
 #
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_DM9000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -492,6 +499,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -533,6 +541,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -613,11 +627,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -650,6 +664,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -712,6 +727,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index b6126ad4d06d22c4a300b7a6807839f455263f16..c0f508d180c4608ecc8f9aed4920f464ba81cb14 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:46 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:21 2006
 #
 CONFIG_MIPS=y
 
@@ -157,26 +157,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -223,7 +225,6 @@ CONFIG_MMU=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_BUILD_ELF64 is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_MIPS32_O32=y
@@ -284,6 +285,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -304,7 +310,6 @@ CONFIG_IEEE80211=y
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=y
 CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_CRYPT_TKIP=y
 
 #
 # Device Drivers
@@ -424,6 +429,7 @@ CONFIG_GALILEO_64240_ETH=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -444,6 +450,7 @@ CONFIG_GALILEO_64240_ETH=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -464,8 +471,6 @@ CONFIG_GALILEO_64240_ETH=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=y
 
 #
 # Wan interfaces
@@ -541,6 +546,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -548,7 +554,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -585,6 +590,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -667,11 +678,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -704,6 +715,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -766,6 +778,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 883626afc47d77904cb6c282326d0fc3c44fab5a..194b3c772bb794875fdc31493e4173da12c041d4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:48 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:22 2006
 #
 CONFIG_MIPS=y
 
@@ -153,26 +153,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -287,6 +290,21 @@ CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -314,6 +332,11 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -322,6 +345,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -334,7 +358,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -397,6 +420,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -514,6 +538,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 # CONFIG_MIPS_AU1X00_ENET is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -619,13 +644,13 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 CONFIG_SERIAL_8250_AU1X00=y
 
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_AU1X00 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
@@ -669,6 +694,12 @@ CONFIG_SYNCLINK_CS=m
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -767,6 +798,7 @@ CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -799,6 +831,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -903,6 +936,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -957,3 +991,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index f8fbc77f924ed75f98c155460a4dca0477c888eb..8985725e6a98a946a6277136062be65fc5d1f4f2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:50 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:24 2006
 #
 CONFIG_MIPS=y
 
@@ -152,26 +152,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -293,6 +296,21 @@ CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -320,6 +338,11 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -328,6 +351,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -340,7 +364,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -403,6 +426,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -589,6 +613,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -609,6 +634,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -629,8 +655,6 @@ CONFIG_MIPS_AU1X00_ENET=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # PCMCIA network device support
@@ -728,16 +752,15 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 CONFIG_SERIAL_8250_AU1X00=y
 
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_AU1X00 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -781,6 +804,12 @@ CONFIG_SYNCLINK_CS=m
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -874,6 +903,7 @@ CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -906,6 +936,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1010,6 +1041,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -1064,3 +1096,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index 3d694cd68d38841df4e4fe6feed2a9fb50583bfc..adbf997b540e3ea3a0a607fa9bbaa6d38b6748bb 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:52 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:25 2006
 #
 CONFIG_MIPS=y
 
@@ -152,26 +152,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -293,6 +296,21 @@ CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -320,6 +338,11 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -328,6 +351,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -340,7 +364,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -403,6 +426,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -589,6 +613,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -609,6 +634,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -629,8 +655,6 @@ CONFIG_MIPS_AU1X00_ENET=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # PCMCIA network device support
@@ -720,16 +744,15 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 CONFIG_SERIAL_8250_AU1X00=y
 
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_AU1X00 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -773,6 +796,12 @@ CONFIG_SYNCLINK_CS=m
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -866,6 +895,7 @@ CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -898,6 +928,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1002,6 +1033,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -1056,3 +1088,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index fba624a792a914eea4d2c30dcd2c3707595fb235..b5db700450ba99ba6451fd34f93339ebf90f16c1 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:54 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:26 2006
 #
 CONFIG_MIPS=y
 
@@ -151,28 +151,30 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -281,6 +283,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -308,7 +315,7 @@ CONFIG_TCP_CONG_BIC=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -435,7 +442,7 @@ CONFIG_SCSI_CONSTANTS=y
 # SCSI Transport Attributes
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_SCSI_SAS_ATTRS is not set
 
@@ -464,13 +471,7 @@ CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -528,6 +529,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -571,6 +573,7 @@ CONFIG_8139TOO_8129=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -668,7 +671,6 @@ CONFIG_HW_CONSOLE=y
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_IP3106 is not set
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -705,6 +707,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -801,6 +809,8 @@ CONFIG_USB_STORAGE_USBAT=y
 CONFIG_USB_STORAGE_SDDR09=y
 CONFIG_USB_STORAGE_SDDR55=y
 CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
@@ -823,6 +833,7 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
 
@@ -906,11 +917,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -946,6 +957,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1049,18 +1061,20 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 CONFIG_DEBUG_SLAB=y
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
index 4c650e7081339c57ea99ecf800d58574566e86a7..4187287f0763b2b193b69575924d4ec90fca7cdf 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:06:58 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:28 2006
 #
 CONFIG_MIPS=y
 
@@ -152,27 +152,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -279,6 +281,21 @@ CONFIG_NETFILTER=y
 #
 # CONFIG_NETFILTER_NETLINK is not set
 # CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -312,6 +329,11 @@ CONFIG_NETFILTER=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -320,6 +342,7 @@ CONFIG_NETFILTER=y
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -339,7 +362,7 @@ CONFIG_NETFILTER=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -466,7 +489,7 @@ CONFIG_BLK_DEV_SD=y
 # SCSI Transport Attributes
 #
 CONFIG_SCSI_SPI_ATTRS=m
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_SCSI_SAS_ATTRS is not set
 
@@ -500,13 +523,7 @@ CONFIG_AIC7XXX_DEBUG_MASK=0
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -564,6 +581,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -607,6 +625,7 @@ CONFIG_8139TOO=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -721,6 +740,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
+# CONFIG_SYNCLINK_GT is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -737,7 +757,6 @@ CONFIG_SERIAL_NONSTANDARD=y
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_IP3106 is not set
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -824,6 +843,12 @@ CONFIG_I2C_ALGOBIT=m
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -863,6 +888,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83792D is not set
 # CONFIG_SENSORS_W83L785TS is not set
@@ -918,7 +944,6 @@ CONFIG_FB=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_SMIVGX is not set
-# CONFIG_FB_CYBLA is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 
@@ -988,13 +1013,16 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
 # CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
@@ -1008,6 +1036,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
 
@@ -1107,6 +1136,7 @@ CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -1142,6 +1172,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1246,6 +1277,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -1299,3 +1331,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index c02becab850bce471bf1f7a241589e45c26ea633..31f5afabafa8605bc733f485e1a555440a4e5092 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.16-rc2
-# Fri Feb  3 17:14:27 2006
+# Sun Feb 12 19:18:55 2006
 #
 CONFIG_MIPS=y
 
@@ -133,7 +133,6 @@ CONFIG_PREEMPT_NONE=y
 # Code maturity level options
 #
 # CONFIG_EXPERIMENTAL is not set
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -145,7 +144,7 @@ CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
@@ -222,6 +221,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -476,8 +476,9 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_UNIX98_PTYS is not set
-# CONFIG_LEGACY_PTYS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
 
 #
 # IPMI
@@ -627,7 +628,7 @@ CONFIG_FUSE_FS=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
-# CONFIG_SYSFS is not set
+CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -680,12 +681,13 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE="console=ttyS0 debug ip=172.20.0.2:172.20.0.1::255.255.0.0"
+CONFIG_CMDLINE=""
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
index 9aaa43024aec16ae6144a5ec92b6ce3512d10310..b126f763cf511d1f0784c004df7c293059f4f261 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:07:03 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:30 2006
 #
 CONFIG_MIPS=y
 
@@ -160,27 +160,30 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-# CONFIG_KOBJECT_UEVENT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -291,6 +294,21 @@ CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -324,6 +342,11 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -332,6 +355,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -407,6 +431,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -598,6 +623,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_DM9000 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 
 #
@@ -654,6 +680,7 @@ CONFIG_NET_PCI=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -687,8 +714,8 @@ CONFIG_NET_RADIO=y
 # Wireless 802.11b ISA/PCI cards support
 #
 # CONFIG_IPW2100 is not set
-# CONFIG_IPW_DEBUG is not set
 CONFIG_IPW2200=m
+# CONFIG_IPW2200_DEBUG is not set
 # CONFIG_HERMES is not set
 # CONFIG_ATMEL is not set
 
@@ -795,7 +822,6 @@ CONFIG_HW_CONSOLE=y
 # Non-8250 serial port support
 #
 CONFIG_HAS_TXX9_SERIAL=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -832,6 +858,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -887,7 +919,6 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 CONFIG_FB_ATY=y
 CONFIG_FB_ATY_CT=y
 # CONFIG_FB_ATY_GENERIC_LCD is not set
-# CONFIG_FB_ATY_XL_INIT is not set
 # CONFIG_FB_ATY_GX is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
@@ -896,7 +927,6 @@ CONFIG_FB_ATY_CT=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_SMIVGX is not set
-# CONFIG_FB_CYBLA is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 
@@ -958,12 +988,14 @@ CONFIG_USB=y
 # may also be needed; see USB_STORAGE Help for more information
 #
 # CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
@@ -977,6 +1009,7 @@ CONFIG_USB_HIDDEV=y
 CONFIG_USB_YEALINK=m
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
 
@@ -1078,6 +1111,7 @@ CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -1115,6 +1149,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1228,6 +1263,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
@@ -1281,3 +1317,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index abf61095931ee6461b266d6e0fed0a6e82521331..463ed3dbf6ae919482065d7713422c9163f62e8e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:07:06 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:31 2006
 #
 CONFIG_MIPS=y
 
@@ -161,27 +161,29 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -297,6 +299,28 @@ CONFIG_BRIDGE_NETFILTER=y
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -315,39 +339,23 @@ CONFIG_IP_NF_AMANDA=m
 CONFIG_IP_NF_PPTP=m
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
 CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_PHYSDEV=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_DCCP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
 CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_MATCH_STRING=m
+CONFIG_IP_NF_MATCH_POLICY=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_TARGET_NFQUEUE=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -364,13 +372,9 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
 CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
 CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
@@ -380,26 +384,20 @@ CONFIG_IP_NF_ARP_MANGLE=m
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_FRAG=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_MULTIPORT=m
 CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_MATCH_PHYSDEV=m
+CONFIG_IP6_NF_MATCH_POLICY=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_TARGET_NFQUEUE=m
 CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
 CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 
@@ -451,6 +449,11 @@ CONFIG_DECNET=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -530,7 +533,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -541,7 +543,7 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -657,7 +659,7 @@ CONFIG_SCSI_CONSTANTS=y
 # SCSI Transport Attributes
 #
 CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
 
@@ -678,6 +680,7 @@ CONFIG_ISCSI_TCP=m
 CONFIG_MEGARAID_NEWGEN=y
 CONFIG_MEGARAID_MM=m
 CONFIG_MEGARAID_MAILBOX=m
+# CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -704,13 +707,7 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 # CONFIG_SCSI_QLOGIC_FAS is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
@@ -801,6 +798,7 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_DM9000 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 
 #
@@ -858,6 +856,7 @@ CONFIG_EEPRO100=m
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 CONFIG_VIA_VELOCITY=m
 # CONFIG_TIGON3 is not set
@@ -879,8 +878,6 @@ CONFIG_VIA_VELOCITY=m
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -969,6 +966,7 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=m
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 # CONFIG_SERIAL_8250_MANY_PORTS is not set
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -979,7 +977,6 @@ CONFIG_SERIAL_8250_RSA=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_CORE=m
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -1020,6 +1017,12 @@ CONFIG_RTC=m
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -1123,12 +1126,15 @@ CONFIG_USB_STORAGE_DPCM=y
 CONFIG_USB_STORAGE_SDDR09=y
 CONFIG_USB_STORAGE_SDDR55=y
 CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=m
 CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
 CONFIG_HID_FF=y
 CONFIG_HID_PID=y
 CONFIG_LOGITECH_FF=y
@@ -1151,6 +1157,7 @@ CONFIG_USB_EGALAX=m
 CONFIG_USB_YEALINK=m
 CONFIG_USB_XPAD=m
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
 
@@ -1309,6 +1316,7 @@ CONFIG_XFS_QUOTA=y
 CONFIG_XFS_SECURITY=y
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=m
 CONFIG_ROMFS_FS=m
 CONFIG_INOTIFY=y
@@ -1351,6 +1359,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1432,6 +1441,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -1487,6 +1497,7 @@ CONFIG_NLS_UTF8=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 52048c906079a4f8d5774a22983771339ecf38ad..da68c3f72050732edb7d2ac7d83195f8aa9e5790 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:07:09 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:32 2006
 #
 CONFIG_MIPS=y
 
@@ -173,27 +173,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_CPUSETS=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -247,7 +249,6 @@ CONFIG_MMU=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_BUILD_ELF64 is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_MIPS32_O32=y
@@ -309,6 +310,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -329,7 +335,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -472,6 +477,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -493,6 +499,7 @@ CONFIG_MII=y
 CONFIG_NET_SB1250_MAC=y
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -513,8 +520,6 @@ CONFIG_NET_SB1250_MAC=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -560,12 +565,15 @@ CONFIG_SERIO_RAW=m
 #
 # CONFIG_VT is not set
 CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
 # CONFIG_ROCKETPORT is not set
 # CONFIG_CYCLADES is not set
 # CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
+# CONFIG_SYNCLINK_GT is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_SPECIALIX is not set
 # CONFIG_SX is not set
@@ -581,7 +589,6 @@ CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -618,6 +625,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -696,12 +709,12 @@ CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -734,6 +747,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -795,6 +809,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=15
 CONFIG_CROSSCOMPILE=y
index 41dd7082497606f6359a526b8f8ae38ec21fc848..9a936d7b7c0cfb277cf0b498e31df560ba63cdf7 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:07:10 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:33 2006
 #
 CONFIG_MIPS=y
 
@@ -153,25 +153,28 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-# CONFIG_HOTPLUG is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -330,6 +333,7 @@ CONFIG_RAID_ATTRS=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -371,6 +375,12 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -444,7 +454,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -481,6 +490,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -513,6 +523,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -529,6 +540,7 @@ CONFIG_PARTITION_ADVANCED=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 83969466ecf67dc844c4aaf8873df82c0210ebe6..c2dee0d1c72c679e6e4e1927a1a6d625bb6a6c1d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:07:12 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:34 2006
 #
 CONFIG_MIPS=y
 
@@ -63,11 +63,12 @@ CONFIG_MACH_VR41XX=y
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_CASIO_E55 is not set
 # CONFIG_IBM_WORKPAD is not set
+# CONFIG_NEC_CMBVR4133 is not set
 CONFIG_TANBAC_TB022X=y
 CONFIG_TANBAC_TB0226=y
+CONFIG_TANBAC_TB0287=y
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 CONFIG_PCI_VR41XX=y
@@ -91,7 +92,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_MIPS64_R2 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
@@ -104,23 +105,18 @@ CONFIG_CPU_VR41XX=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_VR41XX=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
 #
 # Kernel type
 #
-CONFIG_32BIT=y
+# CONFIG_32BIT is not set
 # CONFIG_64BIT is not set
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_MIPS_MT is not set
-# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -156,26 +152,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -191,7 +189,6 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
-# CONFIG_LBD is not set
 
 #
 # IO Schedulers
@@ -229,7 +226,6 @@ CONFIG_MMU=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
 
 #
 # Networking
@@ -293,6 +289,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -313,7 +314,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -324,7 +324,7 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -397,7 +397,7 @@ CONFIG_SCSI_MULTI_LUN=y
 # SCSI Transport Attributes
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_SCSI_SAS_ATTRS is not set
 
@@ -426,13 +426,7 @@ CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -499,6 +493,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -538,6 +533,7 @@ CONFIG_EEPRO100=y
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -559,7 +555,6 @@ CONFIG_EEPRO100=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW2200 is not set
 
 #
 # Wan interfaces
@@ -630,11 +625,6 @@ CONFIG_HW_CONSOLE=y
 #
 # Non-8250 serial port support
 #
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_VR41XX=y
-CONFIG_SERIAL_VR41XX_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -650,7 +640,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
 # CONFIG_GEN_RTC is not set
-# CONFIG_RTC_VR41XX is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -674,6 +663,12 @@ CONFIG_GPIO_VR41XX=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -770,6 +765,8 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
@@ -792,6 +789,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
 
@@ -877,11 +875,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=m
 CONFIG_INOTIFY=y
@@ -914,6 +912,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1021,6 +1020,7 @@ CONFIG_NLS_ISO8859_1=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index ce7b9ed44432258b1423a868ec9aee12743057dc..be99261d7997d38e1be9ddcf43d3cb3fbe4e17ea 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:07:15 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:35 2006
 #
 CONFIG_MIPS=y
 
@@ -63,11 +63,12 @@ CONFIG_MACH_VR41XX=y
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_CASIO_E55 is not set
 # CONFIG_IBM_WORKPAD is not set
+# CONFIG_NEC_CMBVR4133 is not set
 CONFIG_TANBAC_TB022X=y
 # CONFIG_TANBAC_TB0226 is not set
+CONFIG_TANBAC_TB0287=y
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 CONFIG_PCI_VR41XX=y
@@ -91,7 +92,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_MIPS64_R2 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
@@ -104,23 +105,18 @@ CONFIG_CPU_VR41XX=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_VR41XX=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
 #
 # Kernel type
 #
-CONFIG_32BIT=y
+# CONFIG_32BIT is not set
 # CONFIG_64BIT is not set
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_MIPS_MT is not set
-# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -156,26 +152,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -191,7 +189,6 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
-# CONFIG_LBD is not set
 
 #
 # IO Schedulers
@@ -229,7 +226,6 @@ CONFIG_MMU=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
 
 #
 # Networking
@@ -294,6 +290,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -314,7 +315,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -436,6 +436,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -480,6 +481,7 @@ CONFIG_R8169=y
 # CONFIG_R8169_NAPI is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -501,8 +503,6 @@ CONFIG_R8169=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -583,11 +583,6 @@ CONFIG_HW_CONSOLE=y
 #
 # Non-8250 serial port support
 #
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_VR41XX=y
-CONFIG_SERIAL_VR41XX_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -603,7 +598,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
 # CONFIG_GEN_RTC is not set
-# CONFIG_RTC_VR41XX is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -613,7 +607,6 @@ CONFIG_TANBAC_TB0219=y
 # Ftape, the floppy tape device driver
 #
 # CONFIG_DRM is not set
-CONFIG_GPIO_VR41XX=y
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -627,6 +620,12 @@ CONFIG_GPIO_VR41XX=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -715,6 +714,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # may also be needed; see USB_STORAGE Help for more information
 #
 # CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
@@ -737,6 +737,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
 
@@ -840,6 +841,7 @@ CONFIG_XFS_QUOTA=y
 # CONFIG_XFS_SECURITY is not set
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=m
 CONFIG_INOTIFY=y
@@ -879,6 +881,7 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -986,6 +989,7 @@ CONFIG_NLS_ISO8859_1=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
deleted file mode 100644 (file)
index 9534483..0000000
+++ /dev/null
@@ -1,1105 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc5-mm1
-# Tue Oct 25 00:20:22 2005
-#
-CONFIG_MIPS=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SWAP_PREFETCH=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Machine selection
-#
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_EV96100 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_DDB5074 is not set
-# CONFIG_DDB5476 is not set
-# CONFIG_DDB5477 is not set
-CONFIG_MACH_VR41XX=y
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_QEMU is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_NEC_CMBVR4133 is not set
-CONFIG_TANBAC_TB022X=y
-# CONFIG_TANBAC_TB0226 is not set
-CONFIG_TANBAC_TB0287=y
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-CONFIG_PCI_VR41XX=y
-# CONFIG_VRC4173 is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-# CONFIG_CPU_BIG_ENDIAN is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_IRQ_CPU=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-
-#
-# CPU selection
-#
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-CONFIG_CPU_VR41XX=y
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-CONFIG_32BIT=y
-# CONFIG_64BIT is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-# CONFIG_MIPS_MT is not set
-# CONFIG_CPU_ADVANCED is not set
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-
-#
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_HW_HAS_PCI=y
-CONFIG_PCI=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_ASK_IP_FIB_HASH=y
-# CONFIG_IP_FIB_TRIE is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-# CONFIG_NET_IPGRE_BROADCAST is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-CONFIG_TCP_CONG_ADVANCED=y
-
-#
-# TCP congestion control
-#
-CONFIG_TCP_CONG_BIC=y
-CONFIG_TCP_CONG_WESTWOOD=m
-CONFIG_TCP_CONG_HTCP=m
-# CONFIG_TCP_CONG_HSTCP is not set
-# CONFIG_TCP_CONG_HYBLA is not set
-# CONFIG_TCP_CONG_VEGAS is not set
-# CONFIG_TCP_CONG_SCALABLE is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_BLK_DEV_GENERIC is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-CONFIG_BLK_DEV_SIIMAGE=y
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI Transport Layers
-#
-# CONFIG_SAS_CLASS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-CONFIG_IEEE1394=m
-
-#
-# Subsystem Options
-#
-# CONFIG_IEEE1394_VERBOSEDEBUG is not set
-# CONFIG_IEEE1394_OUI_DB is not set
-CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
-CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
-# CONFIG_IEEE1394_EXPORT_FULL_API is not set
-
-#
-# Device Drivers
-#
-
-#
-# Texas Instruments PCILynx requires I2C
-#
-CONFIG_IEEE1394_OHCI1394=m
-
-#
-# Protocol Drivers
-#
-CONFIG_IEEE1394_VIDEO1394=m
-CONFIG_IEEE1394_SBP2=m
-# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
-CONFIG_IEEE1394_ETH1394=m
-CONFIG_IEEE1394_DV1394=m
-CONFIG_IEEE1394_RAWIO=m
-CONFIG_IEEE1394_CMP=m
-CONFIG_IEEE1394_AMDTP=m
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_PCI is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-CONFIG_R8169=y
-# CONFIG_R8169_NAPI is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-# CONFIG_HOSTAP is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_KGDBOE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NETPOLL_RX is not set
-# CONFIG_NETPOLL_TRAP is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_VR41XX=y
-CONFIG_SERIAL_VR41XX_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_RTC_VR41XX is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_TANBAC_TB0219 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-CONFIG_GPIO_VR41XX=y
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia Capabilities Port drivers
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Speakup console speech
-#
-# CONFIG_SPEAKUP is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_EHCI_HCD=m
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_ISP116X_HCD is not set
-CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-# CONFIG_USB_UHCI_HCD is not set
-# CONFIG_USB_SL811_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# may also be needed; see USB_STORAGE Help for more information
-#
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-CONFIG_USB_MON=y
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_GOTEMP is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
-#
-# CONFIG_EDAC is not set
-
-#
-# Distributed Lock Manager
-#
-# CONFIG_DLM is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISER4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-CONFIG_XFS_FS=y
-CONFIG_XFS_QUOTA=y
-# CONFIG_XFS_SECURITY is not set
-CONFIG_XFS_POSIX_ACL=y
-# CONFIG_XFS_RT is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=m
-CONFIG_INOTIFY=y
-# CONFIG_QUOTA is not set
-CONFIG_QUOTACTL=y
-# CONFIG_DNOTIFY is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=y
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_ASFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=m
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=m
index 02b2551023d468b8536a529d26051e33cf1f5696..7132e296d40acb3224b70a9031a01f278465f551 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:07:17 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:36 2006
 #
 CONFIG_MIPS=y
 
@@ -63,9 +63,9 @@ CONFIG_MACH_VR41XX=y
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_CASIO_E55 is not set
 CONFIG_IBM_WORKPAD=y
+# CONFIG_NEC_CMBVR4133 is not set
 # CONFIG_TANBAC_TB022X is not set
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
@@ -88,7 +88,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_MIPS64_R2 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
@@ -101,23 +101,18 @@ CONFIG_CPU_VR41XX=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_VR41XX=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
 #
 # Kernel type
 #
-CONFIG_32BIT=y
+# CONFIG_32BIT is not set
 # CONFIG_64BIT is not set
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_MIPS_MT is not set
-# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -153,26 +148,28 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -188,7 +185,6 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
-# CONFIG_LBD is not set
 
 #
 # IO Schedulers
@@ -234,7 +230,6 @@ CONFIG_PCMCIA_PROBE=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
 
 #
 # Networking
@@ -289,6 +284,11 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -309,7 +309,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -445,6 +444,7 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_DM9000 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_AT1700 is not set
 # CONFIG_DEPCA is not set
@@ -556,10 +556,6 @@ CONFIG_HW_CONSOLE=y
 #
 # Non-8250 serial port support
 #
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_VR41XX=y
-CONFIG_SERIAL_VR41XX_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -588,7 +584,6 @@ CONFIG_WATCHDOG=y
 # CONFIG_WDT is not set
 # CONFIG_RTC is not set
 # CONFIG_GEN_RTC is not set
-# CONFIG_RTC_VR41XX is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
@@ -602,7 +597,6 @@ CONFIG_WATCHDOG=y
 # CONFIG_SYNCLINK_CS is not set
 # CONFIG_CARDMAN_4000 is not set
 # CONFIG_CARDMAN_4040 is not set
-# CONFIG_GPIO_VR41XX is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -616,6 +610,12 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -699,12 +699,12 @@ CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -737,6 +737,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -798,6 +799,7 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 468c2e443d710cc1427086ce43ccbe215d3b59bb..67457850941d06f0fd11aaffe8c6d98a3ddb4375 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:07:19 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:40:37 2006
 #
 CONFIG_MIPS=y
 
@@ -154,8 +154,6 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
@@ -164,19 +162,22 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -184,6 +185,7 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
@@ -295,7 +297,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -413,6 +414,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -452,8 +454,6 @@ CONFIG_TITAN_GE=y
 # Wireless LAN (non-hamradio)
 #
 # CONFIG_NET_RADIO is not set
-# CONFIG_IPW_DEBUG is not set
-CONFIG_IPW2200=m
 
 #
 # Wan interfaces
@@ -498,6 +498,7 @@ CONFIG_IPW2200=m
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -505,7 +506,6 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -541,6 +541,12 @@ CONFIG_GEN_RTC_X=y
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -615,7 +621,6 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -694,12 +699,13 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
 # CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -707,6 +713,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
index 83d4556c3cb59dbd60cbd234b038003f5d2405c8..81cb5a76cfb7b9b07e3acf3616902cf1cace0879 100644 (file)
@@ -45,7 +45,7 @@ static inline void pmax_setup_memory_region(void)
         */
        for (memory_page = (unsigned char *)CKSEG1 + CHUNK_SIZE;
             mem_err == 0 && memory_page < (unsigned char *)CKSEG1 + 0x1e00000;
-            memory_page += CHUNK_SIZE) {
+            memory_page += CHUNK_SIZE) {
                dummy = *memory_page;
        }
        memcpy((void *)(CKSEG0 + 0x80), &old_handler, 0x80);
index 4f125e9e8e0b4c6ae0b503ccebdd43ab491168ff..42d5cd7927cbf26f1e824b0c105e8b7e43b57469 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc2
-# Thu Nov 24 01:05:49 2005
+# Linux kernel version: 2.6.16-rc1
+# Fri Jan 27 15:39:51 2006
 #
 CONFIG_MIPS=y
 
@@ -158,27 +158,29 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -317,6 +319,28 @@ CONFIG_NETFILTER=y
 CONFIG_NETFILTER_NETLINK=m
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
 #
 # IP: Netfilter Configuration
@@ -335,39 +359,23 @@ CONFIG_IP_NF_AMANDA=m
 CONFIG_IP_NF_PPTP=m
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
 CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_OWNER=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_DCCP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_CONNBYTES=m
 CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_MATCH_STRING=m
+CONFIG_IP_NF_MATCH_POLICY=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_TARGET_NFQUEUE=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -384,13 +392,9 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
 CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
 CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
@@ -400,25 +404,20 @@ CONFIG_IP_NF_ARP_MANGLE=m
 #
 CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_FRAG=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_MULTIPORT=m
 CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_POLICY=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_TARGET_NFQUEUE=m
 CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
 CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 
@@ -445,6 +444,11 @@ CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 CONFIG_NET_DIVERT=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
@@ -504,7 +508,6 @@ CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
 CONFIG_IEEE80211_CRYPT_WEP=m
 CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
 
 #
 # Device Drivers
@@ -641,6 +644,7 @@ CONFIG_CICADA_PHY=m
 #
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_DM9000 is not set
 CONFIG_SGISEEQ=y
 
 #
@@ -786,6 +790,12 @@ CONFIG_MAX_RAW_DEVS=256
 #
 # CONFIG_I2C is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Dallas's 1-wire bus
 #
@@ -892,6 +902,7 @@ CONFIG_XFS_QUOTA=y
 CONFIG_XFS_SECURITY=y
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=m
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -934,6 +945,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1007,6 +1019,7 @@ CONFIG_MSDOS_PARTITION=y
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -1062,6 +1075,7 @@ CONFIG_NLS_UTF8=m
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
index 4dbcf91db8849fb0c956932ed82fdecf5664ec14..dc752c67b528c2962344fec31352c808e11eba47 100644 (file)
@@ -248,17 +248,17 @@ loc_call: /*
                and     t2,s1
                sh      t2,JAZZ_IO_IRQ_ENABLE
 
-               nor     s1,zero,s1
+               nor     s1,zero,s1
                jal     do_IRQ
 
-               /*
-                * Reenable interrupt
-                */
+               /*
+                * Reenable interrupt
+                */
                lhu     t2,JAZZ_IO_IRQ_ENABLE
-               or      t2,s1
+               or      t2,s1
                sh      t2,JAZZ_IO_IRQ_ENABLE
 
-               j       ret_from_irq
+               j       ret_from_irq
 
 /*
  * "Jump extender" to reach spurious_interrupt
index 292f8b243a5e6a83539d8d6b82ab3f9349e4e089..58b3b14873cb572a10d9a87e2b57cece1fc061b8 100644 (file)
@@ -291,7 +291,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
                 * for documentation.  Commented out because it shares
                 * it's c0_prid id number with the TX3900.
                 */
-               c->cputype = CPU_R4650;
+               c->cputype = CPU_R4650;
                c->isa_level = MIPS_CPU_ISA_III;
                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
                c->tlbsize = 48;
@@ -604,7 +604,7 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
        case PRID_IMP_AU1_REV2:
                switch ((c->processor_id >> 24) & 0xff) {
                case 0:
-                       c->cputype = CPU_AU1000;
+                       c->cputype = CPU_AU1000;
                        break;
                case 1:
                        c->cputype = CPU_AU1500;
@@ -705,7 +705,7 @@ __init void cpu_probe(void)
                break;
        case PRID_COMP_PHILIPS:
                cpu_probe_philips(c);
-               break;
+               break;
        default:
                c->cputype = CPU_UNKNOWN;
        }
index 83b8986f94011b0113d7d686535461c8bcd76275..235ad9f6bd350595318335171a2ab4e2db5b72d5 100644 (file)
@@ -41,7 +41,7 @@
  */
                .align  5
                NESTED(trap_low, GDB_FR_SIZE, sp)
-               .set    noat
+               .set    noat
                .set    noreorder
 
                mfc0    k0, CP0_STATUS
index e00e5f6e7fdd784d2d067dc4e6ccffcdc2eea009..013bc93688e8a3dd28caf15da957da976998d05b 100644 (file)
@@ -69,7 +69,7 @@
  * Revalidate the inode. This is required for proper NFS attribute caching.
  */
 
-int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
+int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
        struct compat_stat tmp;
 
@@ -106,6 +106,10 @@ sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
        unsigned long error;
 
        error = -EINVAL;
+       if (pgoff & (~PAGE_MASK >> 12))
+               goto out;
+       pgoff >>= PAGE_SHIFT-12;
+
        if (!(flags & MAP_ANONYMOUS)) {
                error = -EBADF;
                file = fget(fd);
@@ -125,7 +129,7 @@ out:
 }
 
 
-asmlinkage int sys_truncate64(const char *path, unsigned int high,
+asmlinkage int sys_truncate64(const char __user *path, unsigned int high,
                              unsigned int low)
 {
        if ((int)high < 0)
@@ -161,12 +165,6 @@ out:
        return error;
 }
 
-asmlinkage int
-sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
-{
-       return compat_sys_wait4(pid, stat_addr, options, NULL);
-}
-
 asmlinkage long
 sysn32_waitid(int which, compat_pid_t pid,
              siginfo_t __user *uinfo, int options,
@@ -175,6 +173,7 @@ sysn32_waitid(int which, compat_pid_t pid,
        struct rusage ru;
        long ret;
        mm_segment_t old_fs = get_fs();
+       int si_signo;
 
        if (!access_ok(VERIFY_WRITE, uinfo, sizeof(*uinfo)))
                return -EFAULT;
@@ -184,7 +183,9 @@ sysn32_waitid(int which, compat_pid_t pid,
                         uru ? (struct rusage __user *) &ru : NULL);
        set_fs (old_fs);
 
-       if (ret < 0 || uinfo->si_signo == 0)
+       if (__get_user(si_signo, &uinfo->si_signo))
+               return -EFAULT;
+       if (ret < 0 || si_signo == 0)
                return ret;
 
        if (uru)
@@ -208,14 +209,14 @@ struct sysinfo32 {
        char _f[8];
 };
 
-asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
+asmlinkage int sys32_sysinfo(struct sysinfo32 __user *info)
 {
        struct sysinfo s;
        int ret, err;
        mm_segment_t old_fs = get_fs ();
 
        set_fs (KERNEL_DS);
-       ret = sys_sysinfo(&s);
+       ret = sys_sysinfo((struct sysinfo __user *)&s);
        set_fs (old_fs);
        err = put_user (s.uptime, &info->uptime);
        err |= __put_user (s.loads[0], &info->loads[0]);
@@ -245,11 +246,11 @@ struct rlimit32 {
 };
 
 #ifdef __MIPSEB__
-asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy,
+asmlinkage long sys32_truncate64(const char __user * path, unsigned long __dummy,
        int length_hi, int length_lo)
 #endif
 #ifdef __MIPSEL__
-asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy,
+asmlinkage long sys32_truncate64(const char __user * path, unsigned long __dummy,
        int length_lo, int length_hi)
 #endif
 {
@@ -277,7 +278,7 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
 }
 
 static inline long
-get_tv32(struct timeval *o, struct compat_timeval *i)
+get_tv32(struct timeval *o, struct compat_timeval __user *i)
 {
        return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
                (__get_user(o->tv_sec, &i->tv_sec) |
@@ -285,7 +286,7 @@ get_tv32(struct timeval *o, struct compat_timeval *i)
 }
 
 static inline long
-put_tv32(struct compat_timeval *o, struct timeval *i)
+put_tv32(struct compat_timeval __user *o, struct timeval *i)
 {
        return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
                (__put_user(i->tv_sec, &o->tv_sec) |
@@ -295,7 +296,7 @@ put_tv32(struct compat_timeval *o, struct timeval *i)
 extern struct timezone sys_tz;
 
 asmlinkage int
-sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
+sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
 {
        if (tv) {
                struct timeval ktv;
@@ -310,7 +311,7 @@ sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
        return 0;
 }
 
-static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
+static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
 {
        long usec;
 
@@ -325,7 +326,7 @@ static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
 }
 
 asmlinkage int
-sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
+sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
 {
        struct timespec kts;
        struct timezone ktz;
@@ -343,7 +344,7 @@ sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
 }
 
 asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
-                           unsigned int offset_low, loff_t * result,
+                           unsigned int offset_low, loff_t __user * result,
                            unsigned int origin)
 {
        return sys_llseek(fd, offset_high, offset_low, result, origin);
@@ -353,12 +354,12 @@ asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
    lseek back to original location.  They fail just like lseek does on
    non-seekable files.  */
 
-asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf,
+asmlinkage ssize_t sys32_pread(unsigned int fd, char __user * buf,
                               size_t count, u32 unused, u64 a4, u64 a5)
 {
        ssize_t ret;
        struct file * file;
-       ssize_t (*read)(struct file *, char *, size_t, loff_t *);
+       ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
        loff_t pos;
 
        ret = -EBADF;
@@ -388,12 +389,12 @@ bad_file:
        return ret;
 }
 
-asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf,
+asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char __user * buf,
                                size_t count, u32 unused, u64 a4, u64 a5)
 {
        ssize_t ret;
        struct file * file;
-       ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
+       ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
        loff_t pos;
 
        ret = -EBADF;
@@ -426,14 +427,14 @@ bad_file:
 }
 
 asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
-       struct compat_timespec *interval)
+       struct compat_timespec __user *interval)
 {
        struct timespec t;
        int ret;
        mm_segment_t old_fs = get_fs ();
 
        set_fs (KERNEL_DS);
-       ret = sys_sched_rr_get_interval(pid, &t);
+       ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
        set_fs (old_fs);
        if (put_user (t.tv_sec, &interval->tv_sec) ||
            __put_user (t.tv_nsec, &interval->tv_nsec))
@@ -551,7 +552,7 @@ struct ipc_kludge32 {
 };
 
 static int
-do_sys32_semctl(int first, int second, int third, void *uptr)
+do_sys32_semctl(int first, int second, int third, void __user *uptr)
 {
        union semun fourth;
        u32 pad;
@@ -562,12 +563,12 @@ do_sys32_semctl(int first, int second, int third, void *uptr)
        if (!uptr)
                return -EINVAL;
        err = -EFAULT;
-       if (get_user (pad, (u32 *)uptr))
+       if (get_user (pad, (u32 __user *)uptr))
                return err;
        if ((third & ~IPC_64) == SETVAL)
                fourth.val = (int)pad;
        else
-               fourth.__pad = (void *)A(pad);
+               fourth.__pad = (void __user *)A(pad);
        switch (third & ~IPC_64) {
        case IPC_INFO:
        case IPC_RMID:
@@ -585,14 +586,14 @@ do_sys32_semctl(int first, int second, int third, void *uptr)
 
        case IPC_STAT:
        case SEM_STAT:
-               fourth.__pad = &s;
+               fourth.__pad = (struct semid64_ds __user *)&s;
                old_fs = get_fs();
                set_fs(KERNEL_DS);
                err = sys_semctl(first, second, third | IPC_64, fourth);
                set_fs(old_fs);
 
                if (third & IPC_64) {
-                       struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad);
+                       struct semid64_ds32 __user *usp64 = (struct semid64_ds32 __user *) A(pad);
 
                        if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
                                err = -EFAULT;
@@ -609,7 +610,7 @@ do_sys32_semctl(int first, int second, int third, void *uptr)
                        err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime);
                        err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems);
                } else {
-                       struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad);
+                       struct semid_ds32 __user *usp32 = (struct semid_ds32 __user *) A(pad);
 
                        if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
                                err = -EFAULT;
@@ -639,9 +640,9 @@ do_sys32_semctl(int first, int second, int third, void *uptr)
 }
 
 static int
-do_sys32_msgsnd (int first, int second, int third, void *uptr)
+do_sys32_msgsnd (int first, int second, int third, void __user *uptr)
 {
-       struct msgbuf32 *up = (struct msgbuf32 *)uptr;
+       struct msgbuf32 __user *up = (struct msgbuf32 __user *)uptr;
        struct msgbuf *p;
        mm_segment_t old_fs;
        int err;
@@ -660,7 +661,7 @@ do_sys32_msgsnd (int first, int second, int third, void *uptr)
                goto out;
        old_fs = get_fs ();
        set_fs (KERNEL_DS);
-       err = sys_msgsnd (first, p, second, third);
+       err = sys_msgsnd (first, (struct msgbuf __user *)p, second, third);
        set_fs (old_fs);
 out:
        kfree (p);
@@ -670,15 +671,15 @@ out:
 
 static int
 do_sys32_msgrcv (int first, int second, int msgtyp, int third,
-                int version, void *uptr)
+                int version, void __user *uptr)
 {
-       struct msgbuf32 *up;
+       struct msgbuf32 __user *up;
        struct msgbuf *p;
        mm_segment_t old_fs;
        int err;
 
        if (!version) {
-               struct ipc_kludge32 *uipck = (struct ipc_kludge32 *)uptr;
+               struct ipc_kludge32 __user *uipck = (struct ipc_kludge32 __user *)uptr;
                struct ipc_kludge32 ipck;
 
                err = -EINVAL;
@@ -687,7 +688,7 @@ do_sys32_msgrcv (int first, int second, int msgtyp, int third,
                err = -EFAULT;
                if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32)))
                        goto out;
-               uptr = (void *)AA(ipck.msgp);
+               uptr = (void __user *)AA(ipck.msgp);
                msgtyp = ipck.msgtyp;
        }
 
@@ -699,11 +700,11 @@ do_sys32_msgrcv (int first, int second, int msgtyp, int third,
                goto out;
        old_fs = get_fs ();
        set_fs (KERNEL_DS);
-       err = sys_msgrcv (first, p, second + 4, msgtyp, third);
+       err = sys_msgrcv (first, (struct msgbuf __user *)p, second + 4, msgtyp, third);
        set_fs (old_fs);
        if (err < 0)
                goto free_then_out;
-       up = (struct msgbuf32 *)uptr;
+       up = (struct msgbuf32 __user *)uptr;
        if (put_user (p->mtype, &up->mtype) ||
            __copy_to_user (&up->mtext, p->mtext, err))
                err = -EFAULT;
@@ -714,19 +715,19 @@ out:
 }
 
 static int
-do_sys32_msgctl (int first, int second, void *uptr)
+do_sys32_msgctl (int first, int second, void __user *uptr)
 {
        int err = -EINVAL, err2;
        struct msqid64_ds m;
-       struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
-       struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
+       struct msqid_ds32 __user *up32 = (struct msqid_ds32 __user *)uptr;
+       struct msqid64_ds32 __user *up64 = (struct msqid64_ds32 __user *)uptr;
        mm_segment_t old_fs;
 
        switch (second & ~IPC_64) {
        case IPC_INFO:
        case IPC_RMID:
        case MSG_INFO:
-               err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
+               err = sys_msgctl (first, second, (struct msqid_ds __user *)uptr);
                break;
 
        case IPC_SET:
@@ -753,7 +754,7 @@ do_sys32_msgctl (int first, int second, void *uptr)
                        break;
                old_fs = get_fs();
                set_fs(KERNEL_DS);
-               err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m);
+               err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m);
                set_fs(old_fs);
                break;
 
@@ -761,7 +762,7 @@ do_sys32_msgctl (int first, int second, void *uptr)
        case MSG_STAT:
                old_fs = get_fs();
                set_fs(KERNEL_DS);
-               err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m);
+               err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m);
                set_fs(old_fs);
                if (second & IPC_64) {
                        if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
@@ -815,10 +816,10 @@ do_sys32_msgctl (int first, int second, void *uptr)
 }
 
 static int
-do_sys32_shmat (int first, int second, int third, int version, void *uptr)
+do_sys32_shmat (int first, int second, int third, int version, void __user *uptr)
 {
        unsigned long raddr;
-       u32 *uaddr = (u32 *)A((u32)third);
+       u32 __user *uaddr = (u32 __user *)A((u32)third);
        int err = -EINVAL;
 
        if (version == 1)
@@ -837,11 +838,11 @@ struct shm_info32 {
 };
 
 static int
-do_sys32_shmctl (int first, int second, void *uptr)
+do_sys32_shmctl (int first, int second, void __user *uptr)
 {
-       struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
-       struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
-       struct shm_info32 *uip = (struct shm_info32 *)uptr;
+       struct shmid64_ds32 __user *up64 = (struct shmid64_ds32 __user *)uptr;
+       struct shmid_ds32 __user *up32 = (struct shmid_ds32 __user *)uptr;
+       struct shm_info32 __user *uip = (struct shm_info32 __user *)uptr;
        int err = -EFAULT, err2;
        struct shmid64_ds s64;
        mm_segment_t old_fs;
@@ -854,7 +855,7 @@ do_sys32_shmctl (int first, int second, void *uptr)
        case IPC_RMID:
        case SHM_LOCK:
        case SHM_UNLOCK:
-               err = sys_shmctl(first, second, (struct shmid_ds *)uptr);
+               err = sys_shmctl(first, second, (struct shmid_ds __user *)uptr);
                break;
        case IPC_SET:
                if (second & IPC_64) {
@@ -870,7 +871,7 @@ do_sys32_shmctl (int first, int second, void *uptr)
                        break;
                old_fs = get_fs();
                set_fs(KERNEL_DS);
-               err = sys_shmctl(first, second & ~IPC_64, &s);
+               err = sys_shmctl(first, second & ~IPC_64, (struct shmid_ds __user *)&s);
                set_fs(old_fs);
                break;
 
@@ -878,7 +879,7 @@ do_sys32_shmctl (int first, int second, void *uptr)
        case SHM_STAT:
                old_fs = get_fs();
                set_fs(KERNEL_DS);
-               err = sys_shmctl(first, second | IPC_64, (void *) &s64);
+               err = sys_shmctl(first, second | IPC_64, (void __user *) &s64);
                set_fs(old_fs);
                if (err < 0)
                        break;
@@ -928,7 +929,7 @@ do_sys32_shmctl (int first, int second, void *uptr)
        case SHM_INFO:
                old_fs = get_fs();
                set_fs(KERNEL_DS);
-               err = sys_shmctl(first, second, (void *)&si);
+               err = sys_shmctl(first, second, (void __user *)&si);
                set_fs(old_fs);
                if (err < 0)
                        break;
@@ -950,11 +951,11 @@ do_sys32_shmctl (int first, int second, void *uptr)
        return err;
 }
 
-static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems,
-                            const struct compat_timespec *timeout32)
+static int sys32_semtimedop(int semid, struct sembuf __user *tsems, int nsems,
+                            const struct compat_timespec __user *timeout32)
 {
        struct compat_timespec t32;
-       struct timespec *t64 = compat_alloc_user_space(sizeof(*t64));
+       struct timespec __user *t64 = compat_alloc_user_space(sizeof(*t64));
 
        if (copy_from_user(&t32, timeout32, sizeof(t32)))
                return -EFAULT;
@@ -977,11 +978,11 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
        switch (call) {
        case SEMOP:
                /* struct sembuf is the same on 32 and 64bit :)) */
-               err = sys_semtimedop (first, (struct sembuf *)AA(ptr), second,
+               err = sys_semtimedop (first, (struct sembuf __user *)AA(ptr), second,
                                      NULL);
                break;
        case SEMTIMEDOP:
-               err = sys32_semtimedop (first, (struct sembuf *)AA(ptr), second,
+               err = sys32_semtimedop (first, (struct sembuf __user *)AA(ptr), second,
                                      (const struct compat_timespec __user *)AA(fifth));
                break;
        case SEMGET:
@@ -989,36 +990,36 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
                break;
        case SEMCTL:
                err = do_sys32_semctl (first, second, third,
-                                      (void *)AA(ptr));
+                                      (void __user *)AA(ptr));
                break;
 
        case MSGSND:
                err = do_sys32_msgsnd (first, second, third,
-                                      (void *)AA(ptr));
+                                      (void __user *)AA(ptr));
                break;
        case MSGRCV:
                err = do_sys32_msgrcv (first, second, fifth, third,
-                                      version, (void *)AA(ptr));
+                                      version, (void __user *)AA(ptr));
                break;
        case MSGGET:
                err = sys_msgget ((key_t) first, second);
                break;
        case MSGCTL:
-               err = do_sys32_msgctl (first, second, (void *)AA(ptr));
+               err = do_sys32_msgctl (first, second, (void __user *)AA(ptr));
                break;
 
        case SHMAT:
                err = do_sys32_shmat (first, second, third,
-                                     version, (void *)AA(ptr));
+                                     version, (void __user *)AA(ptr));
                break;
        case SHMDT:
-               err = sys_shmdt ((char *)A(ptr));
+               err = sys_shmdt ((char __user *)A(ptr));
                break;
        case SHMGET:
                err = sys_shmget (first, (unsigned)second, third);
                break;
        case SHMCTL:
-               err = do_sys32_shmctl (first, second, (void *)AA(ptr));
+               err = do_sys32_shmctl (first, second, (void __user *)AA(ptr));
                break;
        default:
                err = -EINVAL;
@@ -1029,7 +1030,7 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
 }
 
 asmlinkage long sys32_shmat(int shmid, char __user *shmaddr,
-                         int shmflg, int32_t *addr)
+                         int shmflg, int32_t __user *addr)
 {
        unsigned long raddr;
        int err;
@@ -1054,12 +1055,13 @@ struct sysctl_args32
 
 #ifdef CONFIG_SYSCTL
 
-asmlinkage long sys32_sysctl(struct sysctl_args32 *args)
+asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args)
 {
        struct sysctl_args32 tmp;
        int error;
-       size_t oldlen, *oldlenp = NULL;
-       unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
+       size_t oldlen;
+       size_t __user *oldlenp = NULL;
+       unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7;
 
        if (copy_from_user(&tmp, args, sizeof(tmp)))
                return -EFAULT;
@@ -1071,20 +1073,20 @@ asmlinkage long sys32_sysctl(struct sysctl_args32 *args)
                   basically copy the whole sysctl.c here, and
                   glibc's __sysctl uses rw memory for the structure
                   anyway.  */
-               if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
-                   put_user(oldlen, (size_t *)addr))
+               if (get_user(oldlen, (u32 __user *)A(tmp.oldlenp)) ||
+                   put_user(oldlen, (size_t __user *)addr))
                        return -EFAULT;
-               oldlenp = (size_t *)addr;
+               oldlenp = (size_t __user *)addr;
        }
 
        lock_kernel();
-       error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
-                         oldlenp, (void *)A(tmp.newval), tmp.newlen);
+       error = do_sysctl((int __user *)A(tmp.name), tmp.nlen, (void __user *)A(tmp.oldval),
+                         oldlenp, (void __user *)A(tmp.newval), tmp.newlen);
        unlock_kernel();
        if (oldlenp) {
                if (!error) {
-                       if (get_user(oldlen, (size_t *)addr) ||
-                           put_user(oldlen, (u32 *)A(tmp.oldlenp)))
+                       if (get_user(oldlen, (size_t __user *)addr) ||
+                           put_user(oldlen, (u32 __user *)A(tmp.oldlenp)))
                                error = -EFAULT;
                }
                copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
@@ -1094,7 +1096,7 @@ asmlinkage long sys32_sysctl(struct sysctl_args32 *args)
 
 #endif /* CONFIG_SYSCTL */
 
-asmlinkage long sys32_newuname(struct new_utsname * name)
+asmlinkage long sys32_newuname(struct new_utsname __user * name)
 {
        int ret = 0;
 
@@ -1129,9 +1131,9 @@ struct ustat32 {
        char            f_fpack[6];
 };
 
-extern asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf);
+extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf);
 
-asmlinkage int sys32_ustat(dev_t dev, struct ustat32 * ubuf32)
+asmlinkage int sys32_ustat(dev_t dev, struct ustat32 __user * ubuf32)
 {
        int err;
         struct ustat tmp;
@@ -1139,7 +1141,7 @@ asmlinkage int sys32_ustat(dev_t dev, struct ustat32 * ubuf32)
        mm_segment_t old_fs = get_fs();
 
        set_fs(KERNEL_DS);
-       err = sys_ustat(dev, &tmp);
+       err = sys_ustat(dev, (struct ustat __user *)&tmp);
        set_fs (old_fs);
 
        if (err)
@@ -1172,7 +1174,7 @@ struct timex32 {
 
 extern int do_adjtimex(struct timex *);
 
-asmlinkage int sys32_adjtimex(struct timex32 *utp)
+asmlinkage int sys32_adjtimex(struct timex32 __user *utp)
 {
        struct timex txc;
        int ret;
@@ -1228,7 +1230,7 @@ asmlinkage int sys32_adjtimex(struct timex32 *utp)
        return ret;
 }
 
-asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset,
+asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset,
        s32 count)
 {
        mm_segment_t old_fs = get_fs();
@@ -1239,7 +1241,7 @@ asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset,
                return -EFAULT;
 
        set_fs(KERNEL_DS);
-       ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
+       ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, count);
        set_fs(old_fs);
 
        if (offset && put_user(of, offset))
@@ -1269,7 +1271,7 @@ static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
  *  it is set by the callees.
  */
 
-asmlinkage long sys32_socketcall(int call, unsigned int *args32)
+asmlinkage long sys32_socketcall(int call, unsigned int __user *args32)
 {
        unsigned int a[6];
        unsigned int a0,a1;
@@ -1291,7 +1293,7 @@ asmlinkage long sys32_socketcall(int call, unsigned int *args32)
                                            struct sockaddr __user *addr, int __user *addr_len);
        extern asmlinkage long sys_shutdown(int fd, int how);
        extern asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen);
-       extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int *optlen);
+       extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen);
        extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
        extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags);
 
@@ -1411,7 +1413,7 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs)
        newsp = regs.regs[5];
        if (!newsp)
                newsp = regs.regs[29];
-       parent_tidptr = (int *) regs.regs[6];
+       parent_tidptr = (int __user *) regs.regs[6];
 
        /* Use __dummy4 instead of getting it off the stack, so that
           syscall() works.  */
index 86fe15b273cd60c5df1d0198c35f14a0f89fd0a4..84ab959f924ac57d1b05edc73aa48ce84c2da04f 100644 (file)
@@ -135,6 +135,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                cpu_has_vce ? "%u" : "not available");
        seq_printf(m, fmt, 'D', vced_count);
        seq_printf(m, fmt, 'I', vcei_count);
+       seq_printf(m, "\n");
 
        return 0;
 }
index 092679c2dca9b83bd3e66503d83413daf29853d7..a8f435d82940375ccdcd0e5e2cc245deb5a88944 100644 (file)
@@ -60,17 +60,9 @@ ATTRIB_NORET void cpu_idle(void)
        }
 }
 
-extern void do_signal(struct pt_regs *regs);
-extern void do_signal32(struct pt_regs *regs);
-
 /*
  * Native o32 and N64 ABI without DSP ASE
  */
-extern int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
-        int signr, sigset_t *set);
-extern int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
-        int signr, sigset_t *set, siginfo_t *info);
-
 struct mips_abi mips_abi = {
        .do_signal      = do_signal,
 #ifdef CONFIG_TRAD_SIGNALS
@@ -83,11 +75,6 @@ struct mips_abi mips_abi = {
 /*
  * o32 compatibility on 64-bit kernels, without DSP ASE
  */
-extern int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-        int signr, sigset_t *set);
-extern int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-        int signr, sigset_t *set, siginfo_t *info);
-
 struct mips_abi mips_abi_32 = {
        .do_signal      = do_signal32,
        .setup_frame    = setup_frame_32,
@@ -99,9 +86,6 @@ struct mips_abi mips_abi_32 = {
 /*
  * N32 on 64-bit kernels, without DSP ASE
  */
-extern int setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs,
-        int signr, sigset_t *set, siginfo_t *info);
-
 struct mips_abi mips_abi_n32 = {
        .do_signal      = do_signal,
        .setup_rt_frame = setup_rt_frame_n32
index d9293c558e413a7020a0c9467d8788afde3ac34f..0cb3b6097e0efecdf1a5ca9142258e5248adc47d 100644 (file)
@@ -447,21 +447,10 @@ static inline void resource_init(void)
 {
        int i;
 
-#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
-       /*
-        * The 64bit code in 32bit object format trick can't represent
-        * 64bit wide relocations for linker script symbols.
-        */
-       code_resource.start = CPHYSADDR(&_text);
-       code_resource.end = CPHYSADDR(&_etext) - 1;
-       data_resource.start = CPHYSADDR(&_etext);
-       data_resource.end = CPHYSADDR(&_edata) - 1;
-#else
        code_resource.start = virt_to_phys(&_text);
        code_resource.end = virt_to_phys(&_etext) - 1;
        data_resource.start = virt_to_phys(&_etext);
        data_resource.end = virt_to_phys(&_edata) - 1;
-#endif
 
        /*
         * Request address space for all standard RAM.
index 36bfc2588aa351cb1776edfe14a9663f11f972ba..3ca786215d48c172fe0948c450c359d16e3f3c20 100644 (file)
@@ -166,11 +166,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
        sp = regs->regs[29];
 
        /*
-        * FPU emulator may have it's own trampoline active just
-        * above the user stack, 16-bytes before the next lowest
-        * 16 byte boundary.  Try to avoid trashing it.
-        */
-       sp -= 32;
+        * FPU emulator may have it's own trampoline active just
+        * above the user stack, 16-bytes before the next lowest
+        * 16 byte boundary.  Try to avoid trashing it.
+        */
+       sp -= 32;
 
        /* This is the X/Open sanctioned signal stack switching.  */
        if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
index c974cc9b30eb73bae60e0329df1ff425887c4b05..402efd27c79e87bfc7ed2c0e8a1cbc284313be7e 100644 (file)
@@ -100,8 +100,8 @@ _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 }
 
 #ifdef CONFIG_TRAD_SIGNALS
-asmlinkage int sys_sigaction(int sig, const struct sigaction *act,
-       struct sigaction *oact)
+asmlinkage int sys_sigaction(int sig, const struct sigaction __user *act,
+       struct sigaction __user *oact)
 {
        struct k_sigaction new_ka, old_ka;
        int ret;
@@ -331,7 +331,7 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->rs_uc.uc_flags);
        err |= __put_user(NULL, &frame->rs_uc.uc_link);
-       err |= __put_user((void *)current->sas_ss_sp,
+       err |= __put_user((void __user *)current->sas_ss_sp,
                          &frame->rs_uc.uc_stack.ss_sp);
        err |= __put_user(sas_ss_flags(regs->regs[29]),
                          &frame->rs_uc.uc_stack.ss_flags);
index 237cd8a2cd323dc8391b20cb474a6063813188b1..f32a22997c3d68d1754f745564b9dbac4e3928d2 100644 (file)
@@ -163,7 +163,7 @@ static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
        return err;
 }
 
-static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t *ubuf)
+static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
 {
        int err = 0;
        unsigned long sig[4];
@@ -195,10 +195,10 @@ save_static_function(sys32_sigsuspend);
 __attribute_used__ noinline static int
 _sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
 {
-       compat_sigset_t *uset;
+       compat_sigset_t __user *uset;
        sigset_t newset;
 
-       uset = (compat_sigset_t *) regs.regs[4];
+       uset = (compat_sigset_t __user *) regs.regs[4];
        if (get_sigset(&newset, uset))
                return -EFAULT;
        sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -219,7 +219,7 @@ save_static_function(sys32_rt_sigsuspend);
 __attribute_used__ noinline static int
 _sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 {
-       compat_sigset_t *uset;
+       compat_sigset_t __user *uset;
        sigset_t newset;
        size_t sigsetsize;
 
@@ -228,7 +228,7 @@ _sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
        if (sigsetsize != sizeof(compat_sigset_t))
                return -EINVAL;
 
-       uset = (compat_sigset_t *) regs.regs[4];
+       uset = (compat_sigset_t __user *) regs.regs[4];
        if (get_sigset(&newset, uset))
                return -EFAULT;
        sigdelsetmask(&newset, ~_BLOCKABLE);
@@ -236,7 +236,7 @@ _sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
        spin_lock_irq(&current->sighand->siglock);
        current->saved_sigmask = current->blocked;
        current->blocked = newset;
-        recalc_sigpending();
+       recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
        current->state = TASK_INTERRUPTIBLE;
@@ -245,8 +245,8 @@ _sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
        return -ERESTARTNOHAND;
 }
 
-asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
-                               struct sigaction32 *oact)
+asmlinkage int sys32_sigaction(int sig, const struct sigaction32 __user *act,
+                               struct sigaction32 __user *oact)
 {
        struct k_sigaction new_ka, old_ka;
        int ret;
@@ -272,15 +272,15 @@ asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
 
        if (!ret && oact) {
                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
-                        return -EFAULT;
+                       return -EFAULT;
                err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
                err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
                                  &oact->sa_handler);
                err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
-                err |= __put_user(0, &oact->sa_mask.sig[1]);
-                err |= __put_user(0, &oact->sa_mask.sig[2]);
-                err |= __put_user(0, &oact->sa_mask.sig[3]);
-                if (err)
+               err |= __put_user(0, &oact->sa_mask.sig[1]);
+               err |= __put_user(0, &oact->sa_mask.sig[2]);
+               err |= __put_user(0, &oact->sa_mask.sig[3]);
+               if (err)
                        return -EFAULT;
        }
 
@@ -301,7 +301,7 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
                if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
                        return -EFAULT;
                err |= __get_user(sp, &uss->ss_sp);
-               kss.ss_sp = (void *) (long) sp;
+               kss.ss_sp = (void __user *) (long) sp;
                err |= __get_user(kss.ss_size, &uss->ss_size);
                err |= __get_user(kss.ss_flags, &uss->ss_flags);
                if (err)
@@ -316,7 +316,7 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
        if (!ret && uoss) {
                if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
                        return -EFAULT;
-               sp = (int) (long) koss.ss_sp;
+               sp = (int) (unsigned long) koss.ss_sp;
                err |= __put_user(sp, &uoss->ss_sp);
                err |= __put_user(koss.ss_size, &uoss->ss_size);
                err |= __put_user(koss.ss_flags, &uoss->ss_flags);
@@ -527,7 +527,7 @@ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
        /* The ucontext contains a stack32_t, so we must convert!  */
        if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
                goto badframe;
-       st.ss_sp = (void *)(long) sp;
+       st.ss_sp = (void __user *)(long) sp;
        if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
                goto badframe;
        if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
@@ -624,11 +624,11 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
        sp = regs->regs[29];
 
        /*
-        * FPU emulator may have it's own trampoline active just
-        * above the user stack, 16-bytes before the next lowest
-        * 16 byte boundary.  Try to avoid trashing it.
-        */
-       sp -= 32;
+        * FPU emulator may have it's own trampoline active just
+        * above the user stack, 16-bytes before the next lowest
+        * 16 byte boundary.  Try to avoid trashing it.
+        */
+       sp -= 32;
 
        /* This is the X/Open sanctioned signal stack switching.  */
        if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
@@ -868,7 +868,7 @@ no_signal:
        }
 }
 
-asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
+asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
                                  struct sigaction32 __user *oact,
                                  unsigned int sigsetsize)
 {
@@ -912,7 +912,7 @@ out:
        return ret;
 }
 
-asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set,
+asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
        compat_sigset_t __user *oset, unsigned int sigsetsize)
 {
        sigset_t old_set, new_set;
index 3e168c08a3a8841b337d4a45644c3da02754b4ef..477c5334ec1b459eefb010c9ef5918ca1358b47b 100644 (file)
@@ -87,7 +87,8 @@ save_static_function(sysn32_rt_sigsuspend);
 __attribute_used__ noinline static int
 _sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 {
-       compat_sigset_t __user *unewset, uset;
+       compat_sigset_t __user *unewset;
+       compat_sigset_t uset;
        size_t sigsetsize;
        sigset_t newset;
 
@@ -141,7 +142,7 @@ _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
        /* The ucontext contains a stack32_t, so we must convert!  */
        if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
                goto badframe;
-       st.ss_sp = (void *)(long) sp;
+       st.ss_sp = (void __user *)(long) sp;
        if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
                goto badframe;
        if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
index 1da2eeb3ef9ed5194b4c30471ba6e78d5e967de5..2aeaa2fd4b322a1ebec61d1861eda4aab1ad4e0a 100644 (file)
@@ -162,7 +162,10 @@ asmlinkage unsigned long
 sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
           unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
-       return do_mmap2(addr, len, prot, flags, fd, pgoff);
+       if (pgoff & (~PAGE_MASK >> 12))
+               return -EINVAL;
+
+       return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
 }
 
 save_static_function(sys_fork);
@@ -345,7 +348,7 @@ asmlinkage int sys_ipc (uint call, int first, int second,
                union semun fourth;
                if (!ptr)
                        return -EINVAL;
-               if (get_user(fourth.__pad, (void *__user *) ptr))
+               if (get_user(fourth.__pad, (void __user *__user *) ptr))
                        return -EFAULT;
                return sys_semctl (first, second, third, fourth);
        }
index 005debbfbe84416540e30fb88cd5123e9dbef33b..bed0eb6cf55d58f7178ecf0f550e05c8a7ac6c47 100644 (file)
@@ -576,7 +576,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
                }
 #endif
                /*
-                * Unimplemented operation exception.  If we've got the full
+                * Unimplemented operation exception.  If we've got the full
                 * software emulator on-board, let's use it...
                 *
                 * Force FPU to dump state into task/thread context.  We're
index ca22336f6c36db3bf58bfc40f54f8e2effe739ff..988f8ad189cb19d29c47a489f07e10190b934985 100644 (file)
@@ -16,7 +16,8 @@ SECTIONS
   _image_start = ADDR(.data);
   _image_size = SIZEOF(.data);
 
-  .other : {
-       *(.*)
+  .other :
+  {
+    *(.*)
   }
 }
index a397ecb872d65423dbe47537e241f6e7eb06f1c9..ddd5c73a29719c2cbfb1a2187c373d9e0f7d3ac7 100644 (file)
@@ -98,7 +98,7 @@
        and     s0, s1
 
 #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
-       .set    mips32
+       .set    mips32
        clz     a0, s0
        .set    mips0
        negu    a0
index 9987a85aabeb36f87f3f6a3c75c0517750dea7fd..5b84c7fe1022f6a70c8cf5a288c891a0ed799e46 100644 (file)
@@ -96,7 +96,7 @@
         andi   a0, s0, CAUSEF_IP3      # delay slot, check hw1 interrupt
 #else
        beq     a0, zero, 1f            # delay slot, check hw3 interrupt
-        andi   a0, s0, CAUSEF_IP5
+        andi   a0, s0, CAUSEF_IP5
 #endif
 
        /* Wheee, combined hardware level zero interrupt. */
index 835f0387fcd4b1467ff934b358b21873b7d2c0ff..da52297a221635b839b9537c8ef6a5ad4c8d70c6 100644 (file)
@@ -42,7 +42,7 @@
        and     s0, s1
 
 #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
-       .set    mips32
+       .set    mips32
        clz     a0, s0
        .set    mips0
        negu    a0
index 19824359f5dec69fff83fc228a959045418e21b6..a9f0c2bfe4ad7b4ee63480d6ec4b88b919a80c17 100644 (file)
@@ -115,7 +115,7 @@ void prom_prepare_cpus(unsigned int max_cpus)
 #ifdef CONFIG_MIPS_MT_SMTC
        void mipsmt_prepare_cpus(int c);
        /*
-        * As noted above, we can assume a single CPU for now
+        * As noted above, we can assume a single CPU for now
         * but it may be multithreaded.
         */
 
index b0178da019f0b46ed94967c97aa6b96e90bfdd5d..4a6220116c96423ea7f572244a474f6d2c0319da 100644 (file)
@@ -12,7 +12,7 @@ obj-$(CONFIG_HIGHMEM)         += highmem.o
 obj-$(CONFIG_CPU_MIPS32)       += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
 obj-$(CONFIG_CPU_MIPS64)       += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
 obj-$(CONFIG_CPU_NEVADA)       += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
-obj-$(CONFIG_CPU_R10000)       += c-r4k.o cex-gen.o pg-r4k.o tlb-andes.o
+obj-$(CONFIG_CPU_R10000)       += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
 obj-$(CONFIG_CPU_R3000)                += c-r3k.o tlb-r3k.o pg-r4k.o
 obj-$(CONFIG_CPU_R4300)                += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
 obj-$(CONFIG_CPU_R4X00)                += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
index 27f4fa25e8c951fcd41ee3929a2bea0569cf84db..9dd1352d57484a0b015b992c8759089ab5b483ab 100644 (file)
@@ -129,7 +129,7 @@ static void r3k_flush_icache_range(unsigned long start, unsigned long end)
                        "sb\t$0, 0x014(%0)\n\t"
                        "sb\t$0, 0x018(%0)\n\t"
                        "sb\t$0, 0x01c(%0)\n\t"
-                       "sb\t$0, 0x020(%0)\n\t"
+                       "sb\t$0, 0x020(%0)\n\t"
                        "sb\t$0, 0x024(%0)\n\t"
                        "sb\t$0, 0x028(%0)\n\t"
                        "sb\t$0, 0x02c(%0)\n\t"
@@ -145,7 +145,7 @@ static void r3k_flush_icache_range(unsigned long start, unsigned long end)
                        "sb\t$0, 0x054(%0)\n\t"
                        "sb\t$0, 0x058(%0)\n\t"
                        "sb\t$0, 0x05c(%0)\n\t"
-                       "sb\t$0, 0x060(%0)\n\t"
+                       "sb\t$0, 0x060(%0)\n\t"
                        "sb\t$0, 0x064(%0)\n\t"
                        "sb\t$0, 0x068(%0)\n\t"
                        "sb\t$0, 0x06c(%0)\n\t"
@@ -182,31 +182,31 @@ static void r3k_flush_dcache_range(unsigned long start, unsigned long end)
                        "sb\t$0, 0x004(%0)\n\t"
                        "sb\t$0, 0x008(%0)\n\t"
                        "sb\t$0, 0x00c(%0)\n\t"
-                       "sb\t$0, 0x010(%0)\n\t"
+                       "sb\t$0, 0x010(%0)\n\t"
                        "sb\t$0, 0x014(%0)\n\t"
                        "sb\t$0, 0x018(%0)\n\t"
                        "sb\t$0, 0x01c(%0)\n\t"
-                       "sb\t$0, 0x020(%0)\n\t"
+                       "sb\t$0, 0x020(%0)\n\t"
                        "sb\t$0, 0x024(%0)\n\t"
                        "sb\t$0, 0x028(%0)\n\t"
                        "sb\t$0, 0x02c(%0)\n\t"
-                       "sb\t$0, 0x030(%0)\n\t"
+                       "sb\t$0, 0x030(%0)\n\t"
                        "sb\t$0, 0x034(%0)\n\t"
                        "sb\t$0, 0x038(%0)\n\t"
                        "sb\t$0, 0x03c(%0)\n\t"
-                       "sb\t$0, 0x040(%0)\n\t"
+                       "sb\t$0, 0x040(%0)\n\t"
                        "sb\t$0, 0x044(%0)\n\t"
                        "sb\t$0, 0x048(%0)\n\t"
                        "sb\t$0, 0x04c(%0)\n\t"
-                       "sb\t$0, 0x050(%0)\n\t"
+                       "sb\t$0, 0x050(%0)\n\t"
                        "sb\t$0, 0x054(%0)\n\t"
                        "sb\t$0, 0x058(%0)\n\t"
                        "sb\t$0, 0x05c(%0)\n\t"
-                       "sb\t$0, 0x060(%0)\n\t"
+                       "sb\t$0, 0x060(%0)\n\t"
                        "sb\t$0, 0x064(%0)\n\t"
                        "sb\t$0, 0x068(%0)\n\t"
                        "sb\t$0, 0x06c(%0)\n\t"
-                       "sb\t$0, 0x070(%0)\n\t"
+                       "sb\t$0, 0x070(%0)\n\t"
                        "sb\t$0, 0x074(%0)\n\t"
                        "sb\t$0, 0x078(%0)\n\t"
                        "sb\t$0, 0x07c(%0)\n\t"
index 9572ed44f0d5783d971218c8b579c40e2d980bcc..32b7f6aeb983271201702594c9d3a2da3e32ce5b 100644 (file)
@@ -786,6 +786,7 @@ static void __init probe_pcache(void)
                c->dcache.waybit = 0;
 
                c->options |= MIPS_CPU_CACHE_CDEX_P;
+               c->options |= MIPS_CPU_PREFETCH;
                break;
 
        case CPU_R4000PC:
index f51e180072e3a9f3e737437d7113948310fbe09d..e4390dc3eb48e29d9b9a950d5a020d27af32676e 100644 (file)
@@ -124,7 +124,7 @@ static inline void build_nop(void)
 
 static inline void build_src_pref(int advance)
 {
-       if (!(load_offset & (cpu_dcache_line_size() - 1))) {
+       if (!(load_offset & (cpu_dcache_line_size() - 1)) && advance) {
                union mips_instruction mi;
 
                mi.i_format.opcode     = pref_op;
@@ -166,7 +166,7 @@ static inline void build_load_reg(int reg)
 
 static inline void build_dst_pref(int advance)
 {
-       if (!(store_offset & (cpu_dcache_line_size() - 1))) {
+       if (!(store_offset & (cpu_dcache_line_size() - 1)) && advance) {
                union mips_instruction mi;
 
                mi.i_format.opcode     = pref_op;
@@ -340,6 +340,12 @@ void __init build_clear_page(void)
 
        if (cpu_has_prefetch) {
                switch (current_cpu_data.cputype) {
+               case CPU_TX49XX:
+                       /* TX49 supports only Pref_Load */
+                       pref_offset_clear = 0;
+                       pref_offset_copy = 0;
+                       break;
+
                case CPU_RM9000:
                        /*
                         * As a workaround for erratum G105 which make the
index 9e8ff8badb1935c694841592ed5b478f0caadf56..3b6cc9ba1b052651b0c9b77fcb379e39668d0784 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/bitops.h>
 
 #include <asm/addrspace.h>
 #include <asm/bcache.h>
@@ -43,14 +44,7 @@ static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size)
        /* Catch bad driver code */
        BUG_ON(size == 0);
 
-       a = addr & ~(sc_lsize - 1);
-       end = (addr + size - 1) & ~(sc_lsize - 1);
-       while (1) {
-               flush_scache_line(a);   /* Hit_Writeback_Inv_SD */
-               if (a == end)
-                       break;
-               a += sc_lsize;
-       }
+       blast_scache_range(addr, addr + size);
 
        if (!rm7k_tcache_enabled)
                return;
@@ -74,14 +68,7 @@ static void rm7k_sc_inv(unsigned long addr, unsigned long size)
        /* Catch bad driver code */
        BUG_ON(size == 0);
 
-       a = addr & ~(sc_lsize - 1);
-       end = (addr + size - 1) & ~(sc_lsize - 1);
-       while (1) {
-               invalidate_scache_line(a);      /* Hit_Invalidate_SD */
-               if (a == end)
-                       break;
-               a += sc_lsize;
-       }
+       blast_inv_scache_range(addr, addr + size);
 
        if (!rm7k_tcache_enabled)
                return;
@@ -143,11 +130,17 @@ struct bcache_ops rm7k_sc_ops = {
 
 void __init rm7k_sc_init(void)
 {
+       struct cpuinfo_mips *c = &current_cpu_data;
        unsigned int config = read_c0_config();
 
        if ((config & RM7K_CONF_SC))
                return;
 
+       c->scache.linesz = sc_lsize;
+       c->scache.ways = 4;
+       c->scache.waybit= ffs(scache_size / c->scache.ways) - 1;
+       c->scache.waysize = scache_size / c->scache.ways;
+       c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways);
        printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n",
               (scache_size >> 10), sc_lsize);
 
diff --git a/arch/mips/mm/tlb-andes.c b/arch/mips/mm/tlb-andes.c
deleted file mode 100644 (file)
index 3f422a8..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999 Silicon Graphics, Inc.
- * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/mmu_context.h>
-
-extern void build_tlb_refill_handler(void);
-
-#define NTLB_ENTRIES       64
-#define NTLB_ENTRIES_HALF  32
-
-void local_flush_tlb_all(void)
-{
-       unsigned long flags;
-       unsigned long old_ctx;
-       unsigned long entry;
-
-       local_irq_save(flags);
-       /* Save old context and create impossible VPN2 value */
-       old_ctx = read_c0_entryhi() & ASID_MASK;
-       write_c0_entryhi(CKSEG0);
-       write_c0_entrylo0(0);
-       write_c0_entrylo1(0);
-
-       entry = read_c0_wired();
-
-       /* Blast 'em all away. */
-       while (entry < NTLB_ENTRIES) {
-               write_c0_index(entry);
-               tlb_write_indexed();
-               entry++;
-       }
-       write_c0_entryhi(old_ctx);
-       local_irq_restore(flags);
-}
-
-void local_flush_tlb_mm(struct mm_struct *mm)
-{
-       int cpu = smp_processor_id();
-       if (cpu_context(cpu, mm) != 0) {
-               drop_mmu_context(mm,cpu);
-       }
-}
-
-void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
-                           unsigned long end)
-{
-       struct mm_struct *mm = vma->vm_mm;
-       int cpu = smp_processor_id();
-
-       if (cpu_context(cpu, mm) != 0) {
-               unsigned long flags;
-               int size;
-
-               local_irq_save(flags);
-               size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
-               size = (size + 1) >> 1;
-               if (size <= NTLB_ENTRIES_HALF) {
-                       int oldpid = (read_c0_entryhi() & ASID_MASK);
-                       int newpid = (cpu_context(smp_processor_id(), mm)
-                                     & ASID_MASK);
-
-                       start &= (PAGE_MASK << 1);
-                       end += ((PAGE_SIZE << 1) - 1);
-                       end &= (PAGE_MASK << 1);
-                       while(start < end) {
-                               int idx;
-
-                               write_c0_entryhi(start | newpid);
-                               start += (PAGE_SIZE << 1);
-                               tlb_probe();
-                               idx = read_c0_index();
-                               write_c0_entrylo0(0);
-                               write_c0_entrylo1(0);
-                               write_c0_entryhi(CKSEG0);
-                               if(idx < 0)
-                                       continue;
-                               tlb_write_indexed();
-                       }
-                       write_c0_entryhi(oldpid);
-               } else {
-                       drop_mmu_context(mm, cpu);
-               }
-               local_irq_restore(flags);
-       }
-}
-
-void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
-       unsigned long flags;
-       int size;
-
-       size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
-       size = (size + 1) >> 1;
-
-       local_irq_save(flags);
-       if (size <= NTLB_ENTRIES_HALF) {
-               int pid = read_c0_entryhi();
-
-               start &= (PAGE_MASK << 1);
-               end += ((PAGE_SIZE << 1) - 1);
-               end &= (PAGE_MASK << 1);
-
-               while (start < end) {
-                       int idx;
-
-                       write_c0_entryhi(start);
-                       start += (PAGE_SIZE << 1);
-                       tlb_probe();
-                       idx = read_c0_index();
-                       write_c0_entrylo0(0);
-                       write_c0_entrylo1(0);
-                       write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT+1)));
-                       if (idx < 0)
-                               continue;
-                       tlb_write_indexed();
-               }
-               write_c0_entryhi(pid);
-       } else {
-               local_flush_tlb_all();
-       }
-       local_irq_restore(flags);
-}
-
-void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
-       if (cpu_context(smp_processor_id(), vma->vm_mm) != 0) {
-               unsigned long flags;
-               int oldpid, newpid, idx;
-
-               newpid = (cpu_context(smp_processor_id(), vma->vm_mm) &
-                         ASID_MASK);
-               page &= (PAGE_MASK << 1);
-               local_irq_save(flags);
-               oldpid = (read_c0_entryhi() & ASID_MASK);
-               write_c0_entryhi(page | newpid);
-               tlb_probe();
-               idx = read_c0_index();
-               write_c0_entrylo0(0);
-               write_c0_entrylo1(0);
-               write_c0_entryhi(CKSEG0);
-               if (idx < 0)
-                       goto finish;
-               tlb_write_indexed();
-
-       finish:
-               write_c0_entryhi(oldpid);
-               local_irq_restore(flags);
-       }
-}
-
-/*
- * This one is only used for pages with the global bit set so we don't care
- * much about the ASID.
- */
-void local_flush_tlb_one(unsigned long page)
-{
-       unsigned long flags;
-       int oldpid, idx;
-
-       local_irq_save(flags);
-       page &= (PAGE_MASK << 1);
-       oldpid = read_c0_entryhi() & 0xff;
-       write_c0_entryhi(page);
-       tlb_probe();
-       idx = read_c0_index();
-       write_c0_entrylo0(0);
-       write_c0_entrylo1(0);
-       if (idx >= 0) {
-               /* Make sure all entries differ. */
-               write_c0_entryhi(CKSEG0+(idx<<(PAGE_SHIFT+1)));
-               tlb_write_indexed();
-       }
-       write_c0_entryhi(oldpid);
-
-       local_irq_restore(flags);
-}
-
-/* XXX Simplify this.  On the R10000 writing a TLB entry for an virtual
-   address that already exists will overwrite the old entry and not result
-   in TLB malfunction or TLB shutdown.  */
-void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
-{
-       unsigned long flags;
-       pgd_t *pgdp;
-       pud_t *pudp;
-       pmd_t *pmdp;
-       pte_t *ptep;
-       int idx, pid;
-
-       /*
-        * Handle debugger faulting in for debugee.
-        */
-       if (current->active_mm != vma->vm_mm)
-               return;
-
-       pid = read_c0_entryhi() & ASID_MASK;
-
-       if ((pid != (cpu_context(smp_processor_id(), vma->vm_mm) & ASID_MASK))
-           || (cpu_context(smp_processor_id(), vma->vm_mm) == 0)) {
-               printk(KERN_WARNING
-                      "%s: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
-                      __FUNCTION__, (int) (cpu_context(smp_processor_id(),
-                      vma->vm_mm) & ASID_MASK), pid);
-       }
-
-       local_irq_save(flags);
-       address &= (PAGE_MASK << 1);
-       write_c0_entryhi(address | (pid));
-       pgdp = pgd_offset(vma->vm_mm, address);
-       tlb_probe();
-       pudp = pud_offset(pgdp, address);
-       pmdp = pmd_offset(pudp, address);
-       idx = read_c0_index();
-       ptep = pte_offset_map(pmdp, address);
-       write_c0_entrylo0(pte_val(*ptep++) >> 6);
-       write_c0_entrylo1(pte_val(*ptep) >> 6);
-       write_c0_entryhi(address | pid);
-       if (idx < 0) {
-               tlb_write_random();
-       } else {
-               tlb_write_indexed();
-       }
-       write_c0_entryhi(pid);
-       local_irq_restore(flags);
-}
-
-void __init tlb_init(void)
-{
-       /*
-        * You should never change this register:
-        *   - On R4600 1.7 the tlbp never hits for pages smaller than
-        *     the value in the c0_pagemask register.
-        *   - The entire mm handling assumes the c0_pagemask register to
-        *     be set for 4kb pages.
-        */
-       write_c0_pagemask(PM_4K);
-       write_c0_wired(0);
-       write_c0_framemask(0);
-
-        /* From this point on the ARC firmware is dead.  */
-       local_flush_tlb_all();
-
-       /* Did I tell you that ARC SUCKS?  */
-
-       build_tlb_refill_handler();
-}
index 8297970f0bb1de64cc2731c2a14cc61971020950..a865f2394cb0d1de5d44acfdbbb1ee45b83beb28 100644 (file)
@@ -424,8 +424,13 @@ void __init tlb_init(void)
        probe_tlb(config);
        write_c0_pagemask(PM_DEFAULT_MASK);
        write_c0_wired(0);
+       write_c0_framemask(0);
        temp_tlb_entry = current_cpu_data.tlbsize - 1;
+
+        /* From this point on the ARC firmware is dead.  */
        local_flush_tlb_all();
 
+       /* Did I tell you that ARC SUCKS?  */
+
        build_tlb_refill_handler();
 }
index ac4f4bfaae50af41ddf5184cd4e87e4c3752536f..599b3c297186d360e3ce05cfd8f5135a827d021a 100644 (file)
@@ -951,7 +951,6 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
        /* No i_nop needed here, since the next insn doesn't touch TMP. */
 
 #ifdef CONFIG_SMP
-# ifdef CONFIG_BUILD_ELF64
        /*
         * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
         * stored in CONTEXT.
@@ -962,18 +961,6 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
        i_daddu(p, ptr, ptr, tmp);
        i_dmfc0(p, tmp, C0_BADVADDR);
        i_ld(p, ptr, rel_lo(pgdc), ptr);
-# else
-       /*
-        * 64 bit SMP running in compat space has the lower part of
-        * &pgd_current[smp_processor_id()] stored in CONTEXT.
-        */
-       if (!in_compat_space_p(pgdc))
-               panic("Invalid page directory address!");
-
-       i_dmfc0(p, ptr, C0_CONTEXT);
-       i_dsra(p, ptr, ptr, 23);
-       i_ld(p, ptr, 0, ptr);
-# endif
 #else
        i_LA_mostly(p, ptr, pgdc);
        i_ld(p, ptr, rel_lo(pgdc), ptr);
index c4236b1e59fa55b8d1b4ead6b51751903f82289e..ce9fb2e3d952194945b51e6eef25363b2f7a8c1e 100644 (file)
@@ -32,7 +32,7 @@ void momenco_jaguar_restart(char *command)
 #else
        void *nvram = (void*) 0xfc807000;
 #endif
-       /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
+       /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
        writeb(0x84, nvram + 0xff7);
 
        /* wait for the watchdog to go off */
index 2699917b640ac40f0ab07a35aacc96898ee35009..3784c898db1a00850ab1116986251df24b571230 100644 (file)
@@ -461,7 +461,7 @@ void __init plat_setup(void)
          unsigned int tbControl;
          tbControl =
            0 << 26 |  /* post trigger delay 0 */
-                   0x2 << 16 |         /* sequential trace mode */
+                   0x2 << 16 |         /* sequential trace mode */
            //      0x0 << 16 |         /* non-sequential trace mode */
            //      0xf << 4 |          /* watchpoints disabled */
            2 << 2 |            /* armed */
index 72b4423c0864538b7ec7736a4b773792a74ef8b2..9d86d2468376f387163b0d875a1dcff9603d284e 100644 (file)
@@ -34,7 +34,7 @@ void momenco_ocelot_restart(char *command)
        /* base address of timekeeper portion of part */
        void *nvram = (void *) 0xfc807000L;
 
-       /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
+       /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
        writeb(0x84, nvram + 0xff7);
 
        /* wait for the watchdog to go off */
index 6a2489f3b9a0f3648d7459d8c7e833e7e9bc41a5..9dcd154c77672b7856cbf67843a3c51bd64a921b 100644 (file)
@@ -34,7 +34,7 @@ void momenco_ocelot_restart(char *command)
                0xfc807000;
 #endif
 
-       /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
+       /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
        writeb(0x84, nvram + 0xff7);
 
        /* wait for the watchdog to go off */
index 03a0ff2fc99362b3f59591d5f1960a3addf9c6d1..a8a47b494b23be496a008eec42947bbbf3965a63 100644 (file)
@@ -45,7 +45,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
 
        /*
         * we have to open the bridges' windows down to 0 because otherwise
-        * we cannot access ISA south bridge I/O registers that get mapped from
+        * we cannot access ISA south bridge I/O registers that get mapped from
         * 0. for example, 8259 PIC would be unaccessible without that
         */
        if(dev->vendor == PCI_VENDOR_ID_INTEL && dev->device == PCI_DEVICE_ID_INTEL_S21152BB) {
index 0406b50a37d8d46c4f72219feed294fd97f7dea4..8e57d4c5d90f54c984e758d035ce01bf3a095f50 100644 (file)
@@ -253,9 +253,9 @@ static int write_config_byte(struct pci_config_swap *swap,
 static int prefix##_##rw##_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 star val) \
 { \
        if (size == 1) \
-               return rw##_config_byte(pciswap, bus, devfn, where, (u8 star)val); \
+               return rw##_config_byte(pciswap, bus, devfn, where, (u8 star)val); \
        else if (size == 2) \
-               return rw##_config_word(pciswap, bus, devfn, where, (u16 star)val); \
+               return rw##_config_word(pciswap, bus, devfn, where, (u16 star)val); \
        /* Size must be 4 */ \
        return rw##_config_dword(pciswap, bus, devfn, where, val); \
 }
index 4c0dcfce52976496ab40e9f2f698f9617d4d5d7d..0ff083489efdba7e5537ea4b8ee871a346fba5ff 100644 (file)
@@ -34,16 +34,16 @@ struct resource pci_mem_resource = {
 };
 
 struct resource tx4938_pcic1_pci_io_resource = {
-               .name   = "PCI1 IO",
-               .start  = 0,
-               .end    = 0,
-               .flags  = IORESOURCE_IO
+       .name   = "PCI1 IO",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_IO
 };
 struct resource tx4938_pcic1_pci_mem_resource = {
-               .name   = "PCI1 mem",
-               .start  = 0,
-               .end    = 0,
-               .flags  = IORESOURCE_MEM
+       .name   = "PCI1 mem",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_MEM
 };
 
 static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
index ca975e7d32ffba36d5b5d0ec68c3314464d6d902..f4ef1a35ca18bc6e4ad9bbb25cca9a5b6143463d 100644 (file)
@@ -100,7 +100,7 @@ static int bcm1480_pci_can_access(struct pci_bus *bus, int devfn)
 
        if (bus->number == 0) {
                devno = PCI_SLOT(devfn);
-               if (bcm1480_bus_status & PCI_DEVICE_MODE)
+               if (bcm1480_bus_status & PCI_DEVICE_MODE)
                        return 0;
                else
                        return 1;
index aca4a2e7a1c6893693d34aa248a90a7bf03eb39e..a3eebe5890a76db08e87fe305d6bc65dd76c1a6c 100644 (file)
@@ -95,7 +95,7 @@ static int bcm1480ht_can_access(struct pci_bus *bus, int devfn)
 
        if (bus->number == 0) {
                devno = PCI_SLOT(devfn);
-               if (bcm1480ht_bus_status & PCI_DEVICE_MODE)
+               if (bcm1480ht_bus_status & PCI_DEVICE_MODE)
                        return 0;
        }
        return 1;
index efc96ce99eebfce61bf5b4b67e0cb5ba1b24d2bc..6002d2a6a262b019d770ff6cf4f3532a13cde873 100644 (file)
@@ -379,18 +379,18 @@ int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid)
        bridge = (bridge_t *) RAW_NODE_SWIN_BASE(nasid, widget_id);
 
        /*
-        * Clear all pending interrupts.
-        */
+        * Clear all pending interrupts.
+        */
        bridge->b_int_rst_stat = BRIDGE_IRR_ALL_CLR;
 
        /*
-        * Until otherwise set up, assume all interrupts are from slot 0
-        */
+        * Until otherwise set up, assume all interrupts are from slot 0
+        */
        bridge->b_int_device = 0x0;
 
        /*
-        * swap pio's to pci mem and io space (big windows)
-        */
+        * swap pio's to pci mem and io space (big windows)
+        */
        bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP |
                                 BRIDGE_CTRL_MEM_SWAP;
 
index 546144988bf564fd22604834ad095a27bd4c9944..c500e2d41f2c5f8d6c30ee843a98ca50f3576233 100644 (file)
@@ -251,7 +251,7 @@ void __init arch_init_irq(void)
                if (gic_int_line == (PNX8550_INT_GPIO0 - PNX8550_INT_GIC_MIN)) {
                        /* PCI INT through gpio 8, which is setup in
                         * pnx8550_setup.c and routed to GPIO
-                        * Interrupt Level 0 (GPIO Connection 58).
+                        * Interrupt Level 0 (GPIO Connection 58).
                         * Set it active low. */
 
                        PNX8550_GIC_REQ(gic_int_line) = 0x1E020000;
index 934944ab9e850445c8feae95819f9ec735f990ed..6a8e8bcef5528181dec4943c60f2d3635a150201 100644 (file)
@@ -3,3 +3,5 @@
 #
 
 obj-y          = q-firmware.o q-int.o q-irq.o q-mem.o q-setup.o
+
+obj-$(CONFIG_SMP) += q-smp.o
diff --git a/arch/mips/qemu/q-smp.c b/arch/mips/qemu/q-smp.c
new file mode 100644 (file)
index 0000000..5a12354
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Symmetric Uniprocessor (TM) Support
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+/*
+ * Send inter-processor interrupt
+ */
+void core_send_ipi(int cpu, unsigned int action)
+{
+       panic(KERN_ERR "%s called", __FUNCTION__);
+}
+
+/*
+ *  After we've done initial boot, this function is called to allow the
+ *  board code to clean up state, if needed
+ */
+void prom_init_secondary(void)
+{
+}
+
+void prom_smp_finish(void)
+{
+}
+
+/* Hook for after all CPUs are online */
+void prom_cpus_done(void)
+{
+}
+
+void __init prom_prepare_cpus(unsigned int max_cpus)
+{
+       cpus_clear(phys_cpu_present_map);
+}
+
+/*
+ * Firmware CPU startup hook
+ */
+void prom_boot_secondary(int cpu, struct task_struct *idle)
+{
+}
index ef20d9ac0ba3d0d39d7510c46f465d41ea041932..ed93a9792959f240555f1746dd28daaa97dff506 100644 (file)
@@ -540,8 +540,8 @@ void __init mem_init(void)
                struct page *end, *p;
 
                /*
-                * This will free up the bootmem, ie, slot 0 memory.
-                */
+                * This will free up the bootmem, ie, slot 0 memory.
+                */
                totalram_pages += free_all_bootmem_node(NODE_DATA(node));
 
                /*
index 2c38770b1e1bcf0a5750af1d3dd96604cc7a42bd..2f50c79b7887f0044d2a232e19ef67ba20982b73 100644 (file)
@@ -98,7 +98,7 @@ void __init plat_setup(void)
        board_timer_setup = ip32_timer_setup;
 
 #ifdef CONFIG_SERIAL_8250
-       {
+       {
                static struct uart_port o2_serial[2];
 
                memset(o2_serial, 0, sizeof(o2_serial));
index e19e2be70f76ef3209b8562b672037369be9fc35..efe50562f0ce52a11b9c829feccb0781aa73708b 100644 (file)
@@ -70,10 +70,10 @@ void __init prom_init(void)
 
        if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) {
                mips_machtype = MACH_TOSHIBA_RBTX4927;
-               toshiba_name  = "TX4927";
+               toshiba_name  = "TX4927";
        } else {
                mips_machtype = MACH_TOSHIBA_RBTX4937;
-               toshiba_name  = "TX4937";
+               toshiba_name  = "TX4937";
        }
 
        msize = tx4927_get_mem_size();
index 5c7ace982a4958eb9951a3d740f1b91426a131cc..9166cd4557eb01f1b5e7db4777d882ac4a97416c 100644 (file)
@@ -684,7 +684,7 @@ void __init tx4938_board_setup(void)
        for (i = 0; i < 8; i++) {
                if (!(tx4938_ebuscptr->cr[i] & 0x8))
                        continue;       /* disabled */
-               rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i);
+               rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i);
                txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i));
        }
 
index de0c1b35f11ce046afb5895f29e41c35bed34c9f..ff272b2e8395693154c579199fad36a409b243a5 100644 (file)
@@ -183,11 +183,11 @@ static inline unsigned long calculate_tclock(uint16_t clkspeed, unsigned long pc
        switch (current_cpu_data.cputype) {
        case CPU_VR4111:
                if (!(clkspeed & DIV2B))
-                       tclock = pclock / 2;
+                       tclock = pclock / 2;
                else if (!(clkspeed & DIV3B))
-                       tclock = pclock / 3;
+                       tclock = pclock / 3;
                else if (!(clkspeed & DIV4B))
-                       tclock = pclock / 4;
+                       tclock = pclock / 4;
                break;
        case CPU_VR4121:
                tclock = pclock / DIVT(clkspeed);
index 5be05f47109e478fa608f4cf2a41eadccd84b677..5b2ffcc6e2b2f50db26ead76ba384118065b79e1 100644 (file)
                ___start___ksymtab_gpl = .;                                   \
                        *(__ksymtab_gpl)                                      \
                ___stop___ksymtab_gpl = .;                                    \
+               /* Kernel symbol table: GPL-future symbols */                 \
+               ___start___ksymtab_gpl_future = .;                            \
+                       *(__ksymtab_gpl_future)                               \
+               ___stop___ksymtab_gpl_future = .;                             \
                /* Kernel symbol table: strings */                            \
                        *(__ksymtab_strings)                                  \
                /* Kernel symbol table: Normal symbols */                     \
                ___start___kcrctab_gpl = .;                                   \
                        *(__kcrctab_gpl)                                      \
                ___stop___kcrctab_gpl = .;                                    \
+               /* Kernel symbol table: GPL-future symbols */                 \
+               ___start___kcrctab_gpl_future = .;                            \
+                       *(__kcrctab_gpl_future)                               \
+               ___stop___kcrctab_gpl_future = .;                             \
                /* Built-in module parameters */                              \
                . = ALIGN (4) ;                                               \
                ___start___param = .;                                         \
index db57546a709d96b77e7dbc8987fc2c61ec40cf80..64510fd88621245c82dc0064c67a9b312ea47072 100644 (file)
 #include <linux/kmod.h>
 #include <linux/kobj_map.h>
 #include <linux/buffer_head.h>
+#include <linux/mutex.h>
 
 #define MAX_PROBE_HASH 255     /* random */
 
 static struct subsystem block_subsys;
 
-static DECLARE_MUTEX(block_subsys_sem);
+static DEFINE_MUTEX(block_subsys_lock);
 
 /*
  * Can be deleted altogether. Later.
@@ -46,7 +47,7 @@ struct blkdev_info {
 /*
  * iterate over a list of blkdev_info structures.  allows
  * the major_names array to be iterated over from outside this file
- * must be called with the block_subsys_sem held
+ * must be called with the block_subsys_lock held
  */
 void *get_next_blkdev(void *dev)
 {
@@ -85,20 +86,20 @@ out:
 
 void *acquire_blkdev_list(void)
 {
-        down(&block_subsys_sem);
+        mutex_lock(&block_subsys_lock);
         return get_next_blkdev(NULL);
 }
 
 void release_blkdev_list(void *dev)
 {
-        up(&block_subsys_sem);
+        mutex_unlock(&block_subsys_lock);
         kfree(dev);
 }
 
 
 /*
  * Count the number of records in the blkdev_list.
- * must be called with the block_subsys_sem held
+ * must be called with the block_subsys_lock held
  */
 int count_blkdev_list(void)
 {
@@ -118,7 +119,7 @@ int count_blkdev_list(void)
 /*
  * extract the major and name values from a blkdev_info struct
  * passed in as a void to *dev.  Must be called with
- * block_subsys_sem held
+ * block_subsys_lock held
  */
 int get_blkdev_info(void *dev, int *major, char **name)
 {
@@ -138,7 +139,7 @@ int register_blkdev(unsigned int major, const char *name)
        struct blk_major_name **n, *p;
        int index, ret = 0;
 
-       down(&block_subsys_sem);
+       mutex_lock(&block_subsys_lock);
 
        /* temporary */
        if (major == 0) {
@@ -183,7 +184,7 @@ int register_blkdev(unsigned int major, const char *name)
                kfree(p);
        }
 out:
-       up(&block_subsys_sem);
+       mutex_unlock(&block_subsys_lock);
        return ret;
 }
 
@@ -197,7 +198,7 @@ int unregister_blkdev(unsigned int major, const char *name)
        int index = major_to_index(major);
        int ret = 0;
 
-       down(&block_subsys_sem);
+       mutex_lock(&block_subsys_lock);
        for (n = &major_names[index]; *n; n = &(*n)->next)
                if ((*n)->major == major)
                        break;
@@ -207,7 +208,7 @@ int unregister_blkdev(unsigned int major, const char *name)
                p = *n;
                *n = p->next;
        }
-       up(&block_subsys_sem);
+       mutex_unlock(&block_subsys_lock);
        kfree(p);
 
        return ret;
@@ -301,7 +302,7 @@ static void *part_start(struct seq_file *part, loff_t *pos)
        struct list_head *p;
        loff_t l = *pos;
 
-       down(&block_subsys_sem);
+       mutex_lock(&block_subsys_lock);
        list_for_each(p, &block_subsys.kset.list)
                if (!l--)
                        return list_entry(p, struct gendisk, kobj.entry);
@@ -318,7 +319,7 @@ static void *part_next(struct seq_file *part, void *v, loff_t *pos)
 
 static void part_stop(struct seq_file *part, void *v)
 {
-       up(&block_subsys_sem);
+       mutex_unlock(&block_subsys_lock);
 }
 
 static int show_partition(struct seq_file *part, void *v)
@@ -377,7 +378,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
 
 static int __init genhd_device_init(void)
 {
-       bdev_map = kobj_map_init(base_probe, &block_subsys_sem);
+       bdev_map = kobj_map_init(base_probe, &block_subsys_lock);
        blk_dev_init();
        subsystem_register(&block_subsys);
        return 0;
@@ -611,7 +612,7 @@ static void *diskstats_start(struct seq_file *part, loff_t *pos)
        loff_t k = *pos;
        struct list_head *p;
 
-       down(&block_subsys_sem);
+       mutex_lock(&block_subsys_lock);
        list_for_each(p, &block_subsys.kset.list)
                if (!k--)
                        return list_entry(p, struct gendisk, kobj.entry);
@@ -628,7 +629,7 @@ static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos)
 
 static void diskstats_stop(struct seq_file *part, void *v)
 {
-       up(&block_subsys_sem);
+       mutex_unlock(&block_subsys_lock);
 }
 
 static int diskstats_show(struct seq_file *s, void *v)
index 07a7f97e1de9d95a488f9fea90288052786f6e98..29f3d7504da1fd797d8753f644e0b408ef2a8b19 100644 (file)
@@ -141,7 +141,7 @@ int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
        return error;
 }
 
-struct sys_device *get_cpu_sysdev(int cpu)
+struct sys_device *get_cpu_sysdev(unsigned cpu)
 {
        if (cpu < NR_CPUS)
                return cpu_sys_devices[cpu];
index e97e911ebf7a0374117245f18910f496319c53a9..472318205236162eaca67da28be8b3ece20b50bc 100644 (file)
@@ -211,18 +211,20 @@ static int
 fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
 {
        u8 *new_data;
+       int new_size = fw_priv->alloc_size;
 
        if (min_size <= fw_priv->alloc_size)
                return 0;
 
-       new_data = vmalloc(fw_priv->alloc_size + PAGE_SIZE);
+       new_size = ALIGN(min_size, PAGE_SIZE);
+       new_data = vmalloc(new_size);
        if (!new_data) {
                printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
                /* Make sure that we don't keep incomplete data */
                fw_load_abort(fw_priv);
                return -ENOMEM;
        }
-       fw_priv->alloc_size += PAGE_SIZE;
+       fw_priv->alloc_size = new_size;
        if (fw_priv->fw->data) {
                memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
                vfree(fw_priv->fw->data);
index b449dae6f0d30fcb8385ce68c1f9bdfd34f6ff64..e87017f3685356854629a439ae4ec5900a7129e2 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/mutex.h>
 #include <linux/kdev_t.h>
 #include <linux/kobject.h>
 #include <linux/kobj_map.h>
@@ -25,7 +26,7 @@ struct kobj_map {
                int (*lock)(dev_t, void *);
                void *data;
        } *probes[255];
-       struct semaphore *sem;
+       struct mutex *lock;
 };
 
 int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
@@ -53,7 +54,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
                p->range = range;
                p->data = data;
        }
-       down(domain->sem);
+       mutex_lock(domain->lock);
        for (i = 0, p -= n; i < n; i++, p++, index++) {
                struct probe **s = &domain->probes[index % 255];
                while (*s && (*s)->range < range)
@@ -61,7 +62,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
                p->next = *s;
                *s = p;
        }
-       up(domain->sem);
+       mutex_unlock(domain->lock);
        return 0;
 }
 
@@ -75,7 +76,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
        if (n > 255)
                n = 255;
 
-       down(domain->sem);
+       mutex_lock(domain->lock);
        for (i = 0; i < n; i++, index++) {
                struct probe **s;
                for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) {
@@ -88,7 +89,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
                        }
                }
        }
-       up(domain->sem);
+       mutex_unlock(domain->lock);
        kfree(found);
 }
 
@@ -99,7 +100,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
        unsigned long best = ~0UL;
 
 retry:
-       down(domain->sem);
+       mutex_lock(domain->lock);
        for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) {
                struct kobject *(*probe)(dev_t, int *, void *);
                struct module *owner;
@@ -120,7 +121,7 @@ retry:
                        module_put(owner);
                        continue;
                }
-               up(domain->sem);
+               mutex_unlock(domain->lock);
                kobj = probe(dev, index, data);
                /* Currently ->owner protects _only_ ->probe() itself. */
                module_put(owner);
@@ -128,11 +129,11 @@ retry:
                        return kobj;
                goto retry;
        }
-       up(domain->sem);
+       mutex_unlock(domain->lock);
        return NULL;
 }
 
-struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem)
+struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct mutex *lock)
 {
        struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);
        struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL);
@@ -149,6 +150,6 @@ struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem)
        base->get = base_probe;
        for (i = 0; i < 255; i++)
                p->probes[i] = base;
-       p->sem = sem;
+       p->lock = lock;
        return p;
 }
index 461554a025172d329b714e9bc46a389991eabe28..89b268321321bf3e7695e88fe18412f24f87d0bf 100644 (file)
@@ -61,7 +61,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
 {
        struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
 
-       return r ? r->start : 0;
+       return r ? r->start : -ENXIO;
 }
 EXPORT_SYMBOL_GPL(platform_get_irq);
 
@@ -98,7 +98,7 @@ int platform_get_irq_byname(struct platform_device *dev, char *name)
 {
        struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
 
-       return r ? r->start : 0;
+       return r ? r->start : -ENXIO;
 }
 EXPORT_SYMBOL_GPL(platform_get_irq_byname);
 
index 503dd901d406bad8e432ce267642926ce325e9c3..090d154098bb726bcdf2ae34489bf927bc8484fa 100644 (file)
@@ -31,7 +31,7 @@ obj-$(CONFIG_MOXA_INTELLIO)   += moxa.o
 obj-$(CONFIG_A2232)            += ser_a2232.o generic_serial.o
 obj-$(CONFIG_ATARI_DSP56K)     += dsp56k.o
 obj-$(CONFIG_MOXA_SMARTIO)     += mxser.o
-obj-$(CONFIG_COMPUTONE)                += ip2.o ip2main.o
+obj-$(CONFIG_COMPUTONE)                += ip2/
 obj-$(CONFIG_RISCOM8)          += riscom8.o
 obj-$(CONFIG_ISI)              += isicom.o
 obj-$(CONFIG_SYNCLINK)         += synclink.o
index 56ace9d5e2aef75b4cd095b3424e4cbc00094b23..5278c388d3e747dbc40251c70985e25ef5d4eceb 100644 (file)
@@ -37,8 +37,8 @@ config DRM_RADEON
        help
          Choose this option if you have an ATI Radeon graphics card.  There
          are both PCI and AGP versions.  You don't need to choose this to
-         run the Radeon in plain VGA mode.  There is a product page at
-         <http://www.ati.com/na/pages/products/pc/radeon32/index.html>.
+         run the Radeon in plain VGA mode.
+         
          If M is selected, the module will be called radeon.
 
 config DRM_I810
diff --git a/drivers/char/ip2.c b/drivers/char/ip2.c
deleted file mode 100644 (file)
index 7cadfc6..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-// ip2.c
-// This is a dummy module to make the firmware available when needed
-// and allows it to be unloaded when not. Rumor is the __initdata 
-// macro doesn't always works on all platforms so we use this kludge.
-// If not compiled as a module it just makes fip_firm avaliable then
-//  __initdata should work as advertized
-//
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/wait.h>
-
-#ifndef __init
-#define __init
-#endif
-#ifndef __initfunc
-#define __initfunc(a) a
-#endif
-#ifndef __initdata
-#define __initdata
-#endif
-
-#include "./ip2/ip2types.h"            
-#include "./ip2/fip_firm.h"            // the meat
-
-int
-ip2_loadmain(int *, int  *, unsigned char *, int ); // ref into ip2main.c
-
-/* Note: Add compiled in defaults to these arrays, not to the structure
-       in ip2/ip2.h any longer.  That structure WILL get overridden
-       by these values, or command line values, or insmod values!!!  =mhw=
-*/
-static int io[IP2_MAX_BOARDS]= { 0, 0, 0, 0 };
-static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 }; 
-
-static int poll_only = 0;
-
-MODULE_AUTHOR("Doug McNash");
-MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
-module_param_array(irq, int, NULL, 0);
-MODULE_PARM_DESC(irq,"Interrupts for IntelliPort Cards");
-module_param_array(io, int, NULL, 0);
-MODULE_PARM_DESC(io,"I/O ports for IntelliPort Cards");
-module_param(poll_only, bool, 0);
-MODULE_PARM_DESC(poll_only,"Do not use card interrupts");
-
-
-static int __init ip2_init(void)
-{
-       if( poll_only ) {
-               /* Hard lock the interrupts to zero */
-               irq[0] = irq[1] = irq[2] = irq[3] = 0;
-       }
-
-       return ip2_loadmain(io,irq,(unsigned char *)fip_firm,sizeof(fip_firm));
-}
-module_init(ip2_init);
-
-MODULE_LICENSE("GPL");
-
-#ifndef MODULE
-/******************************************************************************
- *     ip2_setup:
- *             str: kernel command line string
- *
- *     Can't autoprobe the boards so user must specify configuration on
- *     kernel command line.  Sane people build it modular but the others
- *     come here.
- *
- *     Alternating pairs of io,irq for up to 4 boards.
- *             ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3
- *
- *             io=0 => No board
- *             io=1 => PCI
- *             io=2 => EISA
- *             else => ISA I/O address
- *
- *             irq=0 or invalid for ISA will revert to polling mode
- *
- *             Any value = -1, do not overwrite compiled in value.
- *
- ******************************************************************************/
-static int __init ip2_setup(char *str)
-{
-       int     ints[10];       /* 4 boards, 2 parameters + 2 */
-       int     i, j;
-
-       str = get_options (str, ARRAY_SIZE(ints), ints);
-
-       for( i = 0, j = 1; i < 4; i++ ) {
-               if( j > ints[0] ) {
-                       break;
-               }
-               if( ints[j] >= 0 ) {
-                       io[i] = ints[j];
-               }
-               j++;
-               if( j > ints[0] ) {
-                       break;
-               }
-               if( ints[j] >= 0 ) {
-                       irq[i] = ints[j];
-               }
-               j++;
-       }
-       return 1;
-}
-__setup("ip2=", ip2_setup);
-#endif /* !MODULE */
diff --git a/drivers/char/ip2/Makefile b/drivers/char/ip2/Makefile
new file mode 100644 (file)
index 0000000..6bfe254
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the Computone IntelliPort Plus Driver
+#
+
+obj-$(CONFIG_COMPUTONE)         += ip2.o ip2main.o
+
+ip2-objs                       := ip2base.o
+
diff --git a/drivers/char/ip2/ip2base.c b/drivers/char/ip2/ip2base.c
new file mode 100644 (file)
index 0000000..435ccfc
--- /dev/null
@@ -0,0 +1,109 @@
+// ip2.c
+// This is a dummy module to make the firmware available when needed
+// and allows it to be unloaded when not. Rumor is the __initdata 
+// macro doesn't always works on all platforms so we use this kludge.
+// If not compiled as a module it just makes fip_firm avaliable then
+//  __initdata should work as advertized
+//
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+
+#ifndef __init
+#define __init
+#endif
+#ifndef __initfunc
+#define __initfunc(a) a
+#endif
+#ifndef __initdata
+#define __initdata
+#endif
+
+#include "ip2types.h"          
+#include "fip_firm.h"          // the meat
+
+int
+ip2_loadmain(int *, int  *, unsigned char *, int ); // ref into ip2main.c
+
+/* Note: Add compiled in defaults to these arrays, not to the structure
+       in ip2.h any longer.  That structure WILL get overridden
+       by these values, or command line values, or insmod values!!!  =mhw=
+*/
+static int io[IP2_MAX_BOARDS]= { 0, 0, 0, 0 };
+static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 }; 
+
+static int poll_only = 0;
+
+MODULE_AUTHOR("Doug McNash");
+MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
+module_param_array(irq, int, NULL, 0);
+MODULE_PARM_DESC(irq,"Interrupts for IntelliPort Cards");
+module_param_array(io, int, NULL, 0);
+MODULE_PARM_DESC(io,"I/O ports for IntelliPort Cards");
+module_param(poll_only, bool, 0);
+MODULE_PARM_DESC(poll_only,"Do not use card interrupts");
+
+
+static int __init ip2_init(void)
+{
+       if( poll_only ) {
+               /* Hard lock the interrupts to zero */
+               irq[0] = irq[1] = irq[2] = irq[3] = 0;
+       }
+
+       return ip2_loadmain(io,irq,(unsigned char *)fip_firm,sizeof(fip_firm));
+}
+module_init(ip2_init);
+
+MODULE_LICENSE("GPL");
+
+#ifndef MODULE
+/******************************************************************************
+ *     ip2_setup:
+ *             str: kernel command line string
+ *
+ *     Can't autoprobe the boards so user must specify configuration on
+ *     kernel command line.  Sane people build it modular but the others
+ *     come here.
+ *
+ *     Alternating pairs of io,irq for up to 4 boards.
+ *             ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3
+ *
+ *             io=0 => No board
+ *             io=1 => PCI
+ *             io=2 => EISA
+ *             else => ISA I/O address
+ *
+ *             irq=0 or invalid for ISA will revert to polling mode
+ *
+ *             Any value = -1, do not overwrite compiled in value.
+ *
+ ******************************************************************************/
+static int __init ip2_setup(char *str)
+{
+       int     ints[10];       /* 4 boards, 2 parameters + 2 */
+       int     i, j;
+
+       str = get_options (str, ARRAY_SIZE(ints), ints);
+
+       for( i = 0, j = 1; i < 4; i++ ) {
+               if( j > ints[0] ) {
+                       break;
+               }
+               if( ints[j] >= 0 ) {
+                       io[i] = ints[j];
+               }
+               j++;
+               if( j > ints[0] ) {
+                       break;
+               }
+               if( ints[j] >= 0 ) {
+                       irq[i] = ints[j];
+               }
+               j++;
+       }
+       return 1;
+}
+__setup("ip2=", ip2_setup);
+#endif /* !MODULE */
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
new file mode 100644 (file)
index 0000000..03db1cb
--- /dev/null
@@ -0,0 +1,3211 @@
+/*
+*
+*   (c) 1999 by Computone Corporation
+*
+********************************************************************************
+*
+*   PACKAGE:     Linux tty Device Driver for IntelliPort family of multiport
+*                serial I/O controllers.
+*
+*   DESCRIPTION: Mainline code for the device driver
+*
+*******************************************************************************/
+// ToDo:
+//
+// Fix the immediate DSS_NOW problem.
+// Work over the channel stats return logic in ip2_ipl_ioctl so they
+//     make sense for all 256 possible channels and so the user space
+//     utilities will compile and work properly.
+//
+// Done:
+//
+// 1.2.14      /\/\|=mhw=|\/\/
+// Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts.
+// Changed the definition of ip2trace to be more consistent with kernel style
+//     Thanks to Andreas Dilger <adilger@turbolabs.com> for these updates
+//
+// 1.2.13      /\/\|=mhw=|\/\/
+// DEVFS: Renamed ttf/{n} to tts/F{n} and cuf/{n} to cua/F{n} to conform
+//     to agreed devfs serial device naming convention.
+//
+// 1.2.12      /\/\|=mhw=|\/\/
+// Cleaned up some remove queue cut and paste errors
+//
+// 1.2.11      /\/\|=mhw=|\/\/
+// Clean up potential NULL pointer dereferences
+// Clean up devfs registration
+// Add kernel command line parsing for io and irq
+//     Compile defaults for io and irq are now set in ip2.c not ip2.h!
+// Reworked poll_only hack for explicit parameter setting
+//     You must now EXPLICITLY set poll_only = 1 or set all irqs to 0
+// Merged ip2_loadmain and old_ip2_init
+// Converted all instances of interruptible_sleep_on into queue calls
+//     Most of these had no race conditions but better to clean up now
+//
+// 1.2.10      /\/\|=mhw=|\/\/
+// Fixed the bottom half interrupt handler and enabled USE_IQI
+//     to split the interrupt handler into a formal top-half / bottom-half
+// Fixed timing window on high speed processors that queued messages to
+//     the outbound mail fifo faster than the board could handle.
+//
+// 1.2.9
+// Four box EX was barfing on >128k kmalloc, made structure smaller by
+// reducing output buffer size
+//
+// 1.2.8
+// Device file system support (MHW)
+//
+// 1.2.7 
+// Fixed
+// Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules
+//
+// 1.2.6
+//Fixes DCD problems
+//     DCD was not reported when CLOCAL was set on call to TIOCMGET
+//
+//Enhancements:
+//     TIOCMGET requests and waits for status return
+//     No DSS interrupts enabled except for DCD when needed
+//
+// For internal use only
+//
+//#define IP2DEBUG_INIT
+//#define IP2DEBUG_OPEN
+//#define IP2DEBUG_WRITE
+//#define IP2DEBUG_READ
+//#define IP2DEBUG_IOCTL
+//#define IP2DEBUG_IPL
+
+//#define IP2DEBUG_TRACE
+//#define DEBUG_FIFO
+
+/************/
+/* Includes */
+/************/
+#include <linux/config.h>
+
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/major.h>
+#include <linux/wait.h>
+#include <linux/device.h>
+
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/termios.h>
+#include <linux/tty_driver.h>
+#include <linux/serial.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+
+#include <linux/cdk.h>
+#include <linux/comstats.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+
+#include "ip2types.h"
+#include "ip2trace.h"
+#include "ip2ioctl.h"
+#include "ip2.h"
+#include "i2ellis.h"
+#include "i2lib.h"
+
+/*****************
+ * /proc/ip2mem  *
+ *****************/
+
+#include <linux/proc_fs.h>
+
+static int ip2_read_procmem(char *, char **, off_t, int);
+static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
+
+/********************/
+/* Type Definitions */
+/********************/
+
+/*************/
+/* Constants */
+/*************/
+
+/* String constants to identify ourselves */
+static char *pcName    = "Computone IntelliPort Plus multiport driver";
+static char *pcVersion = "1.2.14";
+
+/* String constants for port names */
+static char *pcDriver_name   = "ip2";
+static char *pcIpl              = "ip2ipl";
+
+/* Serial subtype definitions */
+#define SERIAL_TYPE_NORMAL    1
+
+// cheezy kludge or genius - you decide?
+int ip2_loadmain(int *, int *, unsigned char *, int);
+static unsigned char *Fip_firmware;
+static int Fip_firmware_size;
+
+/***********************/
+/* Function Prototypes */
+/***********************/
+
+/* Global module entry functions */
+
+/* Private (static) functions */
+static int  ip2_open(PTTY, struct file *);
+static void ip2_close(PTTY, struct file *);
+static int  ip2_write(PTTY, const unsigned char *, int);
+static void ip2_putchar(PTTY, unsigned char);
+static void ip2_flush_chars(PTTY);
+static int  ip2_write_room(PTTY);
+static int  ip2_chars_in_buf(PTTY);
+static void ip2_flush_buffer(PTTY);
+static int  ip2_ioctl(PTTY, struct file *, UINT, ULONG);
+static void ip2_set_termios(PTTY, struct termios *);
+static void ip2_set_line_discipline(PTTY);
+static void ip2_throttle(PTTY);
+static void ip2_unthrottle(PTTY);
+static void ip2_stop(PTTY);
+static void ip2_start(PTTY);
+static void ip2_hangup(PTTY);
+static int  ip2_tiocmget(struct tty_struct *tty, struct file *file);
+static int  ip2_tiocmset(struct tty_struct *tty, struct file *file,
+                        unsigned int set, unsigned int clear);
+
+static void set_irq(int, int);
+static void ip2_interrupt_bh(i2eBordStrPtr pB);
+static irqreturn_t ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static void ip2_poll(unsigned long arg);
+static inline void service_all_boards(void);
+static void do_input(void *p);
+static void do_status(void *p);
+
+static void ip2_wait_until_sent(PTTY,int);
+
+static void set_params (i2ChanStrPtr, struct termios *);
+static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
+static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
+
+static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
+static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
+static int ip2_ipl_ioctl(struct inode *, struct file *, UINT, ULONG);
+static int ip2_ipl_open(struct inode *, struct file *);
+
+static int DumpTraceBuffer(char __user *, int);
+static int DumpFifoBuffer( char __user *, int);
+
+static void ip2_init_board(int);
+static unsigned short find_eisa_board(int);
+
+/***************/
+/* Static Data */
+/***************/
+
+static struct tty_driver *ip2_tty_driver;
+
+/* Here, then is a table of board pointers which the interrupt routine should
+ * scan through to determine who it must service.
+ */
+static unsigned short i2nBoards; // Number of boards here
+
+static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
+
+static i2ChanStrPtr  DevTable[IP2_MAX_PORTS];
+//DevTableMem just used to save addresses for kfree
+static void  *DevTableMem[IP2_MAX_BOARDS];
+
+/* This is the driver descriptor for the ip2ipl device, which is used to
+ * download the loadware to the boards.
+ */
+static struct file_operations ip2_ipl = {
+       .owner          = THIS_MODULE,
+       .read           = ip2_ipl_read,
+       .write          = ip2_ipl_write,
+       .ioctl          = ip2_ipl_ioctl,
+       .open           = ip2_ipl_open,
+}; 
+
+static unsigned long irq_counter = 0;
+static unsigned long bh_counter = 0;
+
+// Use immediate queue to service interrupts
+#define USE_IQI
+//#define USE_IQ       // PCI&2.2 needs work
+
+/* The timer_list entry for our poll routine. If interrupt operation is not
+ * selected, the board is serviced periodically to see if anything needs doing.
+ */
+#define  POLL_TIMEOUT   (jiffies + 1)
+static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
+static char  TimerOn;
+
+#ifdef IP2DEBUG_TRACE
+/* Trace (debug) buffer data */
+#define TRACEMAX  1000
+static unsigned long tracebuf[TRACEMAX];
+static int tracestuff;
+static int tracestrip;
+static int tracewrap;
+#endif
+
+/**********/
+/* Macros */
+/**********/
+
+#if defined(MODULE) && defined(IP2DEBUG_OPEN)
+#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \
+                   tty->name,(pCh->flags),ip2_tty_driver->refcount, \
+                   tty->count,/*GET_USE_COUNT(module)*/0,s)
+#else
+#define DBG_CNT(s)
+#endif
+
+/********/
+/* Code */
+/********/
+
+#include "i2ellis.c"    /* Extremely low-level interface services */
+#include "i2cmd.c"      /* Standard loadware command definitions */
+#include "i2lib.c"      /* High level interface services */
+
+/* Configuration area for modprobe */
+
+MODULE_AUTHOR("Doug McNash");
+MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
+
+static int poll_only = 0;
+
+static int Eisa_irq;
+static int Eisa_slot;
+
+static int iindx;
+static char rirqs[IP2_MAX_BOARDS];
+static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
+
+/* for sysfs class support */
+static struct class *ip2_class;
+
+// Some functions to keep track of what irq's we have
+
+static int __init
+is_valid_irq(int irq)
+{
+       int *i = Valid_Irqs;
+       
+       while ((*i != 0) && (*i != irq)) {
+               i++;
+       }
+       return (*i);
+}
+
+static void __init
+mark_requested_irq( char irq )
+{
+       rirqs[iindx++] = irq;
+}
+
+#ifdef MODULE
+static int __init
+clear_requested_irq( char irq )
+{
+       int i;
+       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               if (rirqs[i] == irq) {
+                       rirqs[i] = 0;
+                       return 1;
+               }
+       }
+       return 0;
+}
+#endif
+
+static int __init
+have_requested_irq( char irq )
+{
+       // array init to zeros so 0 irq will not be requested as a side effect
+       int i;
+       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               if (rirqs[i] == irq)
+                       return 1;
+       }
+       return 0;
+}
+
+/******************************************************************************/
+/* Function:   init_module()                                                  */
+/* Parameters: None                                                           */
+/* Returns:    Success (0)                                                    */
+/*                                                                            */
+/* Description:                                                               */
+/* This is a required entry point for an installable module. It simply calls  */
+/* the driver initialisation function and returns what it returns.            */
+/******************************************************************************/
+#ifdef MODULE
+int
+init_module(void)
+{
+#ifdef IP2DEBUG_INIT
+       printk (KERN_DEBUG "Loading module ...\n" );
+#endif
+    return 0;
+}
+#endif /* MODULE */
+
+/******************************************************************************/
+/* Function:   cleanup_module()                                               */
+/* Parameters: None                                                           */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/* This is a required entry point for an installable module. It has to return */
+/* the device and the driver to a passive state. It should not be necessary   */
+/* to reset the board fully, especially as the loadware is downloaded         */
+/* externally rather than in the driver. We just want to disable the board    */
+/* and clear the loadware to a reset state. To allow this there has to be a   */
+/* way to detect whether the board has the loadware running at init time to   */
+/* handle subsequent installations of the driver. All memory allocated by the */
+/* driver should be returned since it may be unloaded from memory.            */
+/******************************************************************************/
+#ifdef MODULE
+void
+cleanup_module(void)
+{
+       int err;
+       int i;
+
+#ifdef IP2DEBUG_INIT
+       printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion );
+#endif
+       /* Stop poll timer if we had one. */
+       if ( TimerOn ) {
+               del_timer ( &PollTimer );
+               TimerOn = 0;
+       }
+
+       /* Reset the boards we have. */
+       for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               if ( i2BoardPtrTable[i] ) {
+                       iiReset( i2BoardPtrTable[i] );
+               }
+       }
+
+       /* The following is done at most once, if any boards were installed. */
+       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               if ( i2BoardPtrTable[i] ) {
+                       iiResetDelay( i2BoardPtrTable[i] );
+                       /* free io addresses and Tibet */
+                       release_region( ip2config.addr[i], 8 );
+                       class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
+                       devfs_remove("ip2/ipl%d", i);
+                       class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
+                       devfs_remove("ip2/stat%d", i);
+               }
+               /* Disable and remove interrupt handler. */
+               if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { 
+                       free_irq ( ip2config.irq[i], (void *)&pcName);
+                       clear_requested_irq( ip2config.irq[i]);
+               }
+       }
+       class_destroy(ip2_class);
+       devfs_remove("ip2");
+       if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
+               printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
+       }
+       put_tty_driver(ip2_tty_driver);
+       if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) {
+               printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err);
+       }
+       remove_proc_entry("ip2mem", &proc_root);
+
+       // free memory
+       for (i = 0; i < IP2_MAX_BOARDS; i++) {
+               void *pB;
+#ifdef CONFIG_PCI
+               if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
+                       pci_disable_device(ip2config.pci_dev[i]);
+                       ip2config.pci_dev[i] = NULL;
+               }
+#endif
+               if ((pB = i2BoardPtrTable[i]) != 0 ) {
+                       kfree ( pB );
+                       i2BoardPtrTable[i] = NULL;
+               }
+               if ((DevTableMem[i]) != NULL ) {
+                       kfree ( DevTableMem[i]  );
+                       DevTableMem[i] = NULL;
+               }
+       }
+
+       /* Cleanup the iiEllis subsystem. */
+       iiEllisCleanup();
+#ifdef IP2DEBUG_INIT
+       printk (KERN_DEBUG "IP2 Unloaded\n" );
+#endif
+}
+#endif /* MODULE */
+
+static struct tty_operations ip2_ops = {
+       .open            = ip2_open,
+       .close           = ip2_close,
+       .write           = ip2_write,
+       .put_char        = ip2_putchar,
+       .flush_chars     = ip2_flush_chars,
+       .write_room      = ip2_write_room,
+       .chars_in_buffer = ip2_chars_in_buf,
+       .flush_buffer    = ip2_flush_buffer,
+       .ioctl           = ip2_ioctl,
+       .throttle        = ip2_throttle,
+       .unthrottle      = ip2_unthrottle,
+       .set_termios     = ip2_set_termios,
+       .set_ldisc       = ip2_set_line_discipline,
+       .stop            = ip2_stop,
+       .start           = ip2_start,
+       .hangup          = ip2_hangup,
+       .read_proc       = ip2_read_proc,
+       .tiocmget        = ip2_tiocmget,
+       .tiocmset        = ip2_tiocmset,
+};
+
+/******************************************************************************/
+/* Function:   ip2_loadmain()                                                 */
+/* Parameters: irq, io from command line of insmod et. al.                    */
+/*             pointer to fip firmware and firmware size for boards          */
+/* Returns:    Success (0)                                                    */
+/*                                                                            */
+/* Description:                                                               */
+/* This was the required entry point for all drivers (now in ip2.c)           */
+/* It performs all                                                            */
+/* initialisation of the devices and driver structures, and registers itself  */
+/* with the relevant kernel modules.                                          */
+/******************************************************************************/
+/* SA_INTERRUPT- if set blocks all interrupts else only this line */
+/* SA_SHIRQ    - for shared irq PCI or maybe EISA only */
+/* SA_RANDOM   - can be source for cert. random number generators */
+#define IP2_SA_FLAGS   0
+
+int
+ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) 
+{
+       int i, j, box;
+       int err = 0;
+       int status = 0;
+       static int loaded;
+       i2eBordStrPtr pB = NULL;
+       int rc = -1;
+
+       ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 );
+
+       /* process command line arguments to modprobe or
+               insmod i.e. iop & irqp */
+       /* irqp and iop should ALWAYS be specified now...  But we check
+               them individually just to be sure, anyways... */
+       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               if (iop) {
+                       ip2config.addr[i] = iop[i];
+                       if (irqp) {
+                               if( irqp[i] >= 0 ) {
+                                       ip2config.irq[i] = irqp[i];
+                               } else {
+                                       ip2config.irq[i] = 0;
+                               }
+       // This is a little bit of a hack.  If poll_only=1 on command
+       // line back in ip2.c OR all IRQs on all specified boards are
+       // explicitly set to 0, then drop to poll only mode and override
+       // PCI or EISA interrupts.  This superceeds the old hack of
+       // triggering if all interrupts were zero (like da default).
+       // Still a hack but less prone to random acts of terrorism.
+       //
+       // What we really should do, now that the IRQ default is set
+       // to -1, is to use 0 as a hard coded, do not probe.
+       //
+       //      /\/\|=mhw=|\/\/
+                               poll_only |= irqp[i];
+                       }
+               }
+       }
+       poll_only = !poll_only;
+
+       Fip_firmware = firmware;
+       Fip_firmware_size = firmsize;
+
+       /* Announce our presence */
+       printk( KERN_INFO "%s version %s\n", pcName, pcVersion );
+
+       // ip2 can be unloaded and reloaded for no good reason
+       // we can't let that happen here or bad things happen
+       // second load hoses board but not system - fixme later
+       if (loaded) {
+               printk( KERN_INFO "Still loaded\n" );
+               return 0;
+       }
+       loaded++;
+
+       ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
+       if (!ip2_tty_driver)
+               return -ENOMEM;
+
+       /* Initialise the iiEllis subsystem. */
+       iiEllisInit();
+
+       /* Initialize arrays. */
+       memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable );
+       memset( DevTable, 0, sizeof DevTable );
+
+       /* Initialise all the boards we can find (up to the maximum). */
+       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               switch ( ip2config.addr[i] ) { 
+               case 0: /* skip this slot even if card is present */
+                       break;
+               default: /* ISA */
+                  /* ISA address must be specified */
+                       if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) {
+                               printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n",
+                                                        i, ip2config.addr[i] );
+                               ip2config.addr[i] = 0;
+                       } else {
+                               ip2config.type[i] = ISA;
+
+                               /* Check for valid irq argument, set for polling if invalid */
+                               if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) {
+                                       printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]);
+                                       ip2config.irq[i] = 0;// 0 is polling and is valid in that sense
+                               }
+                       }
+                       break;
+               case PCI:
+#ifdef CONFIG_PCI
+                       {
+                               struct pci_dev *pci_dev_i = NULL;
+                               pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE,
+                                                         PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
+                               if (pci_dev_i != NULL) {
+                                       unsigned int addr;
+
+                                       if (pci_enable_device(pci_dev_i)) {
+                                               printk( KERN_ERR "IP2: can't enable PCI device at %s\n",
+                                                       pci_name(pci_dev_i));
+                                               break;
+                                       }
+                                       ip2config.type[i] = PCI;
+                                       ip2config.pci_dev[i] = pci_dev_i;
+                                       status =
+                                       pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
+                                       if ( addr & 1 ) {
+                                               ip2config.addr[i]=(USHORT)(addr&0xfffe);
+                                       } else {
+                                               printk( KERN_ERR "IP2: PCI I/O address error\n");
+                                       }
+
+//             If the PCI BIOS assigned it, lets try and use it.  If we
+//             can't acquire it or it screws up, deal with it then.
+
+//                                     if (!is_valid_irq(pci_irq)) {
+//                                             printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
+//                                             pci_irq = 0;
+//                                     }
+                                       ip2config.irq[i] = pci_dev_i->irq;
+                               } else {        // ann error
+                                       ip2config.addr[i] = 0;
+                                       if (status == PCIBIOS_DEVICE_NOT_FOUND) {
+                                               printk( KERN_ERR "IP2: PCI board %d not found\n", i );
+                                       } else {
+                                               printk( KERN_ERR "IP2: PCI error 0x%x \n", status );
+                                       }
+                               } 
+                       }
+#else
+                       printk( KERN_ERR "IP2: PCI card specified but PCI support not\n");
+                       printk( KERN_ERR "IP2: configured in this kernel.\n");
+                       printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n");
+#endif /* CONFIG_PCI */
+                       break;
+               case EISA:
+                       if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) {
+                               /* Eisa_irq set as side effect, boo */
+                               ip2config.type[i] = EISA;
+                       } 
+                       ip2config.irq[i] = Eisa_irq;
+                       break;
+               }       /* switch */
+       }       /* for */
+       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               if ( ip2config.addr[i] ) {
+                       pB = kmalloc( sizeof(i2eBordStr), GFP_KERNEL);
+                       if ( pB != NULL ) {
+                               i2BoardPtrTable[i] = pB;
+                               memset( pB, 0, sizeof(i2eBordStr) );
+                               iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer );
+                               iiReset( pB );
+                       } else {
+                               printk(KERN_ERR "IP2: board memory allocation error\n");
+                       }
+               }
+       }
+       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               if ( ( pB = i2BoardPtrTable[i] ) != NULL ) {
+                       iiResetDelay( pB );
+                       break;
+               }
+       }
+       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               if ( i2BoardPtrTable[i] != NULL ) {
+                       ip2_init_board( i );
+               }
+       }
+
+       ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 );
+
+       ip2_tty_driver->owner               = THIS_MODULE;
+       ip2_tty_driver->name                 = "ttyF";
+       ip2_tty_driver->devfs_name          = "tts/F";
+       ip2_tty_driver->driver_name          = pcDriver_name;
+       ip2_tty_driver->major                = IP2_TTY_MAJOR;
+       ip2_tty_driver->minor_start          = 0;
+       ip2_tty_driver->type                 = TTY_DRIVER_TYPE_SERIAL;
+       ip2_tty_driver->subtype              = SERIAL_TYPE_NORMAL;
+       ip2_tty_driver->init_termios         = tty_std_termios;
+       ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
+       ip2_tty_driver->flags                = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+       tty_set_operations(ip2_tty_driver, &ip2_ops);
+
+       ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 );
+
+       /* Register the tty devices. */
+       if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) {
+               printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err);
+               put_tty_driver(ip2_tty_driver);
+               return -EINVAL;
+       } else
+       /* Register the IPL driver. */
+       if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) {
+               printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
+       } else {
+               /* create the sysfs class */
+               ip2_class = class_create(THIS_MODULE, "ip2");
+               if (IS_ERR(ip2_class)) {
+                       err = PTR_ERR(ip2_class);
+                       goto out_chrdev;        
+               }
+       }
+       /* Register the read_procmem thing */
+       if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) {
+               printk(KERN_ERR "IP2: failed to register read_procmem\n");
+       } else {
+
+       ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 );
+               /* Register the interrupt handler or poll handler, depending upon the
+                * specified interrupt.
+                */
+
+               for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+                       if ( 0 == ip2config.addr[i] ) {
+                               continue;
+                       }
+
+                       if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
+                               class_device_create(ip2_class, NULL,
+                                               MKDEV(IP2_IPL_MAJOR, 4 * i),
+                                               NULL, "ipl%d", i);
+                               err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
+                                               S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
+                                               "ip2/ipl%d", i);
+                               if (err) {
+                                       class_device_destroy(ip2_class,
+                                               MKDEV(IP2_IPL_MAJOR, 4 * i));
+                                       goto out_class;
+                               }
+
+                               class_device_create(ip2_class, NULL,
+                                               MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
+                                               NULL, "stat%d", i);
+                               err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
+                                               S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
+                                               "ip2/stat%d", i);
+                               if (err) {
+                                       class_device_destroy(ip2_class,
+                                               MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
+                                       goto out_class;
+                               }
+
+                           for ( box = 0; box < ABS_MAX_BOXES; ++box )
+                           {
+                               for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
+                               {
+                                   if ( pB->i2eChannelMap[box] & (1 << j) )
+                                   {
+                                       tty_register_device(ip2_tty_driver,
+                                           j + ABS_BIGGEST_BOX *
+                                                   (box+i*ABS_MAX_BOXES), NULL);
+                                   }
+                               }
+                           }
+                       }
+
+                       if (poll_only) {
+//             Poll only forces driver to only use polling and
+//             to ignore the probed PCI or EISA interrupts.
+                               ip2config.irq[i] = CIR_POLL;
+                       }
+                       if ( ip2config.irq[i] == CIR_POLL ) {
+retry:
+                               if (!TimerOn) {
+                                       PollTimer.expires = POLL_TIMEOUT;
+                                       add_timer ( &PollTimer );
+                                       TimerOn = 1;
+                                       printk( KERN_INFO "IP2: polling\n");
+                               }
+                       } else {
+                               if (have_requested_irq(ip2config.irq[i]))
+                                       continue;
+                               rc = request_irq( ip2config.irq[i], ip2_interrupt,
+                                       IP2_SA_FLAGS | (ip2config.type[i] == PCI ? SA_SHIRQ : 0),
+                                       pcName, (void *)&pcName);
+                               if (rc) {
+                                       printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc);
+                                       ip2config.irq[i] = CIR_POLL;
+                                       printk( KERN_INFO "IP2: Polling %ld/sec.\n",
+                                                       (POLL_TIMEOUT - jiffies));
+                                       goto retry;
+                               } 
+                               mark_requested_irq(ip2config.irq[i]);
+                               /* Initialise the interrupt handler bottom half (aka slih). */
+                       }
+               }
+               for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+                       if ( i2BoardPtrTable[i] ) {
+                               set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */
+                       }
+               }
+       }
+       ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 );
+       goto out;
+
+out_class:
+       class_destroy(ip2_class);
+out_chrdev:
+       unregister_chrdev(IP2_IPL_MAJOR, "ip2");
+out:
+       return err;
+}
+
+EXPORT_SYMBOL(ip2_loadmain);
+
+/******************************************************************************/
+/* Function:   ip2_init_board()                                               */
+/* Parameters: Index of board in configuration structure                      */
+/* Returns:    Success (0)                                                    */
+/*                                                                            */
+/* Description:                                                               */
+/* This function initializes the specified board. The loadware is copied to   */
+/* the board, the channel structures are initialized, and the board details   */
+/* are reported on the console.                                               */
+/******************************************************************************/
+static void __init
+ip2_init_board( int boardnum )
+{
+       int i;
+       int nports = 0, nboxes = 0;
+       i2ChanStrPtr pCh;
+       i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
+
+       if ( !iiInitialize ( pB ) ) {
+               printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n",
+                        pB->i2eBase, pB->i2eError );
+               goto err_initialize;
+       }
+       printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1,
+              ip2config.addr[boardnum], ip2config.irq[boardnum] );
+
+       if (!request_region( ip2config.addr[boardnum], 8, pcName )) {
+               printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]);
+               goto err_initialize;
+       }
+
+       if ( iiDownloadAll ( pB, (loadHdrStrPtr)Fip_firmware, 1, Fip_firmware_size )
+           != II_DOWN_GOOD ) {
+               printk ( KERN_ERR "IP2: failed to download loadware\n" );
+               goto err_release_region;
+       } else {
+               printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n",
+                        pB->i2ePom.e.porVersion,
+                        pB->i2ePom.e.porRevision,
+                        pB->i2ePom.e.porSubRev, pB->i2eLVersion,
+                        pB->i2eLRevision, pB->i2eLSub );
+       }
+
+       switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) {
+
+       default:
+               printk( KERN_ERR "IP2: Unknown board type, ID = %x\n",
+                               pB->i2ePom.e.porID );
+               nports = 0;
+               goto err_release_region;
+               break;
+
+       case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */
+               printk ( KERN_INFO "IP2: ISA-4\n" );
+               nports = 4;
+               break;
+
+       case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */
+               printk ( KERN_INFO "IP2: ISA-8 std\n" );
+               nports = 8;
+               break;
+
+       case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
+               printk ( KERN_INFO "IP2: ISA-8 RJ11\n" );
+               nports = 8;
+               break;
+
+       case POR_ID_FIIEX: /* IntelliPort IIEX */
+       {
+               int portnum = IP2_PORTS_PER_BOARD * boardnum;
+               int            box;
+
+               for( box = 0; box < ABS_MAX_BOXES; ++box ) {
+                       if ( pB->i2eChannelMap[box] != 0 ) {
+                               ++nboxes;
+                       }
+                       for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
+                               if ( pB->i2eChannelMap[box] & 1<< i ) {
+                                       ++nports;
+                               }
+                       }
+               }
+               DevTableMem[boardnum] = pCh =
+                       kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL );
+               if ( !pCh ) {
+                       printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
+                       goto err_release_region;
+               }
+               if ( !i2InitChannels( pB, nports, pCh ) ) {
+                       printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
+                       kfree ( pCh );
+                       goto err_release_region;
+               }
+               pB->i2eChannelPtr = &DevTable[portnum];
+               pB->i2eChannelCnt = ABS_MOST_PORTS;
+
+               for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) {
+                       for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
+                               if ( pB->i2eChannelMap[box] & (1 << i) ) {
+                                       DevTable[portnum + i] = pCh;
+                                       pCh->port_index = portnum + i;
+                                       pCh++;
+                               }
+                       }
+               }
+               printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n",
+                       nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 );
+               }
+               goto ex_exit;
+       }
+       DevTableMem[boardnum] = pCh =
+               kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL );
+       if ( !pCh ) {
+               printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
+               goto err_release_region;
+       }
+       pB->i2eChannelPtr = pCh;
+       pB->i2eChannelCnt = nports;
+       if ( !i2InitChannels( pB, nports, pCh ) ) {
+               printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
+               kfree ( pCh );
+               goto err_release_region;
+       }
+       pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum];
+
+       for( i = 0; i < pB->i2eChannelCnt; ++i ) {
+               DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh;
+               pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i;
+               pCh++;
+       }
+ex_exit:
+       INIT_WORK(&pB->tqueue_interrupt, (void(*)(void*)) ip2_interrupt_bh, pB);
+       return;
+
+err_release_region:
+       release_region(ip2config.addr[boardnum], 8);
+err_initialize:
+       kfree ( pB );
+       i2BoardPtrTable[boardnum] = NULL;
+       return;
+}
+
+/******************************************************************************/
+/* Function:   find_eisa_board ( int start_slot )                             */
+/* Parameters: First slot to check                                            */
+/* Returns:    Address of EISA IntelliPort II controller                      */
+/*                                                                            */
+/* Description:                                                               */
+/* This function searches for an EISA IntelliPort controller, starting        */
+/* from the specified slot number. If the motherboard is not identified as an */
+/* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */
+/* it returns the base address of the controller.                             */
+/******************************************************************************/
+static unsigned short __init
+find_eisa_board( int start_slot )
+{
+       int i, j;
+       unsigned int idm = 0;
+       unsigned int idp = 0;
+       unsigned int base = 0;
+       unsigned int value;
+       int setup_address;
+       int setup_irq;
+       int ismine = 0;
+
+       /*
+        * First a check for an EISA motherboard, which we do by comparing the
+        * EISA ID registers for the system board and the first couple of slots.
+        * No slot ID should match the system board ID, but on an ISA or PCI
+        * machine the odds are that an empty bus will return similar values for
+        * each slot.
+        */
+       i = 0x0c80;
+       value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3);
+       for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) {
+               j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3);
+               if ( value == j )
+                       return 0;
+       }
+
+       /*
+        * OK, so we are inclined to believe that this is an EISA machine. Find
+        * an IntelliPort controller.
+        */
+       for( i = start_slot; i < 16; i++ ) {
+               base = i << 12;
+               idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff);
+               idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff);
+               ismine = 0;
+               if ( idm == 0x0e8e ) {
+                       if ( idp == 0x0281 || idp == 0x0218 ) {
+                               ismine = 1;
+                       } else if ( idp == 0x0282 || idp == 0x0283 ) {
+                               ismine = 3;     /* Can do edge-trigger */
+                       }
+                       if ( ismine ) {
+                               Eisa_slot = i;
+                               break;
+                       }
+               }
+       }
+       if ( !ismine )
+               return 0;
+
+       /* It's some sort of EISA card, but at what address is it configured? */
+
+       setup_address = base + 0xc88;
+       value = inb(base + 0xc86);
+       setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0;
+
+       if ( (ismine & 2) && !(value & 0x10) ) {
+               ismine = 1;     /* Could be edging, but not */
+       }
+
+       if ( Eisa_irq == 0 ) {
+               Eisa_irq = setup_irq;
+       } else if ( Eisa_irq != setup_irq ) {
+               printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" );
+       }
+
+#ifdef IP2DEBUG_INIT
+printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
+              base >> 12, idm, idp, setup_address);
+       if ( Eisa_irq ) {
+               printk(KERN_DEBUG ", Interrupt %d %s\n",
+                      setup_irq, (ismine & 2) ? "(edge)" : "(level)");
+       } else {
+               printk(KERN_DEBUG ", (polled)\n");
+       }
+#endif
+       return setup_address;
+}
+
+/******************************************************************************/
+/* Function:   set_irq()                                                      */
+/* Parameters: index to board in board table                                  */
+/*             IRQ to use                                                     */
+/* Returns:    Success (0)                                                    */
+/*                                                                            */
+/* Description:                                                               */
+/******************************************************************************/
+static void
+set_irq( int boardnum, int boardIrq )
+{
+       unsigned char tempCommand[16];
+       i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
+       unsigned long flags;
+
+       /*
+        * Notify the boards they may generate interrupts. This is done by
+        * sending an in-line command to channel 0 on each board. This is why
+        * the channels have to be defined already. For each board, if the
+        * interrupt has never been defined, we must do so NOW, directly, since
+        * board will not send flow control or even give an interrupt until this
+        * is done.  If polling we must send 0 as the interrupt parameter.
+        */
+
+       // We will get an interrupt here at the end of this function
+
+       iiDisableMailIrq(pB);
+
+       /* We build up the entire packet header. */
+       CHANNEL_OF(tempCommand) = 0;
+       PTYPE_OF(tempCommand) = PTYPE_INLINE;
+       CMD_COUNT_OF(tempCommand) = 2;
+       (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ;
+       (CMD_OF(tempCommand))[1] = boardIrq;
+       /*
+        * Write to FIFO; don't bother to adjust fifo capacity for this, since
+        * board will respond almost immediately after SendMail hit.
+        */
+       WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+       iiWriteBuf(pB, tempCommand, 4);
+       WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+       pB->i2eUsingIrq = boardIrq;
+       pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
+
+       /* Need to update number of boards before you enable mailbox int */
+       ++i2nBoards;
+
+       CHANNEL_OF(tempCommand) = 0;
+       PTYPE_OF(tempCommand) = PTYPE_BYPASS;
+       CMD_COUNT_OF(tempCommand) = 6;
+       (CMD_OF(tempCommand))[0] = 88;  // SILO
+       (CMD_OF(tempCommand))[1] = 64;  // chars
+       (CMD_OF(tempCommand))[2] = 32;  // ms
+
+       (CMD_OF(tempCommand))[3] = 28;  // MAX_BLOCK
+       (CMD_OF(tempCommand))[4] = 64;  // chars
+
+       (CMD_OF(tempCommand))[5] = 87;  // HW_TEST
+       WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+       iiWriteBuf(pB, tempCommand, 8);
+       WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+
+       CHANNEL_OF(tempCommand) = 0;
+       PTYPE_OF(tempCommand) = PTYPE_BYPASS;
+       CMD_COUNT_OF(tempCommand) = 1;
+       (CMD_OF(tempCommand))[0] = 84;  /* get BOX_IDS */
+       iiWriteBuf(pB, tempCommand, 3);
+
+#ifdef XXX
+       // enable heartbeat for test porpoises
+       CHANNEL_OF(tempCommand) = 0;
+       PTYPE_OF(tempCommand) = PTYPE_BYPASS;
+       CMD_COUNT_OF(tempCommand) = 2;
+       (CMD_OF(tempCommand))[0] = 44;  /* get ping */
+       (CMD_OF(tempCommand))[1] = 200; /* 200 ms */
+       WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+       iiWriteBuf(pB, tempCommand, 4);
+       WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+#endif
+
+       iiEnableMailIrq(pB);
+       iiSendPendingMail(pB);
+}
+
+/******************************************************************************/
+/* Interrupt Handler Section                                                  */
+/******************************************************************************/
+
+static inline void
+service_all_boards(void)
+{
+       int i;
+       i2eBordStrPtr  pB;
+
+       /* Service every board on the list */
+       for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               pB = i2BoardPtrTable[i];
+               if ( pB ) {
+                       i2ServiceBoard( pB );
+               }
+       }
+}
+
+
+/******************************************************************************/
+/* Function:   ip2_interrupt_bh(pB)                                           */
+/* Parameters: pB - pointer to the board structure                            */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/*     Service the board in a bottom half interrupt handler and then         */
+/*     reenable the board's interrupts if it has an IRQ number               */
+/*                                                                            */
+/******************************************************************************/
+static void
+ip2_interrupt_bh(i2eBordStrPtr pB)
+{
+//     pB better well be set or we have a problem!  We can only get
+//     here from the IMMEDIATE queue.  Here, we process the boards.
+//     Checking pB doesn't cost much and it saves us from the sanity checkers.
+
+       bh_counter++; 
+
+       if ( pB ) {
+               i2ServiceBoard( pB );
+               if( pB->i2eUsingIrq ) {
+//                     Re-enable his interrupts
+                       iiEnableMailIrq(pB);
+               }
+       }
+}
+
+
+/******************************************************************************/
+/* Function:   ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs)    */
+/* Parameters: irq - interrupt number                                         */
+/*             pointer to optional device ID structure                        */
+/*             pointer to register structure                                  */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*     Our task here is simply to identify each board which needs servicing. */
+/*     If we are queuing then, queue it to be serviced, and disable its irq  */
+/*     mask otherwise process the board directly.                            */
+/*                                                                            */
+/*     We could queue by IRQ but that just complicates things on both ends   */
+/*     with very little gain in performance (how many instructions does      */
+/*     it take to iterate on the immediate queue).                           */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static irqreturn_t
+ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+       int i;
+       i2eBordStrPtr  pB;
+       int handled = 0;
+
+       ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq );
+
+       /* Service just the boards on the list using this irq */
+       for( i = 0; i < i2nBoards; ++i ) {
+               pB = i2BoardPtrTable[i];
+
+//             Only process those boards which match our IRQ.
+//                     IRQ = 0 for polled boards, we won't poll "IRQ" boards
+
+               if ( pB && (pB->i2eUsingIrq == irq) ) {
+                       handled = 1;
+#ifdef USE_IQI
+
+                   if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) {
+//                     Disable his interrupt (will be enabled when serviced)
+//                     This is mostly to protect from reentrancy.
+                       iiDisableMailIrq(pB);
+
+//                     Park the board on the immediate queue for processing.
+                       schedule_work(&pB->tqueue_interrupt);
+
+//                     Make sure the immediate queue is flagged to fire.
+                   }
+#else
+//             We are using immediate servicing here.  This sucks and can
+//             cause all sorts of havoc with ppp and others.  The failsafe
+//             check on iiSendPendingMail could also throw a hairball.
+                       i2ServiceBoard( pB );
+#endif /* USE_IQI */
+               }
+       }
+
+       ++irq_counter;
+
+       ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
+       return IRQ_RETVAL(handled);
+}
+
+/******************************************************************************/
+/* Function:   ip2_poll(unsigned long arg)                                    */
+/* Parameters: ?                                                              */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/* This function calls the library routine i2ServiceBoard for each board in   */
+/* the board table. This is used instead of the interrupt routine when polled */
+/* mode is specified.                                                         */
+/******************************************************************************/
+static void
+ip2_poll(unsigned long arg)
+{
+       ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
+
+       TimerOn = 0; // it's the truth but not checked in service
+
+       // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
+       // It will NOT poll boards handled by hard interrupts.
+       // The issue of queued BH interrups is handled in ip2_interrupt().
+       ip2_interrupt(0, NULL, NULL);
+
+       PollTimer.expires = POLL_TIMEOUT;
+       add_timer( &PollTimer );
+       TimerOn = 1;
+
+       ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
+}
+
+static void do_input(void *p)
+{
+       i2ChanStrPtr pCh = p;
+       unsigned long flags;
+
+       ip2trace(CHANN, ITRC_INPUT, 21, 0 );
+
+       // Data input
+       if ( pCh->pTTY != NULL ) {
+               READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
+               if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {
+                       READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+                       i2Input( pCh );
+               } else
+                       READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+       } else {
+               ip2trace(CHANN, ITRC_INPUT, 22, 0 );
+
+               i2InputFlush( pCh );
+       }
+}
+
+// code duplicated from n_tty (ldisc)
+static inline void  isig(int sig, struct tty_struct *tty, int flush)
+{
+       if (tty->pgrp > 0)
+               kill_pg(tty->pgrp, sig, 1);
+       if (flush || !L_NOFLSH(tty)) {
+               if ( tty->ldisc.flush_buffer )  
+                       tty->ldisc.flush_buffer(tty);
+               i2InputFlush( tty->driver_data );
+       }
+}
+
+static void do_status(void *p)
+{
+       i2ChanStrPtr pCh = p;
+       int status;
+
+       status =  i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
+
+       ip2trace (CHANN, ITRC_STATUS, 21, 1, status );
+
+       if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) {
+               if ( (status & I2_BRK) ) {
+                       // code duplicated from n_tty (ldisc)
+                       if (I_IGNBRK(pCh->pTTY))
+                               goto skip_this;
+                       if (I_BRKINT(pCh->pTTY)) {
+                               isig(SIGINT, pCh->pTTY, 1);
+                               goto skip_this;
+                       }
+                       wake_up_interruptible(&pCh->pTTY->read_wait);
+               }
+#ifdef NEVER_HAPPENS_AS_SETUP_XXX
+       // and can't work because we don't know the_char
+       // as the_char is reported on a separate path
+       // The intelligent board does this stuff as setup
+       {
+       char brkf = TTY_NORMAL;
+       unsigned char brkc = '\0';
+       unsigned char tmp;
+               if ( (status & I2_BRK) ) {
+                       brkf = TTY_BREAK;
+                       brkc = '\0';
+               } 
+               else if (status & I2_PAR) {
+                       brkf = TTY_PARITY;
+                       brkc = the_char;
+               } else if (status & I2_FRA) {
+                       brkf = TTY_FRAME;
+                       brkc = the_char;
+               } else if (status & I2_OVR) {
+                       brkf = TTY_OVERRUN;
+                       brkc = the_char;
+               }
+               tmp = pCh->pTTY->real_raw;
+               pCh->pTTY->real_raw = 0;
+               pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
+               pCh->pTTY->real_raw = tmp;
+       }
+#endif /* NEVER_HAPPENS_AS_SETUP_XXX */
+       }
+skip_this:
+
+       if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {
+               wake_up_interruptible(&pCh->delta_msr_wait);
+
+               if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {
+                       if ( status & I2_DCD ) {
+                               if ( pCh->wopen ) {
+                                       wake_up_interruptible ( &pCh->open_wait );
+                               }
+                       } else {
+                               if (pCh->pTTY &&  (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
+                                       tty_hangup( pCh->pTTY );
+                               }
+                       }
+               }
+       }
+
+       ip2trace (CHANN, ITRC_STATUS, 26, 0 );
+}
+
+/******************************************************************************/
+/* Device Open/Close/Ioctl Entry Point Section                                */
+/******************************************************************************/
+
+/******************************************************************************/
+/* Function:   open_sanity_check()                                            */
+/* Parameters: Pointer to tty structure                                       */
+/*             Pointer to file structure                                      */
+/* Returns:    Success or failure                                             */
+/*                                                                            */
+/* Description:                                                               */
+/* Verifies the structure magic numbers and cross links.                      */
+/******************************************************************************/
+#ifdef IP2DEBUG_OPEN
+static void 
+open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd )
+{
+       if ( pBrd->i2eValid != I2E_MAGIC ) {
+               printk(KERN_ERR "IP2: invalid board structure\n" );
+       } else if ( pBrd != pCh->pMyBord ) {
+               printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n",
+                        pCh->pMyBord );
+       } else if ( pBrd->i2eChannelCnt < pCh->port_index ) {
+               printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index );
+       } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) {
+       } else {
+               printk(KERN_INFO "IP2: all pointers check out!\n" );
+       }
+}
+#endif
+
+
+/******************************************************************************/
+/* Function:   ip2_open()                                                     */
+/* Parameters: Pointer to tty structure                                       */
+/*             Pointer to file structure                                      */
+/* Returns:    Success or failure                                             */
+/*                                                                            */
+/* Description: (MANDATORY)                                                   */
+/* A successful device open has to run a gauntlet of checks before it         */
+/* completes. After some sanity checking and pointer setup, the function      */
+/* blocks until all conditions are satisfied. It then initialises the port to */
+/* the default characteristics and returns.                                   */
+/******************************************************************************/
+static int
+ip2_open( PTTY tty, struct file *pFile )
+{
+       wait_queue_t wait;
+       int rc = 0;
+       int do_clocal = 0;
+       i2ChanStrPtr  pCh = DevTable[tty->index];
+
+       ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 );
+
+       if ( pCh == NULL ) {
+               return -ENODEV;
+       }
+       /* Setup pointer links in device and tty structures */
+       pCh->pTTY = tty;
+       tty->driver_data = pCh;
+
+#ifdef IP2DEBUG_OPEN
+       printk(KERN_DEBUG \
+                       "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n",
+              tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index);
+       open_sanity_check ( pCh, pCh->pMyBord );
+#endif
+
+       i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP);
+       pCh->dataSetOut |= (I2_DTR | I2_RTS);
+       serviceOutgoingFifo( pCh->pMyBord );
+
+       /* Block here until the port is ready (per serial and istallion) */
+       /*
+        * 1. If the port is in the middle of closing wait for the completion
+        *    and then return the appropriate error.
+        */
+       init_waitqueue_entry(&wait, current);
+       add_wait_queue(&pCh->close_wait, &wait);
+       set_current_state( TASK_INTERRUPTIBLE );
+
+       if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {
+               if ( pCh->flags & ASYNC_CLOSING ) {
+                       schedule();
+               }
+               if ( tty_hung_up_p(pFile) ) {
+                       set_current_state( TASK_RUNNING );
+                       remove_wait_queue(&pCh->close_wait, &wait);
+                       return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS;
+               }
+       }
+       set_current_state( TASK_RUNNING );
+       remove_wait_queue(&pCh->close_wait, &wait);
+
+       /*
+        * 3. Handle a non-blocking open of a normal port.
+        */
+       if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
+               pCh->flags |= ASYNC_NORMAL_ACTIVE;
+               goto noblock;
+       }
+       /*
+        * 4. Now loop waiting for the port to be free and carrier present
+        *    (if required).
+        */
+       if ( tty->termios->c_cflag & CLOCAL )
+               do_clocal = 1;
+
+#ifdef IP2DEBUG_OPEN
+       printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
+#endif
+
+       ++pCh->wopen;
+
+       init_waitqueue_entry(&wait, current);
+       add_wait_queue(&pCh->open_wait, &wait);
+
+       for(;;) {
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
+               pCh->dataSetOut |= (I2_DTR | I2_RTS);
+               set_current_state( TASK_INTERRUPTIBLE );
+               serviceOutgoingFifo( pCh->pMyBord );
+               if ( tty_hung_up_p(pFile) ) {
+                       set_current_state( TASK_RUNNING );
+                       remove_wait_queue(&pCh->open_wait, &wait);
+                       return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS;
+               }
+               if (!(pCh->flags & ASYNC_CLOSING) && 
+                               (do_clocal || (pCh->dataSetIn & I2_DCD) )) {
+                       rc = 0;
+                       break;
+               }
+
+#ifdef IP2DEBUG_OPEN
+               printk(KERN_DEBUG "ASYNC_CLOSING = %s\n",
+                       (pCh->flags & ASYNC_CLOSING)?"True":"False");
+               printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n");
+#endif
+               ip2trace (CHANN, ITRC_OPEN, 3, 2, 0,
+                               (pCh->flags & ASYNC_CLOSING) );
+               /* check for signal */
+               if (signal_pending(current)) {
+                       rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS);
+                       break;
+               }
+               schedule();
+       }
+       set_current_state( TASK_RUNNING );
+       remove_wait_queue(&pCh->open_wait, &wait);
+
+       --pCh->wopen; //why count?
+
+       ip2trace (CHANN, ITRC_OPEN, 4, 0 );
+
+       if (rc != 0 ) {
+               return rc;
+       }
+       pCh->flags |= ASYNC_NORMAL_ACTIVE;
+
+noblock:
+
+       /* first open - Assign termios structure to port */
+       if ( tty->count == 1 ) {
+               i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
+               /* Now we must send the termios settings to the loadware */
+               set_params( pCh, NULL );
+       }
+
+       /*
+        * Now set any i2lib options. These may go away if the i2lib code ends
+        * up rolled into the mainline.
+        */
+       pCh->channelOptions |= CO_NBLOCK_WRITE;
+
+#ifdef IP2DEBUG_OPEN
+       printk (KERN_DEBUG "IP2: open completed\n" );
+#endif
+       serviceOutgoingFifo( pCh->pMyBord );
+
+       ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );
+
+       return 0;
+}
+
+/******************************************************************************/
+/* Function:   ip2_close()                                                    */
+/* Parameters: Pointer to tty structure                                       */
+/*             Pointer to file structure                                      */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static void
+ip2_close( PTTY tty, struct file *pFile )
+{
+       i2ChanStrPtr  pCh = tty->driver_data;
+
+       if ( !pCh ) {
+               return;
+       }
+
+       ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );
+
+#ifdef IP2DEBUG_OPEN
+       printk(KERN_DEBUG "IP2:close %s:\n",tty->name);
+#endif
+
+       if ( tty_hung_up_p ( pFile ) ) {
+
+               ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );
+
+               return;
+       }
+       if ( tty->count > 1 ) { /* not the last close */
+
+               ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );
+
+               return;
+       }
+       pCh->flags |= ASYNC_CLOSING;    // last close actually
+
+       tty->closing = 1;
+
+       if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {
+               /*
+                * Before we drop DTR, make sure the transmitter has completely drained.
+                * This uses an timeout, after which the close
+                * completes.
+                */
+               ip2_wait_until_sent(tty, pCh->ClosingWaitTime );
+       }
+       /*
+        * At this point we stop accepting input. Here we flush the channel
+        * input buffer which will allow the board to send up more data. Any
+        * additional input is tossed at interrupt/poll time.
+        */
+       i2InputFlush( pCh );
+
+       /* disable DSS reporting */
+       i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
+                               CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
+       if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
+               pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
+               i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
+       }
+
+       serviceOutgoingFifo ( pCh->pMyBord );
+
+       if ( tty->driver->flush_buffer ) 
+               tty->driver->flush_buffer(tty);
+       if ( tty->ldisc.flush_buffer )  
+               tty->ldisc.flush_buffer(tty);
+       tty->closing = 0;
+       
+       pCh->pTTY = NULL;
+
+       if (pCh->wopen) {
+               if (pCh->ClosingDelay) {
+                       msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
+               }
+               wake_up_interruptible(&pCh->open_wait);
+       }
+
+       pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+       wake_up_interruptible(&pCh->close_wait);
+
+#ifdef IP2DEBUG_OPEN
+       DBG_CNT("ip2_close: after wakeups--");
+#endif
+
+
+       ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
+
+       return;
+}
+
+/******************************************************************************/
+/* Function:   ip2_hangup()                                                   */
+/* Parameters: Pointer to tty structure                                       */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static void
+ip2_hangup ( PTTY tty )
+{
+       i2ChanStrPtr  pCh = tty->driver_data;
+
+       if( !pCh ) {
+               return;
+       }
+
+       ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
+
+       ip2_flush_buffer(tty);
+
+       /* disable DSS reporting */
+
+       i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP);
+       i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
+       if ( (tty->termios->c_cflag & HUPCL) ) {
+               i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN);
+               pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
+               i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
+       }
+       i2QueueCommands(PTYPE_INLINE, pCh, 1, 3, 
+                               CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
+       serviceOutgoingFifo ( pCh->pMyBord );
+
+       wake_up_interruptible ( &pCh->delta_msr_wait );
+
+       pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
+       pCh->pTTY = NULL;
+       wake_up_interruptible ( &pCh->open_wait );
+
+       ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
+}
+
+/******************************************************************************/
+/******************************************************************************/
+/* Device Output Section                                                      */
+/******************************************************************************/
+/******************************************************************************/
+
+/******************************************************************************/
+/* Function:   ip2_write()                                                    */
+/* Parameters: Pointer to tty structure                                       */
+/*             Flag denoting data is in user (1) or kernel (0) space          */
+/*             Pointer to data                                                */
+/*             Number of bytes to write                                       */
+/* Returns:    Number of bytes actually written                               */
+/*                                                                            */
+/* Description: (MANDATORY)                                                   */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static int
+ip2_write( PTTY tty, const unsigned char *pData, int count)
+{
+       i2ChanStrPtr  pCh = tty->driver_data;
+       int bytesSent = 0;
+       unsigned long flags;
+
+       ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
+
+       /* Flush out any buffered data left over from ip2_putchar() calls. */
+       ip2_flush_chars( tty );
+
+       /* This is the actual move bit. Make sure it does what we need!!!!! */
+       WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+       bytesSent = i2Output( pCh, pData, count, 0 );
+       WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+
+       ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
+
+       return bytesSent > 0 ? bytesSent : 0;
+}
+
+/******************************************************************************/
+/* Function:   ip2_putchar()                                                  */
+/* Parameters: Pointer to tty structure                                       */
+/*             Character to write                                             */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static void
+ip2_putchar( PTTY tty, unsigned char ch )
+{
+       i2ChanStrPtr  pCh = tty->driver_data;
+       unsigned long flags;
+
+//     ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
+
+       WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+       pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
+       if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
+               WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+               ip2_flush_chars( tty );
+       } else
+               WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+
+//     ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
+}
+
+/******************************************************************************/
+/* Function:   ip2_flush_chars()                                              */
+/* Parameters: Pointer to tty structure                                       */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/******************************************************************************/
+static void
+ip2_flush_chars( PTTY tty )
+{
+       int   strip;
+       i2ChanStrPtr  pCh = tty->driver_data;
+       unsigned long flags;
+
+       WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+       if ( pCh->Pbuf_stuff ) {
+
+//             ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
+
+               //
+               // We may need to restart i2Output if it does not fullfill this request
+               //
+               strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff, 0 );
+               if ( strip != pCh->Pbuf_stuff ) {
+                       memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
+               }
+               pCh->Pbuf_stuff -= strip;
+       }
+       WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+}
+
+/******************************************************************************/
+/* Function:   ip2_write_room()                                               */
+/* Parameters: Pointer to tty structure                                       */
+/* Returns:    Number of bytes that the driver can accept                     */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/******************************************************************************/
+static int
+ip2_write_room ( PTTY tty )
+{
+       int bytesFree;
+       i2ChanStrPtr  pCh = tty->driver_data;
+       unsigned long flags;
+
+       READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+       bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
+       READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+
+       ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
+
+       return ((bytesFree > 0) ? bytesFree : 0);
+}
+
+/******************************************************************************/
+/* Function:   ip2_chars_in_buf()                                             */
+/* Parameters: Pointer to tty structure                                       */
+/* Returns:    Number of bytes queued for transmission                        */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static int
+ip2_chars_in_buf ( PTTY tty )
+{
+       i2ChanStrPtr  pCh = tty->driver_data;
+       int rc;
+       unsigned long flags;
+
+       ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
+
+#ifdef IP2DEBUG_WRITE
+       printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n",
+                                pCh->Obuf_char_count + pCh->Pbuf_stuff,
+                                pCh->Obuf_char_count, pCh->Pbuf_stuff );
+#endif
+       READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
+       rc =  pCh->Obuf_char_count;
+       READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
+       READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+       rc +=  pCh->Pbuf_stuff;
+       READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+       return rc;
+}
+
+/******************************************************************************/
+/* Function:   ip2_flush_buffer()                                             */
+/* Parameters: Pointer to tty structure                                       */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static void
+ip2_flush_buffer( PTTY tty )
+{
+       i2ChanStrPtr  pCh = tty->driver_data;
+       unsigned long flags;
+
+       ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
+
+#ifdef IP2DEBUG_WRITE
+       printk (KERN_DEBUG "IP2: flush buffer\n" );
+#endif
+       WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+       pCh->Pbuf_stuff = 0;
+       WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+       i2FlushOutput( pCh );
+       ip2_owake(tty);
+
+       ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
+
+}
+
+/******************************************************************************/
+/* Function:   ip2_wait_until_sent()                                          */
+/* Parameters: Pointer to tty structure                                       */
+/*             Timeout for wait.                                              */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/* This function is used in place of the normal tty_wait_until_sent, which    */
+/* only waits for the driver buffers to be empty (or rather, those buffers    */
+/* reported by chars_in_buffer) which doesn't work for IP2 due to the         */
+/* indeterminate number of bytes buffered on the board.                       */
+/******************************************************************************/
+static void
+ip2_wait_until_sent ( PTTY tty, int timeout )
+{
+       int i = jiffies;
+       i2ChanStrPtr  pCh = tty->driver_data;
+
+       tty_wait_until_sent(tty, timeout );
+       if ( (i = timeout - (jiffies -i)) > 0)
+               i2DrainOutput( pCh, i );
+}
+
+/******************************************************************************/
+/******************************************************************************/
+/* Device Input Section                                                       */
+/******************************************************************************/
+/******************************************************************************/
+
+/******************************************************************************/
+/* Function:   ip2_throttle()                                                 */
+/* Parameters: Pointer to tty structure                                       */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static void
+ip2_throttle ( PTTY tty )
+{
+       i2ChanStrPtr  pCh = tty->driver_data;
+
+#ifdef IP2DEBUG_READ
+       printk (KERN_DEBUG "IP2: throttle\n" );
+#endif
+       /*
+        * Signal the poll/interrupt handlers not to forward incoming data to
+        * the line discipline. This will cause the buffers to fill up in the
+        * library and thus cause the library routines to send the flow control
+        * stuff.
+        */
+       pCh->throttled = 1;
+}
+
+/******************************************************************************/
+/* Function:   ip2_unthrottle()                                               */
+/* Parameters: Pointer to tty structure                                       */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static void
+ip2_unthrottle ( PTTY tty )
+{
+       i2ChanStrPtr  pCh = tty->driver_data;
+       unsigned long flags;
+
+#ifdef IP2DEBUG_READ
+       printk (KERN_DEBUG "IP2: unthrottle\n" );
+#endif
+
+       /* Pass incoming data up to the line discipline again. */
+       pCh->throttled = 0;
+       i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
+       serviceOutgoingFifo( pCh->pMyBord );
+       READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
+       if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
+               READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+#ifdef IP2DEBUG_READ
+               printk (KERN_DEBUG "i2Input called from unthrottle\n" );
+#endif
+               i2Input( pCh );
+       } else
+               READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+}
+
+static void
+ip2_start ( PTTY tty )
+{
+       i2ChanStrPtr  pCh = DevTable[tty->index];
+
+       i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
+       i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND);
+       i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME);
+#ifdef IP2DEBUG_WRITE
+       printk (KERN_DEBUG "IP2: start tx\n" );
+#endif
+}
+
+static void
+ip2_stop ( PTTY tty )
+{
+       i2ChanStrPtr  pCh = DevTable[tty->index];
+
+       i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
+#ifdef IP2DEBUG_WRITE
+       printk (KERN_DEBUG "IP2: stop tx\n" );
+#endif
+}
+
+/******************************************************************************/
+/* Device Ioctl Section                                                       */
+/******************************************************************************/
+
+static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
+{
+       i2ChanStrPtr pCh = DevTable[tty->index];
+#ifdef ENABLE_DSSNOW
+       wait_queue_t wait;
+#endif
+
+       if (pCh == NULL)
+               return -ENODEV;
+
+/*
+       FIXME - the following code is causing a NULL pointer dereference in
+       2.3.51 in an interrupt handler.  It's suppose to prompt the board
+       to return the DSS signal status immediately.  Why doesn't it do
+       the same thing in 2.2.14?
+*/
+
+/*     This thing is still busted in the 1.2.12 driver on 2.4.x
+       and even hoses the serial console so the oops can be trapped.
+               /\/\|=mhw=|\/\/                 */
+
+#ifdef ENABLE_DSSNOW
+       i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
+
+       init_waitqueue_entry(&wait, current);
+       add_wait_queue(&pCh->dss_now_wait, &wait);
+       set_current_state( TASK_INTERRUPTIBLE );
+
+       serviceOutgoingFifo( pCh->pMyBord );
+
+       schedule();
+
+       set_current_state( TASK_RUNNING );
+       remove_wait_queue(&pCh->dss_now_wait, &wait);
+
+       if (signal_pending(current)) {
+               return -EINTR;
+       }
+#endif
+       return  ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
+             | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
+             | ((pCh->dataSetIn  & I2_DCD) ? TIOCM_CAR : 0)
+             | ((pCh->dataSetIn  & I2_RI)  ? TIOCM_RNG : 0)
+             | ((pCh->dataSetIn  & I2_DSR) ? TIOCM_DSR : 0)
+             | ((pCh->dataSetIn  & I2_CTS) ? TIOCM_CTS : 0);
+}
+
+static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
+                       unsigned int set, unsigned int clear)
+{
+       i2ChanStrPtr pCh = DevTable[tty->index];
+
+       if (pCh == NULL)
+               return -ENODEV;
+
+       if (set & TIOCM_RTS) {
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
+               pCh->dataSetOut |= I2_RTS;
+       }
+       if (set & TIOCM_DTR) {
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
+               pCh->dataSetOut |= I2_DTR;
+       }
+
+       if (clear & TIOCM_RTS) {
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
+               pCh->dataSetOut &= ~I2_RTS;
+       }
+       if (clear & TIOCM_DTR) {
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
+               pCh->dataSetOut &= ~I2_DTR;
+       }
+       serviceOutgoingFifo( pCh->pMyBord );
+       return 0;
+}
+
+/******************************************************************************/
+/* Function:   ip2_ioctl()                                                    */
+/* Parameters: Pointer to tty structure                                       */
+/*             Pointer to file structure                                      */
+/*             Command                                                        */
+/*             Argument                                                       */
+/* Returns:    Success or failure                                             */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static int
+ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
+{
+       wait_queue_t wait;
+       i2ChanStrPtr pCh = DevTable[tty->index];
+       i2eBordStrPtr pB;
+       struct async_icount cprev, cnow;        /* kernel counter temps */
+       struct serial_icounter_struct __user *p_cuser;
+       int rc = 0;
+       unsigned long flags;
+       void __user *argp = (void __user *)arg;
+
+       if ( pCh == NULL )
+               return -ENODEV;
+
+       pB = pCh->pMyBord;
+
+       ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
+
+#ifdef IP2DEBUG_IOCTL
+       printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
+#endif
+
+       switch(cmd) {
+       case TIOCGSERIAL:
+
+               ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
+
+               rc = get_serial_info(pCh, argp);
+               if (rc)
+                       return rc;
+               break;
+
+       case TIOCSSERIAL:
+
+               ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
+
+               rc = set_serial_info(pCh, argp);
+               if (rc)
+                       return rc;
+               break;
+
+       case TCXONC:
+               rc = tty_check_change(tty);
+               if (rc)
+                       return rc;
+               switch (arg) {
+               case TCOOFF:
+                       //return  -ENOIOCTLCMD;
+                       break;
+               case TCOON:
+                       //return  -ENOIOCTLCMD;
+                       break;
+               case TCIOFF:
+                       if (STOP_CHAR(tty) != __DISABLED_CHAR) {
+                               i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
+                                               CMD_XMIT_NOW(STOP_CHAR(tty)));
+                       }
+                       break;
+               case TCION:
+                       if (START_CHAR(tty) != __DISABLED_CHAR) {
+                               i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
+                                               CMD_XMIT_NOW(START_CHAR(tty)));
+                       }
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               return 0;
+
+       case TCSBRK:   /* SVID version: non-zero arg --> no break */
+               rc = tty_check_change(tty);
+
+               ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
+
+               if (!rc) {
+                       ip2_wait_until_sent(tty,0);
+                       if (!arg) {
+                               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
+                               serviceOutgoingFifo( pCh->pMyBord );
+                       }
+               }
+               break;
+
+       case TCSBRKP:  /* support for POSIX tcsendbreak() */
+               rc = tty_check_change(tty);
+
+               ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc );
+
+               if (!rc) {
+                       ip2_wait_until_sent(tty,0);
+                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
+                               CMD_SEND_BRK(arg ? arg*100 : 250));
+                       serviceOutgoingFifo ( pCh->pMyBord );   
+               }
+               break;
+
+       case TIOCGSOFTCAR:
+
+               ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
+
+                       rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
+               if (rc) 
+                       return rc;
+       break;
+
+       case TIOCSSOFTCAR:
+
+               ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
+
+               rc = get_user(arg,(unsigned long __user *) argp);
+               if (rc) 
+                       return rc;
+               tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
+                                        | (arg ? CLOCAL : 0));
+               
+               break;
+
+       /*
+        * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
+        * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
+        * for masking). Caller should use TIOCGICOUNT to see which one it was
+        */
+       case TIOCMIWAIT:
+               WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
+               cprev = pCh->icount;     /* note the counters on entry */
+               WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
+               i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4, 
+                                               CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
+               init_waitqueue_entry(&wait, current);
+               add_wait_queue(&pCh->delta_msr_wait, &wait);
+               set_current_state( TASK_INTERRUPTIBLE );
+
+               serviceOutgoingFifo( pCh->pMyBord );
+               for(;;) {
+                       ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
+
+                       schedule();
+
+                       ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
+
+                       /* see if a signal did it */
+                       if (signal_pending(current)) {
+                               rc = -ERESTARTSYS;
+                               break;
+                       }
+                       WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
+                       cnow = pCh->icount; /* atomic copy */
+                       WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
+                       if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+                               cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
+                               rc =  -EIO; /* no change => rc */
+                               break;
+                       }
+                       if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+                           ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+                           ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+                           ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+                               rc =  0;
+                               break;
+                       }
+                       cprev = cnow;
+               }
+               set_current_state( TASK_RUNNING );
+               remove_wait_queue(&pCh->delta_msr_wait, &wait);
+
+               i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3, 
+                                                CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
+               if ( ! (pCh->flags      & ASYNC_CHECK_CD)) {
+                       i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP);
+               }
+               serviceOutgoingFifo( pCh->pMyBord );
+               return rc;
+               break;
+
+       /*
+        * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+        * Return: write counters to the user passed counter struct
+        * NB: both 1->0 and 0->1 transitions are counted except for RI where
+        * only 0->1 is counted. The controller is quite capable of counting
+        * both, but this done to preserve compatibility with the standard
+        * serial driver.
+        */
+       case TIOCGICOUNT:
+               ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
+
+               WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
+               cnow = pCh->icount;
+               WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
+               p_cuser = argp;
+               rc = put_user(cnow.cts, &p_cuser->cts);
+               rc = put_user(cnow.dsr, &p_cuser->dsr);
+               rc = put_user(cnow.rng, &p_cuser->rng);
+               rc = put_user(cnow.dcd, &p_cuser->dcd);
+               rc = put_user(cnow.rx, &p_cuser->rx);
+               rc = put_user(cnow.tx, &p_cuser->tx);
+               rc = put_user(cnow.frame, &p_cuser->frame);
+               rc = put_user(cnow.overrun, &p_cuser->overrun);
+               rc = put_user(cnow.parity, &p_cuser->parity);
+               rc = put_user(cnow.brk, &p_cuser->brk);
+               rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
+               break;
+
+       /*
+        * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
+        * will be passed to the line discipline for it to handle.
+        */
+       case TIOCSERCONFIG:
+       case TIOCSERGWILD:
+       case TIOCSERGETLSR:
+       case TIOCSERSWILD:
+       case TIOCSERGSTRUCT:
+       case TIOCSERGETMULTI:
+       case TIOCSERSETMULTI:
+
+       default:
+               ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
+
+               rc =  -ENOIOCTLCMD;
+               break;
+       }
+
+       ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
+
+       return rc;
+}
+
+/******************************************************************************/
+/* Function:   GetSerialInfo()                                                */
+/* Parameters: Pointer to channel structure                                   */
+/*             Pointer to old termios structure                               */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/* This is to support the setserial command, and requires processing of the   */
+/* standard Linux serial structure.                                           */
+/******************************************************************************/
+static int
+get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
+{
+       struct serial_struct tmp;
+
+       memset ( &tmp, 0, sizeof(tmp) );
+       tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16];
+       if (BID_HAS_654(tmp.type)) {
+               tmp.type = PORT_16650;
+       } else {
+               tmp.type = PORT_CIRRUS;
+       }
+       tmp.line = pCh->port_index;
+       tmp.port = pCh->pMyBord->i2eBase;
+       tmp.irq  = ip2config.irq[pCh->port_index/64];
+       tmp.flags = pCh->flags;
+       tmp.baud_base = pCh->BaudBase;
+       tmp.close_delay = pCh->ClosingDelay;
+       tmp.closing_wait = pCh->ClosingWaitTime;
+       tmp.custom_divisor = pCh->BaudDivisor;
+       return copy_to_user(retinfo,&tmp,sizeof(*retinfo));
+}
+
+/******************************************************************************/
+/* Function:   SetSerialInfo()                                                */
+/* Parameters: Pointer to channel structure                                   */
+/*             Pointer to old termios structure                               */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/* This function provides support for setserial, which uses the TIOCSSERIAL   */
+/* ioctl. Not all setserial parameters are relevant. If the user attempts to  */
+/* change the IRQ, address or type of the port the ioctl fails.               */
+/******************************************************************************/
+static int
+set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
+{
+       struct serial_struct ns;
+       int   old_flags, old_baud_divisor;
+
+       if (copy_from_user(&ns, new_info, sizeof (ns)))
+               return -EFAULT;
+
+       /*
+        * We don't allow setserial to change IRQ, board address, type or baud
+        * base. Also line nunber as such is meaningless but we use it for our
+        * array index so it is fixed also.
+        */
+       if ( (ns.irq        != ip2config.irq[pCh->port_index])
+           || ((int) ns.port      != ((int) (pCh->pMyBord->i2eBase)))
+           || (ns.baud_base != pCh->BaudBase)
+           || (ns.line      != pCh->port_index) ) {
+               return -EINVAL;
+       }
+
+       old_flags = pCh->flags;
+       old_baud_divisor = pCh->BaudDivisor;
+
+       if ( !capable(CAP_SYS_ADMIN) ) {
+               if ( ( ns.close_delay != pCh->ClosingDelay ) ||
+                   ( (ns.flags & ~ASYNC_USR_MASK) !=
+                     (pCh->flags & ~ASYNC_USR_MASK) ) ) {
+                       return -EPERM;
+               }
+
+               pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
+                              (ns.flags & ASYNC_USR_MASK);
+               pCh->BaudDivisor = ns.custom_divisor;
+       } else {
+               pCh->flags = (pCh->flags & ~ASYNC_FLAGS) |
+                              (ns.flags & ASYNC_FLAGS);
+               pCh->BaudDivisor = ns.custom_divisor;
+               pCh->ClosingDelay = ns.close_delay * HZ/100;
+               pCh->ClosingWaitTime = ns.closing_wait * HZ/100;
+       }
+
+       if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) )
+           || (old_baud_divisor != pCh->BaudDivisor) ) {
+               // Invalidate speed and reset parameters
+               set_params( pCh, NULL );
+       }
+
+       return 0;
+}
+
+/******************************************************************************/
+/* Function:   ip2_set_termios()                                              */
+/* Parameters: Pointer to tty structure                                       */
+/*             Pointer to old termios structure                               */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static void
+ip2_set_termios( PTTY tty, struct termios *old_termios )
+{
+       i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
+
+#ifdef IP2DEBUG_IOCTL
+       printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
+#endif
+
+       set_params( pCh, old_termios );
+}
+
+/******************************************************************************/
+/* Function:   ip2_set_line_discipline()                                      */
+/* Parameters: Pointer to tty structure                                       */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:  Does nothing                                                 */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static void
+ip2_set_line_discipline ( PTTY tty )
+{
+#ifdef IP2DEBUG_IOCTL
+       printk (KERN_DEBUG "IP2: set line discipline\n" );
+#endif
+
+       ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
+
+}
+
+/******************************************************************************/
+/* Function:   SetLine Characteristics()                                      */
+/* Parameters: Pointer to channel structure                                   */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/* This routine is called to update the channel structure with the new line   */
+/* characteristics, and send the appropriate commands to the board when they  */
+/* change.                                                                    */
+/******************************************************************************/
+static void
+set_params( i2ChanStrPtr pCh, struct termios *o_tios )
+{
+       tcflag_t cflag, iflag, lflag;
+       char stop_char, start_char;
+       struct termios dummy;
+
+       lflag = pCh->pTTY->termios->c_lflag;
+       cflag = pCh->pTTY->termios->c_cflag;
+       iflag = pCh->pTTY->termios->c_iflag;
+
+       if (o_tios == NULL) {
+               dummy.c_lflag = ~lflag;
+               dummy.c_cflag = ~cflag;
+               dummy.c_iflag = ~iflag;
+               o_tios = &dummy;
+       }
+
+       {
+               switch ( cflag & CBAUD ) {
+               case B0:
+                       i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
+                       pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
+                       i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
+                       pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag);
+                       goto service_it;
+                       break;
+               case B38400:
+                       /*
+                        * This is the speed that is overloaded with all the other high
+                        * speeds, depending upon the flag settings.
+                        */
+                       if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) {
+                               pCh->speed = CBR_57600;
+                       } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) {
+                               pCh->speed = CBR_115200;
+                       } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) {
+                               pCh->speed = CBR_C1;
+                       } else {
+                               pCh->speed = CBR_38400;
+                       }
+                       break;
+               case B50:      pCh->speed = CBR_50;      break;
+               case B75:      pCh->speed = CBR_75;      break;
+               case B110:     pCh->speed = CBR_110;     break;
+               case B134:     pCh->speed = CBR_134;     break;
+               case B150:     pCh->speed = CBR_150;     break;
+               case B200:     pCh->speed = CBR_200;     break;
+               case B300:     pCh->speed = CBR_300;     break;
+               case B600:     pCh->speed = CBR_600;     break;
+               case B1200:    pCh->speed = CBR_1200;    break;
+               case B1800:    pCh->speed = CBR_1800;    break;
+               case B2400:    pCh->speed = CBR_2400;    break;
+               case B4800:    pCh->speed = CBR_4800;    break;
+               case B9600:    pCh->speed = CBR_9600;    break;
+               case B19200:   pCh->speed = CBR_19200;   break;
+               case B57600:   pCh->speed = CBR_57600;   break;
+               case B115200:  pCh->speed = CBR_115200;  break;
+               case B153600:  pCh->speed = CBR_153600;  break;
+               case B230400:  pCh->speed = CBR_230400;  break;
+               case B307200:  pCh->speed = CBR_307200;  break;
+               case B460800:  pCh->speed = CBR_460800;  break;
+               case B921600:  pCh->speed = CBR_921600;  break;
+               default:       pCh->speed = CBR_9600;    break;
+               }
+               if ( pCh->speed == CBR_C1 ) {
+                       // Process the custom speed parameters.
+                       int bps = pCh->BaudBase / pCh->BaudDivisor;
+                       if ( bps == 921600 ) {
+                               pCh->speed = CBR_921600;
+                       } else {
+                               bps = bps/10;
+                               i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
+                       }
+               }
+               i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
+               
+               i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
+               pCh->dataSetOut |= (I2_DTR | I2_RTS);
+       }
+       if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag)) 
+       {
+               i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, 
+                       CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
+       }
+       if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag)) 
+       {
+               i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
+                       CMD_SETPAR( 
+                               (cflag & PARENB ?  (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
+                       )
+               );
+       }
+       /* byte size and parity */
+       if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag)) 
+       {
+               int datasize;
+               switch ( cflag & CSIZE ) {
+               case CS5: datasize = CSZ_5; break;
+               case CS6: datasize = CSZ_6; break;
+               case CS7: datasize = CSZ_7; break;
+               case CS8: datasize = CSZ_8; break;
+               default:  datasize = CSZ_5; break;      /* as per serial.c */
+               }
+               i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
+       }
+       /* Process CTS flow control flag setting */
+       if ( (cflag & CRTSCTS) ) {
+               i2QueueCommands(PTYPE_INLINE, pCh, 100,
+                                               2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB);
+       } else {
+               i2QueueCommands(PTYPE_INLINE, pCh, 100,
+                                               2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
+       }
+       //
+       // Process XON/XOFF flow control flags settings
+       //
+       stop_char = STOP_CHAR(pCh->pTTY);
+       start_char = START_CHAR(pCh->pTTY);
+
+       //////////// can't be \000
+       if (stop_char == __DISABLED_CHAR ) 
+       {
+               stop_char = ~__DISABLED_CHAR; 
+       }
+       if (start_char == __DISABLED_CHAR ) 
+       {
+               start_char = ~__DISABLED_CHAR;
+       }
+       /////////////////////////////////
+
+       if ( o_tios->c_cc[VSTART] != start_char ) 
+       {
+               i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
+       }
+       if ( o_tios->c_cc[VSTOP] != stop_char ) 
+       {
+                i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
+                i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
+       }
+       if (stop_char == __DISABLED_CHAR ) 
+       {
+               stop_char = ~__DISABLED_CHAR;  //TEST123
+               goto no_xoff;
+       }
+       if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF))) 
+       {
+               if ( iflag & IXOFF ) {  // Enable XOFF output flow control
+                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON));
+               } else {        // Disable XOFF output flow control
+no_xoff:
+                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
+               }
+       }
+       if (start_char == __DISABLED_CHAR ) 
+       {
+               goto no_xon;
+       }
+       if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY))) 
+       {
+               if ( iflag & IXON ) {
+                       if ( iflag & IXANY ) { // Enable XON/XANY output flow control
+                               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY));
+                       } else { // Enable XON output flow control
+                               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON));
+                       }
+               } else { // Disable XON output flow control
+no_xon:
+                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
+               }
+       }
+       if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) ) 
+       {
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, 
+                               CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
+       }
+       if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) ) 
+       {
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, 
+                               CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
+       }
+
+       if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) 
+                       ^       ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) ) 
+       {
+               char brkrpt = 0;
+               char parrpt = 0;
+
+               if ( iflag & IGNBRK ) { /* Ignore breaks altogether */
+                       /* Ignore breaks altogether */
+                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
+               } else {
+                       if ( iflag & BRKINT ) {
+                               if ( iflag & PARMRK ) {
+                                       brkrpt = 0x0a;  // exception an inline triple
+                               } else {
+                                       brkrpt = 0x1a;  // exception and NULL
+                               }
+                               brkrpt |= 0x04; // flush input
+                       } else {
+                               if ( iflag & PARMRK ) {
+                                       brkrpt = 0x0b;  //POSIX triple \0377 \0 \0
+                               } else {
+                                       brkrpt = 0x01;  // Null only
+                               }
+                       }
+                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
+               } 
+
+               if (iflag & IGNPAR) {
+                       parrpt = 0x20;
+                                                                                                       /* would be 2 for not cirrus bug */
+                                                                                                       /* would be 0x20 cept for cirrus bug */
+               } else {
+                       if ( iflag & PARMRK ) {
+                               /*
+                                * Replace error characters with 3-byte sequence (\0377,\0,char)
+                                */
+                               parrpt = 0x04 ;
+                               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
+                       } else {
+                               parrpt = 0x03;
+                       } 
+               }
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
+       }
+       if (cflag & CLOCAL) {
+               // Status reporting fails for DCD if this is off
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP);
+               pCh->flags &= ~ASYNC_CHECK_CD;
+       } else {
+               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
+               pCh->flags      |= ASYNC_CHECK_CD;
+       }
+
+service_it:
+       i2DrainOutput( pCh, 100 );              
+}
+
+/******************************************************************************/
+/* IPL Device Section                                                         */
+/******************************************************************************/
+
+/******************************************************************************/
+/* Function:   ip2_ipl_read()                                                  */
+/* Parameters: Pointer to device inode                                        */
+/*             Pointer to file structure                                      */
+/*             Pointer to data                                                */
+/*             Number of bytes to read                                        */
+/* Returns:    Success or failure                                             */
+/*                                                                            */
+/* Description:   Ugly                                                        */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+
+static 
+ssize_t
+ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
+{
+       unsigned int minor = iminor(pFile->f_dentry->d_inode);
+       int rc = 0;
+
+#ifdef IP2DEBUG_IPL
+       printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
+#endif
+
+       switch( minor ) {
+       case 0:     // IPL device
+               rc = -EINVAL;
+               break;
+       case 1:     // Status dump
+               rc = -EINVAL;
+               break;
+       case 2:     // Ping device
+               rc = -EINVAL;
+               break;
+       case 3:     // Trace device
+               rc = DumpTraceBuffer ( pData, count );
+               break;
+       case 4:     // Trace device
+               rc = DumpFifoBuffer ( pData, count );
+               break;
+       default:
+               rc = -ENODEV;
+               break;
+       }
+       return rc;
+}
+
+static int
+DumpFifoBuffer ( char __user *pData, int count )
+{
+#ifdef DEBUG_FIFO
+       int rc;
+       rc = copy_to_user(pData, DBGBuf, count);
+
+       printk(KERN_DEBUG "Last index %d\n", I );
+
+       return count;
+#endif /* DEBUG_FIFO */
+       return 0;
+}
+
+static int
+DumpTraceBuffer ( char __user *pData, int count )
+{
+#ifdef IP2DEBUG_TRACE
+       int rc;
+       int dumpcount;
+       int chunk;
+       int *pIndex = (int __user *)pData;
+
+       if ( count < (sizeof(int) * 6) ) {
+               return -EIO;
+       }
+       rc = put_user(tracewrap, pIndex );
+       rc = put_user(TRACEMAX, ++pIndex );
+       rc = put_user(tracestrip, ++pIndex );
+       rc = put_user(tracestuff, ++pIndex );
+       pData += sizeof(int) * 6;
+       count -= sizeof(int) * 6;
+
+       dumpcount = tracestuff - tracestrip;
+       if ( dumpcount < 0 ) {
+               dumpcount += TRACEMAX;
+       }
+       if ( dumpcount > count ) {
+               dumpcount = count;
+       }
+       chunk = TRACEMAX - tracestrip;
+       if ( dumpcount > chunk ) {
+               rc = copy_to_user(pData, &tracebuf[tracestrip],
+                             chunk * sizeof(tracebuf[0]) );
+               pData += chunk * sizeof(tracebuf[0]);
+               tracestrip = 0;
+               chunk = dumpcount - chunk;
+       } else {
+               chunk = dumpcount;
+       }
+       rc = copy_to_user(pData, &tracebuf[tracestrip],
+                     chunk * sizeof(tracebuf[0]) );
+       tracestrip += chunk;
+       tracewrap = 0;
+
+       rc = put_user(tracestrip, ++pIndex );
+       rc = put_user(tracestuff, ++pIndex );
+
+       return dumpcount;
+#else
+       return 0;
+#endif
+}
+
+/******************************************************************************/
+/* Function:   ip2_ipl_write()                                                 */
+/* Parameters:                                                                */
+/*             Pointer to file structure                                      */
+/*             Pointer to data                                                */
+/*             Number of bytes to write                                       */
+/* Returns:    Success or failure                                             */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static ssize_t
+ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
+{
+#ifdef IP2DEBUG_IPL
+       printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
+#endif
+       return 0;
+}
+
+/******************************************************************************/
+/* Function:   ip2_ipl_ioctl()                                                */
+/* Parameters: Pointer to device inode                                        */
+/*             Pointer to file structure                                      */
+/*             Command                                                        */
+/*             Argument                                                       */
+/* Returns:    Success or failure                                             */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static int
+ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
+{
+       unsigned int iplminor = iminor(pInode);
+       int rc = 0;
+       void __user *argp = (void __user *)arg;
+       ULONG __user *pIndex = argp;
+       i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
+       i2ChanStrPtr pCh;
+
+#ifdef IP2DEBUG_IPL
+       printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
+#endif
+
+       switch ( iplminor ) {
+       case 0:     // IPL device
+               rc = -EINVAL;
+               break;
+       case 1:     // Status dump
+       case 5:
+       case 9:
+       case 13:
+               switch ( cmd ) {
+               case 64:        /* Driver - ip2stat */
+                       rc = put_user(ip2_tty_driver->refcount, pIndex++ );
+                       rc = put_user(irq_counter, pIndex++  );
+                       rc = put_user(bh_counter, pIndex++  );
+                       break;
+
+               case 65:        /* Board  - ip2stat */
+                       if ( pB ) {
+                               rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
+                               rc = put_user(INB(pB->i2eStatus),
+                                       (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
+                       } else {
+                               rc = -ENODEV;
+                       }
+                       break;
+
+               default:
+                       if (cmd < IP2_MAX_PORTS) {
+                               pCh = DevTable[cmd];
+                               if ( pCh )
+                               {
+                                       rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
+                               } else {
+                                       rc = -ENODEV;
+                               }
+                       } else {
+                               rc = -EINVAL;
+                       }
+               }
+               break;
+
+       case 2:     // Ping device
+               rc = -EINVAL;
+               break;
+       case 3:     // Trace device
+               /*
+                * akpm: This used to write a whole bunch of function addresses
+                * to userspace, which generated lots of put_user() warnings.
+                * I killed it all.  Just return "success" and don't do
+                * anything.
+                */
+               if (cmd == 1)
+                       rc = 0;
+               else
+                       rc = -EINVAL;
+               break;
+
+       default:
+               rc = -ENODEV;
+               break;
+       }
+       return rc;
+}
+
+/******************************************************************************/
+/* Function:   ip2_ipl_open()                                                 */
+/* Parameters: Pointer to device inode                                        */
+/*             Pointer to file structure                                      */
+/* Returns:    Success or failure                                             */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+static int
+ip2_ipl_open( struct inode *pInode, struct file *pFile )
+{
+       unsigned int iplminor = iminor(pInode);
+       i2eBordStrPtr pB;
+       i2ChanStrPtr  pCh;
+
+#ifdef IP2DEBUG_IPL
+       printk (KERN_DEBUG "IP2IPL: open\n" );
+#endif
+
+       switch(iplminor) {
+       // These are the IPL devices
+       case 0:
+       case 4:
+       case 8:
+       case 12:
+               break;
+
+       // These are the status devices
+       case 1:
+       case 5:
+       case 9:
+       case 13:
+               break;
+
+       // These are the debug devices
+       case 2:
+       case 6:
+       case 10:
+       case 14:
+               pB = i2BoardPtrTable[iplminor / 4];
+               pCh = (i2ChanStrPtr) pB->i2eChannelPtr;
+               break;
+
+       // This is the trace device
+       case 3:
+               break;
+       }
+       return 0;
+}
+/******************************************************************************/
+/* Function:   ip2_read_procmem                                               */
+/* Parameters:                                                                */
+/*                                                                            */
+/* Returns: Length of output                                                  */
+/*                                                                            */
+/* Description:                                                               */
+/*   Supplies some driver operating parameters                                */
+/*     Not real useful unless your debugging the fifo                                                    */
+/*                                                                            */
+/******************************************************************************/
+
+#define LIMIT  (PAGE_SIZE - 120)
+
+static int
+ip2_read_procmem(char *buf, char **start, off_t offset, int len)
+{
+       i2eBordStrPtr  pB;
+       i2ChanStrPtr  pCh;
+       PTTY tty;
+       int i;
+
+       len = 0;
+
+#define FMTLINE        "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
+#define FMTLIN2        "     0x%04x 0x%04x tx flow 0x%x\n"
+#define FMTLIN3        "     0x%04x 0x%04x rc flow\n"
+
+       len += sprintf(buf+len,"\n");
+
+       for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               pB = i2BoardPtrTable[i];
+               if ( pB ) {
+                       len += sprintf(buf+len,"board %d:\n",i);
+                       len += sprintf(buf+len,"\tFifo rem: %d mty: %x outM %x\n",
+                               pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting);
+               }
+       }
+
+       len += sprintf(buf+len,"#: tty flags, port flags,     cflags,     iflags\n");
+       for (i=0; i < IP2_MAX_PORTS; i++) {
+               if (len > LIMIT)
+                       break;
+               pCh = DevTable[i];
+               if (pCh) {
+                       tty = pCh->pTTY;
+                       if (tty && tty->count) {
+                               len += sprintf(buf+len,FMTLINE,i,(int)tty->flags,pCh->flags,
+                                                                       tty->termios->c_cflag,tty->termios->c_iflag);
+
+                               len += sprintf(buf+len,FMTLIN2,
+                                               pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds);
+                               len += sprintf(buf+len,FMTLIN3,pCh->infl.asof,pCh->infl.room);
+                       }
+               }
+       }
+       return len;
+}
+
+/*
+ * This is the handler for /proc/tty/driver/ip2
+ *
+ * This stretch of code has been largely plagerized from at least three
+ * different sources including ip2mkdev.c and a couple of other drivers.
+ * The bugs are all mine.  :-) =mhw=
+ */
+static int ip2_read_proc(char *page, char **start, off_t off,
+                               int count, int *eof, void *data)
+{
+       int     i, j, box;
+       int     len = 0;
+       int     boxes = 0;
+       int     ports = 0;
+       int     tports = 0;
+       off_t   begin = 0;
+       i2eBordStrPtr  pB;
+
+       len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
+       len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
+                       IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
+                       IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
+
+       for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
+               /* This need to be reset for a board by board count... */
+               boxes = 0;
+               pB = i2BoardPtrTable[i];
+               if( pB ) {
+                       switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) 
+                       {
+                       case POR_ID_FIIEX:
+                               len += sprintf( page+len, "Board %d: EX ports=", i );
+                               for( box = 0; box < ABS_MAX_BOXES; ++box )
+                               {
+                                       ports = 0;
+
+                                       if( pB->i2eChannelMap[box] != 0 ) ++boxes;
+                                       for( j = 0; j < ABS_BIGGEST_BOX; ++j ) 
+                                       {
+                                               if( pB->i2eChannelMap[box] & 1<< j ) {
+                                                       ++ports;
+                                               }
+                                       }
+                                       len += sprintf( page+len, "%d,", ports );
+                                       tports += ports;
+                               }
+
+                               --len;  /* Backup over that last comma */
+
+                               len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
+                               break;
+
+                       case POR_ID_II_4:
+                               len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
+                               tports = ports = 4;
+                               break;
+
+                       case POR_ID_II_8:
+                               len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
+                               tports = ports = 8;
+                               break;
+
+                       case POR_ID_II_8R:
+                               len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
+                               tports = ports = 8;
+                               break;
+
+                       default:
+                               len += sprintf(page+len, "Board %d: unknown", i );
+                               /* Don't try and probe for minor numbers */
+                               tports = ports = 0;
+                       }
+
+               } else {
+                       /* Don't try and probe for minor numbers */
+                       len += sprintf(page+len, "Board %d: vacant", i );
+                       tports = ports = 0;
+               }
+
+               if( tports ) {
+                       len += sprintf(page+len, " minors=" );
+
+                       for ( box = 0; box < ABS_MAX_BOXES; ++box )
+                       {
+                               for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
+                               {
+                                       if ( pB->i2eChannelMap[box] & (1 << j) )
+                                       {
+                                               len += sprintf (page+len,"%d,",
+                                                       j + ABS_BIGGEST_BOX *
+                                                       (box+i*ABS_MAX_BOXES));
+                                       }
+                               }
+                       }
+
+                       page[ len - 1 ] = '\n'; /* Overwrite that last comma */
+               } else {
+                       len += sprintf (page+len,"\n" );
+               }
+
+               if (len+begin > off+count)
+                       break;
+               if (len+begin < off) {
+                       begin += len;
+                       len = 0;
+               }
+       }
+
+       if (i >= IP2_MAX_BOARDS)
+               *eof = 1;
+       if (off >= len+begin)
+               return 0;
+
+       *start = page + (off-begin);
+       return ((count < begin+len-off) ? count : begin+len-off);
+ }
+/******************************************************************************/
+/* Function:   ip2trace()                                                     */
+/* Parameters: Value to add to trace buffer                                   */
+/* Returns:    Nothing                                                        */
+/*                                                                            */
+/* Description:                                                               */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+#ifdef IP2DEBUG_TRACE
+void
+ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
+{
+       long flags;
+       unsigned long *pCode = &codes;
+       union ip2breadcrumb bc;
+       i2ChanStrPtr  pCh;
+
+
+       tracebuf[tracestuff++] = jiffies;
+       if ( tracestuff == TRACEMAX ) {
+               tracestuff = 0;
+       }
+       if ( tracestuff == tracestrip ) {
+               if ( ++tracestrip == TRACEMAX ) {
+                       tracestrip = 0;
+               }
+               ++tracewrap;
+       }
+
+       bc.hdr.port  = 0xff & pn;
+       bc.hdr.cat   = cat;
+       bc.hdr.codes = (unsigned char)( codes & 0xff );
+       bc.hdr.label = label;
+       tracebuf[tracestuff++] = bc.value;
+
+       for (;;) {
+               if ( tracestuff == TRACEMAX ) {
+                       tracestuff = 0;
+               }
+               if ( tracestuff == tracestrip ) {
+                       if ( ++tracestrip == TRACEMAX ) {
+                               tracestrip = 0;
+                       }
+                       ++tracewrap;
+               }
+
+               if ( !codes-- )
+                       break;
+
+               tracebuf[tracestuff++] = *++pCode;
+       }
+}
+#endif
+
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
deleted file mode 100644 (file)
index 48fcfba..0000000
+++ /dev/null
@@ -1,3211 +0,0 @@
-/*
-*
-*   (c) 1999 by Computone Corporation
-*
-********************************************************************************
-*
-*   PACKAGE:     Linux tty Device Driver for IntelliPort family of multiport
-*                serial I/O controllers.
-*
-*   DESCRIPTION: Mainline code for the device driver
-*
-*******************************************************************************/
-// ToDo:
-//
-// Fix the immediate DSS_NOW problem.
-// Work over the channel stats return logic in ip2_ipl_ioctl so they
-//     make sense for all 256 possible channels and so the user space
-//     utilities will compile and work properly.
-//
-// Done:
-//
-// 1.2.14      /\/\|=mhw=|\/\/
-// Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts.
-// Changed the definition of ip2trace to be more consistent with kernel style
-//     Thanks to Andreas Dilger <adilger@turbolabs.com> for these updates
-//
-// 1.2.13      /\/\|=mhw=|\/\/
-// DEVFS: Renamed ttf/{n} to tts/F{n} and cuf/{n} to cua/F{n} to conform
-//     to agreed devfs serial device naming convention.
-//
-// 1.2.12      /\/\|=mhw=|\/\/
-// Cleaned up some remove queue cut and paste errors
-//
-// 1.2.11      /\/\|=mhw=|\/\/
-// Clean up potential NULL pointer dereferences
-// Clean up devfs registration
-// Add kernel command line parsing for io and irq
-//     Compile defaults for io and irq are now set in ip2.c not ip2/ip2.h!
-// Reworked poll_only hack for explicit parameter setting
-//     You must now EXPLICITLY set poll_only = 1 or set all irqs to 0
-// Merged ip2_loadmain and old_ip2_init
-// Converted all instances of interruptible_sleep_on into queue calls
-//     Most of these had no race conditions but better to clean up now
-//
-// 1.2.10      /\/\|=mhw=|\/\/
-// Fixed the bottom half interrupt handler and enabled USE_IQI
-//     to split the interrupt handler into a formal top-half / bottom-half
-// Fixed timing window on high speed processors that queued messages to
-//     the outbound mail fifo faster than the board could handle.
-//
-// 1.2.9
-// Four box EX was barfing on >128k kmalloc, made structure smaller by
-// reducing output buffer size
-//
-// 1.2.8
-// Device file system support (MHW)
-//
-// 1.2.7 
-// Fixed
-// Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules
-//
-// 1.2.6
-//Fixes DCD problems
-//     DCD was not reported when CLOCAL was set on call to TIOCMGET
-//
-//Enhancements:
-//     TIOCMGET requests and waits for status return
-//     No DSS interrupts enabled except for DCD when needed
-//
-// For internal use only
-//
-//#define IP2DEBUG_INIT
-//#define IP2DEBUG_OPEN
-//#define IP2DEBUG_WRITE
-//#define IP2DEBUG_READ
-//#define IP2DEBUG_IOCTL
-//#define IP2DEBUG_IPL
-
-//#define IP2DEBUG_TRACE
-//#define DEBUG_FIFO
-
-/************/
-/* Includes */
-/************/
-#include <linux/config.h>
-
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/major.h>
-#include <linux/wait.h>
-#include <linux/device.h>
-
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/termios.h>
-#include <linux/tty_driver.h>
-#include <linux/serial.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-
-#include <linux/cdk.h>
-#include <linux/comstats.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-
-#include <asm/uaccess.h>
-
-#include "./ip2/ip2types.h"
-#include "./ip2/ip2trace.h"
-#include "./ip2/ip2ioctl.h"
-#include "./ip2/ip2.h"
-#include "./ip2/i2ellis.h"
-#include "./ip2/i2lib.h"
-
-/*****************
- * /proc/ip2mem  *
- *****************/
-
-#include <linux/proc_fs.h>
-
-static int ip2_read_procmem(char *, char **, off_t, int);
-static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
-
-/********************/
-/* Type Definitions */
-/********************/
-
-/*************/
-/* Constants */
-/*************/
-
-/* String constants to identify ourselves */
-static char *pcName    = "Computone IntelliPort Plus multiport driver";
-static char *pcVersion = "1.2.14";
-
-/* String constants for port names */
-static char *pcDriver_name   = "ip2";
-static char *pcIpl              = "ip2ipl";
-
-/* Serial subtype definitions */
-#define SERIAL_TYPE_NORMAL    1
-
-// cheezy kludge or genius - you decide?
-int ip2_loadmain(int *, int *, unsigned char *, int);
-static unsigned char *Fip_firmware;
-static int Fip_firmware_size;
-
-/***********************/
-/* Function Prototypes */
-/***********************/
-
-/* Global module entry functions */
-
-/* Private (static) functions */
-static int  ip2_open(PTTY, struct file *);
-static void ip2_close(PTTY, struct file *);
-static int  ip2_write(PTTY, const unsigned char *, int);
-static void ip2_putchar(PTTY, unsigned char);
-static void ip2_flush_chars(PTTY);
-static int  ip2_write_room(PTTY);
-static int  ip2_chars_in_buf(PTTY);
-static void ip2_flush_buffer(PTTY);
-static int  ip2_ioctl(PTTY, struct file *, UINT, ULONG);
-static void ip2_set_termios(PTTY, struct termios *);
-static void ip2_set_line_discipline(PTTY);
-static void ip2_throttle(PTTY);
-static void ip2_unthrottle(PTTY);
-static void ip2_stop(PTTY);
-static void ip2_start(PTTY);
-static void ip2_hangup(PTTY);
-static int  ip2_tiocmget(struct tty_struct *tty, struct file *file);
-static int  ip2_tiocmset(struct tty_struct *tty, struct file *file,
-                        unsigned int set, unsigned int clear);
-
-static void set_irq(int, int);
-static void ip2_interrupt_bh(i2eBordStrPtr pB);
-static irqreturn_t ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs);
-static void ip2_poll(unsigned long arg);
-static inline void service_all_boards(void);
-static void do_input(void *p);
-static void do_status(void *p);
-
-static void ip2_wait_until_sent(PTTY,int);
-
-static void set_params (i2ChanStrPtr, struct termios *);
-static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
-static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
-
-static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
-static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
-static int ip2_ipl_ioctl(struct inode *, struct file *, UINT, ULONG);
-static int ip2_ipl_open(struct inode *, struct file *);
-
-static int DumpTraceBuffer(char __user *, int);
-static int DumpFifoBuffer( char __user *, int);
-
-static void ip2_init_board(int);
-static unsigned short find_eisa_board(int);
-
-/***************/
-/* Static Data */
-/***************/
-
-static struct tty_driver *ip2_tty_driver;
-
-/* Here, then is a table of board pointers which the interrupt routine should
- * scan through to determine who it must service.
- */
-static unsigned short i2nBoards; // Number of boards here
-
-static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
-
-static i2ChanStrPtr  DevTable[IP2_MAX_PORTS];
-//DevTableMem just used to save addresses for kfree
-static void  *DevTableMem[IP2_MAX_BOARDS];
-
-/* This is the driver descriptor for the ip2ipl device, which is used to
- * download the loadware to the boards.
- */
-static struct file_operations ip2_ipl = {
-       .owner          = THIS_MODULE,
-       .read           = ip2_ipl_read,
-       .write          = ip2_ipl_write,
-       .ioctl          = ip2_ipl_ioctl,
-       .open           = ip2_ipl_open,
-}; 
-
-static unsigned long irq_counter = 0;
-static unsigned long bh_counter = 0;
-
-// Use immediate queue to service interrupts
-#define USE_IQI
-//#define USE_IQ       // PCI&2.2 needs work
-
-/* The timer_list entry for our poll routine. If interrupt operation is not
- * selected, the board is serviced periodically to see if anything needs doing.
- */
-#define  POLL_TIMEOUT   (jiffies + 1)
-static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
-static char  TimerOn;
-
-#ifdef IP2DEBUG_TRACE
-/* Trace (debug) buffer data */
-#define TRACEMAX  1000
-static unsigned long tracebuf[TRACEMAX];
-static int tracestuff;
-static int tracestrip;
-static int tracewrap;
-#endif
-
-/**********/
-/* Macros */
-/**********/
-
-#if defined(MODULE) && defined(IP2DEBUG_OPEN)
-#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \
-                   tty->name,(pCh->flags),ip2_tty_driver->refcount, \
-                   tty->count,/*GET_USE_COUNT(module)*/0,s)
-#else
-#define DBG_CNT(s)
-#endif
-
-/********/
-/* Code */
-/********/
-
-#include "./ip2/i2ellis.c"    /* Extremely low-level interface services */
-#include "./ip2/i2cmd.c"      /* Standard loadware command definitions */
-#include "./ip2/i2lib.c"      /* High level interface services */
-
-/* Configuration area for modprobe */
-
-MODULE_AUTHOR("Doug McNash");
-MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
-
-static int poll_only = 0;
-
-static int Eisa_irq;
-static int Eisa_slot;
-
-static int iindx;
-static char rirqs[IP2_MAX_BOARDS];
-static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
-
-/* for sysfs class support */
-static struct class *ip2_class;
-
-// Some functions to keep track of what irq's we have
-
-static int __init
-is_valid_irq(int irq)
-{
-       int *i = Valid_Irqs;
-       
-       while ((*i != 0) && (*i != irq)) {
-               i++;
-       }
-       return (*i);
-}
-
-static void __init
-mark_requested_irq( char irq )
-{
-       rirqs[iindx++] = irq;
-}
-
-#ifdef MODULE
-static int __init
-clear_requested_irq( char irq )
-{
-       int i;
-       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               if (rirqs[i] == irq) {
-                       rirqs[i] = 0;
-                       return 1;
-               }
-       }
-       return 0;
-}
-#endif
-
-static int __init
-have_requested_irq( char irq )
-{
-       // array init to zeros so 0 irq will not be requested as a side effect
-       int i;
-       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               if (rirqs[i] == irq)
-                       return 1;
-       }
-       return 0;
-}
-
-/******************************************************************************/
-/* Function:   init_module()                                                  */
-/* Parameters: None                                                           */
-/* Returns:    Success (0)                                                    */
-/*                                                                            */
-/* Description:                                                               */
-/* This is a required entry point for an installable module. It simply calls  */
-/* the driver initialisation function and returns what it returns.            */
-/******************************************************************************/
-#ifdef MODULE
-int
-init_module(void)
-{
-#ifdef IP2DEBUG_INIT
-       printk (KERN_DEBUG "Loading module ...\n" );
-#endif
-    return 0;
-}
-#endif /* MODULE */
-
-/******************************************************************************/
-/* Function:   cleanup_module()                                               */
-/* Parameters: None                                                           */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/* This is a required entry point for an installable module. It has to return */
-/* the device and the driver to a passive state. It should not be necessary   */
-/* to reset the board fully, especially as the loadware is downloaded         */
-/* externally rather than in the driver. We just want to disable the board    */
-/* and clear the loadware to a reset state. To allow this there has to be a   */
-/* way to detect whether the board has the loadware running at init time to   */
-/* handle subsequent installations of the driver. All memory allocated by the */
-/* driver should be returned since it may be unloaded from memory.            */
-/******************************************************************************/
-#ifdef MODULE
-void
-cleanup_module(void)
-{
-       int err;
-       int i;
-
-#ifdef IP2DEBUG_INIT
-       printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion );
-#endif
-       /* Stop poll timer if we had one. */
-       if ( TimerOn ) {
-               del_timer ( &PollTimer );
-               TimerOn = 0;
-       }
-
-       /* Reset the boards we have. */
-       for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               if ( i2BoardPtrTable[i] ) {
-                       iiReset( i2BoardPtrTable[i] );
-               }
-       }
-
-       /* The following is done at most once, if any boards were installed. */
-       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               if ( i2BoardPtrTable[i] ) {
-                       iiResetDelay( i2BoardPtrTable[i] );
-                       /* free io addresses and Tibet */
-                       release_region( ip2config.addr[i], 8 );
-                       class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
-                       devfs_remove("ip2/ipl%d", i);
-                       class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
-                       devfs_remove("ip2/stat%d", i);
-               }
-               /* Disable and remove interrupt handler. */
-               if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { 
-                       free_irq ( ip2config.irq[i], (void *)&pcName);
-                       clear_requested_irq( ip2config.irq[i]);
-               }
-       }
-       class_destroy(ip2_class);
-       devfs_remove("ip2");
-       if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
-               printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
-       }
-       put_tty_driver(ip2_tty_driver);
-       if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) {
-               printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err);
-       }
-       remove_proc_entry("ip2mem", &proc_root);
-
-       // free memory
-       for (i = 0; i < IP2_MAX_BOARDS; i++) {
-               void *pB;
-#ifdef CONFIG_PCI
-               if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
-                       pci_disable_device(ip2config.pci_dev[i]);
-                       ip2config.pci_dev[i] = NULL;
-               }
-#endif
-               if ((pB = i2BoardPtrTable[i]) != 0 ) {
-                       kfree ( pB );
-                       i2BoardPtrTable[i] = NULL;
-               }
-               if ((DevTableMem[i]) != NULL ) {
-                       kfree ( DevTableMem[i]  );
-                       DevTableMem[i] = NULL;
-               }
-       }
-
-       /* Cleanup the iiEllis subsystem. */
-       iiEllisCleanup();
-#ifdef IP2DEBUG_INIT
-       printk (KERN_DEBUG "IP2 Unloaded\n" );
-#endif
-}
-#endif /* MODULE */
-
-static struct tty_operations ip2_ops = {
-       .open            = ip2_open,
-       .close           = ip2_close,
-       .write           = ip2_write,
-       .put_char        = ip2_putchar,
-       .flush_chars     = ip2_flush_chars,
-       .write_room      = ip2_write_room,
-       .chars_in_buffer = ip2_chars_in_buf,
-       .flush_buffer    = ip2_flush_buffer,
-       .ioctl           = ip2_ioctl,
-       .throttle        = ip2_throttle,
-       .unthrottle      = ip2_unthrottle,
-       .set_termios     = ip2_set_termios,
-       .set_ldisc       = ip2_set_line_discipline,
-       .stop            = ip2_stop,
-       .start           = ip2_start,
-       .hangup          = ip2_hangup,
-       .read_proc       = ip2_read_proc,
-       .tiocmget        = ip2_tiocmget,
-       .tiocmset        = ip2_tiocmset,
-};
-
-/******************************************************************************/
-/* Function:   ip2_loadmain()                                                 */
-/* Parameters: irq, io from command line of insmod et. al.                    */
-/*             pointer to fip firmware and firmware size for boards          */
-/* Returns:    Success (0)                                                    */
-/*                                                                            */
-/* Description:                                                               */
-/* This was the required entry point for all drivers (now in ip2.c)           */
-/* It performs all                                                            */
-/* initialisation of the devices and driver structures, and registers itself  */
-/* with the relevant kernel modules.                                          */
-/******************************************************************************/
-/* SA_INTERRUPT- if set blocks all interrupts else only this line */
-/* SA_SHIRQ    - for shared irq PCI or maybe EISA only */
-/* SA_RANDOM   - can be source for cert. random number generators */
-#define IP2_SA_FLAGS   0
-
-int
-ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) 
-{
-       int i, j, box;
-       int err = 0;
-       int status = 0;
-       static int loaded;
-       i2eBordStrPtr pB = NULL;
-       int rc = -1;
-
-       ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 );
-
-       /* process command line arguments to modprobe or
-               insmod i.e. iop & irqp */
-       /* irqp and iop should ALWAYS be specified now...  But we check
-               them individually just to be sure, anyways... */
-       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               if (iop) {
-                       ip2config.addr[i] = iop[i];
-                       if (irqp) {
-                               if( irqp[i] >= 0 ) {
-                                       ip2config.irq[i] = irqp[i];
-                               } else {
-                                       ip2config.irq[i] = 0;
-                               }
-       // This is a little bit of a hack.  If poll_only=1 on command
-       // line back in ip2.c OR all IRQs on all specified boards are
-       // explicitly set to 0, then drop to poll only mode and override
-       // PCI or EISA interrupts.  This superceeds the old hack of
-       // triggering if all interrupts were zero (like da default).
-       // Still a hack but less prone to random acts of terrorism.
-       //
-       // What we really should do, now that the IRQ default is set
-       // to -1, is to use 0 as a hard coded, do not probe.
-       //
-       //      /\/\|=mhw=|\/\/
-                               poll_only |= irqp[i];
-                       }
-               }
-       }
-       poll_only = !poll_only;
-
-       Fip_firmware = firmware;
-       Fip_firmware_size = firmsize;
-
-       /* Announce our presence */
-       printk( KERN_INFO "%s version %s\n", pcName, pcVersion );
-
-       // ip2 can be unloaded and reloaded for no good reason
-       // we can't let that happen here or bad things happen
-       // second load hoses board but not system - fixme later
-       if (loaded) {
-               printk( KERN_INFO "Still loaded\n" );
-               return 0;
-       }
-       loaded++;
-
-       ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
-       if (!ip2_tty_driver)
-               return -ENOMEM;
-
-       /* Initialise the iiEllis subsystem. */
-       iiEllisInit();
-
-       /* Initialize arrays. */
-       memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable );
-       memset( DevTable, 0, sizeof DevTable );
-
-       /* Initialise all the boards we can find (up to the maximum). */
-       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               switch ( ip2config.addr[i] ) { 
-               case 0: /* skip this slot even if card is present */
-                       break;
-               default: /* ISA */
-                  /* ISA address must be specified */
-                       if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) {
-                               printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n",
-                                                        i, ip2config.addr[i] );
-                               ip2config.addr[i] = 0;
-                       } else {
-                               ip2config.type[i] = ISA;
-
-                               /* Check for valid irq argument, set for polling if invalid */
-                               if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) {
-                                       printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]);
-                                       ip2config.irq[i] = 0;// 0 is polling and is valid in that sense
-                               }
-                       }
-                       break;
-               case PCI:
-#ifdef CONFIG_PCI
-                       {
-                               struct pci_dev *pci_dev_i = NULL;
-                               pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE,
-                                                         PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
-                               if (pci_dev_i != NULL) {
-                                       unsigned int addr;
-
-                                       if (pci_enable_device(pci_dev_i)) {
-                                               printk( KERN_ERR "IP2: can't enable PCI device at %s\n",
-                                                       pci_name(pci_dev_i));
-                                               break;
-                                       }
-                                       ip2config.type[i] = PCI;
-                                       ip2config.pci_dev[i] = pci_dev_i;
-                                       status =
-                                       pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
-                                       if ( addr & 1 ) {
-                                               ip2config.addr[i]=(USHORT)(addr&0xfffe);
-                                       } else {
-                                               printk( KERN_ERR "IP2: PCI I/O address error\n");
-                                       }
-
-//             If the PCI BIOS assigned it, lets try and use it.  If we
-//             can't acquire it or it screws up, deal with it then.
-
-//                                     if (!is_valid_irq(pci_irq)) {
-//                                             printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
-//                                             pci_irq = 0;
-//                                     }
-                                       ip2config.irq[i] = pci_dev_i->irq;
-                               } else {        // ann error
-                                       ip2config.addr[i] = 0;
-                                       if (status == PCIBIOS_DEVICE_NOT_FOUND) {
-                                               printk( KERN_ERR "IP2: PCI board %d not found\n", i );
-                                       } else {
-                                               printk( KERN_ERR "IP2: PCI error 0x%x \n", status );
-                                       }
-                               } 
-                       }
-#else
-                       printk( KERN_ERR "IP2: PCI card specified but PCI support not\n");
-                       printk( KERN_ERR "IP2: configured in this kernel.\n");
-                       printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n");
-#endif /* CONFIG_PCI */
-                       break;
-               case EISA:
-                       if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) {
-                               /* Eisa_irq set as side effect, boo */
-                               ip2config.type[i] = EISA;
-                       } 
-                       ip2config.irq[i] = Eisa_irq;
-                       break;
-               }       /* switch */
-       }       /* for */
-       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               if ( ip2config.addr[i] ) {
-                       pB = kmalloc( sizeof(i2eBordStr), GFP_KERNEL);
-                       if ( pB != NULL ) {
-                               i2BoardPtrTable[i] = pB;
-                               memset( pB, 0, sizeof(i2eBordStr) );
-                               iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer );
-                               iiReset( pB );
-                       } else {
-                               printk(KERN_ERR "IP2: board memory allocation error\n");
-                       }
-               }
-       }
-       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               if ( ( pB = i2BoardPtrTable[i] ) != NULL ) {
-                       iiResetDelay( pB );
-                       break;
-               }
-       }
-       for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               if ( i2BoardPtrTable[i] != NULL ) {
-                       ip2_init_board( i );
-               }
-       }
-
-       ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 );
-
-       ip2_tty_driver->owner               = THIS_MODULE;
-       ip2_tty_driver->name                 = "ttyF";
-       ip2_tty_driver->devfs_name          = "tts/F";
-       ip2_tty_driver->driver_name          = pcDriver_name;
-       ip2_tty_driver->major                = IP2_TTY_MAJOR;
-       ip2_tty_driver->minor_start          = 0;
-       ip2_tty_driver->type                 = TTY_DRIVER_TYPE_SERIAL;
-       ip2_tty_driver->subtype              = SERIAL_TYPE_NORMAL;
-       ip2_tty_driver->init_termios         = tty_std_termios;
-       ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
-       ip2_tty_driver->flags                = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
-       tty_set_operations(ip2_tty_driver, &ip2_ops);
-
-       ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 );
-
-       /* Register the tty devices. */
-       if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) {
-               printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err);
-               put_tty_driver(ip2_tty_driver);
-               return -EINVAL;
-       } else
-       /* Register the IPL driver. */
-       if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) {
-               printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
-       } else {
-               /* create the sysfs class */
-               ip2_class = class_create(THIS_MODULE, "ip2");
-               if (IS_ERR(ip2_class)) {
-                       err = PTR_ERR(ip2_class);
-                       goto out_chrdev;        
-               }
-       }
-       /* Register the read_procmem thing */
-       if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) {
-               printk(KERN_ERR "IP2: failed to register read_procmem\n");
-       } else {
-
-       ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 );
-               /* Register the interrupt handler or poll handler, depending upon the
-                * specified interrupt.
-                */
-
-               for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-                       if ( 0 == ip2config.addr[i] ) {
-                               continue;
-                       }
-
-                       if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
-                               class_device_create(ip2_class, NULL,
-                                               MKDEV(IP2_IPL_MAJOR, 4 * i),
-                                               NULL, "ipl%d", i);
-                               err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
-                                               S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
-                                               "ip2/ipl%d", i);
-                               if (err) {
-                                       class_device_destroy(ip2_class,
-                                               MKDEV(IP2_IPL_MAJOR, 4 * i));
-                                       goto out_class;
-                               }
-
-                               class_device_create(ip2_class, NULL,
-                                               MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
-                                               NULL, "stat%d", i);
-                               err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
-                                               S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
-                                               "ip2/stat%d", i);
-                               if (err) {
-                                       class_device_destroy(ip2_class,
-                                               MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
-                                       goto out_class;
-                               }
-
-                           for ( box = 0; box < ABS_MAX_BOXES; ++box )
-                           {
-                               for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
-                               {
-                                   if ( pB->i2eChannelMap[box] & (1 << j) )
-                                   {
-                                       tty_register_device(ip2_tty_driver,
-                                           j + ABS_BIGGEST_BOX *
-                                                   (box+i*ABS_MAX_BOXES), NULL);
-                                   }
-                               }
-                           }
-                       }
-
-                       if (poll_only) {
-//             Poll only forces driver to only use polling and
-//             to ignore the probed PCI or EISA interrupts.
-                               ip2config.irq[i] = CIR_POLL;
-                       }
-                       if ( ip2config.irq[i] == CIR_POLL ) {
-retry:
-                               if (!TimerOn) {
-                                       PollTimer.expires = POLL_TIMEOUT;
-                                       add_timer ( &PollTimer );
-                                       TimerOn = 1;
-                                       printk( KERN_INFO "IP2: polling\n");
-                               }
-                       } else {
-                               if (have_requested_irq(ip2config.irq[i]))
-                                       continue;
-                               rc = request_irq( ip2config.irq[i], ip2_interrupt,
-                                       IP2_SA_FLAGS | (ip2config.type[i] == PCI ? SA_SHIRQ : 0),
-                                       pcName, (void *)&pcName);
-                               if (rc) {
-                                       printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc);
-                                       ip2config.irq[i] = CIR_POLL;
-                                       printk( KERN_INFO "IP2: Polling %ld/sec.\n",
-                                                       (POLL_TIMEOUT - jiffies));
-                                       goto retry;
-                               } 
-                               mark_requested_irq(ip2config.irq[i]);
-                               /* Initialise the interrupt handler bottom half (aka slih). */
-                       }
-               }
-               for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-                       if ( i2BoardPtrTable[i] ) {
-                               set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */
-                       }
-               }
-       }
-       ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 );
-       goto out;
-
-out_class:
-       class_destroy(ip2_class);
-out_chrdev:
-       unregister_chrdev(IP2_IPL_MAJOR, "ip2");
-out:
-       return err;
-}
-
-EXPORT_SYMBOL(ip2_loadmain);
-
-/******************************************************************************/
-/* Function:   ip2_init_board()                                               */
-/* Parameters: Index of board in configuration structure                      */
-/* Returns:    Success (0)                                                    */
-/*                                                                            */
-/* Description:                                                               */
-/* This function initializes the specified board. The loadware is copied to   */
-/* the board, the channel structures are initialized, and the board details   */
-/* are reported on the console.                                               */
-/******************************************************************************/
-static void __init
-ip2_init_board( int boardnum )
-{
-       int i;
-       int nports = 0, nboxes = 0;
-       i2ChanStrPtr pCh;
-       i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
-
-       if ( !iiInitialize ( pB ) ) {
-               printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n",
-                        pB->i2eBase, pB->i2eError );
-               goto err_initialize;
-       }
-       printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1,
-              ip2config.addr[boardnum], ip2config.irq[boardnum] );
-
-       if (!request_region( ip2config.addr[boardnum], 8, pcName )) {
-               printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]);
-               goto err_initialize;
-       }
-
-       if ( iiDownloadAll ( pB, (loadHdrStrPtr)Fip_firmware, 1, Fip_firmware_size )
-           != II_DOWN_GOOD ) {
-               printk ( KERN_ERR "IP2: failed to download loadware\n" );
-               goto err_release_region;
-       } else {
-               printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n",
-                        pB->i2ePom.e.porVersion,
-                        pB->i2ePom.e.porRevision,
-                        pB->i2ePom.e.porSubRev, pB->i2eLVersion,
-                        pB->i2eLRevision, pB->i2eLSub );
-       }
-
-       switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) {
-
-       default:
-               printk( KERN_ERR "IP2: Unknown board type, ID = %x\n",
-                               pB->i2ePom.e.porID );
-               nports = 0;
-               goto err_release_region;
-               break;
-
-       case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */
-               printk ( KERN_INFO "IP2: ISA-4\n" );
-               nports = 4;
-               break;
-
-       case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */
-               printk ( KERN_INFO "IP2: ISA-8 std\n" );
-               nports = 8;
-               break;
-
-       case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
-               printk ( KERN_INFO "IP2: ISA-8 RJ11\n" );
-               nports = 8;
-               break;
-
-       case POR_ID_FIIEX: /* IntelliPort IIEX */
-       {
-               int portnum = IP2_PORTS_PER_BOARD * boardnum;
-               int            box;
-
-               for( box = 0; box < ABS_MAX_BOXES; ++box ) {
-                       if ( pB->i2eChannelMap[box] != 0 ) {
-                               ++nboxes;
-                       }
-                       for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
-                               if ( pB->i2eChannelMap[box] & 1<< i ) {
-                                       ++nports;
-                               }
-                       }
-               }
-               DevTableMem[boardnum] = pCh =
-                       kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL );
-               if ( !pCh ) {
-                       printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
-                       goto err_release_region;
-               }
-               if ( !i2InitChannels( pB, nports, pCh ) ) {
-                       printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
-                       kfree ( pCh );
-                       goto err_release_region;
-               }
-               pB->i2eChannelPtr = &DevTable[portnum];
-               pB->i2eChannelCnt = ABS_MOST_PORTS;
-
-               for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) {
-                       for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
-                               if ( pB->i2eChannelMap[box] & (1 << i) ) {
-                                       DevTable[portnum + i] = pCh;
-                                       pCh->port_index = portnum + i;
-                                       pCh++;
-                               }
-                       }
-               }
-               printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n",
-                       nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 );
-               }
-               goto ex_exit;
-       }
-       DevTableMem[boardnum] = pCh =
-               kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL );
-       if ( !pCh ) {
-               printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
-               goto err_release_region;
-       }
-       pB->i2eChannelPtr = pCh;
-       pB->i2eChannelCnt = nports;
-       if ( !i2InitChannels( pB, nports, pCh ) ) {
-               printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
-               kfree ( pCh );
-               goto err_release_region;
-       }
-       pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum];
-
-       for( i = 0; i < pB->i2eChannelCnt; ++i ) {
-               DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh;
-               pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i;
-               pCh++;
-       }
-ex_exit:
-       INIT_WORK(&pB->tqueue_interrupt, (void(*)(void*)) ip2_interrupt_bh, pB);
-       return;
-
-err_release_region:
-       release_region(ip2config.addr[boardnum], 8);
-err_initialize:
-       kfree ( pB );
-       i2BoardPtrTable[boardnum] = NULL;
-       return;
-}
-
-/******************************************************************************/
-/* Function:   find_eisa_board ( int start_slot )                             */
-/* Parameters: First slot to check                                            */
-/* Returns:    Address of EISA IntelliPort II controller                      */
-/*                                                                            */
-/* Description:                                                               */
-/* This function searches for an EISA IntelliPort controller, starting        */
-/* from the specified slot number. If the motherboard is not identified as an */
-/* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */
-/* it returns the base address of the controller.                             */
-/******************************************************************************/
-static unsigned short __init
-find_eisa_board( int start_slot )
-{
-       int i, j;
-       unsigned int idm = 0;
-       unsigned int idp = 0;
-       unsigned int base = 0;
-       unsigned int value;
-       int setup_address;
-       int setup_irq;
-       int ismine = 0;
-
-       /*
-        * First a check for an EISA motherboard, which we do by comparing the
-        * EISA ID registers for the system board and the first couple of slots.
-        * No slot ID should match the system board ID, but on an ISA or PCI
-        * machine the odds are that an empty bus will return similar values for
-        * each slot.
-        */
-       i = 0x0c80;
-       value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3);
-       for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) {
-               j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3);
-               if ( value == j )
-                       return 0;
-       }
-
-       /*
-        * OK, so we are inclined to believe that this is an EISA machine. Find
-        * an IntelliPort controller.
-        */
-       for( i = start_slot; i < 16; i++ ) {
-               base = i << 12;
-               idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff);
-               idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff);
-               ismine = 0;
-               if ( idm == 0x0e8e ) {
-                       if ( idp == 0x0281 || idp == 0x0218 ) {
-                               ismine = 1;
-                       } else if ( idp == 0x0282 || idp == 0x0283 ) {
-                               ismine = 3;     /* Can do edge-trigger */
-                       }
-                       if ( ismine ) {
-                               Eisa_slot = i;
-                               break;
-                       }
-               }
-       }
-       if ( !ismine )
-               return 0;
-
-       /* It's some sort of EISA card, but at what address is it configured? */
-
-       setup_address = base + 0xc88;
-       value = inb(base + 0xc86);
-       setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0;
-
-       if ( (ismine & 2) && !(value & 0x10) ) {
-               ismine = 1;     /* Could be edging, but not */
-       }
-
-       if ( Eisa_irq == 0 ) {
-               Eisa_irq = setup_irq;
-       } else if ( Eisa_irq != setup_irq ) {
-               printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" );
-       }
-
-#ifdef IP2DEBUG_INIT
-printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
-              base >> 12, idm, idp, setup_address);
-       if ( Eisa_irq ) {
-               printk(KERN_DEBUG ", Interrupt %d %s\n",
-                      setup_irq, (ismine & 2) ? "(edge)" : "(level)");
-       } else {
-               printk(KERN_DEBUG ", (polled)\n");
-       }
-#endif
-       return setup_address;
-}
-
-/******************************************************************************/
-/* Function:   set_irq()                                                      */
-/* Parameters: index to board in board table                                  */
-/*             IRQ to use                                                     */
-/* Returns:    Success (0)                                                    */
-/*                                                                            */
-/* Description:                                                               */
-/******************************************************************************/
-static void
-set_irq( int boardnum, int boardIrq )
-{
-       unsigned char tempCommand[16];
-       i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
-       unsigned long flags;
-
-       /*
-        * Notify the boards they may generate interrupts. This is done by
-        * sending an in-line command to channel 0 on each board. This is why
-        * the channels have to be defined already. For each board, if the
-        * interrupt has never been defined, we must do so NOW, directly, since
-        * board will not send flow control or even give an interrupt until this
-        * is done.  If polling we must send 0 as the interrupt parameter.
-        */
-
-       // We will get an interrupt here at the end of this function
-
-       iiDisableMailIrq(pB);
-
-       /* We build up the entire packet header. */
-       CHANNEL_OF(tempCommand) = 0;
-       PTYPE_OF(tempCommand) = PTYPE_INLINE;
-       CMD_COUNT_OF(tempCommand) = 2;
-       (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ;
-       (CMD_OF(tempCommand))[1] = boardIrq;
-       /*
-        * Write to FIFO; don't bother to adjust fifo capacity for this, since
-        * board will respond almost immediately after SendMail hit.
-        */
-       WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
-       iiWriteBuf(pB, tempCommand, 4);
-       WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
-       pB->i2eUsingIrq = boardIrq;
-       pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
-
-       /* Need to update number of boards before you enable mailbox int */
-       ++i2nBoards;
-
-       CHANNEL_OF(tempCommand) = 0;
-       PTYPE_OF(tempCommand) = PTYPE_BYPASS;
-       CMD_COUNT_OF(tempCommand) = 6;
-       (CMD_OF(tempCommand))[0] = 88;  // SILO
-       (CMD_OF(tempCommand))[1] = 64;  // chars
-       (CMD_OF(tempCommand))[2] = 32;  // ms
-
-       (CMD_OF(tempCommand))[3] = 28;  // MAX_BLOCK
-       (CMD_OF(tempCommand))[4] = 64;  // chars
-
-       (CMD_OF(tempCommand))[5] = 87;  // HW_TEST
-       WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
-       iiWriteBuf(pB, tempCommand, 8);
-       WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
-
-       CHANNEL_OF(tempCommand) = 0;
-       PTYPE_OF(tempCommand) = PTYPE_BYPASS;
-       CMD_COUNT_OF(tempCommand) = 1;
-       (CMD_OF(tempCommand))[0] = 84;  /* get BOX_IDS */
-       iiWriteBuf(pB, tempCommand, 3);
-
-#ifdef XXX
-       // enable heartbeat for test porpoises
-       CHANNEL_OF(tempCommand) = 0;
-       PTYPE_OF(tempCommand) = PTYPE_BYPASS;
-       CMD_COUNT_OF(tempCommand) = 2;
-       (CMD_OF(tempCommand))[0] = 44;  /* get ping */
-       (CMD_OF(tempCommand))[1] = 200; /* 200 ms */
-       WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
-       iiWriteBuf(pB, tempCommand, 4);
-       WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
-#endif
-
-       iiEnableMailIrq(pB);
-       iiSendPendingMail(pB);
-}
-
-/******************************************************************************/
-/* Interrupt Handler Section                                                  */
-/******************************************************************************/
-
-static inline void
-service_all_boards(void)
-{
-       int i;
-       i2eBordStrPtr  pB;
-
-       /* Service every board on the list */
-       for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               pB = i2BoardPtrTable[i];
-               if ( pB ) {
-                       i2ServiceBoard( pB );
-               }
-       }
-}
-
-
-/******************************************************************************/
-/* Function:   ip2_interrupt_bh(pB)                                           */
-/* Parameters: pB - pointer to the board structure                            */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/*     Service the board in a bottom half interrupt handler and then         */
-/*     reenable the board's interrupts if it has an IRQ number               */
-/*                                                                            */
-/******************************************************************************/
-static void
-ip2_interrupt_bh(i2eBordStrPtr pB)
-{
-//     pB better well be set or we have a problem!  We can only get
-//     here from the IMMEDIATE queue.  Here, we process the boards.
-//     Checking pB doesn't cost much and it saves us from the sanity checkers.
-
-       bh_counter++; 
-
-       if ( pB ) {
-               i2ServiceBoard( pB );
-               if( pB->i2eUsingIrq ) {
-//                     Re-enable his interrupts
-                       iiEnableMailIrq(pB);
-               }
-       }
-}
-
-
-/******************************************************************************/
-/* Function:   ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs)    */
-/* Parameters: irq - interrupt number                                         */
-/*             pointer to optional device ID structure                        */
-/*             pointer to register structure                                  */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*     Our task here is simply to identify each board which needs servicing. */
-/*     If we are queuing then, queue it to be serviced, and disable its irq  */
-/*     mask otherwise process the board directly.                            */
-/*                                                                            */
-/*     We could queue by IRQ but that just complicates things on both ends   */
-/*     with very little gain in performance (how many instructions does      */
-/*     it take to iterate on the immediate queue).                           */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static irqreturn_t
-ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-       int i;
-       i2eBordStrPtr  pB;
-       int handled = 0;
-
-       ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq );
-
-       /* Service just the boards on the list using this irq */
-       for( i = 0; i < i2nBoards; ++i ) {
-               pB = i2BoardPtrTable[i];
-
-//             Only process those boards which match our IRQ.
-//                     IRQ = 0 for polled boards, we won't poll "IRQ" boards
-
-               if ( pB && (pB->i2eUsingIrq == irq) ) {
-                       handled = 1;
-#ifdef USE_IQI
-
-                   if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) {
-//                     Disable his interrupt (will be enabled when serviced)
-//                     This is mostly to protect from reentrancy.
-                       iiDisableMailIrq(pB);
-
-//                     Park the board on the immediate queue for processing.
-                       schedule_work(&pB->tqueue_interrupt);
-
-//                     Make sure the immediate queue is flagged to fire.
-                   }
-#else
-//             We are using immediate servicing here.  This sucks and can
-//             cause all sorts of havoc with ppp and others.  The failsafe
-//             check on iiSendPendingMail could also throw a hairball.
-                       i2ServiceBoard( pB );
-#endif /* USE_IQI */
-               }
-       }
-
-       ++irq_counter;
-
-       ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
-       return IRQ_RETVAL(handled);
-}
-
-/******************************************************************************/
-/* Function:   ip2_poll(unsigned long arg)                                    */
-/* Parameters: ?                                                              */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/* This function calls the library routine i2ServiceBoard for each board in   */
-/* the board table. This is used instead of the interrupt routine when polled */
-/* mode is specified.                                                         */
-/******************************************************************************/
-static void
-ip2_poll(unsigned long arg)
-{
-       ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
-
-       TimerOn = 0; // it's the truth but not checked in service
-
-       // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
-       // It will NOT poll boards handled by hard interrupts.
-       // The issue of queued BH interrups is handled in ip2_interrupt().
-       ip2_interrupt(0, NULL, NULL);
-
-       PollTimer.expires = POLL_TIMEOUT;
-       add_timer( &PollTimer );
-       TimerOn = 1;
-
-       ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
-}
-
-static void do_input(void *p)
-{
-       i2ChanStrPtr pCh = p;
-       unsigned long flags;
-
-       ip2trace(CHANN, ITRC_INPUT, 21, 0 );
-
-       // Data input
-       if ( pCh->pTTY != NULL ) {
-               READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
-               if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {
-                       READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
-                       i2Input( pCh );
-               } else
-                       READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
-       } else {
-               ip2trace(CHANN, ITRC_INPUT, 22, 0 );
-
-               i2InputFlush( pCh );
-       }
-}
-
-// code duplicated from n_tty (ldisc)
-static inline void  isig(int sig, struct tty_struct *tty, int flush)
-{
-       if (tty->pgrp > 0)
-               kill_pg(tty->pgrp, sig, 1);
-       if (flush || !L_NOFLSH(tty)) {
-               if ( tty->ldisc.flush_buffer )  
-                       tty->ldisc.flush_buffer(tty);
-               i2InputFlush( tty->driver_data );
-       }
-}
-
-static void do_status(void *p)
-{
-       i2ChanStrPtr pCh = p;
-       int status;
-
-       status =  i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
-
-       ip2trace (CHANN, ITRC_STATUS, 21, 1, status );
-
-       if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) {
-               if ( (status & I2_BRK) ) {
-                       // code duplicated from n_tty (ldisc)
-                       if (I_IGNBRK(pCh->pTTY))
-                               goto skip_this;
-                       if (I_BRKINT(pCh->pTTY)) {
-                               isig(SIGINT, pCh->pTTY, 1);
-                               goto skip_this;
-                       }
-                       wake_up_interruptible(&pCh->pTTY->read_wait);
-               }
-#ifdef NEVER_HAPPENS_AS_SETUP_XXX
-       // and can't work because we don't know the_char
-       // as the_char is reported on a separate path
-       // The intelligent board does this stuff as setup
-       {
-       char brkf = TTY_NORMAL;
-       unsigned char brkc = '\0';
-       unsigned char tmp;
-               if ( (status & I2_BRK) ) {
-                       brkf = TTY_BREAK;
-                       brkc = '\0';
-               } 
-               else if (status & I2_PAR) {
-                       brkf = TTY_PARITY;
-                       brkc = the_char;
-               } else if (status & I2_FRA) {
-                       brkf = TTY_FRAME;
-                       brkc = the_char;
-               } else if (status & I2_OVR) {
-                       brkf = TTY_OVERRUN;
-                       brkc = the_char;
-               }
-               tmp = pCh->pTTY->real_raw;
-               pCh->pTTY->real_raw = 0;
-               pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
-               pCh->pTTY->real_raw = tmp;
-       }
-#endif /* NEVER_HAPPENS_AS_SETUP_XXX */
-       }
-skip_this:
-
-       if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {
-               wake_up_interruptible(&pCh->delta_msr_wait);
-
-               if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {
-                       if ( status & I2_DCD ) {
-                               if ( pCh->wopen ) {
-                                       wake_up_interruptible ( &pCh->open_wait );
-                               }
-                       } else {
-                               if (pCh->pTTY &&  (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
-                                       tty_hangup( pCh->pTTY );
-                               }
-                       }
-               }
-       }
-
-       ip2trace (CHANN, ITRC_STATUS, 26, 0 );
-}
-
-/******************************************************************************/
-/* Device Open/Close/Ioctl Entry Point Section                                */
-/******************************************************************************/
-
-/******************************************************************************/
-/* Function:   open_sanity_check()                                            */
-/* Parameters: Pointer to tty structure                                       */
-/*             Pointer to file structure                                      */
-/* Returns:    Success or failure                                             */
-/*                                                                            */
-/* Description:                                                               */
-/* Verifies the structure magic numbers and cross links.                      */
-/******************************************************************************/
-#ifdef IP2DEBUG_OPEN
-static void 
-open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd )
-{
-       if ( pBrd->i2eValid != I2E_MAGIC ) {
-               printk(KERN_ERR "IP2: invalid board structure\n" );
-       } else if ( pBrd != pCh->pMyBord ) {
-               printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n",
-                        pCh->pMyBord );
-       } else if ( pBrd->i2eChannelCnt < pCh->port_index ) {
-               printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index );
-       } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) {
-       } else {
-               printk(KERN_INFO "IP2: all pointers check out!\n" );
-       }
-}
-#endif
-
-
-/******************************************************************************/
-/* Function:   ip2_open()                                                     */
-/* Parameters: Pointer to tty structure                                       */
-/*             Pointer to file structure                                      */
-/* Returns:    Success or failure                                             */
-/*                                                                            */
-/* Description: (MANDATORY)                                                   */
-/* A successful device open has to run a gauntlet of checks before it         */
-/* completes. After some sanity checking and pointer setup, the function      */
-/* blocks until all conditions are satisfied. It then initialises the port to */
-/* the default characteristics and returns.                                   */
-/******************************************************************************/
-static int
-ip2_open( PTTY tty, struct file *pFile )
-{
-       wait_queue_t wait;
-       int rc = 0;
-       int do_clocal = 0;
-       i2ChanStrPtr  pCh = DevTable[tty->index];
-
-       ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 );
-
-       if ( pCh == NULL ) {
-               return -ENODEV;
-       }
-       /* Setup pointer links in device and tty structures */
-       pCh->pTTY = tty;
-       tty->driver_data = pCh;
-
-#ifdef IP2DEBUG_OPEN
-       printk(KERN_DEBUG \
-                       "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n",
-              tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index);
-       open_sanity_check ( pCh, pCh->pMyBord );
-#endif
-
-       i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP);
-       pCh->dataSetOut |= (I2_DTR | I2_RTS);
-       serviceOutgoingFifo( pCh->pMyBord );
-
-       /* Block here until the port is ready (per serial and istallion) */
-       /*
-        * 1. If the port is in the middle of closing wait for the completion
-        *    and then return the appropriate error.
-        */
-       init_waitqueue_entry(&wait, current);
-       add_wait_queue(&pCh->close_wait, &wait);
-       set_current_state( TASK_INTERRUPTIBLE );
-
-       if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {
-               if ( pCh->flags & ASYNC_CLOSING ) {
-                       schedule();
-               }
-               if ( tty_hung_up_p(pFile) ) {
-                       set_current_state( TASK_RUNNING );
-                       remove_wait_queue(&pCh->close_wait, &wait);
-                       return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS;
-               }
-       }
-       set_current_state( TASK_RUNNING );
-       remove_wait_queue(&pCh->close_wait, &wait);
-
-       /*
-        * 3. Handle a non-blocking open of a normal port.
-        */
-       if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
-               pCh->flags |= ASYNC_NORMAL_ACTIVE;
-               goto noblock;
-       }
-       /*
-        * 4. Now loop waiting for the port to be free and carrier present
-        *    (if required).
-        */
-       if ( tty->termios->c_cflag & CLOCAL )
-               do_clocal = 1;
-
-#ifdef IP2DEBUG_OPEN
-       printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
-#endif
-
-       ++pCh->wopen;
-
-       init_waitqueue_entry(&wait, current);
-       add_wait_queue(&pCh->open_wait, &wait);
-
-       for(;;) {
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
-               pCh->dataSetOut |= (I2_DTR | I2_RTS);
-               set_current_state( TASK_INTERRUPTIBLE );
-               serviceOutgoingFifo( pCh->pMyBord );
-               if ( tty_hung_up_p(pFile) ) {
-                       set_current_state( TASK_RUNNING );
-                       remove_wait_queue(&pCh->open_wait, &wait);
-                       return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS;
-               }
-               if (!(pCh->flags & ASYNC_CLOSING) && 
-                               (do_clocal || (pCh->dataSetIn & I2_DCD) )) {
-                       rc = 0;
-                       break;
-               }
-
-#ifdef IP2DEBUG_OPEN
-               printk(KERN_DEBUG "ASYNC_CLOSING = %s\n",
-                       (pCh->flags & ASYNC_CLOSING)?"True":"False");
-               printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n");
-#endif
-               ip2trace (CHANN, ITRC_OPEN, 3, 2, 0,
-                               (pCh->flags & ASYNC_CLOSING) );
-               /* check for signal */
-               if (signal_pending(current)) {
-                       rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS);
-                       break;
-               }
-               schedule();
-       }
-       set_current_state( TASK_RUNNING );
-       remove_wait_queue(&pCh->open_wait, &wait);
-
-       --pCh->wopen; //why count?
-
-       ip2trace (CHANN, ITRC_OPEN, 4, 0 );
-
-       if (rc != 0 ) {
-               return rc;
-       }
-       pCh->flags |= ASYNC_NORMAL_ACTIVE;
-
-noblock:
-
-       /* first open - Assign termios structure to port */
-       if ( tty->count == 1 ) {
-               i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
-               /* Now we must send the termios settings to the loadware */
-               set_params( pCh, NULL );
-       }
-
-       /*
-        * Now set any i2lib options. These may go away if the i2lib code ends
-        * up rolled into the mainline.
-        */
-       pCh->channelOptions |= CO_NBLOCK_WRITE;
-
-#ifdef IP2DEBUG_OPEN
-       printk (KERN_DEBUG "IP2: open completed\n" );
-#endif
-       serviceOutgoingFifo( pCh->pMyBord );
-
-       ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );
-
-       return 0;
-}
-
-/******************************************************************************/
-/* Function:   ip2_close()                                                    */
-/* Parameters: Pointer to tty structure                                       */
-/*             Pointer to file structure                                      */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static void
-ip2_close( PTTY tty, struct file *pFile )
-{
-       i2ChanStrPtr  pCh = tty->driver_data;
-
-       if ( !pCh ) {
-               return;
-       }
-
-       ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );
-
-#ifdef IP2DEBUG_OPEN
-       printk(KERN_DEBUG "IP2:close %s:\n",tty->name);
-#endif
-
-       if ( tty_hung_up_p ( pFile ) ) {
-
-               ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );
-
-               return;
-       }
-       if ( tty->count > 1 ) { /* not the last close */
-
-               ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );
-
-               return;
-       }
-       pCh->flags |= ASYNC_CLOSING;    // last close actually
-
-       tty->closing = 1;
-
-       if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {
-               /*
-                * Before we drop DTR, make sure the transmitter has completely drained.
-                * This uses an timeout, after which the close
-                * completes.
-                */
-               ip2_wait_until_sent(tty, pCh->ClosingWaitTime );
-       }
-       /*
-        * At this point we stop accepting input. Here we flush the channel
-        * input buffer which will allow the board to send up more data. Any
-        * additional input is tossed at interrupt/poll time.
-        */
-       i2InputFlush( pCh );
-
-       /* disable DSS reporting */
-       i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
-                               CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
-       if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
-               pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
-               i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
-       }
-
-       serviceOutgoingFifo ( pCh->pMyBord );
-
-       if ( tty->driver->flush_buffer ) 
-               tty->driver->flush_buffer(tty);
-       if ( tty->ldisc.flush_buffer )  
-               tty->ldisc.flush_buffer(tty);
-       tty->closing = 0;
-       
-       pCh->pTTY = NULL;
-
-       if (pCh->wopen) {
-               if (pCh->ClosingDelay) {
-                       msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
-               }
-               wake_up_interruptible(&pCh->open_wait);
-       }
-
-       pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-       wake_up_interruptible(&pCh->close_wait);
-
-#ifdef IP2DEBUG_OPEN
-       DBG_CNT("ip2_close: after wakeups--");
-#endif
-
-
-       ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
-
-       return;
-}
-
-/******************************************************************************/
-/* Function:   ip2_hangup()                                                   */
-/* Parameters: Pointer to tty structure                                       */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static void
-ip2_hangup ( PTTY tty )
-{
-       i2ChanStrPtr  pCh = tty->driver_data;
-
-       if( !pCh ) {
-               return;
-       }
-
-       ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
-
-       ip2_flush_buffer(tty);
-
-       /* disable DSS reporting */
-
-       i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP);
-       i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
-       if ( (tty->termios->c_cflag & HUPCL) ) {
-               i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN);
-               pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
-               i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
-       }
-       i2QueueCommands(PTYPE_INLINE, pCh, 1, 3, 
-                               CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
-       serviceOutgoingFifo ( pCh->pMyBord );
-
-       wake_up_interruptible ( &pCh->delta_msr_wait );
-
-       pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
-       pCh->pTTY = NULL;
-       wake_up_interruptible ( &pCh->open_wait );
-
-       ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/* Device Output Section                                                      */
-/******************************************************************************/
-/******************************************************************************/
-
-/******************************************************************************/
-/* Function:   ip2_write()                                                    */
-/* Parameters: Pointer to tty structure                                       */
-/*             Flag denoting data is in user (1) or kernel (0) space          */
-/*             Pointer to data                                                */
-/*             Number of bytes to write                                       */
-/* Returns:    Number of bytes actually written                               */
-/*                                                                            */
-/* Description: (MANDATORY)                                                   */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static int
-ip2_write( PTTY tty, const unsigned char *pData, int count)
-{
-       i2ChanStrPtr  pCh = tty->driver_data;
-       int bytesSent = 0;
-       unsigned long flags;
-
-       ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
-
-       /* Flush out any buffered data left over from ip2_putchar() calls. */
-       ip2_flush_chars( tty );
-
-       /* This is the actual move bit. Make sure it does what we need!!!!! */
-       WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
-       bytesSent = i2Output( pCh, pData, count, 0 );
-       WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
-
-       ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
-
-       return bytesSent > 0 ? bytesSent : 0;
-}
-
-/******************************************************************************/
-/* Function:   ip2_putchar()                                                  */
-/* Parameters: Pointer to tty structure                                       */
-/*             Character to write                                             */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static void
-ip2_putchar( PTTY tty, unsigned char ch )
-{
-       i2ChanStrPtr  pCh = tty->driver_data;
-       unsigned long flags;
-
-//     ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
-
-       WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
-       pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
-       if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
-               WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
-               ip2_flush_chars( tty );
-       } else
-               WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
-
-//     ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
-}
-
-/******************************************************************************/
-/* Function:   ip2_flush_chars()                                              */
-/* Parameters: Pointer to tty structure                                       */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/******************************************************************************/
-static void
-ip2_flush_chars( PTTY tty )
-{
-       int   strip;
-       i2ChanStrPtr  pCh = tty->driver_data;
-       unsigned long flags;
-
-       WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
-       if ( pCh->Pbuf_stuff ) {
-
-//             ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
-
-               //
-               // We may need to restart i2Output if it does not fullfill this request
-               //
-               strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff, 0 );
-               if ( strip != pCh->Pbuf_stuff ) {
-                       memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
-               }
-               pCh->Pbuf_stuff -= strip;
-       }
-       WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
-}
-
-/******************************************************************************/
-/* Function:   ip2_write_room()                                               */
-/* Parameters: Pointer to tty structure                                       */
-/* Returns:    Number of bytes that the driver can accept                     */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/******************************************************************************/
-static int
-ip2_write_room ( PTTY tty )
-{
-       int bytesFree;
-       i2ChanStrPtr  pCh = tty->driver_data;
-       unsigned long flags;
-
-       READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
-       bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
-       READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
-
-       ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
-
-       return ((bytesFree > 0) ? bytesFree : 0);
-}
-
-/******************************************************************************/
-/* Function:   ip2_chars_in_buf()                                             */
-/* Parameters: Pointer to tty structure                                       */
-/* Returns:    Number of bytes queued for transmission                        */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static int
-ip2_chars_in_buf ( PTTY tty )
-{
-       i2ChanStrPtr  pCh = tty->driver_data;
-       int rc;
-       unsigned long flags;
-
-       ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
-
-#ifdef IP2DEBUG_WRITE
-       printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n",
-                                pCh->Obuf_char_count + pCh->Pbuf_stuff,
-                                pCh->Obuf_char_count, pCh->Pbuf_stuff );
-#endif
-       READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
-       rc =  pCh->Obuf_char_count;
-       READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
-       READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
-       rc +=  pCh->Pbuf_stuff;
-       READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
-       return rc;
-}
-
-/******************************************************************************/
-/* Function:   ip2_flush_buffer()                                             */
-/* Parameters: Pointer to tty structure                                       */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static void
-ip2_flush_buffer( PTTY tty )
-{
-       i2ChanStrPtr  pCh = tty->driver_data;
-       unsigned long flags;
-
-       ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
-
-#ifdef IP2DEBUG_WRITE
-       printk (KERN_DEBUG "IP2: flush buffer\n" );
-#endif
-       WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
-       pCh->Pbuf_stuff = 0;
-       WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
-       i2FlushOutput( pCh );
-       ip2_owake(tty);
-
-       ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
-
-}
-
-/******************************************************************************/
-/* Function:   ip2_wait_until_sent()                                          */
-/* Parameters: Pointer to tty structure                                       */
-/*             Timeout for wait.                                              */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/* This function is used in place of the normal tty_wait_until_sent, which    */
-/* only waits for the driver buffers to be empty (or rather, those buffers    */
-/* reported by chars_in_buffer) which doesn't work for IP2 due to the         */
-/* indeterminate number of bytes buffered on the board.                       */
-/******************************************************************************/
-static void
-ip2_wait_until_sent ( PTTY tty, int timeout )
-{
-       int i = jiffies;
-       i2ChanStrPtr  pCh = tty->driver_data;
-
-       tty_wait_until_sent(tty, timeout );
-       if ( (i = timeout - (jiffies -i)) > 0)
-               i2DrainOutput( pCh, i );
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/* Device Input Section                                                       */
-/******************************************************************************/
-/******************************************************************************/
-
-/******************************************************************************/
-/* Function:   ip2_throttle()                                                 */
-/* Parameters: Pointer to tty structure                                       */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static void
-ip2_throttle ( PTTY tty )
-{
-       i2ChanStrPtr  pCh = tty->driver_data;
-
-#ifdef IP2DEBUG_READ
-       printk (KERN_DEBUG "IP2: throttle\n" );
-#endif
-       /*
-        * Signal the poll/interrupt handlers not to forward incoming data to
-        * the line discipline. This will cause the buffers to fill up in the
-        * library and thus cause the library routines to send the flow control
-        * stuff.
-        */
-       pCh->throttled = 1;
-}
-
-/******************************************************************************/
-/* Function:   ip2_unthrottle()                                               */
-/* Parameters: Pointer to tty structure                                       */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static void
-ip2_unthrottle ( PTTY tty )
-{
-       i2ChanStrPtr  pCh = tty->driver_data;
-       unsigned long flags;
-
-#ifdef IP2DEBUG_READ
-       printk (KERN_DEBUG "IP2: unthrottle\n" );
-#endif
-
-       /* Pass incoming data up to the line discipline again. */
-       pCh->throttled = 0;
-       i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
-       serviceOutgoingFifo( pCh->pMyBord );
-       READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
-       if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
-               READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
-#ifdef IP2DEBUG_READ
-               printk (KERN_DEBUG "i2Input called from unthrottle\n" );
-#endif
-               i2Input( pCh );
-       } else
-               READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
-}
-
-static void
-ip2_start ( PTTY tty )
-{
-       i2ChanStrPtr  pCh = DevTable[tty->index];
-
-       i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
-       i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND);
-       i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME);
-#ifdef IP2DEBUG_WRITE
-       printk (KERN_DEBUG "IP2: start tx\n" );
-#endif
-}
-
-static void
-ip2_stop ( PTTY tty )
-{
-       i2ChanStrPtr  pCh = DevTable[tty->index];
-
-       i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
-#ifdef IP2DEBUG_WRITE
-       printk (KERN_DEBUG "IP2: stop tx\n" );
-#endif
-}
-
-/******************************************************************************/
-/* Device Ioctl Section                                                       */
-/******************************************************************************/
-
-static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
-{
-       i2ChanStrPtr pCh = DevTable[tty->index];
-#ifdef ENABLE_DSSNOW
-       wait_queue_t wait;
-#endif
-
-       if (pCh == NULL)
-               return -ENODEV;
-
-/*
-       FIXME - the following code is causing a NULL pointer dereference in
-       2.3.51 in an interrupt handler.  It's suppose to prompt the board
-       to return the DSS signal status immediately.  Why doesn't it do
-       the same thing in 2.2.14?
-*/
-
-/*     This thing is still busted in the 1.2.12 driver on 2.4.x
-       and even hoses the serial console so the oops can be trapped.
-               /\/\|=mhw=|\/\/                 */
-
-#ifdef ENABLE_DSSNOW
-       i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
-
-       init_waitqueue_entry(&wait, current);
-       add_wait_queue(&pCh->dss_now_wait, &wait);
-       set_current_state( TASK_INTERRUPTIBLE );
-
-       serviceOutgoingFifo( pCh->pMyBord );
-
-       schedule();
-
-       set_current_state( TASK_RUNNING );
-       remove_wait_queue(&pCh->dss_now_wait, &wait);
-
-       if (signal_pending(current)) {
-               return -EINTR;
-       }
-#endif
-       return  ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
-             | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
-             | ((pCh->dataSetIn  & I2_DCD) ? TIOCM_CAR : 0)
-             | ((pCh->dataSetIn  & I2_RI)  ? TIOCM_RNG : 0)
-             | ((pCh->dataSetIn  & I2_DSR) ? TIOCM_DSR : 0)
-             | ((pCh->dataSetIn  & I2_CTS) ? TIOCM_CTS : 0);
-}
-
-static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
-                       unsigned int set, unsigned int clear)
-{
-       i2ChanStrPtr pCh = DevTable[tty->index];
-
-       if (pCh == NULL)
-               return -ENODEV;
-
-       if (set & TIOCM_RTS) {
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
-               pCh->dataSetOut |= I2_RTS;
-       }
-       if (set & TIOCM_DTR) {
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
-               pCh->dataSetOut |= I2_DTR;
-       }
-
-       if (clear & TIOCM_RTS) {
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
-               pCh->dataSetOut &= ~I2_RTS;
-       }
-       if (clear & TIOCM_DTR) {
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
-               pCh->dataSetOut &= ~I2_DTR;
-       }
-       serviceOutgoingFifo( pCh->pMyBord );
-       return 0;
-}
-
-/******************************************************************************/
-/* Function:   ip2_ioctl()                                                    */
-/* Parameters: Pointer to tty structure                                       */
-/*             Pointer to file structure                                      */
-/*             Command                                                        */
-/*             Argument                                                       */
-/* Returns:    Success or failure                                             */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static int
-ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
-{
-       wait_queue_t wait;
-       i2ChanStrPtr pCh = DevTable[tty->index];
-       i2eBordStrPtr pB;
-       struct async_icount cprev, cnow;        /* kernel counter temps */
-       struct serial_icounter_struct __user *p_cuser;
-       int rc = 0;
-       unsigned long flags;
-       void __user *argp = (void __user *)arg;
-
-       if ( pCh == NULL )
-               return -ENODEV;
-
-       pB = pCh->pMyBord;
-
-       ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
-
-#ifdef IP2DEBUG_IOCTL
-       printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
-#endif
-
-       switch(cmd) {
-       case TIOCGSERIAL:
-
-               ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
-
-               rc = get_serial_info(pCh, argp);
-               if (rc)
-                       return rc;
-               break;
-
-       case TIOCSSERIAL:
-
-               ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
-
-               rc = set_serial_info(pCh, argp);
-               if (rc)
-                       return rc;
-               break;
-
-       case TCXONC:
-               rc = tty_check_change(tty);
-               if (rc)
-                       return rc;
-               switch (arg) {
-               case TCOOFF:
-                       //return  -ENOIOCTLCMD;
-                       break;
-               case TCOON:
-                       //return  -ENOIOCTLCMD;
-                       break;
-               case TCIOFF:
-                       if (STOP_CHAR(tty) != __DISABLED_CHAR) {
-                               i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
-                                               CMD_XMIT_NOW(STOP_CHAR(tty)));
-                       }
-                       break;
-               case TCION:
-                       if (START_CHAR(tty) != __DISABLED_CHAR) {
-                               i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
-                                               CMD_XMIT_NOW(START_CHAR(tty)));
-                       }
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               return 0;
-
-       case TCSBRK:   /* SVID version: non-zero arg --> no break */
-               rc = tty_check_change(tty);
-
-               ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
-
-               if (!rc) {
-                       ip2_wait_until_sent(tty,0);
-                       if (!arg) {
-                               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
-                               serviceOutgoingFifo( pCh->pMyBord );
-                       }
-               }
-               break;
-
-       case TCSBRKP:  /* support for POSIX tcsendbreak() */
-               rc = tty_check_change(tty);
-
-               ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc );
-
-               if (!rc) {
-                       ip2_wait_until_sent(tty,0);
-                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
-                               CMD_SEND_BRK(arg ? arg*100 : 250));
-                       serviceOutgoingFifo ( pCh->pMyBord );   
-               }
-               break;
-
-       case TIOCGSOFTCAR:
-
-               ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
-
-                       rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
-               if (rc) 
-                       return rc;
-       break;
-
-       case TIOCSSOFTCAR:
-
-               ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
-
-               rc = get_user(arg,(unsigned long __user *) argp);
-               if (rc) 
-                       return rc;
-               tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
-                                        | (arg ? CLOCAL : 0));
-               
-               break;
-
-       /*
-        * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
-        * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
-        * for masking). Caller should use TIOCGICOUNT to see which one it was
-        */
-       case TIOCMIWAIT:
-               WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
-               cprev = pCh->icount;     /* note the counters on entry */
-               WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
-               i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4, 
-                                               CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
-               init_waitqueue_entry(&wait, current);
-               add_wait_queue(&pCh->delta_msr_wait, &wait);
-               set_current_state( TASK_INTERRUPTIBLE );
-
-               serviceOutgoingFifo( pCh->pMyBord );
-               for(;;) {
-                       ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
-
-                       schedule();
-
-                       ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
-
-                       /* see if a signal did it */
-                       if (signal_pending(current)) {
-                               rc = -ERESTARTSYS;
-                               break;
-                       }
-                       WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
-                       cnow = pCh->icount; /* atomic copy */
-                       WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
-                       if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
-                               cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
-                               rc =  -EIO; /* no change => rc */
-                               break;
-                       }
-                       if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
-                           ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
-                           ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
-                           ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
-                               rc =  0;
-                               break;
-                       }
-                       cprev = cnow;
-               }
-               set_current_state( TASK_RUNNING );
-               remove_wait_queue(&pCh->delta_msr_wait, &wait);
-
-               i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3, 
-                                                CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
-               if ( ! (pCh->flags      & ASYNC_CHECK_CD)) {
-                       i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP);
-               }
-               serviceOutgoingFifo( pCh->pMyBord );
-               return rc;
-               break;
-
-       /*
-        * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
-        * Return: write counters to the user passed counter struct
-        * NB: both 1->0 and 0->1 transitions are counted except for RI where
-        * only 0->1 is counted. The controller is quite capable of counting
-        * both, but this done to preserve compatibility with the standard
-        * serial driver.
-        */
-       case TIOCGICOUNT:
-               ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
-
-               WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
-               cnow = pCh->icount;
-               WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
-               p_cuser = argp;
-               rc = put_user(cnow.cts, &p_cuser->cts);
-               rc = put_user(cnow.dsr, &p_cuser->dsr);
-               rc = put_user(cnow.rng, &p_cuser->rng);
-               rc = put_user(cnow.dcd, &p_cuser->dcd);
-               rc = put_user(cnow.rx, &p_cuser->rx);
-               rc = put_user(cnow.tx, &p_cuser->tx);
-               rc = put_user(cnow.frame, &p_cuser->frame);
-               rc = put_user(cnow.overrun, &p_cuser->overrun);
-               rc = put_user(cnow.parity, &p_cuser->parity);
-               rc = put_user(cnow.brk, &p_cuser->brk);
-               rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
-               break;
-
-       /*
-        * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
-        * will be passed to the line discipline for it to handle.
-        */
-       case TIOCSERCONFIG:
-       case TIOCSERGWILD:
-       case TIOCSERGETLSR:
-       case TIOCSERSWILD:
-       case TIOCSERGSTRUCT:
-       case TIOCSERGETMULTI:
-       case TIOCSERSETMULTI:
-
-       default:
-               ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
-
-               rc =  -ENOIOCTLCMD;
-               break;
-       }
-
-       ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
-
-       return rc;
-}
-
-/******************************************************************************/
-/* Function:   GetSerialInfo()                                                */
-/* Parameters: Pointer to channel structure                                   */
-/*             Pointer to old termios structure                               */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/* This is to support the setserial command, and requires processing of the   */
-/* standard Linux serial structure.                                           */
-/******************************************************************************/
-static int
-get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
-{
-       struct serial_struct tmp;
-
-       memset ( &tmp, 0, sizeof(tmp) );
-       tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16];
-       if (BID_HAS_654(tmp.type)) {
-               tmp.type = PORT_16650;
-       } else {
-               tmp.type = PORT_CIRRUS;
-       }
-       tmp.line = pCh->port_index;
-       tmp.port = pCh->pMyBord->i2eBase;
-       tmp.irq  = ip2config.irq[pCh->port_index/64];
-       tmp.flags = pCh->flags;
-       tmp.baud_base = pCh->BaudBase;
-       tmp.close_delay = pCh->ClosingDelay;
-       tmp.closing_wait = pCh->ClosingWaitTime;
-       tmp.custom_divisor = pCh->BaudDivisor;
-       return copy_to_user(retinfo,&tmp,sizeof(*retinfo));
-}
-
-/******************************************************************************/
-/* Function:   SetSerialInfo()                                                */
-/* Parameters: Pointer to channel structure                                   */
-/*             Pointer to old termios structure                               */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/* This function provides support for setserial, which uses the TIOCSSERIAL   */
-/* ioctl. Not all setserial parameters are relevant. If the user attempts to  */
-/* change the IRQ, address or type of the port the ioctl fails.               */
-/******************************************************************************/
-static int
-set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
-{
-       struct serial_struct ns;
-       int   old_flags, old_baud_divisor;
-
-       if (copy_from_user(&ns, new_info, sizeof (ns)))
-               return -EFAULT;
-
-       /*
-        * We don't allow setserial to change IRQ, board address, type or baud
-        * base. Also line nunber as such is meaningless but we use it for our
-        * array index so it is fixed also.
-        */
-       if ( (ns.irq        != ip2config.irq[pCh->port_index])
-           || ((int) ns.port      != ((int) (pCh->pMyBord->i2eBase)))
-           || (ns.baud_base != pCh->BaudBase)
-           || (ns.line      != pCh->port_index) ) {
-               return -EINVAL;
-       }
-
-       old_flags = pCh->flags;
-       old_baud_divisor = pCh->BaudDivisor;
-
-       if ( !capable(CAP_SYS_ADMIN) ) {
-               if ( ( ns.close_delay != pCh->ClosingDelay ) ||
-                   ( (ns.flags & ~ASYNC_USR_MASK) !=
-                     (pCh->flags & ~ASYNC_USR_MASK) ) ) {
-                       return -EPERM;
-               }
-
-               pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
-                              (ns.flags & ASYNC_USR_MASK);
-               pCh->BaudDivisor = ns.custom_divisor;
-       } else {
-               pCh->flags = (pCh->flags & ~ASYNC_FLAGS) |
-                              (ns.flags & ASYNC_FLAGS);
-               pCh->BaudDivisor = ns.custom_divisor;
-               pCh->ClosingDelay = ns.close_delay * HZ/100;
-               pCh->ClosingWaitTime = ns.closing_wait * HZ/100;
-       }
-
-       if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) )
-           || (old_baud_divisor != pCh->BaudDivisor) ) {
-               // Invalidate speed and reset parameters
-               set_params( pCh, NULL );
-       }
-
-       return 0;
-}
-
-/******************************************************************************/
-/* Function:   ip2_set_termios()                                              */
-/* Parameters: Pointer to tty structure                                       */
-/*             Pointer to old termios structure                               */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static void
-ip2_set_termios( PTTY tty, struct termios *old_termios )
-{
-       i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
-
-#ifdef IP2DEBUG_IOCTL
-       printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
-#endif
-
-       set_params( pCh, old_termios );
-}
-
-/******************************************************************************/
-/* Function:   ip2_set_line_discipline()                                      */
-/* Parameters: Pointer to tty structure                                       */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:  Does nothing                                                 */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static void
-ip2_set_line_discipline ( PTTY tty )
-{
-#ifdef IP2DEBUG_IOCTL
-       printk (KERN_DEBUG "IP2: set line discipline\n" );
-#endif
-
-       ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
-
-}
-
-/******************************************************************************/
-/* Function:   SetLine Characteristics()                                      */
-/* Parameters: Pointer to channel structure                                   */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/* This routine is called to update the channel structure with the new line   */
-/* characteristics, and send the appropriate commands to the board when they  */
-/* change.                                                                    */
-/******************************************************************************/
-static void
-set_params( i2ChanStrPtr pCh, struct termios *o_tios )
-{
-       tcflag_t cflag, iflag, lflag;
-       char stop_char, start_char;
-       struct termios dummy;
-
-       lflag = pCh->pTTY->termios->c_lflag;
-       cflag = pCh->pTTY->termios->c_cflag;
-       iflag = pCh->pTTY->termios->c_iflag;
-
-       if (o_tios == NULL) {
-               dummy.c_lflag = ~lflag;
-               dummy.c_cflag = ~cflag;
-               dummy.c_iflag = ~iflag;
-               o_tios = &dummy;
-       }
-
-       {
-               switch ( cflag & CBAUD ) {
-               case B0:
-                       i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
-                       pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
-                       i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
-                       pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag);
-                       goto service_it;
-                       break;
-               case B38400:
-                       /*
-                        * This is the speed that is overloaded with all the other high
-                        * speeds, depending upon the flag settings.
-                        */
-                       if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) {
-                               pCh->speed = CBR_57600;
-                       } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) {
-                               pCh->speed = CBR_115200;
-                       } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) {
-                               pCh->speed = CBR_C1;
-                       } else {
-                               pCh->speed = CBR_38400;
-                       }
-                       break;
-               case B50:      pCh->speed = CBR_50;      break;
-               case B75:      pCh->speed = CBR_75;      break;
-               case B110:     pCh->speed = CBR_110;     break;
-               case B134:     pCh->speed = CBR_134;     break;
-               case B150:     pCh->speed = CBR_150;     break;
-               case B200:     pCh->speed = CBR_200;     break;
-               case B300:     pCh->speed = CBR_300;     break;
-               case B600:     pCh->speed = CBR_600;     break;
-               case B1200:    pCh->speed = CBR_1200;    break;
-               case B1800:    pCh->speed = CBR_1800;    break;
-               case B2400:    pCh->speed = CBR_2400;    break;
-               case B4800:    pCh->speed = CBR_4800;    break;
-               case B9600:    pCh->speed = CBR_9600;    break;
-               case B19200:   pCh->speed = CBR_19200;   break;
-               case B57600:   pCh->speed = CBR_57600;   break;
-               case B115200:  pCh->speed = CBR_115200;  break;
-               case B153600:  pCh->speed = CBR_153600;  break;
-               case B230400:  pCh->speed = CBR_230400;  break;
-               case B307200:  pCh->speed = CBR_307200;  break;
-               case B460800:  pCh->speed = CBR_460800;  break;
-               case B921600:  pCh->speed = CBR_921600;  break;
-               default:       pCh->speed = CBR_9600;    break;
-               }
-               if ( pCh->speed == CBR_C1 ) {
-                       // Process the custom speed parameters.
-                       int bps = pCh->BaudBase / pCh->BaudDivisor;
-                       if ( bps == 921600 ) {
-                               pCh->speed = CBR_921600;
-                       } else {
-                               bps = bps/10;
-                               i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
-                       }
-               }
-               i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
-               
-               i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
-               pCh->dataSetOut |= (I2_DTR | I2_RTS);
-       }
-       if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag)) 
-       {
-               i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, 
-                       CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
-       }
-       if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag)) 
-       {
-               i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
-                       CMD_SETPAR( 
-                               (cflag & PARENB ?  (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
-                       )
-               );
-       }
-       /* byte size and parity */
-       if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag)) 
-       {
-               int datasize;
-               switch ( cflag & CSIZE ) {
-               case CS5: datasize = CSZ_5; break;
-               case CS6: datasize = CSZ_6; break;
-               case CS7: datasize = CSZ_7; break;
-               case CS8: datasize = CSZ_8; break;
-               default:  datasize = CSZ_5; break;      /* as per serial.c */
-               }
-               i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
-       }
-       /* Process CTS flow control flag setting */
-       if ( (cflag & CRTSCTS) ) {
-               i2QueueCommands(PTYPE_INLINE, pCh, 100,
-                                               2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB);
-       } else {
-               i2QueueCommands(PTYPE_INLINE, pCh, 100,
-                                               2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
-       }
-       //
-       // Process XON/XOFF flow control flags settings
-       //
-       stop_char = STOP_CHAR(pCh->pTTY);
-       start_char = START_CHAR(pCh->pTTY);
-
-       //////////// can't be \000
-       if (stop_char == __DISABLED_CHAR ) 
-       {
-               stop_char = ~__DISABLED_CHAR; 
-       }
-       if (start_char == __DISABLED_CHAR ) 
-       {
-               start_char = ~__DISABLED_CHAR;
-       }
-       /////////////////////////////////
-
-       if ( o_tios->c_cc[VSTART] != start_char ) 
-       {
-               i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
-       }
-       if ( o_tios->c_cc[VSTOP] != stop_char ) 
-       {
-                i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
-                i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
-       }
-       if (stop_char == __DISABLED_CHAR ) 
-       {
-               stop_char = ~__DISABLED_CHAR;  //TEST123
-               goto no_xoff;
-       }
-       if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF))) 
-       {
-               if ( iflag & IXOFF ) {  // Enable XOFF output flow control
-                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON));
-               } else {        // Disable XOFF output flow control
-no_xoff:
-                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
-               }
-       }
-       if (start_char == __DISABLED_CHAR ) 
-       {
-               goto no_xon;
-       }
-       if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY))) 
-       {
-               if ( iflag & IXON ) {
-                       if ( iflag & IXANY ) { // Enable XON/XANY output flow control
-                               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY));
-                       } else { // Enable XON output flow control
-                               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON));
-                       }
-               } else { // Disable XON output flow control
-no_xon:
-                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
-               }
-       }
-       if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) ) 
-       {
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, 
-                               CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
-       }
-       if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) ) 
-       {
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, 
-                               CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
-       }
-
-       if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) 
-                       ^       ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) ) 
-       {
-               char brkrpt = 0;
-               char parrpt = 0;
-
-               if ( iflag & IGNBRK ) { /* Ignore breaks altogether */
-                       /* Ignore breaks altogether */
-                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
-               } else {
-                       if ( iflag & BRKINT ) {
-                               if ( iflag & PARMRK ) {
-                                       brkrpt = 0x0a;  // exception an inline triple
-                               } else {
-                                       brkrpt = 0x1a;  // exception and NULL
-                               }
-                               brkrpt |= 0x04; // flush input
-                       } else {
-                               if ( iflag & PARMRK ) {
-                                       brkrpt = 0x0b;  //POSIX triple \0377 \0 \0
-                               } else {
-                                       brkrpt = 0x01;  // Null only
-                               }
-                       }
-                       i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
-               } 
-
-               if (iflag & IGNPAR) {
-                       parrpt = 0x20;
-                                                                                                       /* would be 2 for not cirrus bug */
-                                                                                                       /* would be 0x20 cept for cirrus bug */
-               } else {
-                       if ( iflag & PARMRK ) {
-                               /*
-                                * Replace error characters with 3-byte sequence (\0377,\0,char)
-                                */
-                               parrpt = 0x04 ;
-                               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
-                       } else {
-                               parrpt = 0x03;
-                       } 
-               }
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
-       }
-       if (cflag & CLOCAL) {
-               // Status reporting fails for DCD if this is off
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP);
-               pCh->flags &= ~ASYNC_CHECK_CD;
-       } else {
-               i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
-               pCh->flags      |= ASYNC_CHECK_CD;
-       }
-
-service_it:
-       i2DrainOutput( pCh, 100 );              
-}
-
-/******************************************************************************/
-/* IPL Device Section                                                         */
-/******************************************************************************/
-
-/******************************************************************************/
-/* Function:   ip2_ipl_read()                                                  */
-/* Parameters: Pointer to device inode                                        */
-/*             Pointer to file structure                                      */
-/*             Pointer to data                                                */
-/*             Number of bytes to read                                        */
-/* Returns:    Success or failure                                             */
-/*                                                                            */
-/* Description:   Ugly                                                        */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-
-static 
-ssize_t
-ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
-{
-       unsigned int minor = iminor(pFile->f_dentry->d_inode);
-       int rc = 0;
-
-#ifdef IP2DEBUG_IPL
-       printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
-#endif
-
-       switch( minor ) {
-       case 0:     // IPL device
-               rc = -EINVAL;
-               break;
-       case 1:     // Status dump
-               rc = -EINVAL;
-               break;
-       case 2:     // Ping device
-               rc = -EINVAL;
-               break;
-       case 3:     // Trace device
-               rc = DumpTraceBuffer ( pData, count );
-               break;
-       case 4:     // Trace device
-               rc = DumpFifoBuffer ( pData, count );
-               break;
-       default:
-               rc = -ENODEV;
-               break;
-       }
-       return rc;
-}
-
-static int
-DumpFifoBuffer ( char __user *pData, int count )
-{
-#ifdef DEBUG_FIFO
-       int rc;
-       rc = copy_to_user(pData, DBGBuf, count);
-
-       printk(KERN_DEBUG "Last index %d\n", I );
-
-       return count;
-#endif /* DEBUG_FIFO */
-       return 0;
-}
-
-static int
-DumpTraceBuffer ( char __user *pData, int count )
-{
-#ifdef IP2DEBUG_TRACE
-       int rc;
-       int dumpcount;
-       int chunk;
-       int *pIndex = (int __user *)pData;
-
-       if ( count < (sizeof(int) * 6) ) {
-               return -EIO;
-       }
-       rc = put_user(tracewrap, pIndex );
-       rc = put_user(TRACEMAX, ++pIndex );
-       rc = put_user(tracestrip, ++pIndex );
-       rc = put_user(tracestuff, ++pIndex );
-       pData += sizeof(int) * 6;
-       count -= sizeof(int) * 6;
-
-       dumpcount = tracestuff - tracestrip;
-       if ( dumpcount < 0 ) {
-               dumpcount += TRACEMAX;
-       }
-       if ( dumpcount > count ) {
-               dumpcount = count;
-       }
-       chunk = TRACEMAX - tracestrip;
-       if ( dumpcount > chunk ) {
-               rc = copy_to_user(pData, &tracebuf[tracestrip],
-                             chunk * sizeof(tracebuf[0]) );
-               pData += chunk * sizeof(tracebuf[0]);
-               tracestrip = 0;
-               chunk = dumpcount - chunk;
-       } else {
-               chunk = dumpcount;
-       }
-       rc = copy_to_user(pData, &tracebuf[tracestrip],
-                     chunk * sizeof(tracebuf[0]) );
-       tracestrip += chunk;
-       tracewrap = 0;
-
-       rc = put_user(tracestrip, ++pIndex );
-       rc = put_user(tracestuff, ++pIndex );
-
-       return dumpcount;
-#else
-       return 0;
-#endif
-}
-
-/******************************************************************************/
-/* Function:   ip2_ipl_write()                                                 */
-/* Parameters:                                                                */
-/*             Pointer to file structure                                      */
-/*             Pointer to data                                                */
-/*             Number of bytes to write                                       */
-/* Returns:    Success or failure                                             */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static ssize_t
-ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
-{
-#ifdef IP2DEBUG_IPL
-       printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
-#endif
-       return 0;
-}
-
-/******************************************************************************/
-/* Function:   ip2_ipl_ioctl()                                                */
-/* Parameters: Pointer to device inode                                        */
-/*             Pointer to file structure                                      */
-/*             Command                                                        */
-/*             Argument                                                       */
-/* Returns:    Success or failure                                             */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static int
-ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
-{
-       unsigned int iplminor = iminor(pInode);
-       int rc = 0;
-       void __user *argp = (void __user *)arg;
-       ULONG __user *pIndex = argp;
-       i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
-       i2ChanStrPtr pCh;
-
-#ifdef IP2DEBUG_IPL
-       printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
-#endif
-
-       switch ( iplminor ) {
-       case 0:     // IPL device
-               rc = -EINVAL;
-               break;
-       case 1:     // Status dump
-       case 5:
-       case 9:
-       case 13:
-               switch ( cmd ) {
-               case 64:        /* Driver - ip2stat */
-                       rc = put_user(ip2_tty_driver->refcount, pIndex++ );
-                       rc = put_user(irq_counter, pIndex++  );
-                       rc = put_user(bh_counter, pIndex++  );
-                       break;
-
-               case 65:        /* Board  - ip2stat */
-                       if ( pB ) {
-                               rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
-                               rc = put_user(INB(pB->i2eStatus),
-                                       (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
-                       } else {
-                               rc = -ENODEV;
-                       }
-                       break;
-
-               default:
-                       if (cmd < IP2_MAX_PORTS) {
-                               pCh = DevTable[cmd];
-                               if ( pCh )
-                               {
-                                       rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
-                               } else {
-                                       rc = -ENODEV;
-                               }
-                       } else {
-                               rc = -EINVAL;
-                       }
-               }
-               break;
-
-       case 2:     // Ping device
-               rc = -EINVAL;
-               break;
-       case 3:     // Trace device
-               /*
-                * akpm: This used to write a whole bunch of function addresses
-                * to userspace, which generated lots of put_user() warnings.
-                * I killed it all.  Just return "success" and don't do
-                * anything.
-                */
-               if (cmd == 1)
-                       rc = 0;
-               else
-                       rc = -EINVAL;
-               break;
-
-       default:
-               rc = -ENODEV;
-               break;
-       }
-       return rc;
-}
-
-/******************************************************************************/
-/* Function:   ip2_ipl_open()                                                 */
-/* Parameters: Pointer to device inode                                        */
-/*             Pointer to file structure                                      */
-/* Returns:    Success or failure                                             */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-static int
-ip2_ipl_open( struct inode *pInode, struct file *pFile )
-{
-       unsigned int iplminor = iminor(pInode);
-       i2eBordStrPtr pB;
-       i2ChanStrPtr  pCh;
-
-#ifdef IP2DEBUG_IPL
-       printk (KERN_DEBUG "IP2IPL: open\n" );
-#endif
-
-       switch(iplminor) {
-       // These are the IPL devices
-       case 0:
-       case 4:
-       case 8:
-       case 12:
-               break;
-
-       // These are the status devices
-       case 1:
-       case 5:
-       case 9:
-       case 13:
-               break;
-
-       // These are the debug devices
-       case 2:
-       case 6:
-       case 10:
-       case 14:
-               pB = i2BoardPtrTable[iplminor / 4];
-               pCh = (i2ChanStrPtr) pB->i2eChannelPtr;
-               break;
-
-       // This is the trace device
-       case 3:
-               break;
-       }
-       return 0;
-}
-/******************************************************************************/
-/* Function:   ip2_read_procmem                                               */
-/* Parameters:                                                                */
-/*                                                                            */
-/* Returns: Length of output                                                  */
-/*                                                                            */
-/* Description:                                                               */
-/*   Supplies some driver operating parameters                                */
-/*     Not real useful unless your debugging the fifo                                                    */
-/*                                                                            */
-/******************************************************************************/
-
-#define LIMIT  (PAGE_SIZE - 120)
-
-static int
-ip2_read_procmem(char *buf, char **start, off_t offset, int len)
-{
-       i2eBordStrPtr  pB;
-       i2ChanStrPtr  pCh;
-       PTTY tty;
-       int i;
-
-       len = 0;
-
-#define FMTLINE        "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
-#define FMTLIN2        "     0x%04x 0x%04x tx flow 0x%x\n"
-#define FMTLIN3        "     0x%04x 0x%04x rc flow\n"
-
-       len += sprintf(buf+len,"\n");
-
-       for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               pB = i2BoardPtrTable[i];
-               if ( pB ) {
-                       len += sprintf(buf+len,"board %d:\n",i);
-                       len += sprintf(buf+len,"\tFifo rem: %d mty: %x outM %x\n",
-                               pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting);
-               }
-       }
-
-       len += sprintf(buf+len,"#: tty flags, port flags,     cflags,     iflags\n");
-       for (i=0; i < IP2_MAX_PORTS; i++) {
-               if (len > LIMIT)
-                       break;
-               pCh = DevTable[i];
-               if (pCh) {
-                       tty = pCh->pTTY;
-                       if (tty && tty->count) {
-                               len += sprintf(buf+len,FMTLINE,i,(int)tty->flags,pCh->flags,
-                                                                       tty->termios->c_cflag,tty->termios->c_iflag);
-
-                               len += sprintf(buf+len,FMTLIN2,
-                                               pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds);
-                               len += sprintf(buf+len,FMTLIN3,pCh->infl.asof,pCh->infl.room);
-                       }
-               }
-       }
-       return len;
-}
-
-/*
- * This is the handler for /proc/tty/driver/ip2
- *
- * This stretch of code has been largely plagerized from at least three
- * different sources including ip2mkdev.c and a couple of other drivers.
- * The bugs are all mine.  :-) =mhw=
- */
-static int ip2_read_proc(char *page, char **start, off_t off,
-                               int count, int *eof, void *data)
-{
-       int     i, j, box;
-       int     len = 0;
-       int     boxes = 0;
-       int     ports = 0;
-       int     tports = 0;
-       off_t   begin = 0;
-       i2eBordStrPtr  pB;
-
-       len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
-       len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
-                       IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
-                       IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
-
-       for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
-               /* This need to be reset for a board by board count... */
-               boxes = 0;
-               pB = i2BoardPtrTable[i];
-               if( pB ) {
-                       switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) 
-                       {
-                       case POR_ID_FIIEX:
-                               len += sprintf( page+len, "Board %d: EX ports=", i );
-                               for( box = 0; box < ABS_MAX_BOXES; ++box )
-                               {
-                                       ports = 0;
-
-                                       if( pB->i2eChannelMap[box] != 0 ) ++boxes;
-                                       for( j = 0; j < ABS_BIGGEST_BOX; ++j ) 
-                                       {
-                                               if( pB->i2eChannelMap[box] & 1<< j ) {
-                                                       ++ports;
-                                               }
-                                       }
-                                       len += sprintf( page+len, "%d,", ports );
-                                       tports += ports;
-                               }
-
-                               --len;  /* Backup over that last comma */
-
-                               len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
-                               break;
-
-                       case POR_ID_II_4:
-                               len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
-                               tports = ports = 4;
-                               break;
-
-                       case POR_ID_II_8:
-                               len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
-                               tports = ports = 8;
-                               break;
-
-                       case POR_ID_II_8R:
-                               len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
-                               tports = ports = 8;
-                               break;
-
-                       default:
-                               len += sprintf(page+len, "Board %d: unknown", i );
-                               /* Don't try and probe for minor numbers */
-                               tports = ports = 0;
-                       }
-
-               } else {
-                       /* Don't try and probe for minor numbers */
-                       len += sprintf(page+len, "Board %d: vacant", i );
-                       tports = ports = 0;
-               }
-
-               if( tports ) {
-                       len += sprintf(page+len, " minors=" );
-
-                       for ( box = 0; box < ABS_MAX_BOXES; ++box )
-                       {
-                               for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
-                               {
-                                       if ( pB->i2eChannelMap[box] & (1 << j) )
-                                       {
-                                               len += sprintf (page+len,"%d,",
-                                                       j + ABS_BIGGEST_BOX *
-                                                       (box+i*ABS_MAX_BOXES));
-                                       }
-                               }
-                       }
-
-                       page[ len - 1 ] = '\n'; /* Overwrite that last comma */
-               } else {
-                       len += sprintf (page+len,"\n" );
-               }
-
-               if (len+begin > off+count)
-                       break;
-               if (len+begin < off) {
-                       begin += len;
-                       len = 0;
-               }
-       }
-
-       if (i >= IP2_MAX_BOARDS)
-               *eof = 1;
-       if (off >= len+begin)
-               return 0;
-
-       *start = page + (off-begin);
-       return ((count < begin+len-off) ? count : begin+len-off);
- }
-/******************************************************************************/
-/* Function:   ip2trace()                                                     */
-/* Parameters: Value to add to trace buffer                                   */
-/* Returns:    Nothing                                                        */
-/*                                                                            */
-/* Description:                                                               */
-/*                                                                            */
-/*                                                                            */
-/******************************************************************************/
-#ifdef IP2DEBUG_TRACE
-void
-ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
-{
-       long flags;
-       unsigned long *pCode = &codes;
-       union ip2breadcrumb bc;
-       i2ChanStrPtr  pCh;
-
-
-       tracebuf[tracestuff++] = jiffies;
-       if ( tracestuff == TRACEMAX ) {
-               tracestuff = 0;
-       }
-       if ( tracestuff == tracestrip ) {
-               if ( ++tracestrip == TRACEMAX ) {
-                       tracestrip = 0;
-               }
-               ++tracewrap;
-       }
-
-       bc.hdr.port  = 0xff & pn;
-       bc.hdr.cat   = cat;
-       bc.hdr.codes = (unsigned char)( codes & 0xff );
-       bc.hdr.label = label;
-       tracebuf[tracestuff++] = bc.value;
-
-       for (;;) {
-               if ( tracestuff == TRACEMAX ) {
-                       tracestuff = 0;
-               }
-               if ( tracestuff == tracestrip ) {
-                       if ( ++tracestrip == TRACEMAX ) {
-                               tracestrip = 0;
-                       }
-                       ++tracewrap;
-               }
-
-               if ( !codes-- )
-                       break;
-
-               tracebuf[tracestuff++] = *++pCode;
-       }
-}
-#endif
-
-
-MODULE_LICENSE("GPL");
index 2e308657f6f6df733acb3ea381d4604264e60e87..b0038b19b5056a7bbca2991b704749ed5d2a153a 100644 (file)
@@ -448,13 +448,13 @@ static int s3c2410_rtc_probe(struct platform_device *pdev)
        /* find the IRQs */
 
        s3c2410_rtc_tickno = platform_get_irq(pdev, 1);
-       if (s3c2410_rtc_tickno <= 0) {
+       if (s3c2410_rtc_tickno < 0) {
                dev_err(&pdev->dev, "no irq for rtc tick\n");
                return -ENOENT;
        }
 
        s3c2410_rtc_alarmno = platform_get_irq(pdev, 0);
-       if (s3c2410_rtc_alarmno <= 0) {
+       if (s3c2410_rtc_alarmno < 0) {
                dev_err(&pdev->dev, "no irq for alarm\n");
                return -ENOENT;
        }
index b4d843489881adaacdf3e2326ed09bf49b9b0f7d..2c2c517732000a8337d2da0ee54383eb0ce1f0ed 100644 (file)
@@ -338,6 +338,10 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
 
        wdt->dev = &dev->dev;
        wdt->irq = platform_get_irq(dev, 0);
+       if (wdt->irq < 0) {
+               ret = -ENXIO;
+               goto err_free;
+       }
        wdt->base = ioremap(res->start, res->end - res->start + 1);
        if (!wdt->base) {
                ret = -ENOMEM;
index 1414851a17b8ee1ea13df7124060dec12522055b..d00a02fc23e42b3878390d58c2619eec0cf222bf 100644 (file)
@@ -434,7 +434,7 @@ static int
 iop3xx_i2c_probe(struct platform_device *pdev)
 {
        struct resource *res;
-       int ret;
+       int ret, irq;
        struct i2c_adapter *new_adapter;
        struct i2c_algo_iop3xx_data *adapter_data;
 
@@ -470,7 +470,12 @@ iop3xx_i2c_probe(struct platform_device *pdev)
                goto release_region;
        }
 
-       ret = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0,
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = -ENXIO;
+               goto unmap;
+       }
+       ret = request_irq(irq, iop3xx_i2c_irq_handler, 0,
                                pdev->name, adapter_data);
 
        if (ret) {
index 5ccd338a9dc98f19c273bcc81e3e758e0ab85594..2721e4c8184a9a64f505686ebf7bf6e1e80ecf59 100644 (file)
@@ -302,6 +302,10 @@ static int fsl_i2c_probe(struct platform_device *pdev)
        }
 
        i2c->irq = platform_get_irq(pdev, 0);
+       if (i2c->irq < 0) {
+               result = -ENXIO;
+               goto fail_get_irq;
+       }
        i2c->flags = pdata->device_flags;
        init_waitqueue_head(&i2c->queue);
 
@@ -340,6 +344,7 @@ static int fsl_i2c_probe(struct platform_device *pdev)
       fail_irq:
        iounmap(i2c->base);
       fail_map:
+      fail_get_irq:
        kfree(i2c);
        return result;
 };
index 22781d84f79f256d0be11c412be15c1b6f2dc22d..ac5cde1bbd2ba24333d2360ce3b253d60a3426c8 100644 (file)
@@ -516,6 +516,10 @@ mv64xxx_i2c_probe(struct platform_device *pd)
        drv_data->freq_m = pdata->freq_m;
        drv_data->freq_n = pdata->freq_n;
        drv_data->irq = platform_get_irq(pd, 0);
+       if (drv_data->irq < 0) {
+               rc = -ENXIO;
+               goto exit_unmap_regs;
+       }
        drv_data->adapter.id = I2C_HW_MV64XXX;
        drv_data->adapter.algo = &mv64xxx_i2c_algo;
        drv_data->adapter.owner = THIS_MODULE;
index 32431dcf5d8e51cf181ecd2f78b8cfa24fecc6c0..71f27e955d877d86d89bd63862b5206670f28061 100644 (file)
@@ -674,6 +674,11 @@ static int au_ide_probe(struct device *dev)
                ret = -ENODEV;
                goto out;
        }
+       if (ahwif->irq < 0) {
+               pr_debug("%s %d: no IRQ\n", DRV_NAME, pdev->id);
+               ret = -ENODEV;
+               goto out;
+       }
 
        if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
                pr_debug("%s: request_mem_region failed\n", DRV_NAME);
index 34b724afd28daf15ca52e14270a796fc9cfcede3..ecd1a3057c61bf41e9f09c5be5727de78866620d 100644 (file)
@@ -78,25 +78,6 @@ ib_get_agent_port(struct ib_device *device, int port_num)
        return entry;
 }
 
-int smi_check_local_dr_smp(struct ib_smp *smp,
-                          struct ib_device *device,
-                          int port_num)
-{
-       struct ib_agent_port_private *port_priv;
-
-       if (smp->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
-               return 1;
-
-       port_priv = ib_get_agent_port(device, port_num);
-       if (!port_priv) {
-               printk(KERN_DEBUG SPFX "smi_check_local_dr_smp %s port %d "
-                      "not open\n", device->name, port_num);
-               return 1;
-       }
-
-       return smi_check_local_smp(port_priv->agent[0], smp);
-}
-
 int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
                        struct ib_wc *wc, struct ib_device *device,
                        int port_num, int qpn)
index 2514de3480d83bf10fdd84a67e0a81172e10efab..7cfedb8d9bcd963dc81a04ad11eac0322f30eee8 100644 (file)
@@ -121,7 +121,7 @@ struct cm_id_private {
 
        struct rb_node service_node;
        struct rb_node sidr_id_node;
-       spinlock_t lock;
+       spinlock_t lock;        /* Do not acquire inside cm.lock */
        wait_queue_head_t wait;
        atomic_t refcount;
 
@@ -1547,40 +1547,46 @@ static int cm_rep_handler(struct cm_work *work)
                return -EINVAL;
        }
 
+       cm_format_rep_event(work);
+
+       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       switch (cm_id_priv->id.state) {
+       case IB_CM_REQ_SENT:
+       case IB_CM_MRA_REQ_RCVD:
+               break;
+       default:
+               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               ret = -EINVAL;
+               goto error;
+       }
+
        cm_id_priv->timewait_info->work.remote_id = rep_msg->local_comm_id;
        cm_id_priv->timewait_info->remote_ca_guid = rep_msg->local_ca_guid;
        cm_id_priv->timewait_info->remote_qpn = cm_rep_get_local_qpn(rep_msg);
 
-       spin_lock_irqsave(&cm.lock, flags);
+       spin_lock(&cm.lock);
        /* Check for duplicate REP. */
        if (cm_insert_remote_id(cm_id_priv->timewait_info)) {
-               spin_unlock_irqrestore(&cm.lock, flags);
+               spin_unlock(&cm.lock);
+               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
                ret = -EINVAL;
                goto error;
        }
        /* Check for a stale connection. */
        if (cm_insert_remote_qpn(cm_id_priv->timewait_info)) {
-               spin_unlock_irqrestore(&cm.lock, flags);
+               rb_erase(&cm_id_priv->timewait_info->remote_id_node,
+                        &cm.remote_id_table);
+               cm_id_priv->timewait_info->inserted_remote_id = 0;
+               spin_unlock(&cm.lock);
+               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
                cm_issue_rej(work->port, work->mad_recv_wc,
                             IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REP,
                             NULL, 0);
                ret = -EINVAL;
                goto error;
        }
-       spin_unlock_irqrestore(&cm.lock, flags);
-
-       cm_format_rep_event(work);
+       spin_unlock(&cm.lock);
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
-       switch (cm_id_priv->id.state) {
-       case IB_CM_REQ_SENT:
-       case IB_CM_MRA_REQ_RCVD:
-               break;
-       default:
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
-               ret = -EINVAL;
-               goto error;
-       }
        cm_id_priv->id.state = IB_CM_REP_RCVD;
        cm_id_priv->id.remote_id = rep_msg->local_comm_id;
        cm_id_priv->remote_qpn = cm_rep_get_local_qpn(rep_msg);
@@ -1603,7 +1609,7 @@ static int cm_rep_handler(struct cm_work *work)
                cm_deref_id(cm_id_priv);
        return 0;
 
-error: cm_cleanup_timewait(cm_id_priv->timewait_info);
+error:
        cm_deref_id(cm_id_priv);
        return ret;
 }
index d34a6f1c4f4c53a48c2d6ea401ccf5bfcdfa61e0..838bf54458d2d2ddda812583d1fb7273179d491a 100644 (file)
@@ -278,9 +278,9 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd             *pd,
        {
                struct ib_pool_fmr *fmr;
                struct ib_fmr_attr attr = {
-                       .max_pages = params->max_pages_per_fmr,
-                       .max_maps  = IB_FMR_MAX_REMAPS,
-                       .page_size = PAGE_SHIFT
+                       .max_pages  = params->max_pages_per_fmr,
+                       .max_maps   = IB_FMR_MAX_REMAPS,
+                       .page_shift = params->page_shift
                };
 
                for (i = 0; i < params->pool_size; ++i) {
index c82f47a66e48f8ee4d1f48bb80c9eec220bc37c8..f7854b65fd553c1b271bd5b8b7a6def94881d6ff 100644 (file)
@@ -31,7 +31,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: mad.c 2817 2005-07-07 11:29:26Z halr $
+ * $Id: mad.c 5596 2006-03-03 01:00:07Z sean.hefty $
  */
 #include <linux/dma-mapping.h>
 
@@ -679,8 +679,8 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
                goto out;
        }
        /* Check to post send on QP or process locally */
-       ret = smi_check_local_dr_smp(smp, device, port_num);
-       if (!ret || !device->process_mad)
+       ret = smi_check_local_smp(smp, device);
+       if (!ret)
                goto out;
 
        local = kmalloc(sizeof *local, GFP_ATOMIC);
@@ -765,18 +765,67 @@ out:
        return ret;
 }
 
-static int get_buf_length(int hdr_len, int data_len)
+static int get_pad_size(int hdr_len, int data_len)
 {
        int seg_size, pad;
 
        seg_size = sizeof(struct ib_mad) - hdr_len;
        if (data_len && seg_size) {
                pad = seg_size - data_len % seg_size;
-               if (pad == seg_size)
-                       pad = 0;
+               return pad == seg_size ? 0 : pad;
        } else
-               pad = seg_size;
-       return hdr_len + data_len + pad;
+               return seg_size;
+}
+
+static void free_send_rmpp_list(struct ib_mad_send_wr_private *mad_send_wr)
+{
+       struct ib_rmpp_segment *s, *t;
+
+       list_for_each_entry_safe(s, t, &mad_send_wr->rmpp_list, list) {
+               list_del(&s->list);
+               kfree(s);
+       }
+}
+
+static int alloc_send_rmpp_list(struct ib_mad_send_wr_private *send_wr,
+                               gfp_t gfp_mask)
+{
+       struct ib_mad_send_buf *send_buf = &send_wr->send_buf;
+       struct ib_rmpp_mad *rmpp_mad = send_buf->mad;
+       struct ib_rmpp_segment *seg = NULL;
+       int left, seg_size, pad;
+
+       send_buf->seg_size = sizeof (struct ib_mad) - send_buf->hdr_len;
+       seg_size = send_buf->seg_size;
+       pad = send_wr->pad;
+
+       /* Allocate data segments. */
+       for (left = send_buf->data_len + pad; left > 0; left -= seg_size) {
+               seg = kmalloc(sizeof (*seg) + seg_size, gfp_mask);
+               if (!seg) {
+                       printk(KERN_ERR "alloc_send_rmpp_segs: RMPP mem "
+                              "alloc failed for len %zd, gfp %#x\n",
+                              sizeof (*seg) + seg_size, gfp_mask);
+                       free_send_rmpp_list(send_wr);
+                       return -ENOMEM;
+               }
+               seg->num = ++send_buf->seg_count;
+               list_add_tail(&seg->list, &send_wr->rmpp_list);
+       }
+
+       /* Zero any padding */
+       if (pad)
+               memset(seg->data + seg_size - pad, 0, pad);
+
+       rmpp_mad->rmpp_hdr.rmpp_version = send_wr->mad_agent_priv->
+                                         agent.rmpp_version;
+       rmpp_mad->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_DATA;
+       ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
+
+       send_wr->cur_seg = container_of(send_wr->rmpp_list.next,
+                                       struct ib_rmpp_segment, list);
+       send_wr->last_ack_seg = send_wr->cur_seg;
+       return 0;
 }
 
 struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
@@ -787,32 +836,40 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
 {
        struct ib_mad_agent_private *mad_agent_priv;
        struct ib_mad_send_wr_private *mad_send_wr;
-       int buf_size;
+       int pad, message_size, ret, size;
        void *buf;
 
        mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private,
                                      agent);
-       buf_size = get_buf_length(hdr_len, data_len);
+       pad = get_pad_size(hdr_len, data_len);
+       message_size = hdr_len + data_len + pad;
 
        if ((!mad_agent->rmpp_version &&
-            (rmpp_active || buf_size > sizeof(struct ib_mad))) ||
-           (!rmpp_active && buf_size > sizeof(struct ib_mad)))
+            (rmpp_active || message_size > sizeof(struct ib_mad))) ||
+           (!rmpp_active && message_size > sizeof(struct ib_mad)))
                return ERR_PTR(-EINVAL);
 
-       buf = kzalloc(sizeof *mad_send_wr + buf_size, gfp_mask);
+       size = rmpp_active ? hdr_len : sizeof(struct ib_mad);
+       buf = kzalloc(sizeof *mad_send_wr + size, gfp_mask);
        if (!buf)
                return ERR_PTR(-ENOMEM);
 
-       mad_send_wr = buf + buf_size;
+       mad_send_wr = buf + size;
+       INIT_LIST_HEAD(&mad_send_wr->rmpp_list);
        mad_send_wr->send_buf.mad = buf;
+       mad_send_wr->send_buf.hdr_len = hdr_len;
+       mad_send_wr->send_buf.data_len = data_len;
+       mad_send_wr->pad = pad;
 
        mad_send_wr->mad_agent_priv = mad_agent_priv;
-       mad_send_wr->sg_list[0].length = buf_size;
+       mad_send_wr->sg_list[0].length = hdr_len;
        mad_send_wr->sg_list[0].lkey = mad_agent->mr->lkey;
+       mad_send_wr->sg_list[1].length = sizeof(struct ib_mad) - hdr_len;
+       mad_send_wr->sg_list[1].lkey = mad_agent->mr->lkey;
 
        mad_send_wr->send_wr.wr_id = (unsigned long) mad_send_wr;
        mad_send_wr->send_wr.sg_list = mad_send_wr->sg_list;
-       mad_send_wr->send_wr.num_sge = 1;
+       mad_send_wr->send_wr.num_sge = 2;
        mad_send_wr->send_wr.opcode = IB_WR_SEND;
        mad_send_wr->send_wr.send_flags = IB_SEND_SIGNALED;
        mad_send_wr->send_wr.wr.ud.remote_qpn = remote_qpn;
@@ -820,13 +877,11 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
        mad_send_wr->send_wr.wr.ud.pkey_index = pkey_index;
 
        if (rmpp_active) {
-               struct ib_rmpp_mad *rmpp_mad = mad_send_wr->send_buf.mad;
-               rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(hdr_len -
-                                                  IB_MGMT_RMPP_HDR + data_len);
-               rmpp_mad->rmpp_hdr.rmpp_version = mad_agent->rmpp_version;
-               rmpp_mad->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_DATA;
-               ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr,
-                                 IB_MGMT_RMPP_FLAG_ACTIVE);
+               ret = alloc_send_rmpp_list(mad_send_wr, gfp_mask);
+               if (ret) {
+                       kfree(buf);
+                       return ERR_PTR(ret);
+               }
        }
 
        mad_send_wr->send_buf.mad_agent = mad_agent;
@@ -835,14 +890,50 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
 }
 EXPORT_SYMBOL(ib_create_send_mad);
 
+void *ib_get_rmpp_segment(struct ib_mad_send_buf *send_buf, int seg_num)
+{
+       struct ib_mad_send_wr_private *mad_send_wr;
+       struct list_head *list;
+
+       mad_send_wr = container_of(send_buf, struct ib_mad_send_wr_private,
+                                  send_buf);
+       list = &mad_send_wr->cur_seg->list;
+
+       if (mad_send_wr->cur_seg->num < seg_num) {
+               list_for_each_entry(mad_send_wr->cur_seg, list, list)
+                       if (mad_send_wr->cur_seg->num == seg_num)
+                               break;
+       } else if (mad_send_wr->cur_seg->num > seg_num) {
+               list_for_each_entry_reverse(mad_send_wr->cur_seg, list, list)
+                       if (mad_send_wr->cur_seg->num == seg_num)
+                               break;
+       }
+       return mad_send_wr->cur_seg->data;
+}
+EXPORT_SYMBOL(ib_get_rmpp_segment);
+
+static inline void *ib_get_payload(struct ib_mad_send_wr_private *mad_send_wr)
+{
+       if (mad_send_wr->send_buf.seg_count)
+               return ib_get_rmpp_segment(&mad_send_wr->send_buf,
+                                          mad_send_wr->seg_num);
+       else
+               return mad_send_wr->send_buf.mad +
+                      mad_send_wr->send_buf.hdr_len;
+}
+
 void ib_free_send_mad(struct ib_mad_send_buf *send_buf)
 {
        struct ib_mad_agent_private *mad_agent_priv;
+       struct ib_mad_send_wr_private *mad_send_wr;
 
        mad_agent_priv = container_of(send_buf->mad_agent,
                                      struct ib_mad_agent_private, agent);
-       kfree(send_buf->mad);
+       mad_send_wr = container_of(send_buf, struct ib_mad_send_wr_private,
+                                  send_buf);
 
+       free_send_rmpp_list(mad_send_wr);
+       kfree(send_buf->mad);
        if (atomic_dec_and_test(&mad_agent_priv->refcount))
                wake_up(&mad_agent_priv->wait);
 }
@@ -865,10 +956,17 @@ int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
 
        mad_agent = mad_send_wr->send_buf.mad_agent;
        sge = mad_send_wr->sg_list;
-       sge->addr = dma_map_single(mad_agent->device->dma_device,
-                                  mad_send_wr->send_buf.mad, sge->length,
-                                  DMA_TO_DEVICE);
-       pci_unmap_addr_set(mad_send_wr, mapping, sge->addr);
+       sge[0].addr = dma_map_single(mad_agent->device->dma_device,
+                                    mad_send_wr->send_buf.mad,
+                                    sge[0].length,
+                                    DMA_TO_DEVICE);
+       pci_unmap_addr_set(mad_send_wr, header_mapping, sge[0].addr);
+
+       sge[1].addr = dma_map_single(mad_agent->device->dma_device,
+                                    ib_get_payload(mad_send_wr),
+                                    sge[1].length,
+                                    DMA_TO_DEVICE);
+       pci_unmap_addr_set(mad_send_wr, payload_mapping, sge[1].addr);
 
        spin_lock_irqsave(&qp_info->send_queue.lock, flags);
        if (qp_info->send_queue.count < qp_info->send_queue.max_active) {
@@ -885,11 +983,14 @@ int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
                list_add_tail(&mad_send_wr->mad_list.list, list);
        }
        spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
-       if (ret)
+       if (ret) {
                dma_unmap_single(mad_agent->device->dma_device,
-                                pci_unmap_addr(mad_send_wr, mapping),
-                                sge->length, DMA_TO_DEVICE);
-
+                                pci_unmap_addr(mad_send_wr, header_mapping),
+                                sge[0].length, DMA_TO_DEVICE);
+               dma_unmap_single(mad_agent->device->dma_device,
+                                pci_unmap_addr(mad_send_wr, payload_mapping),
+                                sge[1].length, DMA_TO_DEVICE);
+       }
        return ret;
 }
 
@@ -1661,9 +1762,7 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
                                            port_priv->device->node_type,
                                            port_priv->port_num))
                        goto out;
-               if (!smi_check_local_dr_smp(&recv->mad.smp,
-                                           port_priv->device,
-                                           port_priv->port_num))
+               if (!smi_check_local_smp(&recv->mad.smp, port_priv->device))
                        goto out;
        }
 
@@ -1862,8 +1961,11 @@ static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv,
 
 retry:
        dma_unmap_single(mad_send_wr->send_buf.mad_agent->device->dma_device,
-                        pci_unmap_addr(mad_send_wr, mapping),
+                        pci_unmap_addr(mad_send_wr, header_mapping),
                         mad_send_wr->sg_list[0].length, DMA_TO_DEVICE);
+       dma_unmap_single(mad_send_wr->send_buf.mad_agent->device->dma_device,
+                        pci_unmap_addr(mad_send_wr, payload_mapping),
+                        mad_send_wr->sg_list[1].length, DMA_TO_DEVICE);
        queued_send_wr = NULL;
        spin_lock_irqsave(&send_queue->lock, flags);
        list_del(&mad_list->list);
@@ -2262,8 +2364,12 @@ static void timeout_sends(void *data)
 static void ib_mad_thread_completion_handler(struct ib_cq *cq, void *arg)
 {
        struct ib_mad_port_private *port_priv = cq->cq_context;
+       unsigned long flags;
 
-       queue_work(port_priv->wq, &port_priv->work);
+       spin_lock_irqsave(&ib_mad_port_list_lock, flags);
+       if (!list_empty(&port_priv->port_list))
+               queue_work(port_priv->wq, &port_priv->work);
+       spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
 }
 
 /*
@@ -2575,18 +2681,23 @@ static int ib_mad_port_open(struct ib_device *device,
        }
        INIT_WORK(&port_priv->work, ib_mad_completion_handler, port_priv);
 
+       spin_lock_irqsave(&ib_mad_port_list_lock, flags);
+       list_add_tail(&port_priv->port_list, &ib_mad_port_list);
+       spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
+
        ret = ib_mad_port_start(port_priv);
        if (ret) {
                printk(KERN_ERR PFX "Couldn't start port\n");
                goto error9;
        }
 
-       spin_lock_irqsave(&ib_mad_port_list_lock, flags);
-       list_add_tail(&port_priv->port_list, &ib_mad_port_list);
-       spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
        return 0;
 
 error9:
+       spin_lock_irqsave(&ib_mad_port_list_lock, flags);
+       list_del_init(&port_priv->port_list);
+       spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
+
        destroy_workqueue(port_priv->wq);
 error8:
        destroy_mad_qp(&port_priv->qp_info[1]);
@@ -2623,11 +2734,9 @@ static int ib_mad_port_close(struct ib_device *device, int port_num)
                printk(KERN_ERR PFX "Port %d not found\n", port_num);
                return -ENODEV;
        }
-       list_del(&port_priv->port_list);
+       list_del_init(&port_priv->port_list);
        spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
 
-       /* Stop processing completions. */
-       flush_workqueue(port_priv->wq);
        destroy_workqueue(port_priv->wq);
        destroy_mad_qp(&port_priv->qp_info[1]);
        destroy_mad_qp(&port_priv->qp_info[0]);
index 570f78682af34da1c36fc963ddbe8cbfde2d7a92..a7125d4b5ccf24484378aea30c361af9aa2a84aa 100644 (file)
@@ -31,7 +31,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: mad_priv.h 2730 2005-06-28 16:43:03Z sean.hefty $
+ * $Id: mad_priv.h 5596 2006-03-03 01:00:07Z sean.hefty $
  */
 
 #ifndef __IB_MAD_PRIV_H__
@@ -85,6 +85,12 @@ struct ib_mad_private {
        } mad;
 } __attribute__ ((packed));
 
+struct ib_rmpp_segment {
+       struct list_head list;
+       u32 num;
+       u8 data[0];
+};
+
 struct ib_mad_agent_private {
        struct list_head agent_list;
        struct ib_mad_agent agent;
@@ -119,7 +125,8 @@ struct ib_mad_send_wr_private {
        struct list_head agent_list;
        struct ib_mad_agent_private *mad_agent_priv;
        struct ib_mad_send_buf send_buf;
-       DECLARE_PCI_UNMAP_ADDR(mapping)
+       DECLARE_PCI_UNMAP_ADDR(header_mapping)
+       DECLARE_PCI_UNMAP_ADDR(payload_mapping)
        struct ib_send_wr send_wr;
        struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
        __be64 tid;
@@ -130,11 +137,12 @@ struct ib_mad_send_wr_private {
        enum ib_wc_status status;
 
        /* RMPP control */
+       struct list_head rmpp_list;
+       struct ib_rmpp_segment *last_ack_seg;
+       struct ib_rmpp_segment *cur_seg;
        int last_ack;
        int seg_num;
        int newwin;
-       int total_seg;
-       int data_offset;
        int pad;
 };
 
index 3249e1d8c07bd1c69b79932ecd4f344ecbfb4183..bacfdd5bddad4ffb0692f4f155a90832e4342106 100644 (file)
@@ -111,14 +111,14 @@ static int data_offset(u8 mgmt_class)
                return IB_MGMT_RMPP_HDR;
 }
 
-static void format_ack(struct ib_rmpp_mad *ack,
+static void format_ack(struct ib_mad_send_buf *msg,
                       struct ib_rmpp_mad *data,
                       struct mad_rmpp_recv *rmpp_recv)
 {
+       struct ib_rmpp_mad *ack = msg->mad;
        unsigned long flags;
 
-       memcpy(&ack->mad_hdr, &data->mad_hdr,
-              data_offset(data->mad_hdr.mgmt_class));
+       memcpy(ack, &data->mad_hdr, msg->hdr_len);
 
        ack->mad_hdr.method ^= IB_MGMT_METHOD_RESP;
        ack->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_ACK;
@@ -135,16 +135,16 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv,
                     struct ib_mad_recv_wc *recv_wc)
 {
        struct ib_mad_send_buf *msg;
-       int ret;
+       int ret, hdr_len;
 
+       hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class);
        msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
-                                recv_wc->wc->pkey_index, 1, IB_MGMT_RMPP_HDR,
-                                IB_MGMT_RMPP_DATA, GFP_KERNEL);
+                                recv_wc->wc->pkey_index, 1, hdr_len,
+                                0, GFP_KERNEL);
        if (!msg)
                return;
 
-       format_ack(msg->mad, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad,
-                  rmpp_recv);
+       format_ack(msg, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv);
        msg->ah = rmpp_recv->ah;
        ret = ib_post_send_mad(msg, NULL);
        if (ret)
@@ -156,16 +156,17 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent,
 {
        struct ib_mad_send_buf *msg;
        struct ib_ah *ah;
+       int hdr_len;
 
        ah = ib_create_ah_from_wc(agent->qp->pd, recv_wc->wc,
                                  recv_wc->recv_buf.grh, agent->port_num);
        if (IS_ERR(ah))
                return (void *) ah;
 
+       hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class);
        msg = ib_create_send_mad(agent, recv_wc->wc->src_qp,
                                 recv_wc->wc->pkey_index, 1,
-                                IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA,
-                                GFP_KERNEL);
+                                hdr_len, 0, GFP_KERNEL);
        if (IS_ERR(msg))
                ib_destroy_ah(ah);
        else
@@ -195,8 +196,7 @@ static void nack_recv(struct ib_mad_agent_private *agent,
                return;
 
        rmpp_mad = msg->mad;
-       memcpy(rmpp_mad, recv_wc->recv_buf.mad,
-              data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class));
+       memcpy(rmpp_mad, recv_wc->recv_buf.mad, msg->hdr_len);
 
        rmpp_mad->mad_hdr.method ^= IB_MGMT_METHOD_RESP;
        rmpp_mad->rmpp_hdr.rmpp_version = IB_MGMT_RMPP_VERSION;
@@ -433,44 +433,6 @@ static struct ib_mad_recv_wc * complete_rmpp(struct mad_rmpp_recv *rmpp_recv)
        return rmpp_wc;
 }
 
-void ib_coalesce_recv_mad(struct ib_mad_recv_wc *mad_recv_wc, void *buf)
-{
-       struct ib_mad_recv_buf *seg_buf;
-       struct ib_rmpp_mad *rmpp_mad;
-       void *data;
-       int size, len, offset;
-       u8 flags;
-
-       len = mad_recv_wc->mad_len;
-       if (len <= sizeof(struct ib_mad)) {
-               memcpy(buf, mad_recv_wc->recv_buf.mad, len);
-               return;
-       }
-
-       offset = data_offset(mad_recv_wc->recv_buf.mad->mad_hdr.mgmt_class);
-
-       list_for_each_entry(seg_buf, &mad_recv_wc->rmpp_list, list) {
-               rmpp_mad = (struct ib_rmpp_mad *)seg_buf->mad;
-               flags = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr);
-
-               if (flags & IB_MGMT_RMPP_FLAG_FIRST) {
-                       data = rmpp_mad;
-                       size = sizeof(*rmpp_mad);
-               } else {
-                       data = (void *) rmpp_mad + offset;
-                       if (flags & IB_MGMT_RMPP_FLAG_LAST)
-                               size = len;
-                       else
-                               size = sizeof(*rmpp_mad) - offset;
-               }
-
-               memcpy(buf, data, size);
-               len -= size;
-               buf += size;
-       }
-}
-EXPORT_SYMBOL(ib_coalesce_recv_mad);
-
 static struct ib_mad_recv_wc *
 continue_rmpp(struct ib_mad_agent_private *agent,
              struct ib_mad_recv_wc *mad_recv_wc)
@@ -570,50 +532,33 @@ start_rmpp(struct ib_mad_agent_private *agent,
        return mad_recv_wc;
 }
 
-static inline u64 get_seg_addr(struct ib_mad_send_wr_private *mad_send_wr)
-{
-       return mad_send_wr->sg_list[0].addr + mad_send_wr->data_offset +
-              (sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset) *
-              (mad_send_wr->seg_num - 1);
-}
-
 static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
 {
        struct ib_rmpp_mad *rmpp_mad;
        int timeout;
-       u32 paylen;
+       u32 paylen = 0;
 
        rmpp_mad = mad_send_wr->send_buf.mad;
        ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
-       rmpp_mad->rmpp_hdr.seg_num = cpu_to_be32(mad_send_wr->seg_num);
+       rmpp_mad->rmpp_hdr.seg_num = cpu_to_be32(++mad_send_wr->seg_num);
 
        if (mad_send_wr->seg_num == 1) {
                rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_FIRST;
-               paylen = mad_send_wr->total_seg * IB_MGMT_RMPP_DATA -
+               paylen = mad_send_wr->send_buf.seg_count * IB_MGMT_RMPP_DATA -
                         mad_send_wr->pad;
-               rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen);
-               mad_send_wr->sg_list[0].length = sizeof(struct ib_rmpp_mad);
-       } else {
-               mad_send_wr->send_wr.num_sge = 2;
-               mad_send_wr->sg_list[0].length = mad_send_wr->data_offset;
-               mad_send_wr->sg_list[1].addr = get_seg_addr(mad_send_wr);
-               mad_send_wr->sg_list[1].length = sizeof(struct ib_rmpp_mad) -
-                                                mad_send_wr->data_offset;
-               mad_send_wr->sg_list[1].lkey = mad_send_wr->sg_list[0].lkey;
-               rmpp_mad->rmpp_hdr.paylen_newwin = 0;
        }
 
-       if (mad_send_wr->seg_num == mad_send_wr->total_seg) {
+       if (mad_send_wr->seg_num == mad_send_wr->send_buf.seg_count) {
                rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_LAST;
                paylen = IB_MGMT_RMPP_DATA - mad_send_wr->pad;
-               rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen);
        }
+       rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen);
 
        /* 2 seconds for an ACK until we can find the packet lifetime */
        timeout = mad_send_wr->send_buf.timeout_ms;
        if (!timeout || timeout > 2000)
                mad_send_wr->timeout = msecs_to_jiffies(2000);
-       mad_send_wr->seg_num++;
+
        return ib_send_mad(mad_send_wr);
 }
 
@@ -629,7 +574,7 @@ static void abort_send(struct ib_mad_agent_private *agent, __be64 tid,
        if (!mad_send_wr)
                goto out;       /* Unmatched send */
 
-       if ((mad_send_wr->last_ack == mad_send_wr->total_seg) ||
+       if ((mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) ||
            (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS))
                goto out;       /* Send is already done */
 
@@ -645,6 +590,18 @@ out:
        spin_unlock_irqrestore(&agent->lock, flags);
 }
 
+static inline void adjust_last_ack(struct ib_mad_send_wr_private *wr,
+                                  int seg_num)
+{
+       struct list_head *list;
+
+       wr->last_ack = seg_num;
+       list = &wr->last_ack_seg->list;
+       list_for_each_entry(wr->last_ack_seg, list, list)
+               if (wr->last_ack_seg->num == seg_num)
+                       break;
+}
+
 static void process_rmpp_ack(struct ib_mad_agent_private *agent,
                             struct ib_mad_recv_wc *mad_recv_wc)
 {
@@ -675,11 +632,12 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
        if (!mad_send_wr)
                goto out;       /* Unmatched ACK */
 
-       if ((mad_send_wr->last_ack == mad_send_wr->total_seg) ||
+       if ((mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) ||
            (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS))
                goto out;       /* Send is already done */
 
-       if (seg_num > mad_send_wr->total_seg || seg_num > mad_send_wr->newwin) {
+       if (seg_num > mad_send_wr->send_buf.seg_count ||
+           seg_num > mad_send_wr->newwin) {
                spin_unlock_irqrestore(&agent->lock, flags);
                abort_send(agent, rmpp_mad->mad_hdr.tid,
                           IB_MGMT_RMPP_STATUS_S2B);
@@ -691,11 +649,11 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
                goto out;       /* Old ACK */
 
        if (seg_num > mad_send_wr->last_ack) {
-               mad_send_wr->last_ack = seg_num;
+               adjust_last_ack(mad_send_wr, seg_num);
                mad_send_wr->retries = mad_send_wr->send_buf.retries;
        }
        mad_send_wr->newwin = newwin;
-       if (mad_send_wr->last_ack == mad_send_wr->total_seg) {
+       if (mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) {
                /* If no response is expected, the ACK completes the send */
                if (!mad_send_wr->send_buf.timeout_ms) {
                        struct ib_mad_send_wc wc;
@@ -714,7 +672,7 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
                                             mad_send_wr->send_buf.timeout_ms);
        } else if (mad_send_wr->refcount == 1 &&
                   mad_send_wr->seg_num < mad_send_wr->newwin &&
-                  mad_send_wr->seg_num <= mad_send_wr->total_seg) {
+                  mad_send_wr->seg_num < mad_send_wr->send_buf.seg_count) {
                /* Send failure will just result in a timeout/retry */
                ret = send_next_seg(mad_send_wr);
                if (ret)
@@ -838,31 +796,19 @@ out:
 int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr)
 {
        struct ib_rmpp_mad *rmpp_mad;
-       int i, total_len, ret;
+       int ret;
 
        rmpp_mad = mad_send_wr->send_buf.mad;
        if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
              IB_MGMT_RMPP_FLAG_ACTIVE))
                return IB_RMPP_RESULT_UNHANDLED;
 
-       if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA)
+       if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) {
+               mad_send_wr->seg_num = 1;
                return IB_RMPP_RESULT_INTERNAL;
+       }
 
-       if (mad_send_wr->send_wr.num_sge > 1)
-               return -EINVAL;         /* TODO: support num_sge > 1 */
-
-       mad_send_wr->seg_num = 1;
        mad_send_wr->newwin = 1;
-       mad_send_wr->data_offset = data_offset(rmpp_mad->mad_hdr.mgmt_class);
-
-       total_len = 0;
-       for (i = 0; i < mad_send_wr->send_wr.num_sge; i++)
-               total_len += mad_send_wr->send_wr.sg_list[i].length;
-
-        mad_send_wr->total_seg = (total_len - mad_send_wr->data_offset) /
-                       (sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset);
-       mad_send_wr->pad = total_len - IB_MGMT_RMPP_HDR -
-                          be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
 
        /* We need to wait for the final ACK even if there isn't a response */
        mad_send_wr->refcount += (mad_send_wr->timeout == 0);
@@ -893,14 +839,14 @@ int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr,
        if (!mad_send_wr->timeout)
                return IB_RMPP_RESULT_PROCESSED; /* Response received */
 
-       if (mad_send_wr->last_ack == mad_send_wr->total_seg) {
+       if (mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) {
                mad_send_wr->timeout =
                        msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms);
                return IB_RMPP_RESULT_PROCESSED; /* Send done */
        }
 
-       if (mad_send_wr->seg_num > mad_send_wr->newwin ||
-           mad_send_wr->seg_num > mad_send_wr->total_seg)
+       if (mad_send_wr->seg_num == mad_send_wr->newwin ||
+           mad_send_wr->seg_num == mad_send_wr->send_buf.seg_count)
                return IB_RMPP_RESULT_PROCESSED; /* Wait for ACK */
 
        ret = send_next_seg(mad_send_wr);
@@ -921,10 +867,12 @@ int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr)
              IB_MGMT_RMPP_FLAG_ACTIVE))
                return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */
 
-       if (mad_send_wr->last_ack == mad_send_wr->total_seg)
+       if (mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count)
                return IB_RMPP_RESULT_PROCESSED;
 
-       mad_send_wr->seg_num = mad_send_wr->last_ack + 1;
+       mad_send_wr->seg_num = mad_send_wr->last_ack;
+       mad_send_wr->cur_seg = mad_send_wr->last_ack_seg;
+
        ret = send_next_seg(mad_send_wr);
        if (ret)
                return IB_RMPP_RESULT_PROCESSED;
index 2b3c40198f81d93ae5590a582faeb8f0e4a6b2e3..3011bfd86dc5423ca8c74afdc97bf5dd205a4ae9 100644 (file)
@@ -49,19 +49,16 @@ extern int smi_check_forward_dr_smp(struct ib_smp *smp);
 extern int smi_handle_dr_smp_send(struct ib_smp *smp,
                                  u8 node_type,
                                  int port_num);
-extern int smi_check_local_dr_smp(struct ib_smp *smp,
-                                 struct ib_device *device,
-                                 int port_num);
 
 /*
  * Return 1 if the SMP should be handled by the local SMA/SM via process_mad
  */
-static inline int smi_check_local_smp(struct ib_mad_agent *mad_agent,
-                                     struct ib_smp *smp)
+static inline int smi_check_local_smp(struct ib_smp *smp,
+                                     struct ib_device *device)
 {
        /* C14-9:3 -- We're at the end of the DR segment of path */
        /* C14-9:4 -- Hop Pointer = Hop Count + 1 -> give to SMA/SM */
-       return ((mad_agent->device->process_mad &&
+       return ((device->process_mad &&
                !ib_get_smp_direction(smp) &&
                (smp->hop_ptr == smp->hop_cnt + 1)));
 }
index 5982d687a0009e2db11befcce2d0c4d9fde519f8..15121cb5a1f6a3d2b5e69b19011bb122ad247055 100644 (file)
@@ -112,7 +112,7 @@ static ssize_t state_show(struct ib_port *p, struct port_attribute *unused,
                return ret;
 
        return sprintf(buf, "%d: %s\n", attr.state,
-                      attr.state >= 0 && attr.state <= ARRAY_SIZE(state_name) ?
+                      attr.state >= 0 && attr.state < ARRAY_SIZE(state_name) ?
                       state_name[attr.state] : "UNKNOWN");
 }
 
@@ -472,8 +472,10 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *,
                        goto err;
 
                if (snprintf(element->name, sizeof(element->name),
-                            "%d", i) >= sizeof(element->name))
+                            "%d", i) >= sizeof(element->name)) {
+                       kfree(element);
                        goto err;
+               }
 
                element->attr.attr.name  = element->name;
                element->attr.attr.mode  = S_IRUGO;
@@ -628,14 +630,42 @@ static ssize_t show_node_guid(struct class_device *cdev, char *buf)
                       be16_to_cpu(((__be16 *) &dev->node_guid)[3]));
 }
 
+static ssize_t show_node_desc(struct class_device *cdev, char *buf)
+{
+       struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+
+       return sprintf(buf, "%.64s\n", dev->node_desc);
+}
+
+static ssize_t set_node_desc(struct class_device *cdev, const char *buf,
+                             size_t count)
+{
+       struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+       struct ib_device_modify desc = {};
+       int ret;
+
+       if (!dev->modify_device)
+               return -EIO;
+
+       memcpy(desc.node_desc, buf, min_t(int, count, 64));
+       ret = ib_modify_device(dev, IB_DEVICE_MODIFY_NODE_DESC, &desc);
+       if (ret)
+               return ret;
+
+       return count;
+}
+
 static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
 static CLASS_DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);
 static CLASS_DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);
+static CLASS_DEVICE_ATTR(node_desc, S_IRUGO | S_IWUSR, show_node_desc,
+                        set_node_desc);
 
 static struct class_device_attribute *ib_class_attributes[] = {
        &class_device_attr_node_type,
        &class_device_attr_sys_image_guid,
-       &class_device_attr_node_guid
+       &class_device_attr_node_guid,
+       &class_device_attr_node_desc
 };
 
 static struct class ib_class = {
index c908de8db5a9b1201e825684039dca3bd75dd55f..fb6cd42601f96cea267225db4ab76ccb51be33c6 100644 (file)
@@ -31,7 +31,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: user_mad.c 4010 2005-11-09 23:11:56Z roland $
+ * $Id: user_mad.c 5596 2006-03-03 01:00:07Z sean.hefty $
  */
 
 #include <linux/module.h>
@@ -121,6 +121,7 @@ struct ib_umad_file {
 
 struct ib_umad_packet {
        struct ib_mad_send_buf *msg;
+       struct ib_mad_recv_wc  *recv_wc;
        struct list_head   list;
        int                length;
        struct ib_user_mad mad;
@@ -176,31 +177,32 @@ static int queue_packet(struct ib_umad_file *file,
        return ret;
 }
 
+static int data_offset(u8 mgmt_class)
+{
+       if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM)
+               return IB_MGMT_SA_HDR;
+       else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
+                (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))
+               return IB_MGMT_VENDOR_HDR;
+       else
+               return IB_MGMT_RMPP_HDR;
+}
+
 static void send_handler(struct ib_mad_agent *agent,
                         struct ib_mad_send_wc *send_wc)
 {
        struct ib_umad_file *file = agent->context;
-       struct ib_umad_packet *timeout;
        struct ib_umad_packet *packet = send_wc->send_buf->context[0];
 
        ib_destroy_ah(packet->msg->ah);
        ib_free_send_mad(packet->msg);
 
        if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
-               timeout = kzalloc(sizeof *timeout + IB_MGMT_MAD_HDR, GFP_KERNEL);
-               if (!timeout)
-                       goto out;
-
-               timeout->length         = IB_MGMT_MAD_HDR;
-               timeout->mad.hdr.id     = packet->mad.hdr.id;
-               timeout->mad.hdr.status = ETIMEDOUT;
-               memcpy(timeout->mad.data, packet->mad.data,
-                      sizeof (struct ib_mad_hdr));
-
-               if (queue_packet(file, agent, timeout))
-                       kfree(timeout);
+               packet->length = IB_MGMT_MAD_HDR;
+               packet->mad.hdr.status = ETIMEDOUT;
+               if (!queue_packet(file, agent, packet))
+                       return;
        }
-out:
        kfree(packet);
 }
 
@@ -209,22 +211,20 @@ static void recv_handler(struct ib_mad_agent *agent,
 {
        struct ib_umad_file *file = agent->context;
        struct ib_umad_packet *packet;
-       int length;
 
        if (mad_recv_wc->wc->status != IB_WC_SUCCESS)
-               goto out;
+               goto err1;
 
-       length = mad_recv_wc->mad_len;
-       packet = kzalloc(sizeof *packet + length, GFP_KERNEL);
+       packet = kzalloc(sizeof *packet, GFP_KERNEL);
        if (!packet)
-               goto out;
+               goto err1;
 
-       packet->length = length;
-
-       ib_coalesce_recv_mad(mad_recv_wc, packet->mad.data);
+       packet->length = mad_recv_wc->mad_len;
+       packet->recv_wc = mad_recv_wc;
 
        packet->mad.hdr.status    = 0;
-       packet->mad.hdr.length    = length + sizeof (struct ib_user_mad);
+       packet->mad.hdr.length    = sizeof (struct ib_user_mad) +
+                                   mad_recv_wc->mad_len;
        packet->mad.hdr.qpn       = cpu_to_be32(mad_recv_wc->wc->src_qp);
        packet->mad.hdr.lid       = cpu_to_be16(mad_recv_wc->wc->slid);
        packet->mad.hdr.sl        = mad_recv_wc->wc->sl;
@@ -240,12 +240,79 @@ static void recv_handler(struct ib_mad_agent *agent,
        }
 
        if (queue_packet(file, agent, packet))
-               kfree(packet);
+               goto err2;
+       return;
 
-out:
+err2:
+       kfree(packet);
+err1:
        ib_free_recv_mad(mad_recv_wc);
 }
 
+static ssize_t copy_recv_mad(char __user *buf, struct ib_umad_packet *packet,
+                            size_t count)
+{
+       struct ib_mad_recv_buf *recv_buf;
+       int left, seg_payload, offset, max_seg_payload;
+
+       /* We need enough room to copy the first (or only) MAD segment. */
+       recv_buf = &packet->recv_wc->recv_buf;
+       if ((packet->length <= sizeof (*recv_buf->mad) &&
+            count < sizeof (packet->mad) + packet->length) ||
+           (packet->length > sizeof (*recv_buf->mad) &&
+            count < sizeof (packet->mad) + sizeof (*recv_buf->mad)))
+               return -EINVAL;
+
+       if (copy_to_user(buf, &packet->mad, sizeof (packet->mad)))
+               return -EFAULT;
+
+       buf += sizeof (packet->mad);
+       seg_payload = min_t(int, packet->length, sizeof (*recv_buf->mad));
+       if (copy_to_user(buf, recv_buf->mad, seg_payload))
+               return -EFAULT;
+
+       if (seg_payload < packet->length) {
+               /*
+                * Multipacket RMPP MAD message. Copy remainder of message.
+                * Note that last segment may have a shorter payload.
+                */
+               if (count < sizeof (packet->mad) + packet->length) {
+                       /*
+                        * The buffer is too small, return the first RMPP segment,
+                        * which includes the RMPP message length.
+                        */
+                       return -ENOSPC;
+               }
+               offset = data_offset(recv_buf->mad->mad_hdr.mgmt_class);
+               max_seg_payload = sizeof (struct ib_mad) - offset;
+
+               for (left = packet->length - seg_payload, buf += seg_payload;
+                    left; left -= seg_payload, buf += seg_payload) {
+                       recv_buf = container_of(recv_buf->list.next,
+                                               struct ib_mad_recv_buf, list);
+                       seg_payload = min(left, max_seg_payload);
+                       if (copy_to_user(buf, ((void *) recv_buf->mad) + offset,
+                                        seg_payload))
+                               return -EFAULT;
+               }
+       }
+       return sizeof (packet->mad) + packet->length;
+}
+
+static ssize_t copy_send_mad(char __user *buf, struct ib_umad_packet *packet,
+                            size_t count)
+{
+       ssize_t size = sizeof (packet->mad) + packet->length;
+
+       if (count < size)
+               return -EINVAL;
+
+       if (copy_to_user(buf, &packet->mad, size))
+               return -EFAULT;
+
+       return size;
+}
+
 static ssize_t ib_umad_read(struct file *filp, char __user *buf,
                            size_t count, loff_t *pos)
 {
@@ -253,7 +320,7 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf,
        struct ib_umad_packet *packet;
        ssize_t ret;
 
-       if (count < sizeof (struct ib_user_mad) + sizeof (struct ib_mad))
+       if (count < sizeof (struct ib_user_mad))
                return -EINVAL;
 
        spin_lock_irq(&file->recv_lock);
@@ -276,28 +343,44 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf,
 
        spin_unlock_irq(&file->recv_lock);
 
-       if (count < packet->length + sizeof (struct ib_user_mad)) {
-               /* Return length needed (and first RMPP segment) if too small */
-               if (copy_to_user(buf, &packet->mad,
-                                sizeof (struct ib_user_mad) + sizeof (struct ib_mad)))
-                       ret = -EFAULT;
-               else
-                       ret = -ENOSPC;
-       } else if (copy_to_user(buf, &packet->mad,
-                               packet->length + sizeof (struct ib_user_mad)))
-               ret = -EFAULT;
+       if (packet->recv_wc)
+               ret = copy_recv_mad(buf, packet, count);
        else
-               ret = packet->length + sizeof (struct ib_user_mad);
+               ret = copy_send_mad(buf, packet, count);
+
        if (ret < 0) {
                /* Requeue packet */
                spin_lock_irq(&file->recv_lock);
                list_add(&packet->list, &file->recv_list);
                spin_unlock_irq(&file->recv_lock);
-       } else
+       } else {
+               if (packet->recv_wc)
+                       ib_free_recv_mad(packet->recv_wc);
                kfree(packet);
+       }
        return ret;
 }
 
+static int copy_rmpp_mad(struct ib_mad_send_buf *msg, const char __user *buf)
+{
+       int left, seg;
+
+       /* Copy class specific header */
+       if ((msg->hdr_len > IB_MGMT_RMPP_HDR) &&
+           copy_from_user(msg->mad + IB_MGMT_RMPP_HDR, buf + IB_MGMT_RMPP_HDR,
+                          msg->hdr_len - IB_MGMT_RMPP_HDR))
+               return -EFAULT;
+
+       /* All headers are in place.  Copy data segments. */
+       for (seg = 1, left = msg->data_len, buf += msg->hdr_len; left > 0;
+            seg++, left -= msg->seg_size, buf += msg->seg_size) {
+               if (copy_from_user(ib_get_rmpp_segment(msg, seg), buf,
+                                  min(left, msg->seg_size)))
+                       return -EFAULT;
+       }
+       return 0;
+}
+
 static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
                             size_t count, loff_t *pos)
 {
@@ -309,14 +392,12 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
        struct ib_rmpp_mad *rmpp_mad;
        u8 method;
        __be64 *tid;
-       int ret, length, hdr_len, copy_offset;
-       int rmpp_active, has_rmpp_header;
+       int ret, data_len, hdr_len, copy_offset, rmpp_active;
 
        if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)
                return -EINVAL;
 
-       length = count - sizeof (struct ib_user_mad);
-       packet = kmalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL);
+       packet = kzalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL);
        if (!packet)
                return -ENOMEM;
 
@@ -363,35 +444,25 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
        if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) {
                hdr_len = IB_MGMT_SA_HDR;
                copy_offset = IB_MGMT_RMPP_HDR;
-               has_rmpp_header = 1;
+               rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
+                             IB_MGMT_RMPP_FLAG_ACTIVE;
        } else if (rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START &&
                   rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END) {
-                       hdr_len = IB_MGMT_VENDOR_HDR;
-                       copy_offset = IB_MGMT_RMPP_HDR;
-                       has_rmpp_header = 1;
+               hdr_len = IB_MGMT_VENDOR_HDR;
+               copy_offset = IB_MGMT_RMPP_HDR;
+               rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
+                             IB_MGMT_RMPP_FLAG_ACTIVE;
        } else {
                hdr_len = IB_MGMT_MAD_HDR;
                copy_offset = IB_MGMT_MAD_HDR;
-               has_rmpp_header = 0;
-       }
-
-       if (has_rmpp_header)
-               rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
-                             IB_MGMT_RMPP_FLAG_ACTIVE;
-       else
                rmpp_active = 0;
-
-       /* Validate that the management class can support RMPP */
-       if (rmpp_active && !agent->rmpp_version) {
-               ret = -EINVAL;
-               goto err_ah;
        }
 
+       data_len = count - sizeof (struct ib_user_mad) - hdr_len;
        packet->msg = ib_create_send_mad(agent,
                                         be32_to_cpu(packet->mad.hdr.qpn),
-                                        0, rmpp_active,
-                                        hdr_len, length - hdr_len,
-                                        GFP_KERNEL);
+                                        0, rmpp_active, hdr_len,
+                                        data_len, GFP_KERNEL);
        if (IS_ERR(packet->msg)) {
                ret = PTR_ERR(packet->msg);
                goto err_ah;
@@ -402,14 +473,21 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
        packet->msg->retries    = packet->mad.hdr.retries;
        packet->msg->context[0] = packet;
 
-       /* Copy MAD headers (RMPP header in place) */
+       /* Copy MAD header.  Any RMPP header is already in place. */
        memcpy(packet->msg->mad, packet->mad.data, IB_MGMT_MAD_HDR);
-       /* Now, copy rest of message from user into send buffer */
-       if (copy_from_user(packet->msg->mad + copy_offset,
-                          buf + sizeof (struct ib_user_mad) + copy_offset,
-                          length - copy_offset)) {
-               ret = -EFAULT;
-               goto err_msg;
+       buf += sizeof (struct ib_user_mad);
+
+       if (!rmpp_active) {
+               if (copy_from_user(packet->msg->mad + copy_offset,
+                                  buf + copy_offset,
+                                  hdr_len + data_len - copy_offset)) {
+                       ret = -EFAULT;
+                       goto err_msg;
+               }
+       } else {
+               ret = copy_rmpp_mad(packet->msg, buf);
+               if (ret)
+                       goto err_msg;
        }
 
        /*
@@ -433,18 +511,14 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
                goto err_msg;
 
        up_read(&file->port->mutex);
-
        return count;
 
 err_msg:
        ib_free_send_mad(packet->msg);
-
 err_ah:
        ib_destroy_ah(ah);
-
 err_up:
        up_read(&file->port->mutex);
-
 err:
        kfree(packet);
        return ret;
@@ -627,8 +701,11 @@ static int ib_umad_close(struct inode *inode, struct file *filp)
        already_dead = file->agents_dead;
        file->agents_dead = 1;
 
-       list_for_each_entry_safe(packet, tmp, &file->recv_list, list)
+       list_for_each_entry_safe(packet, tmp, &file->recv_list, list) {
+               if (packet->recv_wc)
+                       ib_free_recv_mad(packet->recv_wc);
                kfree(packet);
+       }
 
        list_del(&file->port_list);
 
index f7eecbc6af6c2b0b371ff361508d9ae074cab484..3372d67ff139eb51232f96ad287e50608e5998ef 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
- * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
  * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
  * Copyright (c) 2005 PathScale, Inc. All rights reserved.
@@ -178,10 +178,12 @@ IB_UVERBS_DECLARE_CMD(reg_mr);
 IB_UVERBS_DECLARE_CMD(dereg_mr);
 IB_UVERBS_DECLARE_CMD(create_comp_channel);
 IB_UVERBS_DECLARE_CMD(create_cq);
+IB_UVERBS_DECLARE_CMD(resize_cq);
 IB_UVERBS_DECLARE_CMD(poll_cq);
 IB_UVERBS_DECLARE_CMD(req_notify_cq);
 IB_UVERBS_DECLARE_CMD(destroy_cq);
 IB_UVERBS_DECLARE_CMD(create_qp);
+IB_UVERBS_DECLARE_CMD(query_qp);
 IB_UVERBS_DECLARE_CMD(modify_qp);
 IB_UVERBS_DECLARE_CMD(destroy_qp);
 IB_UVERBS_DECLARE_CMD(post_send);
@@ -193,6 +195,7 @@ IB_UVERBS_DECLARE_CMD(attach_mcast);
 IB_UVERBS_DECLARE_CMD(detach_mcast);
 IB_UVERBS_DECLARE_CMD(create_srq);
 IB_UVERBS_DECLARE_CMD(modify_srq);
+IB_UVERBS_DECLARE_CMD(query_srq);
 IB_UVERBS_DECLARE_CMD(destroy_srq);
 
 #endif /* UVERBS_H */
index 407b6284d7d5c502c88595f1f2820bf856aac1c8..9f69bd48eb1bee6ccf488f0e71a7777efd7f5f0d 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
- * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
  * Copyright (c) 2005 PathScale, Inc.  All rights reserved.
+ * Copyright (c) 2006 Mellanox Technologies.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -675,6 +676,46 @@ err:
        return ret;
 }
 
+ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
+                           const char __user *buf, int in_len,
+                           int out_len)
+{
+       struct ib_uverbs_resize_cq      cmd;
+       struct ib_uverbs_resize_cq_resp resp;
+       struct ib_udata                 udata;
+       struct ib_cq                    *cq;
+       int                             ret = -EINVAL;
+
+       if (copy_from_user(&cmd, buf, sizeof cmd))
+               return -EFAULT;
+
+       INIT_UDATA(&udata, buf + sizeof cmd,
+                  (unsigned long) cmd.response + sizeof resp,
+                  in_len - sizeof cmd, out_len - sizeof resp);
+
+       mutex_lock(&ib_uverbs_idr_mutex);
+
+       cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
+       if (!cq || cq->uobject->context != file->ucontext || !cq->device->resize_cq)
+               goto out;
+
+       ret = cq->device->resize_cq(cq, cmd.cqe, &udata);
+       if (ret)
+               goto out;
+
+       memset(&resp, 0, sizeof resp);
+       resp.cqe = cq->cqe;
+
+       if (copy_to_user((void __user *) (unsigned long) cmd.response,
+                        &resp, sizeof resp))
+               ret = -EFAULT;
+
+out:
+       mutex_unlock(&ib_uverbs_idr_mutex);
+
+       return ret ? ret : in_len;
+}
+
 ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
                          const char __user *buf, int in_len,
                          int out_len)
@@ -956,6 +997,106 @@ err_up:
        return ret;
 }
 
+ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,
+                          const char __user *buf, int in_len,
+                          int out_len)
+{
+       struct ib_uverbs_query_qp      cmd;
+       struct ib_uverbs_query_qp_resp resp;
+       struct ib_qp                   *qp;
+       struct ib_qp_attr              *attr;
+       struct ib_qp_init_attr         *init_attr;
+       int                            ret;
+
+       if (copy_from_user(&cmd, buf, sizeof cmd))
+               return -EFAULT;
+
+       attr      = kmalloc(sizeof *attr, GFP_KERNEL);
+       init_attr = kmalloc(sizeof *init_attr, GFP_KERNEL);
+       if (!attr || !init_attr) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       mutex_lock(&ib_uverbs_idr_mutex);
+
+       qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
+       if (qp && qp->uobject->context == file->ucontext)
+               ret = ib_query_qp(qp, attr, cmd.attr_mask, init_attr);
+       else
+               ret = -EINVAL;
+
+       mutex_unlock(&ib_uverbs_idr_mutex);
+
+       if (ret)
+               goto out;
+
+       memset(&resp, 0, sizeof resp);
+
+       resp.qp_state               = attr->qp_state;
+       resp.cur_qp_state           = attr->cur_qp_state;
+       resp.path_mtu               = attr->path_mtu;
+       resp.path_mig_state         = attr->path_mig_state;
+       resp.qkey                   = attr->qkey;
+       resp.rq_psn                 = attr->rq_psn;
+       resp.sq_psn                 = attr->sq_psn;
+       resp.dest_qp_num            = attr->dest_qp_num;
+       resp.qp_access_flags        = attr->qp_access_flags;
+       resp.pkey_index             = attr->pkey_index;
+       resp.alt_pkey_index         = attr->alt_pkey_index;
+       resp.en_sqd_async_notify    = attr->en_sqd_async_notify;
+       resp.max_rd_atomic          = attr->max_rd_atomic;
+       resp.max_dest_rd_atomic     = attr->max_dest_rd_atomic;
+       resp.min_rnr_timer          = attr->min_rnr_timer;
+       resp.port_num               = attr->port_num;
+       resp.timeout                = attr->timeout;
+       resp.retry_cnt              = attr->retry_cnt;
+       resp.rnr_retry              = attr->rnr_retry;
+       resp.alt_port_num           = attr->alt_port_num;
+       resp.alt_timeout            = attr->alt_timeout;
+
+       memcpy(resp.dest.dgid, attr->ah_attr.grh.dgid.raw, 16);
+       resp.dest.flow_label        = attr->ah_attr.grh.flow_label;
+       resp.dest.sgid_index        = attr->ah_attr.grh.sgid_index;
+       resp.dest.hop_limit         = attr->ah_attr.grh.hop_limit;
+       resp.dest.traffic_class     = attr->ah_attr.grh.traffic_class;
+       resp.dest.dlid              = attr->ah_attr.dlid;
+       resp.dest.sl                = attr->ah_attr.sl;
+       resp.dest.src_path_bits     = attr->ah_attr.src_path_bits;
+       resp.dest.static_rate       = attr->ah_attr.static_rate;
+       resp.dest.is_global         = !!(attr->ah_attr.ah_flags & IB_AH_GRH);
+       resp.dest.port_num          = attr->ah_attr.port_num;
+
+       memcpy(resp.alt_dest.dgid, attr->alt_ah_attr.grh.dgid.raw, 16);
+       resp.alt_dest.flow_label    = attr->alt_ah_attr.grh.flow_label;
+       resp.alt_dest.sgid_index    = attr->alt_ah_attr.grh.sgid_index;
+       resp.alt_dest.hop_limit     = attr->alt_ah_attr.grh.hop_limit;
+       resp.alt_dest.traffic_class = attr->alt_ah_attr.grh.traffic_class;
+       resp.alt_dest.dlid          = attr->alt_ah_attr.dlid;
+       resp.alt_dest.sl            = attr->alt_ah_attr.sl;
+       resp.alt_dest.src_path_bits = attr->alt_ah_attr.src_path_bits;
+       resp.alt_dest.static_rate   = attr->alt_ah_attr.static_rate;
+       resp.alt_dest.is_global     = !!(attr->alt_ah_attr.ah_flags & IB_AH_GRH);
+       resp.alt_dest.port_num      = attr->alt_ah_attr.port_num;
+
+       resp.max_send_wr            = init_attr->cap.max_send_wr;
+       resp.max_recv_wr            = init_attr->cap.max_recv_wr;
+       resp.max_send_sge           = init_attr->cap.max_send_sge;
+       resp.max_recv_sge           = init_attr->cap.max_recv_sge;
+       resp.max_inline_data        = init_attr->cap.max_inline_data;
+       resp.sq_sig_all             = init_attr->sq_sig_type == IB_SIGNAL_ALL_WR;
+
+       if (copy_to_user((void __user *) (unsigned long) cmd.response,
+                        &resp, sizeof resp))
+               ret = -EFAULT;
+
+out:
+       kfree(attr);
+       kfree(init_attr);
+
+       return ret ? ret : in_len;
+}
+
 ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
                            const char __user *buf, int in_len,
                            int out_len)
@@ -990,7 +1131,7 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
        attr->dest_qp_num         = cmd.dest_qp_num;
        attr->qp_access_flags     = cmd.qp_access_flags;
        attr->pkey_index          = cmd.pkey_index;
-       attr->alt_pkey_index      = cmd.pkey_index;
+       attr->alt_pkey_index      = cmd.alt_pkey_index;
        attr->en_sqd_async_notify = cmd.en_sqd_async_notify;
        attr->max_rd_atomic       = cmd.max_rd_atomic;
        attr->max_dest_rd_atomic  = cmd.max_dest_rd_atomic;
@@ -1094,8 +1235,8 @@ out:
 }
 
 ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
-                            const char __user *buf, int in_len,
-                            int out_len)
+                           const char __user *buf, int in_len,
+                           int out_len)
 {
        struct ib_uverbs_post_send      cmd;
        struct ib_uverbs_post_send_resp resp;
@@ -1323,8 +1464,8 @@ err:
 }
 
 ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
-                            const char __user *buf, int in_len,
-                            int out_len)
+                           const char __user *buf, int in_len,
+                           int out_len)
 {
        struct ib_uverbs_post_recv      cmd;
        struct ib_uverbs_post_recv_resp resp;
@@ -1374,8 +1515,8 @@ out:
 }
 
 ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
-                            const char __user *buf, int in_len,
-                            int out_len)
+                               const char __user *buf, int in_len,
+                               int out_len)
 {
        struct ib_uverbs_post_srq_recv      cmd;
        struct ib_uverbs_post_srq_recv_resp resp;
@@ -1723,6 +1864,8 @@ retry:
                goto err_destroy;
 
        resp.srq_handle = uobj->uobject.id;
+       resp.max_wr     = attr.attr.max_wr;
+       resp.max_sge    = attr.attr.max_sge;
 
        if (copy_to_user((void __user *) (unsigned long) cmd.response,
                         &resp, sizeof resp)) {
@@ -1783,6 +1926,49 @@ out:
        return ret ? ret : in_len;
 }
 
+ssize_t ib_uverbs_query_srq(struct ib_uverbs_file *file,
+                           const char __user *buf,
+                           int in_len, int out_len)
+{
+       struct ib_uverbs_query_srq      cmd;
+       struct ib_uverbs_query_srq_resp resp;
+       struct ib_srq_attr              attr;
+       struct ib_srq                   *srq;
+       int                             ret;
+
+       if (out_len < sizeof resp)
+               return -ENOSPC;
+
+       if (copy_from_user(&cmd, buf, sizeof cmd))
+               return -EFAULT;
+
+       mutex_lock(&ib_uverbs_idr_mutex);
+
+       srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
+       if (srq && srq->uobject->context == file->ucontext)
+               ret = ib_query_srq(srq, &attr);
+       else
+               ret = -EINVAL;
+
+       mutex_unlock(&ib_uverbs_idr_mutex);
+
+       if (ret)
+               goto out;
+
+       memset(&resp, 0, sizeof resp);
+
+       resp.max_wr    = attr.max_wr;
+       resp.max_sge   = attr.max_sge;
+       resp.srq_limit = attr.srq_limit;
+
+       if (copy_to_user((void __user *) (unsigned long) cmd.response,
+                        &resp, sizeof resp))
+               ret = -EFAULT;
+
+out:
+       return ret ? ret : in_len;
+}
+
 ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
                              const char __user *buf, int in_len,
                              int out_len)
index 903f85a4bc0cf4dfb461d6b9daf71a2a3e7d64d8..ff092a0a94da0ebf77967dbeef73da9d2943ec8c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
- * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
  * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
  * Copyright (c) 2005 PathScale, Inc. All rights reserved.
@@ -91,10 +91,12 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
        [IB_USER_VERBS_CMD_DEREG_MR]            = ib_uverbs_dereg_mr,
        [IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL] = ib_uverbs_create_comp_channel,
        [IB_USER_VERBS_CMD_CREATE_CQ]           = ib_uverbs_create_cq,
+       [IB_USER_VERBS_CMD_RESIZE_CQ]           = ib_uverbs_resize_cq,
        [IB_USER_VERBS_CMD_POLL_CQ]             = ib_uverbs_poll_cq,
        [IB_USER_VERBS_CMD_REQ_NOTIFY_CQ]       = ib_uverbs_req_notify_cq,
        [IB_USER_VERBS_CMD_DESTROY_CQ]          = ib_uverbs_destroy_cq,
        [IB_USER_VERBS_CMD_CREATE_QP]           = ib_uverbs_create_qp,
+       [IB_USER_VERBS_CMD_QUERY_QP]            = ib_uverbs_query_qp,
        [IB_USER_VERBS_CMD_MODIFY_QP]           = ib_uverbs_modify_qp,
        [IB_USER_VERBS_CMD_DESTROY_QP]          = ib_uverbs_destroy_qp,
        [IB_USER_VERBS_CMD_POST_SEND]           = ib_uverbs_post_send,
@@ -106,6 +108,7 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
        [IB_USER_VERBS_CMD_DETACH_MCAST]        = ib_uverbs_detach_mcast,
        [IB_USER_VERBS_CMD_CREATE_SRQ]          = ib_uverbs_create_srq,
        [IB_USER_VERBS_CMD_MODIFY_SRQ]          = ib_uverbs_modify_srq,
+       [IB_USER_VERBS_CMD_QUERY_SRQ]           = ib_uverbs_query_srq,
        [IB_USER_VERBS_CMD_DESTROY_SRQ]         = ib_uverbs_destroy_srq,
 };
 
@@ -461,7 +464,6 @@ void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
        ib_uverbs_async_handler(uobj->uverbs_file, uobj->uobject.user_handle,
                                event->event, &uobj->async_list,
                                &uobj->async_events_reported);
-                               
 }
 
 void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr)
index c857361be4490d805a811f81bf95b3a21052148a..cae0845f472ac60fd41b4f9684b8111924540484 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
  * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -245,6 +245,258 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
 }
 EXPORT_SYMBOL(ib_create_qp);
 
+static const struct {
+       int                     valid;
+       enum ib_qp_attr_mask    req_param[IB_QPT_RAW_ETY + 1];
+       enum ib_qp_attr_mask    opt_param[IB_QPT_RAW_ETY + 1];
+} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
+       [IB_QPS_RESET] = {
+               [IB_QPS_RESET] = { .valid = 1 },
+               [IB_QPS_ERR]   = { .valid = 1 },
+               [IB_QPS_INIT]  = {
+                       .valid = 1,
+                       .req_param = {
+                               [IB_QPT_UD]  = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_PORT                      |
+                                               IB_QP_QKEY),
+                               [IB_QPT_UC]  = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_PORT                      |
+                                               IB_QP_ACCESS_FLAGS),
+                               [IB_QPT_RC]  = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_PORT                      |
+                                               IB_QP_ACCESS_FLAGS),
+                               [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_QKEY),
+                               [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_QKEY),
+                       }
+               },
+       },
+       [IB_QPS_INIT]  = {
+               [IB_QPS_RESET] = { .valid = 1 },
+               [IB_QPS_ERR] =   { .valid = 1 },
+               [IB_QPS_INIT]  = {
+                       .valid = 1,
+                       .opt_param = {
+                               [IB_QPT_UD]  = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_PORT                      |
+                                               IB_QP_QKEY),
+                               [IB_QPT_UC]  = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_PORT                      |
+                                               IB_QP_ACCESS_FLAGS),
+                               [IB_QPT_RC]  = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_PORT                      |
+                                               IB_QP_ACCESS_FLAGS),
+                               [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_QKEY),
+                               [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_QKEY),
+                       }
+               },
+               [IB_QPS_RTR]   = {
+                       .valid = 1,
+                       .req_param = {
+                               [IB_QPT_UC]  = (IB_QP_AV                        |
+                                               IB_QP_PATH_MTU                  |
+                                               IB_QP_DEST_QPN                  |
+                                               IB_QP_RQ_PSN),
+                               [IB_QPT_RC]  = (IB_QP_AV                        |
+                                               IB_QP_PATH_MTU                  |
+                                               IB_QP_DEST_QPN                  |
+                                               IB_QP_RQ_PSN                    |
+                                               IB_QP_MAX_DEST_RD_ATOMIC        |
+                                               IB_QP_MIN_RNR_TIMER),
+                       },
+                       .opt_param = {
+                                [IB_QPT_UD]  = (IB_QP_PKEY_INDEX               |
+                                                IB_QP_QKEY),
+                                [IB_QPT_UC]  = (IB_QP_ALT_PATH                 |
+                                                IB_QP_ACCESS_FLAGS             |
+                                                IB_QP_PKEY_INDEX),
+                                [IB_QPT_RC]  = (IB_QP_ALT_PATH                 |
+                                                IB_QP_ACCESS_FLAGS             |
+                                                IB_QP_PKEY_INDEX),
+                                [IB_QPT_SMI] = (IB_QP_PKEY_INDEX               |
+                                                IB_QP_QKEY),
+                                [IB_QPT_GSI] = (IB_QP_PKEY_INDEX               |
+                                                IB_QP_QKEY),
+                        }
+               }
+       },
+       [IB_QPS_RTR]   = {
+               [IB_QPS_RESET] = { .valid = 1 },
+               [IB_QPS_ERR] =   { .valid = 1 },
+               [IB_QPS_RTS]   = {
+                       .valid = 1,
+                       .req_param = {
+                               [IB_QPT_UD]  = IB_QP_SQ_PSN,
+                               [IB_QPT_UC]  = IB_QP_SQ_PSN,
+                               [IB_QPT_RC]  = (IB_QP_TIMEOUT                   |
+                                               IB_QP_RETRY_CNT                 |
+                                               IB_QP_RNR_RETRY                 |
+                                               IB_QP_SQ_PSN                    |
+                                               IB_QP_MAX_QP_RD_ATOMIC),
+                               [IB_QPT_SMI] = IB_QP_SQ_PSN,
+                               [IB_QPT_GSI] = IB_QP_SQ_PSN,
+                       },
+                       .opt_param = {
+                                [IB_QPT_UD]  = (IB_QP_CUR_STATE                |
+                                                IB_QP_QKEY),
+                                [IB_QPT_UC]  = (IB_QP_CUR_STATE                |
+                                                IB_QP_ALT_PATH                 |
+                                                IB_QP_ACCESS_FLAGS             |
+                                                IB_QP_PATH_MIG_STATE),
+                                [IB_QPT_RC]  = (IB_QP_CUR_STATE                |
+                                                IB_QP_ALT_PATH                 |
+                                                IB_QP_ACCESS_FLAGS             |
+                                                IB_QP_MIN_RNR_TIMER            |
+                                                IB_QP_PATH_MIG_STATE),
+                                [IB_QPT_SMI] = (IB_QP_CUR_STATE                |
+                                                IB_QP_QKEY),
+                                [IB_QPT_GSI] = (IB_QP_CUR_STATE                |
+                                                IB_QP_QKEY),
+                        }
+               }
+       },
+       [IB_QPS_RTS]   = {
+               [IB_QPS_RESET] = { .valid = 1 },
+               [IB_QPS_ERR] =   { .valid = 1 },
+               [IB_QPS_RTS]   = {
+                       .valid = 1,
+                       .opt_param = {
+                               [IB_QPT_UD]  = (IB_QP_CUR_STATE                 |
+                                               IB_QP_QKEY),
+                               [IB_QPT_UC]  = (IB_QP_CUR_STATE                 |
+                                               IB_QP_ACCESS_FLAGS              |
+                                               IB_QP_ALT_PATH                  |
+                                               IB_QP_PATH_MIG_STATE),
+                               [IB_QPT_RC]  = (IB_QP_CUR_STATE                 |
+                                               IB_QP_ACCESS_FLAGS              |
+                                               IB_QP_ALT_PATH                  |
+                                               IB_QP_PATH_MIG_STATE            |
+                                               IB_QP_MIN_RNR_TIMER),
+                               [IB_QPT_SMI] = (IB_QP_CUR_STATE                 |
+                                               IB_QP_QKEY),
+                               [IB_QPT_GSI] = (IB_QP_CUR_STATE                 |
+                                               IB_QP_QKEY),
+                       }
+               },
+               [IB_QPS_SQD]   = {
+                       .valid = 1,
+                       .opt_param = {
+                               [IB_QPT_UD]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
+                               [IB_QPT_UC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
+                               [IB_QPT_RC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
+                               [IB_QPT_SMI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
+                               [IB_QPT_GSI] = IB_QP_EN_SQD_ASYNC_NOTIFY
+                       }
+               },
+       },
+       [IB_QPS_SQD]   = {
+               [IB_QPS_RESET] = { .valid = 1 },
+               [IB_QPS_ERR] =   { .valid = 1 },
+               [IB_QPS_RTS]   = {
+                       .valid = 1,
+                       .opt_param = {
+                               [IB_QPT_UD]  = (IB_QP_CUR_STATE                 |
+                                               IB_QP_QKEY),
+                               [IB_QPT_UC]  = (IB_QP_CUR_STATE                 |
+                                               IB_QP_ALT_PATH                  |
+                                               IB_QP_ACCESS_FLAGS              |
+                                               IB_QP_PATH_MIG_STATE),
+                               [IB_QPT_RC]  = (IB_QP_CUR_STATE                 |
+                                               IB_QP_ALT_PATH                  |
+                                               IB_QP_ACCESS_FLAGS              |
+                                               IB_QP_MIN_RNR_TIMER             |
+                                               IB_QP_PATH_MIG_STATE),
+                               [IB_QPT_SMI] = (IB_QP_CUR_STATE                 |
+                                               IB_QP_QKEY),
+                               [IB_QPT_GSI] = (IB_QP_CUR_STATE                 |
+                                               IB_QP_QKEY),
+                       }
+               },
+               [IB_QPS_SQD]   = {
+                       .valid = 1,
+                       .opt_param = {
+                               [IB_QPT_UD]  = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_QKEY),
+                               [IB_QPT_UC]  = (IB_QP_AV                        |
+                                               IB_QP_ALT_PATH                  |
+                                               IB_QP_ACCESS_FLAGS              |
+                                               IB_QP_PKEY_INDEX                |
+                                               IB_QP_PATH_MIG_STATE),
+                               [IB_QPT_RC]  = (IB_QP_PORT                      |
+                                               IB_QP_AV                        |
+                                               IB_QP_TIMEOUT                   |
+                                               IB_QP_RETRY_CNT                 |
+                                               IB_QP_RNR_RETRY                 |
+                                               IB_QP_MAX_QP_RD_ATOMIC          |
+                                               IB_QP_MAX_DEST_RD_ATOMIC        |
+                                               IB_QP_ALT_PATH                  |
+                                               IB_QP_ACCESS_FLAGS              |
+                                               IB_QP_PKEY_INDEX                |
+                                               IB_QP_MIN_RNR_TIMER             |
+                                               IB_QP_PATH_MIG_STATE),
+                               [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_QKEY),
+                               [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                |
+                                               IB_QP_QKEY),
+                       }
+               }
+       },
+       [IB_QPS_SQE]   = {
+               [IB_QPS_RESET] = { .valid = 1 },
+               [IB_QPS_ERR] =   { .valid = 1 },
+               [IB_QPS_RTS]   = {
+                       .valid = 1,
+                       .opt_param = {
+                               [IB_QPT_UD]  = (IB_QP_CUR_STATE                 |
+                                               IB_QP_QKEY),
+                               [IB_QPT_UC]  = (IB_QP_CUR_STATE                 |
+                                               IB_QP_ACCESS_FLAGS),
+                               [IB_QPT_SMI] = (IB_QP_CUR_STATE                 |
+                                               IB_QP_QKEY),
+                               [IB_QPT_GSI] = (IB_QP_CUR_STATE                 |
+                                               IB_QP_QKEY),
+                       }
+               }
+       },
+       [IB_QPS_ERR] = {
+               [IB_QPS_RESET] = { .valid = 1 },
+               [IB_QPS_ERR] =   { .valid = 1 }
+       }
+};
+
+int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
+                      enum ib_qp_type type, enum ib_qp_attr_mask mask)
+{
+       enum ib_qp_attr_mask req_param, opt_param;
+
+       if (cur_state  < 0 || cur_state  > IB_QPS_ERR ||
+           next_state < 0 || next_state > IB_QPS_ERR)
+               return 0;
+
+       if (mask & IB_QP_CUR_STATE  &&
+           cur_state != IB_QPS_RTR && cur_state != IB_QPS_RTS &&
+           cur_state != IB_QPS_SQD && cur_state != IB_QPS_SQE)
+               return 0;
+
+       if (!qp_state_table[cur_state][next_state].valid)
+               return 0;
+
+       req_param = qp_state_table[cur_state][next_state].req_param[type];
+       opt_param = qp_state_table[cur_state][next_state].opt_param[type];
+
+       if ((mask & req_param) != req_param)
+               return 0;
+
+       if (mask & ~(req_param | opt_param | IB_QP_STATE))
+               return 0;
+
+       return 1;
+}
+EXPORT_SYMBOL(ib_modify_qp_is_ok);
+
 int ib_modify_qp(struct ib_qp *qp,
                 struct ib_qp_attr *qp_attr,
                 int qp_attr_mask)
@@ -322,11 +574,10 @@ int ib_destroy_cq(struct ib_cq *cq)
 }
 EXPORT_SYMBOL(ib_destroy_cq);
 
-int ib_resize_cq(struct ib_cq *cq,
-                 int           cqe)
+int ib_resize_cq(struct ib_cq *cq, int cqe)
 {
        return cq->device->resize_cq ?
-               cq->device->resize_cq(cq, cqe) : -ENOSYS;
+               cq->device->resize_cq(cq, cqe, NULL) : -ENOSYS;
 }
 EXPORT_SYMBOL(ib_resize_cq);
 
index a19e0ed03d7c51eb4af6cf0960bc784696681fb7..f023d3936518d116a878d2925db708762b2b3162 100644 (file)
@@ -147,7 +147,7 @@ int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah)
        switch (ah->type) {
        case MTHCA_AH_ON_HCA:
                mthca_free(&dev->av_table.alloc,
-                          (ah->avdma - dev->av_table.ddr_av_base) /
+                          (ah->avdma - dev->av_table.ddr_av_base) /
                           MTHCA_AV_SIZE);
                break;
 
@@ -193,6 +193,37 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
        return 0;
 }
 
+int mthca_ah_query(struct ib_ah *ibah, struct ib_ah_attr *attr)
+{
+       struct mthca_ah *ah   = to_mah(ibah);
+       struct mthca_dev *dev = to_mdev(ibah->device);
+
+       /* Only implement for MAD and memfree ah for now. */
+       if (ah->type == MTHCA_AH_ON_HCA)
+               return -ENOSYS;
+
+       memset(attr, 0, sizeof *attr);
+       attr->dlid          = be16_to_cpu(ah->av->dlid);
+       attr->sl            = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28;
+       attr->static_rate   = ah->av->msg_sr & 0x7;
+       attr->src_path_bits = ah->av->g_slid & 0x7F;
+       attr->port_num      = be32_to_cpu(ah->av->port_pd) >> 24;
+       attr->ah_flags      = mthca_ah_grh_present(ah) ? IB_AH_GRH : 0;
+
+       if (attr->ah_flags) {
+               attr->grh.traffic_class =
+                       be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 20;
+               attr->grh.flow_label =
+                       be32_to_cpu(ah->av->sl_tclass_flowlabel) & 0xfffff;
+               attr->grh.hop_limit  = ah->av->hop_limit;
+               attr->grh.sgid_index = ah->av->gid_index &
+                                      (dev->limits.gid_table_len - 1);
+               memcpy(attr->grh.dgid.raw, ah->av->dgid, 16);
+       }
+
+       return 0;
+}
+
 int __devinit mthca_init_av_table(struct mthca_dev *dev)
 {
        int err;
index 2825615ce81c3cd440247a500eedc7111e36871a..343eca507870c53eefcbdf8b881e89e1907791b6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
- * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -182,25 +182,58 @@ struct mthca_cmd_context {
        u8                status;
 };
 
+static int fw_cmd_doorbell = 1;
+module_param(fw_cmd_doorbell, int, 0644);
+MODULE_PARM_DESC(fw_cmd_doorbell, "post FW commands through doorbell page if nonzero "
+                "(and supported by FW)");
+
 static inline int go_bit(struct mthca_dev *dev)
 {
        return readl(dev->hcr + HCR_STATUS_OFFSET) &
                swab32(1 << HCR_GO_BIT);
 }
 
-static int mthca_cmd_post(struct mthca_dev *dev,
-                         u64 in_param,
-                         u64 out_param,
-                         u32 in_modifier,
-                         u8 op_modifier,
-                         u16 op,
-                         u16 token,
-                         int event)
+static void mthca_cmd_post_dbell(struct mthca_dev *dev,
+                                u64 in_param,
+                                u64 out_param,
+                                u32 in_modifier,
+                                u8 op_modifier,
+                                u16 op,
+                                u16 token)
 {
-       int err = 0;
+       void __iomem *ptr = dev->cmd.dbell_map;
+       u16 *offs = dev->cmd.dbell_offsets;
 
-       mutex_lock(&dev->cmd.hcr_mutex);
+       __raw_writel((__force u32) cpu_to_be32(in_param >> 32),           ptr + offs[0]);
+       wmb();
+       __raw_writel((__force u32) cpu_to_be32(in_param & 0xfffffffful),  ptr + offs[1]);
+       wmb();
+       __raw_writel((__force u32) cpu_to_be32(in_modifier),              ptr + offs[2]);
+       wmb();
+       __raw_writel((__force u32) cpu_to_be32(out_param >> 32),          ptr + offs[3]);
+       wmb();
+       __raw_writel((__force u32) cpu_to_be32(out_param & 0xfffffffful), ptr + offs[4]);
+       wmb();
+       __raw_writel((__force u32) cpu_to_be32(token << 16),              ptr + offs[5]);
+       wmb();
+       __raw_writel((__force u32) cpu_to_be32((1 << HCR_GO_BIT)                |
+                                              (1 << HCA_E_BIT)                 |
+                                              (op_modifier << HCR_OPMOD_SHIFT) |
+                                               op),                      ptr + offs[6]);
+       wmb();
+       __raw_writel((__force u32) 0,                                     ptr + offs[7]);
+       wmb();
+}
 
+static int mthca_cmd_post_hcr(struct mthca_dev *dev,
+                             u64 in_param,
+                             u64 out_param,
+                             u32 in_modifier,
+                             u8 op_modifier,
+                             u16 op,
+                             u16 token,
+                             int event)
+{
        if (event) {
                unsigned long end = jiffies + GO_BIT_TIMEOUT;
 
@@ -210,10 +243,8 @@ static int mthca_cmd_post(struct mthca_dev *dev,
                }
        }
 
-       if (go_bit(dev)) {
-               err = -EAGAIN;
-               goto out;
-       }
+       if (go_bit(dev))
+               return -EAGAIN;
 
        /*
         * We use writel (instead of something like memcpy_toio)
@@ -236,7 +267,29 @@ static int mthca_cmd_post(struct mthca_dev *dev,
                                               (op_modifier << HCR_OPMOD_SHIFT) |
                                               op),                       dev->hcr + 6 * 4);
 
-out:
+       return 0;
+}
+
+static int mthca_cmd_post(struct mthca_dev *dev,
+                         u64 in_param,
+                         u64 out_param,
+                         u32 in_modifier,
+                         u8 op_modifier,
+                         u16 op,
+                         u16 token,
+                         int event)
+{
+       int err = 0;
+
+       mutex_lock(&dev->cmd.hcr_mutex);
+
+       if (event && dev->cmd.flags & MTHCA_CMD_POST_DOORBELLS && fw_cmd_doorbell)
+               mthca_cmd_post_dbell(dev, in_param, out_param, in_modifier,
+                                          op_modifier, op, token);
+       else
+               err = mthca_cmd_post_hcr(dev, in_param, out_param, in_modifier,
+                                        op_modifier, op, token, event);
+
        mutex_unlock(&dev->cmd.hcr_mutex);
        return err;
 }
@@ -275,7 +328,7 @@ static int mthca_cmd_poll(struct mthca_dev *dev,
        }
 
        if (out_is_imm)
-               *out_param = 
+               *out_param =
                        (u64) be32_to_cpu((__force __be32)
                                          __raw_readl(dev->hcr + HCR_OUT_PARAM_OFFSET)) << 32 |
                        (u64) be32_to_cpu((__force __be32)
@@ -386,7 +439,7 @@ static int mthca_cmd_box(struct mthca_dev *dev,
                         unsigned long timeout,
                         u8 *status)
 {
-       if (dev->cmd.use_events)
+       if (dev->cmd.flags & MTHCA_CMD_USE_EVENTS)
                return mthca_cmd_wait(dev, in_param, &out_param, 0,
                                      in_modifier, op_modifier, op,
                                      timeout, status);
@@ -423,7 +476,7 @@ static int mthca_cmd_imm(struct mthca_dev *dev,
                         unsigned long timeout,
                         u8 *status)
 {
-       if (dev->cmd.use_events)
+       if (dev->cmd.flags & MTHCA_CMD_USE_EVENTS)
                return mthca_cmd_wait(dev, in_param, out_param, 1,
                                      in_modifier, op_modifier, op,
                                      timeout, status);
@@ -437,7 +490,7 @@ int mthca_cmd_init(struct mthca_dev *dev)
 {
        mutex_init(&dev->cmd.hcr_mutex);
        sema_init(&dev->cmd.poll_sem, 1);
-       dev->cmd.use_events = 0;
+       dev->cmd.flags = 0;
 
        dev->hcr = ioremap(pci_resource_start(dev->pdev, 0) + MTHCA_HCR_BASE,
                           MTHCA_HCR_SIZE);
@@ -461,6 +514,8 @@ void mthca_cmd_cleanup(struct mthca_dev *dev)
 {
        pci_pool_destroy(dev->cmd.pool);
        iounmap(dev->hcr);
+       if (dev->cmd.flags & MTHCA_CMD_POST_DOORBELLS)
+               iounmap(dev->cmd.dbell_map);
 }
 
 /*
@@ -498,7 +553,8 @@ int mthca_cmd_use_events(struct mthca_dev *dev)
                ; /* nothing */
        --dev->cmd.token_mask;
 
-       dev->cmd.use_events = 1;
+       dev->cmd.flags |= MTHCA_CMD_USE_EVENTS;
+
        down(&dev->cmd.poll_sem);
 
        return 0;
@@ -511,7 +567,7 @@ void mthca_cmd_use_polling(struct mthca_dev *dev)
 {
        int i;
 
-       dev->cmd.use_events = 0;
+       dev->cmd.flags &= ~MTHCA_CMD_USE_EVENTS;
 
        for (i = 0; i < dev->cmd.max_cmds; ++i)
                down(&dev->cmd.event_sem);
@@ -596,8 +652,9 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
                 * address or size and use that as our log2 size.
                 */
                lg = ffs(mthca_icm_addr(&iter) | mthca_icm_size(&iter)) - 1;
-               if (lg < 12) {
-                       mthca_warn(dev, "Got FW area not aligned to 4K (%llx/%lx).\n",
+               if (lg < MTHCA_ICM_PAGE_SHIFT) {
+                       mthca_warn(dev, "Got FW area not aligned to %d (%llx/%lx).\n",
+                                  MTHCA_ICM_PAGE_SIZE,
                                   (unsigned long long) mthca_icm_addr(&iter),
                                   mthca_icm_size(&iter));
                        err = -EINVAL;
@@ -609,8 +666,9 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
                                virt += 1 << lg;
                        }
 
-                       pages[nent * 2 + 1] = cpu_to_be64((mthca_icm_addr(&iter) +
-                                                          (i << lg)) | (lg - 12));
+                       pages[nent * 2 + 1] =
+                               cpu_to_be64((mthca_icm_addr(&iter) + (i << lg)) |
+                                           (lg - MTHCA_ICM_PAGE_SHIFT));
                        ts += 1 << (lg - 10);
                        ++tc;
 
@@ -661,12 +719,41 @@ int mthca_RUN_FW(struct mthca_dev *dev, u8 *status)
        return mthca_cmd(dev, 0, 0, 0, CMD_RUN_FW, CMD_TIME_CLASS_A, status);
 }
 
+static void mthca_setup_cmd_doorbells(struct mthca_dev *dev, u64 base)
+{
+       unsigned long addr;
+       u16 max_off = 0;
+       int i;
+
+       for (i = 0; i < 8; ++i)
+               max_off = max(max_off, dev->cmd.dbell_offsets[i]);
+
+       if ((base & PAGE_MASK) != ((base + max_off) & PAGE_MASK)) {
+               mthca_warn(dev, "Firmware doorbell region at 0x%016llx, "
+                          "length 0x%x crosses a page boundary\n",
+                          (unsigned long long) base, max_off);
+               return;
+       }
+
+       addr = pci_resource_start(dev->pdev, 2) +
+               ((pci_resource_len(dev->pdev, 2) - 1) & base);
+       dev->cmd.dbell_map = ioremap(addr, max_off + sizeof(u32));
+       if (!dev->cmd.dbell_map)
+               return;
+
+       dev->cmd.flags |= MTHCA_CMD_POST_DOORBELLS;
+       mthca_dbg(dev, "Mapped doorbell page for posting FW commands\n");
+}
+
 int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
 {
        struct mthca_mailbox *mailbox;
        u32 *outbox;
+       u64 base;
+       u32 tmp;
        int err = 0;
        u8 lg;
+       int i;
 
 #define QUERY_FW_OUT_SIZE             0x100
 #define QUERY_FW_VER_OFFSET            0x00
@@ -674,6 +761,10 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
 #define QUERY_FW_ERR_START_OFFSET      0x30
 #define QUERY_FW_ERR_SIZE_OFFSET       0x38
 
+#define QUERY_FW_CMD_DB_EN_OFFSET      0x10
+#define QUERY_FW_CMD_DB_OFFSET         0x50
+#define QUERY_FW_CMD_DB_BASE           0x60
+
 #define QUERY_FW_START_OFFSET          0x20
 #define QUERY_FW_END_OFFSET            0x28
 
@@ -702,16 +793,29 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
                ((dev->fw_ver & 0xffff0000ull) >> 16) |
                ((dev->fw_ver & 0x0000ffffull) << 16);
 
+       mthca_dbg(dev, "FW version %012llx, max commands %d\n",
+                 (unsigned long long) dev->fw_ver, dev->cmd.max_cmds);
+
        MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
        dev->cmd.max_cmds = 1 << lg;
        MTHCA_GET(dev->catas_err.addr, outbox, QUERY_FW_ERR_START_OFFSET);
        MTHCA_GET(dev->catas_err.size, outbox, QUERY_FW_ERR_SIZE_OFFSET);
 
-       mthca_dbg(dev, "FW version %012llx, max commands %d\n",
-                 (unsigned long long) dev->fw_ver, dev->cmd.max_cmds);
        mthca_dbg(dev, "Catastrophic error buffer at 0x%llx, size 0x%x\n",
                  (unsigned long long) dev->catas_err.addr, dev->catas_err.size);
 
+       MTHCA_GET(tmp, outbox, QUERY_FW_CMD_DB_EN_OFFSET);
+       if (tmp & 0x1) {
+               mthca_dbg(dev, "FW supports commands through doorbells\n");
+
+               MTHCA_GET(base, outbox, QUERY_FW_CMD_DB_BASE);
+               for (i = 0; i < MTHCA_CMD_NUM_DBELL_DWORDS; ++i)
+                       MTHCA_GET(dev->cmd.dbell_offsets[i], outbox,
+                                 QUERY_FW_CMD_DB_OFFSET + (i << 1));
+
+               mthca_setup_cmd_doorbells(dev, base);
+       }
+
        if (mthca_is_memfree(dev)) {
                MTHCA_GET(dev->fw.arbel.fw_pages,       outbox, QUERY_FW_SIZE_OFFSET);
                MTHCA_GET(dev->fw.arbel.clr_int_base,   outbox, QUERY_FW_CLR_INT_BASE_OFFSET);
@@ -720,12 +824,12 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
                mthca_dbg(dev, "FW size %d KB\n", dev->fw.arbel.fw_pages << 2);
 
                /*
-                * Arbel page size is always 4 KB; round up number of
-                * system pages needed.
+                * Round up number of system pages needed in case
+                * MTHCA_ICM_PAGE_SIZE < PAGE_SIZE.
                 */
                dev->fw.arbel.fw_pages =
-                       ALIGN(dev->fw.arbel.fw_pages, PAGE_SIZE >> 12) >>
-                               (PAGE_SHIFT - 12);
+                       ALIGN(dev->fw.arbel.fw_pages, PAGE_SIZE / MTHCA_ICM_PAGE_SIZE) >>
+                               (PAGE_SHIFT - MTHCA_ICM_PAGE_SHIFT);
 
                mthca_dbg(dev, "Clear int @ %llx, EQ arm @ %llx, EQ set CI @ %llx\n",
                          (unsigned long long) dev->fw.arbel.clr_int_base,
@@ -1173,7 +1277,8 @@ int mthca_INIT_HCA(struct mthca_dev *dev,
        int err;
 
 #define INIT_HCA_IN_SIZE                0x200
-#define INIT_HCA_FLAGS_OFFSET           0x014
+#define INIT_HCA_FLAGS1_OFFSET           0x00c
+#define INIT_HCA_FLAGS2_OFFSET           0x014
 #define INIT_HCA_QPC_OFFSET             0x020
 #define  INIT_HCA_QPC_BASE_OFFSET       (INIT_HCA_QPC_OFFSET + 0x10)
 #define  INIT_HCA_LOG_QP_OFFSET         (INIT_HCA_QPC_OFFSET + 0x17)
@@ -1216,15 +1321,18 @@ int mthca_INIT_HCA(struct mthca_dev *dev,
 
        memset(inbox, 0, INIT_HCA_IN_SIZE);
 
+       if (dev->mthca_flags & MTHCA_FLAG_SINAI_OPT)
+               MTHCA_PUT(inbox, 0x1, INIT_HCA_FLAGS1_OFFSET);
+
 #if defined(__LITTLE_ENDIAN)
-       *(inbox + INIT_HCA_FLAGS_OFFSET / 4) &= ~cpu_to_be32(1 << 1);
+       *(inbox + INIT_HCA_FLAGS2_OFFSET / 4) &= ~cpu_to_be32(1 << 1);
 #elif defined(__BIG_ENDIAN)
-       *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 1);
+       *(inbox + INIT_HCA_FLAGS2_OFFSET / 4) |= cpu_to_be32(1 << 1);
 #else
 #error Host endianness not defined
 #endif
        /* Check port for UD address vector: */
-       *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1);
+       *(inbox + INIT_HCA_FLAGS2_OFFSET / 4) |= cpu_to_be32(1);
 
        /* We leave wqe_quota, responder_exu, etc as 0 (default) */
 
@@ -1438,11 +1546,11 @@ int mthca_SET_ICM_SIZE(struct mthca_dev *dev, u64 icm_size, u64 *aux_pages,
                return ret;
 
        /*
-        * Arbel page size is always 4 KB; round up number of system
-        * pages needed.
+        * Round up number of system pages needed in case
+        * MTHCA_ICM_PAGE_SIZE < PAGE_SIZE.
         */
-       *aux_pages = (*aux_pages + (1 << (PAGE_SHIFT - 12)) - 1) >> (PAGE_SHIFT - 12);
-       *aux_pages = ALIGN(*aux_pages, PAGE_SIZE >> 12) >> (PAGE_SHIFT - 12);
+       *aux_pages = ALIGN(*aux_pages, PAGE_SIZE / MTHCA_ICM_PAGE_SIZE) >>
+               (PAGE_SHIFT - MTHCA_ICM_PAGE_SHIFT);
 
        return 0;
 }
@@ -1514,6 +1622,37 @@ int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
                             CMD_TIME_CLASS_A, status);
 }
 
+int mthca_RESIZE_CQ(struct mthca_dev *dev, int cq_num, u32 lkey, u8 log_size,
+                   u8 *status)
+{
+       struct mthca_mailbox *mailbox;
+       __be32 *inbox;
+       int err;
+
+#define RESIZE_CQ_IN_SIZE              0x40
+#define RESIZE_CQ_LOG_SIZE_OFFSET      0x0c
+#define RESIZE_CQ_LKEY_OFFSET          0x1c
+
+       mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+       inbox = mailbox->buf;
+
+       memset(inbox, 0, RESIZE_CQ_IN_SIZE);
+       /*
+        * Leave start address fields zeroed out -- mthca assumes that
+        * MRs for CQs always start at virtual address 0.
+        */
+       MTHCA_PUT(inbox, log_size, RESIZE_CQ_LOG_SIZE_OFFSET);
+       MTHCA_PUT(inbox, lkey,     RESIZE_CQ_LKEY_OFFSET);
+
+       err = mthca_cmd(dev, mailbox->dma, cq_num, 1, CMD_RESIZE_CQ,
+                       CMD_TIME_CLASS_B, status);
+
+       mthca_free_mailbox(dev, mailbox);
+       return err;
+}
+
 int mthca_SW2HW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
                    int srq_num, u8 *status)
 {
@@ -1529,37 +1668,69 @@ int mthca_HW2SW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
                             CMD_TIME_CLASS_A, status);
 }
 
+int mthca_QUERY_SRQ(struct mthca_dev *dev, u32 num,
+                   struct mthca_mailbox *mailbox, u8 *status)
+{
+       return mthca_cmd_box(dev, 0, mailbox->dma, num, 0,
+                            CMD_QUERY_SRQ, CMD_TIME_CLASS_A, status);
+}
+
 int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status)
 {
        return mthca_cmd(dev, limit, srq_num, 0, CMD_ARM_SRQ,
                         CMD_TIME_CLASS_B, status);
 }
 
-int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
-                   int is_ee, struct mthca_mailbox *mailbox, u32 optmask,
+int mthca_MODIFY_QP(struct mthca_dev *dev, enum ib_qp_state cur,
+                   enum ib_qp_state next, u32 num, int is_ee,
+                   struct mthca_mailbox *mailbox, u32 optmask,
                    u8 *status)
 {
-       static const u16 op[] = {
-               [MTHCA_TRANS_RST2INIT]  = CMD_RST2INIT_QPEE,
-               [MTHCA_TRANS_INIT2INIT] = CMD_INIT2INIT_QPEE,
-               [MTHCA_TRANS_INIT2RTR]  = CMD_INIT2RTR_QPEE,
-               [MTHCA_TRANS_RTR2RTS]   = CMD_RTR2RTS_QPEE,
-               [MTHCA_TRANS_RTS2RTS]   = CMD_RTS2RTS_QPEE,
-               [MTHCA_TRANS_SQERR2RTS] = CMD_SQERR2RTS_QPEE,
-               [MTHCA_TRANS_ANY2ERR]   = CMD_2ERR_QPEE,
-               [MTHCA_TRANS_RTS2SQD]   = CMD_RTS2SQD_QPEE,
-               [MTHCA_TRANS_SQD2SQD]   = CMD_SQD2SQD_QPEE,
-               [MTHCA_TRANS_SQD2RTS]   = CMD_SQD2RTS_QPEE,
-               [MTHCA_TRANS_ANY2RST]   = CMD_ERR2RST_QPEE
+       static const u16 op[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
+               [IB_QPS_RESET] = {
+                       [IB_QPS_RESET]  = CMD_ERR2RST_QPEE,
+                       [IB_QPS_ERR]    = CMD_2ERR_QPEE,
+                       [IB_QPS_INIT]   = CMD_RST2INIT_QPEE,
+               },
+               [IB_QPS_INIT]  = {
+                       [IB_QPS_RESET]  = CMD_ERR2RST_QPEE,
+                       [IB_QPS_ERR]    = CMD_2ERR_QPEE,
+                       [IB_QPS_INIT]   = CMD_INIT2INIT_QPEE,
+                       [IB_QPS_RTR]    = CMD_INIT2RTR_QPEE,
+               },
+               [IB_QPS_RTR]   = {
+                       [IB_QPS_RESET]  = CMD_ERR2RST_QPEE,
+                       [IB_QPS_ERR]    = CMD_2ERR_QPEE,
+                       [IB_QPS_RTS]    = CMD_RTR2RTS_QPEE,
+               },
+               [IB_QPS_RTS]   = {
+                       [IB_QPS_RESET]  = CMD_ERR2RST_QPEE,
+                       [IB_QPS_ERR]    = CMD_2ERR_QPEE,
+                       [IB_QPS_RTS]    = CMD_RTS2RTS_QPEE,
+                       [IB_QPS_SQD]    = CMD_RTS2SQD_QPEE,
+               },
+               [IB_QPS_SQD] = {
+                       [IB_QPS_RESET]  = CMD_ERR2RST_QPEE,
+                       [IB_QPS_ERR]    = CMD_2ERR_QPEE,
+                       [IB_QPS_RTS]    = CMD_SQD2RTS_QPEE,
+                       [IB_QPS_SQD]    = CMD_SQD2SQD_QPEE,
+               },
+               [IB_QPS_SQE] = {
+                       [IB_QPS_RESET]  = CMD_ERR2RST_QPEE,
+                       [IB_QPS_ERR]    = CMD_2ERR_QPEE,
+                       [IB_QPS_RTS]    = CMD_SQERR2RTS_QPEE,
+               },
+               [IB_QPS_ERR] = {
+                       [IB_QPS_RESET]  = CMD_ERR2RST_QPEE,
+                       [IB_QPS_ERR]    = CMD_2ERR_QPEE,
+               }
        };
+
        u8 op_mod = 0;
        int my_mailbox = 0;
        int err;
 
-       if (trans < 0 || trans >= ARRAY_SIZE(op))
-               return -EINVAL;
-
-       if (trans == MTHCA_TRANS_ANY2RST) {
+       if (op[cur][next] == CMD_ERR2RST_QPEE) {
                op_mod = 3;     /* don't write outbox, any->reset */
 
                /* For debugging */
@@ -1571,34 +1742,35 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
                        } else
                                mailbox = NULL;
                }
-       } else {
-               if (0) {
+
+               err = mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0,
+                                   (!!is_ee << 24) | num, op_mod,
+                                   op[cur][next], CMD_TIME_CLASS_C, status);
+
+               if (0 && mailbox) {
                        int i;
                        mthca_dbg(dev, "Dumping QP context:\n");
-                       printk("  opt param mask: %08x\n", be32_to_cpup(mailbox->buf));
+                       printk(" %08x\n", be32_to_cpup(mailbox->buf));
                        for (i = 0; i < 0x100 / 4; ++i) {
                                if (i % 8 == 0)
-                                       printk("  [%02x] ", i * 4);
+                                       printk("[%02x] ", i * 4);
                                printk(" %08x",
                                       be32_to_cpu(((__be32 *) mailbox->buf)[i + 2]));
                                if ((i + 1) % 8 == 0)
                                        printk("\n");
                        }
                }
-       }
-
-       if (trans == MTHCA_TRANS_ANY2RST) {
-               err = mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0,
-                                   (!!is_ee << 24) | num, op_mod,
-                                   op[trans], CMD_TIME_CLASS_C, status);
 
-               if (0 && mailbox) {
+               if (my_mailbox)
+                       mthca_free_mailbox(dev, mailbox);
+       } else {
+               if (0) {
                        int i;
                        mthca_dbg(dev, "Dumping QP context:\n");
-                       printk(" %08x\n", be32_to_cpup(mailbox->buf));
+                       printk("  opt param mask: %08x\n", be32_to_cpup(mailbox->buf));
                        for (i = 0; i < 0x100 / 4; ++i) {
                                if (i % 8 == 0)
-                                       printk("[%02x] ", i * 4);
+                                       printk("  [%02x] ", i * 4);
                                printk(" %08x",
                                       be32_to_cpu(((__be32 *) mailbox->buf)[i + 2]));
                                if ((i + 1) % 8 == 0)
@@ -1606,12 +1778,9 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
                        }
                }
 
-       } else
-               err = mthca_cmd(dev, mailbox->dma, (!!is_ee << 24) | num,
-                               op_mod, op[trans], CMD_TIME_CLASS_C, status);
-
-       if (my_mailbox)
-               mthca_free_mailbox(dev, mailbox);
+               err = mthca_cmd(dev, mailbox->dma, optmask | (!!is_ee << 24) | num,
+                               op_mod, op[cur][next], CMD_TIME_CLASS_C, status);
+       }
 
        return err;
 }
index 18175bec84c27619a69839f1b3e84c527c03a9aa..e4ec35c40dd3c1cf892bf649ec2c4ca92ea5eed4 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2006 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -73,9 +74,9 @@ enum {
        MTHCA_CMD_STAT_REG_BOUND      = 0x21,
        /* HCA local attached memory not present: */
        MTHCA_CMD_STAT_LAM_NOT_PRE    = 0x22,
-        /* Bad management packet (silently discarded): */
+       /* Bad management packet (silently discarded): */
        MTHCA_CMD_STAT_BAD_PKT        = 0x30,
-        /* More outstanding CQEs in CQ than new CQ size: */
+       /* More outstanding CQEs in CQ than new CQ size: */
        MTHCA_CMD_STAT_BAD_SIZE       = 0x40
 };
 
@@ -298,13 +299,18 @@ int mthca_SW2HW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
                   int cq_num, u8 *status);
 int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
                   int cq_num, u8 *status);
+int mthca_RESIZE_CQ(struct mthca_dev *dev, int cq_num, u32 lkey, u8 log_size,
+                   u8 *status);
 int mthca_SW2HW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
                    int srq_num, u8 *status);
 int mthca_HW2SW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
                    int srq_num, u8 *status);
+int mthca_QUERY_SRQ(struct mthca_dev *dev, u32 num,
+                   struct mthca_mailbox *mailbox, u8 *status);
 int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status);
-int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
-                   int is_ee, struct mthca_mailbox *mailbox, u32 optmask,
+int mthca_MODIFY_QP(struct mthca_dev *dev, enum ib_qp_state cur,
+                   enum ib_qp_state next, u32 num, int is_ee,
+                   struct mthca_mailbox *mailbox, u32 optmask,
                    u8 *status);
 int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee,
                   struct mthca_mailbox *mailbox, u8 *status);
index 96f1a86bf04950f54df57b36522ae008bfff00d5..76aabc5bf3714608fdc5420ab6def695e33f8da9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2005 Cisco Systems, Inc. All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems, Inc. All rights reserved.
  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
  * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
  *
@@ -150,24 +150,29 @@ struct mthca_err_cqe {
 #define MTHCA_ARBEL_CQ_DB_REQ_NOT      (2 << 24)
 #define MTHCA_ARBEL_CQ_DB_REQ_NOT_MULT (3 << 24)
 
-static inline struct mthca_cqe *get_cqe(struct mthca_cq *cq, int entry)
+static inline struct mthca_cqe *get_cqe_from_buf(struct mthca_cq_buf *buf,
+                                                int entry)
 {
-       if (cq->is_direct)
-               return cq->queue.direct.buf + (entry * MTHCA_CQ_ENTRY_SIZE);
+       if (buf->is_direct)
+               return buf->queue.direct.buf + (entry * MTHCA_CQ_ENTRY_SIZE);
        else
-               return cq->queue.page_list[entry * MTHCA_CQ_ENTRY_SIZE / PAGE_SIZE].buf
+               return buf->queue.page_list[entry * MTHCA_CQ_ENTRY_SIZE / PAGE_SIZE].buf
                        + (entry * MTHCA_CQ_ENTRY_SIZE) % PAGE_SIZE;
 }
 
-static inline struct mthca_cqe *cqe_sw(struct mthca_cq *cq, int i)
+static inline struct mthca_cqe *get_cqe(struct mthca_cq *cq, int entry)
+{
+       return get_cqe_from_buf(&cq->buf, entry);
+}
+
+static inline struct mthca_cqe *cqe_sw(struct mthca_cqe *cqe)
 {
-       struct mthca_cqe *cqe = get_cqe(cq, i);
        return MTHCA_CQ_ENTRY_OWNER_HW & cqe->owner ? NULL : cqe;
 }
 
 static inline struct mthca_cqe *next_cqe_sw(struct mthca_cq *cq)
 {
-       return cqe_sw(cq, cq->cons_index & cq->ibcq.cqe);
+       return cqe_sw(get_cqe(cq, cq->cons_index & cq->ibcq.cqe));
 }
 
 static inline void set_cqe_hw(struct mthca_cqe *cqe)
@@ -289,7 +294,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
         * from our QP and therefore don't need to be checked.
         */
        for (prod_index = cq->cons_index;
-            cqe_sw(cq, prod_index & cq->ibcq.cqe);
+            cqe_sw(get_cqe(cq, prod_index & cq->ibcq.cqe));
             ++prod_index)
                if (prod_index == cq->cons_index + cq->ibcq.cqe)
                        break;
@@ -324,12 +329,58 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
                wake_up(&cq->wait);
 }
 
-static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
-                           struct mthca_qp *qp, int wqe_index, int is_send,
-                           struct mthca_err_cqe *cqe,
-                           struct ib_wc *entry, int *free_cqe)
+void mthca_cq_resize_copy_cqes(struct mthca_cq *cq)
+{
+       int i;
+
+       /*
+        * In Tavor mode, the hardware keeps the consumer and producer
+        * indices mod the CQ size.  Since we might be making the CQ
+        * bigger, we need to deal with the case where the producer
+        * index wrapped around before the CQ was resized.
+        */
+       if (!mthca_is_memfree(to_mdev(cq->ibcq.device)) &&
+           cq->ibcq.cqe < cq->resize_buf->cqe) {
+               cq->cons_index &= cq->ibcq.cqe;
+               if (cqe_sw(get_cqe(cq, cq->ibcq.cqe)))
+                       cq->cons_index -= cq->ibcq.cqe + 1;
+       }
+
+       for (i = cq->cons_index; cqe_sw(get_cqe(cq, i & cq->ibcq.cqe)); ++i)
+               memcpy(get_cqe_from_buf(&cq->resize_buf->buf,
+                                       i & cq->resize_buf->cqe),
+                      get_cqe(cq, i & cq->ibcq.cqe), MTHCA_CQ_ENTRY_SIZE);
+}
+
+int mthca_alloc_cq_buf(struct mthca_dev *dev, struct mthca_cq_buf *buf, int nent)
+{
+       int ret;
+       int i;
+
+       ret = mthca_buf_alloc(dev, nent * MTHCA_CQ_ENTRY_SIZE,
+                             MTHCA_MAX_DIRECT_CQ_SIZE,
+                             &buf->queue, &buf->is_direct,
+                             &dev->driver_pd, 1, &buf->mr);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < nent; ++i)
+               set_cqe_hw(get_cqe_from_buf(buf, i));
+
+       return 0;
+}
+
+void mthca_free_cq_buf(struct mthca_dev *dev, struct mthca_cq_buf *buf, int cqe)
+{
+       mthca_buf_free(dev, (cqe + 1) * MTHCA_CQ_ENTRY_SIZE, &buf->queue,
+                      buf->is_direct, &buf->mr);
+}
+
+static void handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
+                            struct mthca_qp *qp, int wqe_index, int is_send,
+                            struct mthca_err_cqe *cqe,
+                            struct ib_wc *entry, int *free_cqe)
 {
-       int err;
        int dbd;
        __be32 new_wqe;
 
@@ -412,11 +463,9 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
         * error case, so we don't have to check the doorbell count, etc.
         */
        if (mthca_is_memfree(dev))
-               return 0;
+               return;
 
-       err = mthca_free_err_wqe(dev, qp, is_send, wqe_index, &dbd, &new_wqe);
-       if (err)
-               return err;
+       mthca_free_err_wqe(dev, qp, is_send, wqe_index, &dbd, &new_wqe);
 
        /*
         * If we're at the end of the WQE chain, or we've used up our
@@ -424,15 +473,13 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
         * the next poll operation.
         */
        if (!(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd))
-               return 0;
+               return;
 
        cqe->db_cnt   = cpu_to_be16(be16_to_cpu(cqe->db_cnt) - dbd);
        cqe->wqe      = new_wqe;
        cqe->syndrome = SYNDROME_WR_FLUSH_ERR;
 
        *free_cqe = 0;
-
-       return 0;
 }
 
 static inline int mthca_poll_one(struct mthca_dev *dev,
@@ -518,9 +565,9 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
        }
 
        if (is_error) {
-               err = handle_error_cqe(dev, cq, *cur_qp, wqe_index, is_send,
-                                      (struct mthca_err_cqe *) cqe,
-                                      entry, &free_cqe);
+               handle_error_cqe(dev, cq, *cur_qp, wqe_index, is_send,
+                                (struct mthca_err_cqe *) cqe,
+                                entry, &free_cqe);
                goto out;
        }
 
@@ -614,11 +661,14 @@ int mthca_poll_cq(struct ib_cq *ibcq, int num_entries,
 
        spin_lock_irqsave(&cq->lock, flags);
 
-       for (npolled = 0; npolled < num_entries; ++npolled) {
+       npolled = 0;
+repoll:
+       while (npolled < num_entries) {
                err = mthca_poll_one(dev, cq, &qp,
                                     &freed, entry + npolled);
                if (err)
                        break;
+               ++npolled;
        }
 
        if (freed) {
@@ -626,6 +676,42 @@ int mthca_poll_cq(struct ib_cq *ibcq, int num_entries,
                update_cons_index(dev, cq, freed);
        }
 
+       /*
+        * If a CQ resize is in progress and we discovered that the
+        * old buffer is empty, then peek in the new buffer, and if
+        * it's not empty, switch to the new buffer and continue
+        * polling there.
+        */
+       if (unlikely(err == -EAGAIN && cq->resize_buf &&
+                    cq->resize_buf->state == CQ_RESIZE_READY)) {
+               /*
+                * In Tavor mode, the hardware keeps the producer
+                * index modulo the CQ size.  Since we might be making
+                * the CQ bigger, we need to mask our consumer index
+                * using the size of the old CQ buffer before looking
+                * in the new CQ buffer.
+                */
+               if (!mthca_is_memfree(dev))
+                       cq->cons_index &= cq->ibcq.cqe;
+
+               if (cqe_sw(get_cqe_from_buf(&cq->resize_buf->buf,
+                                           cq->cons_index & cq->resize_buf->cqe))) {
+                       struct mthca_cq_buf tbuf;
+                       int tcqe;
+
+                       tbuf         = cq->buf;
+                       tcqe         = cq->ibcq.cqe;
+                       cq->buf      = cq->resize_buf->buf;
+                       cq->ibcq.cqe = cq->resize_buf->cqe;
+
+                       cq->resize_buf->buf   = tbuf;
+                       cq->resize_buf->cqe   = tcqe;
+                       cq->resize_buf->state = CQ_RESIZE_SWAPPED;
+
+                       goto repoll;
+               }
+       }
+
        spin_unlock_irqrestore(&cq->lock, flags);
 
        return err == 0 || err == -EAGAIN ? npolled : err;
@@ -684,24 +770,14 @@ int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
        return 0;
 }
 
-static void mthca_free_cq_buf(struct mthca_dev *dev, struct mthca_cq *cq)
-{
-       mthca_buf_free(dev, (cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE,
-                      &cq->queue, cq->is_direct, &cq->mr);
-}
-
 int mthca_init_cq(struct mthca_dev *dev, int nent,
                  struct mthca_ucontext *ctx, u32 pdn,
                  struct mthca_cq *cq)
 {
-       int size = nent * MTHCA_CQ_ENTRY_SIZE;
        struct mthca_mailbox *mailbox;
        struct mthca_cq_context *cq_context;
        int err = -ENOMEM;
        u8 status;
-       int i;
-
-       might_sleep();
 
        cq->ibcq.cqe  = nent - 1;
        cq->is_kernel = !ctx;
@@ -739,14 +815,9 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
        cq_context = mailbox->buf;
 
        if (cq->is_kernel) {
-               err = mthca_buf_alloc(dev, size, MTHCA_MAX_DIRECT_CQ_SIZE,
-                                     &cq->queue, &cq->is_direct,
-                                     &dev->driver_pd, 1, &cq->mr);
+               err = mthca_alloc_cq_buf(dev, &cq->buf, nent);
                if (err)
                        goto err_out_mailbox;
-
-               for (i = 0; i < nent; ++i)
-                       set_cqe_hw(get_cqe(cq, i));
        }
 
        spin_lock_init(&cq->lock);
@@ -765,7 +836,7 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
        cq_context->error_eqn       = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_ASYNC].eqn);
        cq_context->comp_eqn        = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_COMP].eqn);
        cq_context->pd              = cpu_to_be32(pdn);
-       cq_context->lkey            = cpu_to_be32(cq->mr.ibmr.lkey);
+       cq_context->lkey            = cpu_to_be32(cq->buf.mr.ibmr.lkey);
        cq_context->cqn             = cpu_to_be32(cq->cqn);
 
        if (mthca_is_memfree(dev)) {
@@ -803,7 +874,7 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
 
 err_out_free_mr:
        if (cq->is_kernel)
-               mthca_free_cq_buf(dev, cq);
+               mthca_free_cq_buf(dev, &cq->buf, cq->ibcq.cqe);
 
 err_out_mailbox:
        mthca_free_mailbox(dev, mailbox);
@@ -832,8 +903,6 @@ void mthca_free_cq(struct mthca_dev *dev,
        int err;
        u8 status;
 
-       might_sleep();
-
        mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
        if (IS_ERR(mailbox)) {
                mthca_warn(dev, "No memory for mailbox to free CQ.\n");
@@ -871,7 +940,7 @@ void mthca_free_cq(struct mthca_dev *dev,
        wait_event(cq->wait, !atomic_read(&cq->refcount));
 
        if (cq->is_kernel) {
-               mthca_free_cq_buf(dev, cq);
+               mthca_free_cq_buf(dev, &cq->buf, cq->ibcq.cqe);
                if (mthca_is_memfree(dev)) {
                        mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM,    cq->arm_db_index);
                        mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
index e481037288d61cbb642890754f999a965f9db5be..ad52edbefe98b16da4bb538cda021da760b539d0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
  * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
  *
@@ -53,8 +53,8 @@
 
 #define DRV_NAME       "ib_mthca"
 #define PFX            DRV_NAME ": "
-#define DRV_VERSION    "0.07"
-#define DRV_RELDATE    "February 13, 2006"
+#define DRV_VERSION    "0.08"
+#define DRV_RELDATE    "February 14, 2006"
 
 enum {
        MTHCA_FLAG_DDR_HIDDEN = 1 << 1,
@@ -64,7 +64,8 @@ enum {
        MTHCA_FLAG_NO_LAM     = 1 << 5,
        MTHCA_FLAG_FMR        = 1 << 6,
        MTHCA_FLAG_MEMFREE    = 1 << 7,
-       MTHCA_FLAG_PCIE       = 1 << 8
+       MTHCA_FLAG_PCIE       = 1 << 8,
+       MTHCA_FLAG_SINAI_OPT  = 1 << 9
 };
 
 enum {
@@ -110,9 +111,17 @@ enum {
        MTHCA_OPCODE_INVALID        = 0xff
 };
 
+enum {
+       MTHCA_CMD_USE_EVENTS         = 1 << 0,
+       MTHCA_CMD_POST_DOORBELLS     = 1 << 1
+};
+
+enum {
+       MTHCA_CMD_NUM_DBELL_DWORDS = 8
+};
+
 struct mthca_cmd {
        struct pci_pool          *pool;
-       int                       use_events;
        struct mutex              hcr_mutex;
        struct semaphore          poll_sem;
        struct semaphore          event_sem;
@@ -121,6 +130,9 @@ struct mthca_cmd {
        int                       free_head;
        struct mthca_cmd_context *context;
        u16                       token_mask;
+       u32                       flags;
+       void __iomem             *dbell_map;
+       u16                       dbell_offsets[MTHCA_CMD_NUM_DBELL_DWORDS];
 };
 
 struct mthca_limits {
@@ -470,12 +482,16 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
                    enum ib_event_type event_type);
 void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
                    struct mthca_srq *srq);
+void mthca_cq_resize_copy_cqes(struct mthca_cq *cq);
+int mthca_alloc_cq_buf(struct mthca_dev *dev, struct mthca_cq_buf *buf, int nent);
+void mthca_free_cq_buf(struct mthca_dev *dev, struct mthca_cq_buf *buf, int cqe);
 
 int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
                    struct ib_srq_attr *attr, struct mthca_srq *srq);
 void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq);
 int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
                     enum ib_srq_attr_mask attr_mask);
+int mthca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
 void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
                     enum ib_event_type event_type);
 void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr);
@@ -486,6 +502,8 @@ int mthca_arbel_post_srq_recv(struct ib_srq *srq, struct ib_recv_wr *wr,
 
 void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
                    enum ib_event_type event_type);
+int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask,
+                  struct ib_qp_init_attr *qp_init_attr);
 int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask);
 int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                          struct ib_send_wr **bad_wr);
@@ -495,8 +513,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                          struct ib_send_wr **bad_wr);
 int mthca_arbel_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
                             struct ib_recv_wr **bad_wr);
-int mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,
-                      int index, int *dbd, __be32 *new_wqe);
+void mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,
+                       int index, int *dbd, __be32 *new_wqe);
 int mthca_alloc_qp(struct mthca_dev *dev,
                   struct mthca_pd *pd,
                   struct mthca_cq *send_cq,
@@ -522,6 +540,7 @@ int mthca_create_ah(struct mthca_dev *dev,
 int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah);
 int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
                  struct ib_ud_header *header);
+int mthca_ah_query(struct ib_ah *ibah, struct ib_ah_attr *attr);
 int mthca_ah_grh_present(struct mthca_ah *ah);
 
 int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
index 2eabb27804cd367b138d2b0e167617a6df20d3b4..cbdc348fb6894c30230da6822b538a1b450f9da4 100644 (file)
@@ -497,7 +497,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
 
        eq->dev  = dev;
        eq->nent = roundup_pow_of_two(max(nent, 2));
-       npages = ALIGN(eq->nent * MTHCA_EQ_ENTRY_SIZE, PAGE_SIZE) / PAGE_SIZE;
+       npages = ALIGN(eq->nent * MTHCA_EQ_ENTRY_SIZE, PAGE_SIZE) / PAGE_SIZE;
 
        eq->page_list = kmalloc(npages * sizeof *eq->page_list,
                                GFP_KERNEL);
@@ -825,7 +825,7 @@ void __devexit mthca_unmap_eq_icm(struct mthca_dev *dev)
 {
        u8 status;
 
-       mthca_UNMAP_ICM(dev, dev->eq_table.icm_virt, PAGE_SIZE / 4096, &status);
+       mthca_UNMAP_ICM(dev, dev->eq_table.icm_virt, 1, &status);
        pci_unmap_page(dev->pdev, dev->eq_table.icm_dma, PAGE_SIZE,
                       PCI_DMA_BIDIRECTIONAL);
        __free_page(dev->eq_table.icm_page);
@@ -928,7 +928,7 @@ int __devinit mthca_init_eq_table(struct mthca_dev *dev)
                mthca_warn(dev, "MAP_EQ for cmd EQ %d returned status 0x%02x\n",
                           dev->eq_table.eq[MTHCA_EQ_CMD].eqn, status);
 
-       for (i = 0; i < MTHCA_EQ_CMD; ++i)
+       for (i = 0; i < MTHCA_NUM_EQ; ++i)
                if (mthca_is_memfree(dev))
                        arbel_eq_req_not(dev, dev->eq_table.eq[i].eqn_mask);
                else
index 1229c604c6e0258e49c73d5d4a4d26f695587c14..4ace6a392f41f030af8d01b2a6ec76c4968f23a0 100644 (file)
@@ -109,6 +109,19 @@ static void smp_snoop(struct ib_device *ibdev,
        }
 }
 
+static void node_desc_override(struct ib_device *dev,
+                              struct ib_mad *mad)
+{
+       if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+            mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
+           mad->mad_hdr.method == IB_MGMT_METHOD_GET_RESP &&
+           mad->mad_hdr.attr_id == IB_SMP_ATTR_NODE_DESC) {
+               mutex_lock(&to_mdev(dev)->cap_mask_mutex);
+               memcpy(((struct ib_smp *) mad)->data, dev->node_desc, 64);
+               mutex_unlock(&to_mdev(dev)->cap_mask_mutex);
+       }
+}
+
 static void forward_trap(struct mthca_dev *dev,
                         u8 port_num,
                         struct ib_mad *mad)
@@ -207,8 +220,10 @@ int mthca_process_mad(struct ib_device *ibdev,
                return IB_MAD_RESULT_FAILURE;
        }
 
-       if (!out_mad->mad_hdr.status)
+       if (!out_mad->mad_hdr.status) {
                smp_snoop(ibdev, port_num, in_mad);
+               node_desc_override(ibdev, out_mad);
+       }
 
        /* set return bit in status of directed route responses */
        if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
index 9c849d27b06e72f9b0773fcc931af28079a4ad77..266f347c670767285c138299a554de729b5b3697 100644 (file)
@@ -935,13 +935,19 @@ enum {
 
 static struct {
        u64 latest_fw;
-       int is_memfree;
-       int is_pcie;
+       u32 flags;
 } mthca_hca_table[] = {
-       [TAVOR]        = { .latest_fw = MTHCA_FW_VER(3, 3, 3), .is_memfree = 0, .is_pcie = 0 },
-       [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 7, 0), .is_memfree = 0, .is_pcie = 1 },
-       [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 1, 0), .is_memfree = 1, .is_pcie = 1 },
-       [SINAI]        = { .latest_fw = MTHCA_FW_VER(1, 0, 1), .is_memfree = 1, .is_pcie = 1 }
+       [TAVOR]        = { .latest_fw = MTHCA_FW_VER(3, 4, 0),
+                          .flags     = 0 },
+       [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 7, 400),
+                          .flags     = MTHCA_FLAG_PCIE },
+       [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 1, 0),
+                          .flags     = MTHCA_FLAG_MEMFREE |
+                                       MTHCA_FLAG_PCIE },
+       [SINAI]        = { .latest_fw = MTHCA_FW_VER(1, 0, 800),
+                          .flags     = MTHCA_FLAG_MEMFREE |
+                                       MTHCA_FLAG_PCIE    |
+                                       MTHCA_FLAG_SINAI_OPT }
 };
 
 static int __devinit mthca_init_one(struct pci_dev *pdev,
@@ -1031,12 +1037,9 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
 
        mdev->pdev = pdev;
 
+       mdev->mthca_flags = mthca_hca_table[id->driver_data].flags;
        if (ddr_hidden)
                mdev->mthca_flags |= MTHCA_FLAG_DDR_HIDDEN;
-       if (mthca_hca_table[id->driver_data].is_memfree)
-               mdev->mthca_flags |= MTHCA_FLAG_MEMFREE;
-       if (mthca_hca_table[id->driver_data].is_pcie)
-               mdev->mthca_flags |= MTHCA_FLAG_PCIE;
 
        /*
         * Now reset the HCA before we touch the PCI capabilities or
index 321f11e707f22864f7d2e6263b38012577f914d5..9965bda9afeddc63aef80ba211e6e502080a1569 100644 (file)
@@ -187,7 +187,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 
        for (i = 0; i < MTHCA_QP_PER_MGM; ++i)
                if (mgm->qp[i] == cpu_to_be32(ibqp->qp_num | (1 << 31))) {
-                       mthca_dbg(dev, "QP %06x already a member of MGM\n", 
+                       mthca_dbg(dev, "QP %06x already a member of MGM\n",
                                  ibqp->qp_num);
                        err = 0;
                        goto out;
index d709cb162a72a72d986c9b553a0f4aa072d27b5b..15cc2f6eb4754fa83a497fec55f381371c466000 100644 (file)
@@ -202,7 +202,8 @@ void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int o
 
        if (--table->icm[i]->refcount == 0) {
                mthca_UNMAP_ICM(dev, table->virt + i * MTHCA_TABLE_CHUNK_SIZE,
-                               MTHCA_TABLE_CHUNK_SIZE >> 12, &status);
+                               MTHCA_TABLE_CHUNK_SIZE / MTHCA_ICM_PAGE_SIZE,
+                               &status);
                mthca_free_icm(dev, table->icm[i]);
                table->icm[i] = NULL;
        }
@@ -336,7 +337,8 @@ err:
        for (i = 0; i < num_icm; ++i)
                if (table->icm[i]) {
                        mthca_UNMAP_ICM(dev, virt + i * MTHCA_TABLE_CHUNK_SIZE,
-                                       MTHCA_TABLE_CHUNK_SIZE >> 12, &status);
+                                       MTHCA_TABLE_CHUNK_SIZE / MTHCA_ICM_PAGE_SIZE,
+                                       &status);
                        mthca_free_icm(dev, table->icm[i]);
                }
 
@@ -353,7 +355,8 @@ void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table *table)
        for (i = 0; i < table->num_icm; ++i)
                if (table->icm[i]) {
                        mthca_UNMAP_ICM(dev, table->virt + i * MTHCA_TABLE_CHUNK_SIZE,
-                                       MTHCA_TABLE_CHUNK_SIZE >> 12, &status);
+                                       MTHCA_TABLE_CHUNK_SIZE / MTHCA_ICM_PAGE_SIZE,
+                                       &status);
                        mthca_free_icm(dev, table->icm[i]);
                }
 
@@ -364,7 +367,7 @@ static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int pag
 {
        return dev->uar_table.uarc_base +
                uar->index * dev->uar_table.uarc_size +
-               page * 4096;
+               page * MTHCA_ICM_PAGE_SIZE;
 }
 
 int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
@@ -401,7 +404,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
        if (ret < 0)
                goto out;
 
-       db_tab->page[i].mem.length = 4096;
+       db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
        db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
 
        ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
@@ -455,7 +458,7 @@ struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev)
        if (!mthca_is_memfree(dev))
                return NULL;
 
-       npages = dev->uar_table.uarc_size / 4096;
+       npages = dev->uar_table.uarc_size / MTHCA_ICM_PAGE_SIZE;
        db_tab = kmalloc(sizeof *db_tab + npages * sizeof *db_tab->page, GFP_KERNEL);
        if (!db_tab)
                return ERR_PTR(-ENOMEM);
@@ -478,7 +481,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
        if (!mthca_is_memfree(dev))
                return;
 
-       for (i = 0; i < dev->uar_table.uarc_size / 4096; ++i) {
+       for (i = 0; i < dev->uar_table.uarc_size / MTHCA_ICM_PAGE_SIZE; ++i) {
                if (db_tab->page[i].uvirt) {
                        mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
                        pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
@@ -551,20 +554,20 @@ int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type,
        page = dev->db_tab->page + end;
 
 alloc:
-       page->db_rec = dma_alloc_coherent(&dev->pdev->dev, 4096,
+       page->db_rec = dma_alloc_coherent(&dev->pdev->dev, MTHCA_ICM_PAGE_SIZE,
                                          &page->mapping, GFP_KERNEL);
        if (!page->db_rec) {
                ret = -ENOMEM;
                goto out;
        }
-       memset(page->db_rec, 0, 4096);
+       memset(page->db_rec, 0, MTHCA_ICM_PAGE_SIZE);
 
        ret = mthca_MAP_ICM_page(dev, page->mapping,
                                 mthca_uarc_virt(dev, &dev->driver_uar, i), &status);
        if (!ret && status)
                ret = -EINVAL;
        if (ret) {
-               dma_free_coherent(&dev->pdev->dev, 4096,
+               dma_free_coherent(&dev->pdev->dev, MTHCA_ICM_PAGE_SIZE,
                                  page->db_rec, page->mapping);
                goto out;
        }
@@ -612,7 +615,7 @@ void mthca_free_db(struct mthca_dev *dev, int type, int db_index)
            i >= dev->db_tab->max_group1 - 1) {
                mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, &dev->driver_uar, i), 1, &status);
 
-               dma_free_coherent(&dev->pdev->dev, 4096,
+               dma_free_coherent(&dev->pdev->dev, MTHCA_ICM_PAGE_SIZE,
                                  page->db_rec, page->mapping);
                page->db_rec = NULL;
 
@@ -640,7 +643,7 @@ int mthca_init_db_tab(struct mthca_dev *dev)
 
        mutex_init(&dev->db_tab->mutex);
 
-       dev->db_tab->npages     = dev->uar_table.uarc_size / 4096;
+       dev->db_tab->npages     = dev->uar_table.uarc_size / MTHCA_ICM_PAGE_SIZE;
        dev->db_tab->max_group1 = 0;
        dev->db_tab->min_group2 = dev->db_tab->npages - 1;
 
@@ -681,7 +684,7 @@ void mthca_cleanup_db_tab(struct mthca_dev *dev)
 
                mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, &dev->driver_uar, i), 1, &status);
 
-               dma_free_coherent(&dev->pdev->dev, 4096,
+               dma_free_coherent(&dev->pdev->dev, MTHCA_ICM_PAGE_SIZE,
                                  dev->db_tab->page[i].db_rec,
                                  dev->db_tab->page[i].mapping);
        }
index 36f1141a08aa6c84901d23adfea0dab0f7f1dadb..6d42947e1dc448c35633a24d3280a25d58cc16da 100644 (file)
        ((256 - sizeof (struct list_head) - 2 * sizeof (int)) /         \
         (sizeof (struct scatterlist)))
 
+enum {
+       MTHCA_ICM_PAGE_SHIFT    = 12,
+       MTHCA_ICM_PAGE_SIZE     = 1 << MTHCA_ICM_PAGE_SHIFT,
+       MTHCA_DB_REC_PER_PAGE   = MTHCA_ICM_PAGE_SIZE / 8
+};
+
 struct mthca_icm_chunk {
        struct list_head   list;
        int                npages;
@@ -131,10 +137,6 @@ static inline unsigned long mthca_icm_size(struct mthca_icm_iter *iter)
        return sg_dma_len(&iter->chunk->mem[iter->page_idx]);
 }
 
-enum {
-       MTHCA_DB_REC_PER_PAGE = 4096 / 8
-};
-
 struct mthca_db_page {
        DECLARE_BITMAP(used, MTHCA_DB_REC_PER_PAGE);
        __be64    *db_rec;
index e995e2aa016dc7c3d661fa654d44e492e47dcbc9..698b621257659e5d45c9378e3647def18a58ef2c 100644 (file)
@@ -76,6 +76,8 @@ struct mthca_mpt_entry {
 #define MTHCA_MPT_STATUS_SW 0xF0
 #define MTHCA_MPT_STATUS_HW 0x00
 
+#define SINAI_FMR_KEY_INC 0x1000000
+
 /*
  * Buddy allocator for MTT segments (currently not very efficient
  * since it doesn't keep a free list and just searches linearly
@@ -330,6 +332,14 @@ static inline u32 key_to_hw_index(struct mthca_dev *dev, u32 key)
                return tavor_key_to_hw_index(key);
 }
 
+static inline u32 adjust_key(struct mthca_dev *dev, u32 key)
+{
+       if (dev->mthca_flags & MTHCA_FLAG_SINAI_OPT)
+               return ((key << 20) & 0x800000) | (key & 0x7fffff);
+       else
+               return key;
+}
+
 int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift,
                   u64 iova, u64 total_size, u32 access, struct mthca_mr *mr)
 {
@@ -340,13 +350,12 @@ int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift,
        int err;
        u8 status;
 
-       might_sleep();
-
        WARN_ON(buffer_size_shift >= 32);
 
        key = mthca_alloc(&dev->mr_table.mpt_alloc);
        if (key == -1)
                return -ENOMEM;
+       key = adjust_key(dev, key);
        mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key);
 
        if (mthca_is_memfree(dev)) {
@@ -467,8 +476,6 @@ void mthca_free_mr(struct mthca_dev *dev, struct mthca_mr *mr)
        int err;
        u8 status;
 
-       might_sleep();
-
        err = mthca_HW2SW_MPT(dev, NULL,
                              key_to_hw_index(dev, mr->ibmr.lkey) &
                              (dev->limits.num_mpts - 1),
@@ -495,9 +502,7 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
        int err = -ENOMEM;
        int i;
 
-       might_sleep();
-
-       if (mr->attr.page_size < 12 || mr->attr.page_size >= 32)
+       if (mr->attr.page_shift < 12 || mr->attr.page_shift >= 32)
                return -EINVAL;
 
        /* For Arbel, all MTTs must fit in the same page. */
@@ -510,6 +515,7 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
        key = mthca_alloc(&dev->mr_table.mpt_alloc);
        if (key == -1)
                return -ENOMEM;
+       key = adjust_key(dev, key);
 
        idx = key & (dev->limits.num_mpts - 1);
        mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key);
@@ -523,7 +529,7 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
                BUG_ON(!mr->mem.arbel.mpt);
        } else
                mr->mem.tavor.mpt = dev->mr_table.tavor_fmr.mpt_base +
-                       sizeof *(mr->mem.tavor.mpt) * idx;
+                       sizeof *(mr->mem.tavor.mpt) * idx;
 
        mr->mtt = __mthca_alloc_mtt(dev, list_len, dev->mr_table.fmr_mtt_buddy);
        if (IS_ERR(mr->mtt))
@@ -549,7 +555,7 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
                                       MTHCA_MPT_FLAG_REGION      |
                                       access);
 
-       mpt_entry->page_size = cpu_to_be32(mr->attr.page_size - 12);
+       mpt_entry->page_size = cpu_to_be32(mr->attr.page_shift - 12);
        mpt_entry->key       = cpu_to_be32(key);
        mpt_entry->pd        = cpu_to_be32(pd);
        memset(&mpt_entry->start, 0,
@@ -617,7 +623,7 @@ static inline int mthca_check_fmr(struct mthca_fmr *fmr, u64 *page_list,
        if (list_len > fmr->attr.max_pages)
                return -EINVAL;
 
-       page_mask = (1 << fmr->attr.page_size) - 1;
+       page_mask = (1 << fmr->attr.page_shift) - 1;
 
        /* We are getting page lists, so va must be page aligned. */
        if (iova & page_mask)
@@ -665,7 +671,7 @@ int mthca_tavor_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
        }
 
        mpt_entry.lkey   = cpu_to_be32(key);
-       mpt_entry.length = cpu_to_be64(list_len * (1ull << fmr->attr.page_size));
+       mpt_entry.length = cpu_to_be64(list_len * (1ull << fmr->attr.page_shift));
        mpt_entry.start  = cpu_to_be64(iova);
 
        __raw_writel((__force u32) mpt_entry.lkey, &fmr->mem.tavor.mpt->key);
@@ -693,7 +699,10 @@ int mthca_arbel_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
        ++fmr->maps;
 
        key = arbel_key_to_hw_index(fmr->ibmr.lkey);
-       key += dev->limits.num_mpts;
+       if (dev->mthca_flags & MTHCA_FLAG_SINAI_OPT)
+               key += SINAI_FMR_KEY_INC;
+       else
+               key += dev->limits.num_mpts;
        fmr->ibmr.lkey = fmr->ibmr.rkey = arbel_hw_index_to_key(key);
 
        *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW;
@@ -706,7 +715,7 @@ int mthca_arbel_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
 
        fmr->mem.arbel.mpt->key    = cpu_to_be32(key);
        fmr->mem.arbel.mpt->lkey   = cpu_to_be32(key);
-       fmr->mem.arbel.mpt->length = cpu_to_be64(list_len * (1ull << fmr->attr.page_size));
+       fmr->mem.arbel.mpt->length = cpu_to_be64(list_len * (1ull << fmr->attr.page_shift));
        fmr->mem.arbel.mpt->start  = cpu_to_be64(iova);
 
        wmb();
@@ -766,6 +775,9 @@ int __devinit mthca_init_mr_table(struct mthca_dev *dev)
        else
                dev->mthca_flags |= MTHCA_FLAG_FMR;
 
+       if (dev->mthca_flags & MTHCA_FLAG_SINAI_OPT)
+               mthca_dbg(dev, "Memory key throughput optimization activated.\n");
+
        err = mthca_buddy_init(&dev->mr_table.mtt_buddy,
                               fls(dev->limits.num_mtt_segs - 1));
 
@@ -785,7 +797,7 @@ int __devinit mthca_init_mr_table(struct mthca_dev *dev)
                }
 
                dev->mr_table.tavor_fmr.mpt_base =
-                       ioremap(dev->mr_table.mpt_base,
+                       ioremap(dev->mr_table.mpt_base,
                                (1 << i) * sizeof (struct mthca_mpt_entry));
 
                if (!dev->mr_table.tavor_fmr.mpt_base) {
@@ -813,7 +825,7 @@ int __devinit mthca_init_mr_table(struct mthca_dev *dev)
                        goto err_reserve_fmr;
 
                dev->mr_table.fmr_mtt_buddy =
-                       &dev->mr_table.tavor_fmr.mtt_buddy;
+                       &dev->mr_table.tavor_fmr.mtt_buddy;
        } else
                dev->mr_table.fmr_mtt_buddy = &dev->mr_table.mtt_buddy;
 
index 3dbf06a6e6f4e097f84aceaa71a56104849ffeca..105fc5faaddf77c7c926ee0ec8f69f2480c0a5ea 100644 (file)
@@ -43,8 +43,6 @@ int mthca_pd_alloc(struct mthca_dev *dev, int privileged, struct mthca_pd *pd)
 {
        int err = 0;
 
-       might_sleep();
-
        pd->privileged = privileged;
 
        atomic_set(&pd->sqp_count, 0);
@@ -66,7 +64,6 @@ int mthca_pd_alloc(struct mthca_dev *dev, int privileged, struct mthca_pd *pd)
 
 void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd)
 {
-       might_sleep();
        if (pd->privileged)
                mthca_free_mr(dev, &pd->ntmr);
        mthca_free(&dev->pd_table.alloc, pd->pd_num);
index 08a909371b0a1060634526b53819314497fcd04a..58d44aa3c30297a6920c8b292a27cb458b1a7763 100644 (file)
@@ -152,7 +152,7 @@ u64 mthca_make_profile(struct mthca_dev *dev,
                }
                if (total_size > mem_avail) {
                        mthca_err(dev, "Profile requires 0x%llx bytes; "
-                                 "won't in 0x%llx bytes of context memory.\n",
+                                 "won't fit in 0x%llx bytes of context memory.\n",
                                  (unsigned long long) total_size,
                                  (unsigned long long) mem_avail);
                        kfree(profile);
@@ -262,6 +262,14 @@ u64 mthca_make_profile(struct mthca_dev *dev,
         */
        dev->limits.num_pds = MTHCA_NUM_PDS;
 
+       if (dev->mthca_flags & MTHCA_FLAG_SINAI_OPT &&
+           init_hca->log_mpt_sz > 23) {
+               mthca_warn(dev, "MPT table too large (requested size 2^%d >= 2^24)\n",
+                          init_hca->log_mpt_sz);
+               mthca_warn(dev, "Disabling memory key throughput optimization.\n");
+               dev->mthca_flags &= ~MTHCA_FLAG_SINAI_OPT;
+       }
+
        /*
         * For Tavor, FMRs use ioremapped PCI memory. For 32 bit
         * systems it may use too much vmalloc space to map all MTT
index e88e39aef85a3cd3794c7de290c9332ab2ebfb50..2c250bc11c332d180d0856f727aad96b241f7c05 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
  * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
  *
@@ -108,12 +108,12 @@ static int mthca_query_device(struct ib_device *ibdev,
        props->max_srq_wr          = mdev->limits.max_srq_wqes;
        props->max_srq_sge         = mdev->limits.max_sg;
        props->local_ca_ack_delay  = mdev->limits.local_ca_ack_delay;
-       props->atomic_cap          = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ? 
+       props->atomic_cap          = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ?
                                        IB_ATOMIC_HCA : IB_ATOMIC_NONE;
        props->max_pkeys           = mdev->limits.pkey_table_len;
        props->max_mcast_grp       = mdev->limits.num_mgms + mdev->limits.num_amgms;
        props->max_mcast_qp_attach = MTHCA_QP_PER_MGM;
-       props->max_total_mcast_qp_attach = props->max_mcast_qp_attach * 
+       props->max_total_mcast_qp_attach = props->max_mcast_qp_attach *
                                           props->max_mcast_grp;
 
        err = 0;
@@ -176,6 +176,23 @@ static int mthca_query_port(struct ib_device *ibdev,
        return err;
 }
 
+static int mthca_modify_device(struct ib_device *ibdev,
+                              int mask,
+                              struct ib_device_modify *props)
+{
+       if (mask & ~IB_DEVICE_MODIFY_NODE_DESC)
+               return -EOPNOTSUPP;
+
+       if (mask & IB_DEVICE_MODIFY_NODE_DESC) {
+               if (mutex_lock_interruptible(&to_mdev(ibdev)->cap_mask_mutex))
+                       return -ERESTARTSYS;
+               memcpy(ibdev->node_desc, props->node_desc, 64);
+               mutex_unlock(&to_mdev(ibdev)->cap_mask_mutex);
+       }
+
+       return 0;
+}
+
 static int mthca_modify_port(struct ib_device *ibdev,
                             u8 port, int port_modify_mask,
                             struct ib_port_modify *props)
@@ -669,9 +686,9 @@ static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
        }
 
        if (context) {
-               cq->mr.ibmr.lkey    = ucmd.lkey;
-               cq->set_ci_db_index = ucmd.set_db_index;
-               cq->arm_db_index    = ucmd.arm_db_index;
+               cq->buf.mr.ibmr.lkey = ucmd.lkey;
+               cq->set_ci_db_index  = ucmd.set_db_index;
+               cq->arm_db_index     = ucmd.arm_db_index;
        }
 
        for (nent = 1; nent <= entries; nent <<= 1)
@@ -689,6 +706,8 @@ static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
                goto err_free;
        }
 
+       cq->resize_buf = NULL;
+
        return &cq->ibcq;
 
 err_free:
@@ -707,6 +726,121 @@ err_unmap_set:
        return ERR_PTR(err);
 }
 
+static int mthca_alloc_resize_buf(struct mthca_dev *dev, struct mthca_cq *cq,
+                                 int entries)
+{
+       int ret;
+
+       spin_lock_irq(&cq->lock);
+       if (cq->resize_buf) {
+               ret = -EBUSY;
+               goto unlock;
+       }
+
+       cq->resize_buf = kmalloc(sizeof *cq->resize_buf, GFP_ATOMIC);
+       if (!cq->resize_buf) {
+               ret = -ENOMEM;
+               goto unlock;
+       }
+
+       cq->resize_buf->state = CQ_RESIZE_ALLOC;
+
+       ret = 0;
+
+unlock:
+       spin_unlock_irq(&cq->lock);
+
+       if (ret)
+               return ret;
+
+       ret = mthca_alloc_cq_buf(dev, &cq->resize_buf->buf, entries);
+       if (ret) {
+               spin_lock_irq(&cq->lock);
+               kfree(cq->resize_buf);
+               cq->resize_buf = NULL;
+               spin_unlock_irq(&cq->lock);
+               return ret;
+       }
+
+       cq->resize_buf->cqe = entries - 1;
+
+       spin_lock_irq(&cq->lock);
+       cq->resize_buf->state = CQ_RESIZE_READY;
+       spin_unlock_irq(&cq->lock);
+
+       return 0;
+}
+
+static int mthca_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
+{
+       struct mthca_dev *dev = to_mdev(ibcq->device);
+       struct mthca_cq *cq = to_mcq(ibcq);
+       struct mthca_resize_cq ucmd;
+       u32 lkey;
+       u8 status;
+       int ret;
+
+       if (entries < 1 || entries > dev->limits.max_cqes)
+               return -EINVAL;
+
+       entries = roundup_pow_of_two(entries + 1);
+       if (entries == ibcq->cqe + 1)
+               return 0;
+
+       if (cq->is_kernel) {
+               ret = mthca_alloc_resize_buf(dev, cq, entries);
+               if (ret)
+                       return ret;
+               lkey = cq->resize_buf->buf.mr.ibmr.lkey;
+       } else {
+               if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
+                       return -EFAULT;
+               lkey = ucmd.lkey;
+       }
+
+       ret = mthca_RESIZE_CQ(dev, cq->cqn, lkey, long_log2(entries), &status);
+       if (status)
+               ret = -EINVAL;
+
+       if (ret) {
+               if (cq->resize_buf) {
+                       mthca_free_cq_buf(dev, &cq->resize_buf->buf,
+                                         cq->resize_buf->cqe);
+                       kfree(cq->resize_buf);
+                       spin_lock_irq(&cq->lock);
+                       cq->resize_buf = NULL;
+                       spin_unlock_irq(&cq->lock);
+               }
+               return ret;
+       }
+
+       if (cq->is_kernel) {
+               struct mthca_cq_buf tbuf;
+               int tcqe;
+
+               spin_lock_irq(&cq->lock);
+               if (cq->resize_buf->state == CQ_RESIZE_READY) {
+                       mthca_cq_resize_copy_cqes(cq);
+                       tbuf         = cq->buf;
+                       tcqe         = cq->ibcq.cqe;
+                       cq->buf      = cq->resize_buf->buf;
+                       cq->ibcq.cqe = cq->resize_buf->cqe;
+               } else {
+                       tbuf = cq->resize_buf->buf;
+                       tcqe = cq->resize_buf->cqe;
+               }
+
+               kfree(cq->resize_buf);
+               cq->resize_buf = NULL;
+               spin_unlock_irq(&cq->lock);
+
+               mthca_free_cq_buf(dev, &tbuf, tcqe);
+       } else
+               ibcq->cqe = entries - 1;
+
+       return 0;
+}
+
 static int mthca_destroy_cq(struct ib_cq *cq)
 {
        if (cq->uobject) {
@@ -1070,6 +1204,20 @@ static int mthca_init_node_data(struct mthca_dev *dev)
                goto out;
 
        init_query_mad(in_mad);
+       in_mad->attr_id = IB_SMP_ATTR_NODE_DESC;
+
+       err = mthca_MAD_IFC(dev, 1, 1,
+                           1, NULL, NULL, in_mad, out_mad,
+                           &status);
+       if (err)
+               goto out;
+       if (status) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       memcpy(dev->ib_dev.node_desc, out_mad->data, 64);
+
        in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
 
        err = mthca_MAD_IFC(dev, 1, 1,
@@ -1113,14 +1261,17 @@ int mthca_register_device(struct mthca_dev *dev)
                (1ull << IB_USER_VERBS_CMD_DEREG_MR)            |
                (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
                (1ull << IB_USER_VERBS_CMD_CREATE_CQ)           |
+               (1ull << IB_USER_VERBS_CMD_RESIZE_CQ)           |
                (1ull << IB_USER_VERBS_CMD_DESTROY_CQ)          |
                (1ull << IB_USER_VERBS_CMD_CREATE_QP)           |
+               (1ull << IB_USER_VERBS_CMD_QUERY_QP)            |
                (1ull << IB_USER_VERBS_CMD_MODIFY_QP)           |
                (1ull << IB_USER_VERBS_CMD_DESTROY_QP)          |
                (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST)        |
                (1ull << IB_USER_VERBS_CMD_DETACH_MCAST)        |
                (1ull << IB_USER_VERBS_CMD_CREATE_SRQ)          |
                (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ)          |
+               (1ull << IB_USER_VERBS_CMD_QUERY_SRQ)           |
                (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
        dev->ib_dev.node_type            = IB_NODE_CA;
        dev->ib_dev.phys_port_cnt        = dev->limits.num_ports;
@@ -1128,6 +1279,7 @@ int mthca_register_device(struct mthca_dev *dev)
        dev->ib_dev.class_dev.dev        = &dev->pdev->dev;
        dev->ib_dev.query_device         = mthca_query_device;
        dev->ib_dev.query_port           = mthca_query_port;
+       dev->ib_dev.modify_device        = mthca_modify_device;
        dev->ib_dev.modify_port          = mthca_modify_port;
        dev->ib_dev.query_pkey           = mthca_query_pkey;
        dev->ib_dev.query_gid            = mthca_query_gid;
@@ -1137,11 +1289,13 @@ int mthca_register_device(struct mthca_dev *dev)
        dev->ib_dev.alloc_pd             = mthca_alloc_pd;
        dev->ib_dev.dealloc_pd           = mthca_dealloc_pd;
        dev->ib_dev.create_ah            = mthca_ah_create;
+       dev->ib_dev.query_ah             = mthca_ah_query;
        dev->ib_dev.destroy_ah           = mthca_ah_destroy;
 
        if (dev->mthca_flags & MTHCA_FLAG_SRQ) {
                dev->ib_dev.create_srq           = mthca_create_srq;
-               dev->ib_dev.modify_srq           = mthca_modify_srq;
+               dev->ib_dev.modify_srq           = mthca_modify_srq;
+               dev->ib_dev.query_srq            = mthca_query_srq;
                dev->ib_dev.destroy_srq          = mthca_destroy_srq;
 
                if (mthca_is_memfree(dev))
@@ -1152,8 +1306,10 @@ int mthca_register_device(struct mthca_dev *dev)
 
        dev->ib_dev.create_qp            = mthca_create_qp;
        dev->ib_dev.modify_qp            = mthca_modify_qp;
+       dev->ib_dev.query_qp             = mthca_query_qp;
        dev->ib_dev.destroy_qp           = mthca_destroy_qp;
        dev->ib_dev.create_cq            = mthca_create_cq;
+       dev->ib_dev.resize_cq            = mthca_resize_cq;
        dev->ib_dev.destroy_cq           = mthca_destroy_cq;
        dev->ib_dev.poll_cq              = mthca_poll_cq;
        dev->ib_dev.get_dma_mr           = mthca_get_dma_mr;
index 1e73947b4702ca8923f698430eeafe5c63ff1089..2e7f5213696510b1828b745e3be9419f21b0ba10 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
- * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -164,9 +164,11 @@ struct mthca_ah {
  * - wait_event until ref count is zero
  *
  * It is the consumer's responsibilty to make sure that no QP
- * operations (WQE posting or state modification) are pending when the
+ * operations (WQE posting or state modification) are pending when a
  * QP is destroyed.  Also, the consumer must make sure that calls to
- * qp_modify are serialized.
+ * qp_modify are serialized.  Similarly, the consumer is responsible
+ * for ensuring that no CQ resize operations are pending when a CQ
+ * is destroyed.
  *
  * Possible optimizations (wait for profile data to see if/where we
  * have locks bouncing between CPUs):
@@ -176,25 +178,40 @@ struct mthca_ah {
  *   send queue and one for the receive queue)
  */
 
+struct mthca_cq_buf {
+       union mthca_buf         queue;
+       struct mthca_mr         mr;
+       int                     is_direct;
+};
+
+struct mthca_cq_resize {
+       struct mthca_cq_buf     buf;
+       int                     cqe;
+       enum {
+               CQ_RESIZE_ALLOC,
+               CQ_RESIZE_READY,
+               CQ_RESIZE_SWAPPED
+       }                       state;
+};
+
 struct mthca_cq {
-       struct ib_cq           ibcq;
-       spinlock_t             lock;
-       atomic_t               refcount;
-       int                    cqn;
-       u32                    cons_index;
-       int                    is_direct;
-       int                    is_kernel;
+       struct ib_cq            ibcq;
+       spinlock_t              lock;
+       atomic_t                refcount;
+       int                     cqn;
+       u32                     cons_index;
+       struct mthca_cq_buf     buf;
+       struct mthca_cq_resize *resize_buf;
+       int                     is_kernel;
 
        /* Next fields are Arbel only */
-       int                    set_ci_db_index;
-       __be32                *set_ci_db;
-       int                    arm_db_index;
-       __be32                *arm_db;
-       int                    arm_sn;
+       int                     set_ci_db_index;
+       __be32                 *set_ci_db;
+       int                     arm_db_index;
+       __be32                 *arm_db;
+       int                     arm_sn;
 
-       union mthca_buf        queue;
-       struct mthca_mr        mr;
-       wait_queue_head_t      wait;
+       wait_queue_head_t       wait;
 };
 
 struct mthca_srq {
index fba608ed7df2fca3c00cff0b4ef762ca9f0c52a5..f673c461e30be23525c6f8d301881097a1ee1c21 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
  * Copyright (c) 2005 Cisco Systems. All rights reserved.
  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
- * Copyright (c) 2004 Voltaire, Inc. All rights reserved. 
+ * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -286,207 +286,6 @@ static int to_mthca_st(int transport)
        }
 }
 
-static const struct {
-       int trans;
-       u32 req_param[NUM_TRANS];
-       u32 opt_param[NUM_TRANS];
-} state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
-       [IB_QPS_RESET] = {
-               [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
-               [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
-               [IB_QPS_INIT]  = {
-                       .trans = MTHCA_TRANS_RST2INIT,
-                       .req_param = {
-                               [UD]  = (IB_QP_PKEY_INDEX |
-                                        IB_QP_PORT       |
-                                        IB_QP_QKEY),
-                               [UC]  = (IB_QP_PKEY_INDEX |
-                                        IB_QP_PORT       |
-                                        IB_QP_ACCESS_FLAGS),
-                               [RC]  = (IB_QP_PKEY_INDEX |
-                                        IB_QP_PORT       |
-                                        IB_QP_ACCESS_FLAGS),
-                               [MLX] = (IB_QP_PKEY_INDEX |
-                                        IB_QP_QKEY),
-                       },
-                       /* bug-for-bug compatibility with VAPI: */
-                       .opt_param = {
-                               [MLX] = IB_QP_PORT
-                       }
-               },
-       },
-       [IB_QPS_INIT]  = {
-               [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
-               [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
-               [IB_QPS_INIT]  = {
-                       .trans = MTHCA_TRANS_INIT2INIT,
-                       .opt_param = {
-                               [UD]  = (IB_QP_PKEY_INDEX |
-                                        IB_QP_PORT       |
-                                        IB_QP_QKEY),
-                               [UC]  = (IB_QP_PKEY_INDEX |
-                                        IB_QP_PORT       |
-                                        IB_QP_ACCESS_FLAGS),
-                               [RC]  = (IB_QP_PKEY_INDEX |
-                                        IB_QP_PORT       |
-                                        IB_QP_ACCESS_FLAGS),
-                               [MLX] = (IB_QP_PKEY_INDEX |
-                                        IB_QP_QKEY),
-                       }
-               },
-               [IB_QPS_RTR]   = {
-                       .trans = MTHCA_TRANS_INIT2RTR,
-                       .req_param = {
-                               [UC]  = (IB_QP_AV                  |
-                                        IB_QP_PATH_MTU            |
-                                        IB_QP_DEST_QPN            |
-                                        IB_QP_RQ_PSN),
-                               [RC]  = (IB_QP_AV                  |
-                                        IB_QP_PATH_MTU            |
-                                        IB_QP_DEST_QPN            |
-                                        IB_QP_RQ_PSN              |
-                                        IB_QP_MAX_DEST_RD_ATOMIC  |
-                                        IB_QP_MIN_RNR_TIMER),
-                       },
-                       .opt_param = {
-                               [UD]  = (IB_QP_PKEY_INDEX |
-                                        IB_QP_QKEY),
-                               [UC]  = (IB_QP_ALT_PATH     |
-                                        IB_QP_ACCESS_FLAGS |
-                                        IB_QP_PKEY_INDEX),
-                               [RC]  = (IB_QP_ALT_PATH     |
-                                        IB_QP_ACCESS_FLAGS |
-                                        IB_QP_PKEY_INDEX),
-                               [MLX] = (IB_QP_PKEY_INDEX |
-                                        IB_QP_QKEY),
-                       }
-               }
-       },
-       [IB_QPS_RTR]   = {
-               [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
-               [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
-               [IB_QPS_RTS]   = {
-                       .trans = MTHCA_TRANS_RTR2RTS,
-                       .req_param = {
-                               [UD]  = IB_QP_SQ_PSN,
-                               [UC]  = IB_QP_SQ_PSN,
-                               [RC]  = (IB_QP_TIMEOUT           |
-                                        IB_QP_RETRY_CNT         |
-                                        IB_QP_RNR_RETRY         |
-                                        IB_QP_SQ_PSN            |
-                                        IB_QP_MAX_QP_RD_ATOMIC),
-                               [MLX] = IB_QP_SQ_PSN,
-                       },
-                       .opt_param = {
-                               [UD]  = (IB_QP_CUR_STATE             |
-                                        IB_QP_QKEY),
-                               [UC]  = (IB_QP_CUR_STATE             |
-                                        IB_QP_ALT_PATH              |
-                                        IB_QP_ACCESS_FLAGS          |
-                                        IB_QP_PATH_MIG_STATE),
-                               [RC]  = (IB_QP_CUR_STATE             |
-                                        IB_QP_ALT_PATH              |
-                                        IB_QP_ACCESS_FLAGS          |
-                                        IB_QP_MIN_RNR_TIMER         |
-                                        IB_QP_PATH_MIG_STATE),
-                               [MLX] = (IB_QP_CUR_STATE             |
-                                        IB_QP_QKEY),
-                       }
-               }
-       },
-       [IB_QPS_RTS]   = {
-               [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
-               [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
-               [IB_QPS_RTS]   = {
-                       .trans = MTHCA_TRANS_RTS2RTS,
-                       .opt_param = {
-                               [UD]  = (IB_QP_CUR_STATE             |
-                                        IB_QP_QKEY),
-                               [UC]  = (IB_QP_ACCESS_FLAGS          |
-                                        IB_QP_ALT_PATH              |
-                                        IB_QP_PATH_MIG_STATE),
-                               [RC]  = (IB_QP_ACCESS_FLAGS          |
-                                        IB_QP_ALT_PATH              |
-                                        IB_QP_PATH_MIG_STATE        |
-                                        IB_QP_MIN_RNR_TIMER),
-                               [MLX] = (IB_QP_CUR_STATE             |
-                                        IB_QP_QKEY),
-                       }
-               },
-               [IB_QPS_SQD]   = {
-                       .trans = MTHCA_TRANS_RTS2SQD,
-               },
-       },
-       [IB_QPS_SQD]   = {
-               [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
-               [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
-               [IB_QPS_RTS]   = {
-                       .trans = MTHCA_TRANS_SQD2RTS,
-                       .opt_param = {
-                               [UD]  = (IB_QP_CUR_STATE             |
-                                        IB_QP_QKEY),
-                               [UC]  = (IB_QP_CUR_STATE             |
-                                        IB_QP_ALT_PATH              |
-                                        IB_QP_ACCESS_FLAGS          |
-                                        IB_QP_PATH_MIG_STATE),
-                               [RC]  = (IB_QP_CUR_STATE             |
-                                        IB_QP_ALT_PATH              |
-                                        IB_QP_ACCESS_FLAGS          |
-                                        IB_QP_MIN_RNR_TIMER         |
-                                        IB_QP_PATH_MIG_STATE),
-                               [MLX] = (IB_QP_CUR_STATE             |
-                                        IB_QP_QKEY),
-                       }
-               },
-               [IB_QPS_SQD]   = {
-                       .trans = MTHCA_TRANS_SQD2SQD,
-                       .opt_param = {
-                               [UD]  = (IB_QP_PKEY_INDEX            |
-                                        IB_QP_QKEY),
-                               [UC]  = (IB_QP_AV                    |
-                                        IB_QP_CUR_STATE             |
-                                        IB_QP_ALT_PATH              |
-                                        IB_QP_ACCESS_FLAGS          |
-                                        IB_QP_PKEY_INDEX            |
-                                        IB_QP_PATH_MIG_STATE),
-                               [RC]  = (IB_QP_AV                    |
-                                        IB_QP_TIMEOUT               |
-                                        IB_QP_RETRY_CNT             |
-                                        IB_QP_RNR_RETRY             |
-                                        IB_QP_MAX_QP_RD_ATOMIC      |
-                                        IB_QP_MAX_DEST_RD_ATOMIC    |
-                                        IB_QP_CUR_STATE             |
-                                        IB_QP_ALT_PATH              |
-                                        IB_QP_ACCESS_FLAGS          |
-                                        IB_QP_PKEY_INDEX            |
-                                        IB_QP_MIN_RNR_TIMER         |
-                                        IB_QP_PATH_MIG_STATE),
-                               [MLX] = (IB_QP_PKEY_INDEX            |
-                                        IB_QP_QKEY),
-                       }
-               }
-       },
-       [IB_QPS_SQE]   = {
-               [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
-               [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
-               [IB_QPS_RTS]   = {
-                       .trans = MTHCA_TRANS_SQERR2RTS,
-                       .opt_param = {
-                               [UD]  = (IB_QP_CUR_STATE             |
-                                        IB_QP_QKEY),
-                               [UC]  = (IB_QP_CUR_STATE             |
-                                        IB_QP_ACCESS_FLAGS),
-                               [MLX] = (IB_QP_CUR_STATE             |
-                                        IB_QP_QKEY),
-                       }
-               }
-       },
-       [IB_QPS_ERR] = {
-               [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
-               [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR }
-       }
-};
-
 static void store_attrs(struct mthca_sqp *sqp, struct ib_qp_attr *attr,
                        int attr_mask)
 {
@@ -549,6 +348,141 @@ static __be32 get_hw_access_flags(struct mthca_qp *qp, struct ib_qp_attr *attr,
        return cpu_to_be32(hw_access_flags);
 }
 
+static inline enum ib_qp_state to_ib_qp_state(int mthca_state)
+{
+       switch (mthca_state) {
+       case MTHCA_QP_STATE_RST:      return IB_QPS_RESET;
+       case MTHCA_QP_STATE_INIT:     return IB_QPS_INIT;
+       case MTHCA_QP_STATE_RTR:      return IB_QPS_RTR;
+       case MTHCA_QP_STATE_RTS:      return IB_QPS_RTS;
+       case MTHCA_QP_STATE_DRAINING:
+       case MTHCA_QP_STATE_SQD:      return IB_QPS_SQD;
+       case MTHCA_QP_STATE_SQE:      return IB_QPS_SQE;
+       case MTHCA_QP_STATE_ERR:      return IB_QPS_ERR;
+       default:                      return -1;
+       }
+}
+
+static inline enum ib_mig_state to_ib_mig_state(int mthca_mig_state)
+{
+       switch (mthca_mig_state) {
+       case 0:  return IB_MIG_ARMED;
+       case 1:  return IB_MIG_REARM;
+       case 3:  return IB_MIG_MIGRATED;
+       default: return -1;
+       }
+}
+
+static int to_ib_qp_access_flags(int mthca_flags)
+{
+       int ib_flags = 0;
+
+       if (mthca_flags & MTHCA_QP_BIT_RRE)
+               ib_flags |= IB_ACCESS_REMOTE_READ;
+       if (mthca_flags & MTHCA_QP_BIT_RWE)
+               ib_flags |= IB_ACCESS_REMOTE_WRITE;
+       if (mthca_flags & MTHCA_QP_BIT_RAE)
+               ib_flags |= IB_ACCESS_REMOTE_ATOMIC;
+
+       return ib_flags;
+}
+
+static void to_ib_ah_attr(struct mthca_dev *dev, struct ib_ah_attr *ib_ah_attr,
+                               struct mthca_qp_path *path)
+{
+       memset(ib_ah_attr, 0, sizeof *path);
+       ib_ah_attr->port_num      = (be32_to_cpu(path->port_pkey) >> 24) & 0x3;
+       ib_ah_attr->dlid          = be16_to_cpu(path->rlid);
+       ib_ah_attr->sl            = be32_to_cpu(path->sl_tclass_flowlabel) >> 28;
+       ib_ah_attr->src_path_bits = path->g_mylmc & 0x7f;
+       ib_ah_attr->static_rate   = path->static_rate & 0x7;
+       ib_ah_attr->ah_flags      = (path->g_mylmc & (1 << 7)) ? IB_AH_GRH : 0;
+       if (ib_ah_attr->ah_flags) {
+               ib_ah_attr->grh.sgid_index = path->mgid_index & (dev->limits.gid_table_len - 1);
+               ib_ah_attr->grh.hop_limit  = path->hop_limit;
+               ib_ah_attr->grh.traffic_class =
+                       (be32_to_cpu(path->sl_tclass_flowlabel) >> 20) & 0xff;
+               ib_ah_attr->grh.flow_label =
+                       be32_to_cpu(path->sl_tclass_flowlabel) & 0xfffff;
+               memcpy(ib_ah_attr->grh.dgid.raw,
+                       path->rgid, sizeof ib_ah_attr->grh.dgid.raw);
+       }
+}
+
+int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask,
+                  struct ib_qp_init_attr *qp_init_attr)
+{
+       struct mthca_dev *dev = to_mdev(ibqp->device);
+       struct mthca_qp *qp = to_mqp(ibqp);
+       int err;
+       struct mthca_mailbox *mailbox;
+       struct mthca_qp_param *qp_param;
+       struct mthca_qp_context *context;
+       int mthca_state;
+       u8 status;
+
+       mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+
+       err = mthca_QUERY_QP(dev, qp->qpn, 0, mailbox, &status);
+       if (err)
+               goto out;
+       if (status) {
+               mthca_warn(dev, "QUERY_QP returned status %02x\n", status);
+               err = -EINVAL;
+               goto out;
+       }
+
+       qp_param    = mailbox->buf;
+       context     = &qp_param->context;
+       mthca_state = be32_to_cpu(context->flags) >> 28;
+
+       qp_attr->qp_state            = to_ib_qp_state(mthca_state);
+       qp_attr->cur_qp_state        = qp_attr->qp_state;
+       qp_attr->path_mtu            = context->mtu_msgmax >> 5;
+       qp_attr->path_mig_state      =
+               to_ib_mig_state((be32_to_cpu(context->flags) >> 11) & 0x3);
+       qp_attr->qkey                = be32_to_cpu(context->qkey);
+       qp_attr->rq_psn              = be32_to_cpu(context->rnr_nextrecvpsn) & 0xffffff;
+       qp_attr->sq_psn              = be32_to_cpu(context->next_send_psn) & 0xffffff;
+       qp_attr->dest_qp_num         = be32_to_cpu(context->remote_qpn) & 0xffffff;
+       qp_attr->qp_access_flags     =
+               to_ib_qp_access_flags(be32_to_cpu(context->params2));
+       qp_attr->cap.max_send_wr     = qp->sq.max;
+       qp_attr->cap.max_recv_wr     = qp->rq.max;
+       qp_attr->cap.max_send_sge    = qp->sq.max_gs;
+       qp_attr->cap.max_recv_sge    = qp->rq.max_gs;
+       qp_attr->cap.max_inline_data = qp->max_inline_data;
+
+       to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path);
+       to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path);
+
+       qp_attr->pkey_index     = be32_to_cpu(context->pri_path.port_pkey) & 0x7f;
+       qp_attr->alt_pkey_index = be32_to_cpu(context->alt_path.port_pkey) & 0x7f;
+
+       /* qp_attr->en_sqd_async_notify is only applicable in modify qp */
+       qp_attr->sq_draining = mthca_state == MTHCA_QP_STATE_DRAINING;
+
+       qp_attr->max_rd_atomic = 1 << ((be32_to_cpu(context->params1) >> 21) & 0x7);
+
+       qp_attr->max_dest_rd_atomic =
+               1 << ((be32_to_cpu(context->params2) >> 21) & 0x7);
+       qp_attr->min_rnr_timer      =
+               (be32_to_cpu(context->rnr_nextrecvpsn) >> 24) & 0x1f;
+       qp_attr->port_num           = qp_attr->ah_attr.port_num;
+       qp_attr->timeout            = context->pri_path.ackto >> 3;
+       qp_attr->retry_cnt          = (be32_to_cpu(context->params1) >> 16) & 0x7;
+       qp_attr->rnr_retry          = context->pri_path.rnr_retry >> 5;
+       qp_attr->alt_port_num       = qp_attr->alt_ah_attr.port_num;
+       qp_attr->alt_timeout        = context->alt_path.ackto >> 3;
+       qp_init_attr->cap           = qp_attr->cap;
+
+out:
+       mthca_free_mailbox(dev, mailbox);
+       return err;
+}
+
 static void mthca_path_set(struct ib_ah_attr *ah, struct mthca_qp_path *path)
 {
        path->g_mylmc     = ah->src_path_bits & 0x7f;
@@ -559,9 +493,9 @@ static void mthca_path_set(struct ib_ah_attr *ah, struct mthca_qp_path *path)
                path->g_mylmc   |= 1 << 7;
                path->mgid_index = ah->grh.sgid_index;
                path->hop_limit  = ah->grh.hop_limit;
-               path->sl_tclass_flowlabel = 
+               path->sl_tclass_flowlabel =
                        cpu_to_be32((ah->sl << 28)                |
-                                   (ah->grh.traffic_class << 20) | 
+                                   (ah->grh.traffic_class << 20) |
                                    (ah->grh.flow_label));
                memcpy(path->rgid, ah->grh.dgid.raw, 16);
        } else
@@ -576,18 +510,12 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
        struct mthca_mailbox *mailbox;
        struct mthca_qp_param *qp_param;
        struct mthca_qp_context *qp_context;
-       u32 req_param, opt_param;
+       u32 sqd_event = 0;
        u8 status;
        int err;
 
        if (attr_mask & IB_QP_CUR_STATE) {
-               if (attr->cur_qp_state != IB_QPS_RTR &&
-                   attr->cur_qp_state != IB_QPS_RTS &&
-                   attr->cur_qp_state != IB_QPS_SQD &&
-                   attr->cur_qp_state != IB_QPS_SQE)
-                       return -EINVAL;
-               else
-                       cur_state = attr->cur_qp_state;
+               cur_state = attr->cur_qp_state;
        } else {
                spin_lock_irq(&qp->sq.lock);
                spin_lock(&qp->rq.lock);
@@ -596,44 +524,20 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
                spin_unlock_irq(&qp->sq.lock);
        }
 
-       if (attr_mask & IB_QP_STATE) {
-               if (attr->qp_state < 0 || attr->qp_state > IB_QPS_ERR)
-                       return -EINVAL;
-               new_state = attr->qp_state;
-       } else
-               new_state = cur_state;
-
-       if (state_table[cur_state][new_state].trans == MTHCA_TRANS_INVALID) {
-               mthca_dbg(dev, "Illegal QP transition "
-                         "%d->%d\n", cur_state, new_state);
-               return -EINVAL;
-       }
-
-       req_param = state_table[cur_state][new_state].req_param[qp->transport];
-       opt_param = state_table[cur_state][new_state].opt_param[qp->transport];
+       new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
 
-       if ((req_param & attr_mask) != req_param) {
-               mthca_dbg(dev, "QP transition "
-                         "%d->%d missing req attr 0x%08x\n",
-                         cur_state, new_state,
-                         req_param & ~attr_mask);
+       if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask)) {
+               mthca_dbg(dev, "Bad QP transition (transport %d) "
+                         "%d->%d with attr 0x%08x\n",
+                         qp->transport, cur_state, new_state,
+                         attr_mask);
                return -EINVAL;
        }
 
-       if (attr_mask & ~(req_param | opt_param | IB_QP_STATE)) {
-               mthca_dbg(dev, "QP transition (transport %d) "
-                         "%d->%d has extra attr 0x%08x\n",
-                         qp->transport,
-                         cur_state, new_state,
-                         attr_mask & ~(req_param | opt_param |
-                                                IB_QP_STATE));
-               return -EINVAL;
-       }
-
-       if ((attr_mask & IB_QP_PKEY_INDEX) && 
+       if ((attr_mask & IB_QP_PKEY_INDEX) &&
             attr->pkey_index >= dev->limits.pkey_table_len) {
-               mthca_dbg(dev, "PKey index (%u) too large. max is %d\n",
-                         attr->pkey_index,dev->limits.pkey_table_len-1); 
+               mthca_dbg(dev, "P_Key index (%u) too large. max is %d\n",
+                         attr->pkey_index, dev->limits.pkey_table_len-1);
                return -EINVAL;
        }
 
@@ -733,7 +637,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
        if (attr_mask & IB_QP_RNR_RETRY) {
                qp_context->alt_path.rnr_retry = qp_context->pri_path.rnr_retry =
                        attr->rnr_retry << 5;
-               qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY | 
+               qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY |
                                                        MTHCA_QP_OPTPAR_ALT_RNR_RETRY);
        }
 
@@ -748,14 +652,20 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
        }
 
        if (attr_mask & IB_QP_ALT_PATH) {
+               if (attr->alt_pkey_index >= dev->limits.pkey_table_len) {
+                       mthca_dbg(dev, "Alternate P_Key index (%u) too large. max is %d\n",
+                                 attr->alt_pkey_index, dev->limits.pkey_table_len-1);
+                       return -EINVAL;
+               }
+
                if (attr->alt_port_num == 0 || attr->alt_port_num > dev->limits.num_ports) {
-                       mthca_dbg(dev, "Alternate port number (%u) is invalid\n", 
+                       mthca_dbg(dev, "Alternate port number (%u) is invalid\n",
                                attr->alt_port_num);
                        return -EINVAL;
                }
 
                mthca_path_set(&attr->alt_ah_attr, &qp_context->alt_path);
-               qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index | 
+               qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index |
                                                              attr->alt_port_num << 24);
                qp_context->alt_path.ackto = attr->alt_timeout << 3;
                qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ALT_ADDR_PATH);
@@ -841,11 +751,16 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
                qp_context->srqn = cpu_to_be32(1 << 24 |
                                               to_msrq(ibqp->srq)->srqn);
 
-       err = mthca_MODIFY_QP(dev, state_table[cur_state][new_state].trans,
-                             qp->qpn, 0, mailbox, 0, &status);
+       if (cur_state == IB_QPS_RTS && new_state == IB_QPS_SQD  &&
+           attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY               &&
+           attr->en_sqd_async_notify)
+               sqd_event = 1 << 31;
+
+       err = mthca_MODIFY_QP(dev, cur_state, new_state, qp->qpn, 0,
+                             mailbox, sqd_event, &status);
        if (status) {
-               mthca_warn(dev, "modify QP %d returned status %02x.\n",
-                          state_table[cur_state][new_state].trans, status);
+               mthca_warn(dev, "modify QP %d->%d returned status %02x.\n",
+                          cur_state, new_state, status);
                err = -EINVAL;
        }
 
@@ -1078,10 +993,10 @@ static int mthca_map_memfree(struct mthca_dev *dev,
                if (ret)
                        goto err_qpc;
 
-               ret = mthca_table_get(dev, dev->qp_table.rdb_table,
-                                     qp->qpn << dev->qp_table.rdb_shift);
-               if (ret)
-                       goto err_eqpc;
+               ret = mthca_table_get(dev, dev->qp_table.rdb_table,
+                                     qp->qpn << dev->qp_table.rdb_shift);
+               if (ret)
+                       goto err_eqpc;
 
        }
 
@@ -1393,7 +1308,8 @@ void mthca_free_qp(struct mthca_dev *dev,
        wait_event(qp->wait, !atomic_read(&qp->refcount));
 
        if (qp->state != IB_QPS_RESET)
-               mthca_MODIFY_QP(dev, MTHCA_TRANS_ANY2RST, qp->qpn, 0, NULL, 0, &status);
+               mthca_MODIFY_QP(dev, qp->state, IB_QPS_RESET, qp->qpn, 0,
+                               NULL, 0, &status);
 
        /*
         * If this is a userspace QP, the buffers, MR, CQs and so on
@@ -1699,7 +1615,9 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                                    mthca_opcode[wr->opcode]);
                wmb();
                ((struct mthca_next_seg *) prev_wqe)->ee_nds =
-                       cpu_to_be32((size0 ? 0 : MTHCA_NEXT_DBD) | size);
+                       cpu_to_be32((size0 ? 0 : MTHCA_NEXT_DBD) | size |
+                                   ((wr->send_flags & IB_SEND_FENCE) ?
+                                   MTHCA_NEXT_FENCE : 0));
 
                if (!size0) {
                        size0 = size;
@@ -2061,7 +1979,9 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                                    mthca_opcode[wr->opcode]);
                wmb();
                ((struct mthca_next_seg *) prev_wqe)->ee_nds =
-                       cpu_to_be32(MTHCA_NEXT_DBD | size);
+                       cpu_to_be32(MTHCA_NEXT_DBD | size |
+                                    ((wr->send_flags & IB_SEND_FENCE) ?
+                                    MTHCA_NEXT_FENCE : 0));
 
                if (!size0) {
                        size0 = size;
@@ -2115,7 +2035,7 @@ int mthca_arbel_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
        int i;
        void *wqe;
 
-       spin_lock_irqsave(&qp->rq.lock, flags);
+       spin_lock_irqsave(&qp->rq.lock, flags);
 
        /* XXX check that state is OK to post receive */
 
@@ -2182,8 +2102,8 @@ out:
        return err;
 }
 
-int mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,
-                      int index, int *dbd, __be32 *new_wqe)
+void mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,
+                       int index, int *dbd, __be32 *new_wqe)
 {
        struct mthca_next_seg *next;
 
@@ -2193,7 +2113,7 @@ int mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,
         */
        if (qp->ibqp.srq) {
                *new_wqe = 0;
-               return 0;
+               return;
        }
 
        if (is_send)
@@ -2207,8 +2127,6 @@ int mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,
                        (next->ee_nds & cpu_to_be32(0x3f));
        else
                *new_wqe = 0;
-
-       return 0;
 }
 
 int __devinit mthca_init_qp_table(struct mthca_dev *dev)
index e7e153d9c4c6d0f9b6c90d90ae301a0aa491ee10..47a6a754a591562e1432f8c859851ca05f75b24a 100644 (file)
@@ -49,7 +49,8 @@ struct mthca_tavor_srq_context {
        __be32 state_pd;
        __be32 lkey;
        __be32 uar;
-       __be32 wqe_cnt;
+       __be16 limit_watermark;
+       __be16 wqe_cnt;
        u32    reserved[2];
 };
 
@@ -271,6 +272,9 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
        srq->first_free = 0;
        srq->last_free  = srq->max - 1;
 
+       attr->max_wr    = (mthca_is_memfree(dev)) ? srq->max - 1 : srq->max;
+       attr->max_sge   = srq->max_gs;
+
        return 0;
 
 err_out_free_srq:
@@ -339,7 +343,7 @@ void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq)
 
 int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
                     enum ib_srq_attr_mask attr_mask)
-{      
+{
        struct mthca_dev *dev = to_mdev(ibsrq->device);
        struct mthca_srq *srq = to_msrq(ibsrq);
        int ret;
@@ -360,6 +364,41 @@ int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
        return 0;
 }
 
+int mthca_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
+{
+       struct mthca_dev *dev = to_mdev(ibsrq->device);
+       struct mthca_srq *srq = to_msrq(ibsrq);
+       struct mthca_mailbox *mailbox;
+       struct mthca_arbel_srq_context *arbel_ctx;
+       struct mthca_tavor_srq_context *tavor_ctx;
+       u8 status;
+       int err;
+
+       mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+
+       err = mthca_QUERY_SRQ(dev, srq->srqn, mailbox, &status);
+       if (err)
+               goto out;
+
+       if (mthca_is_memfree(dev)) {
+               arbel_ctx = mailbox->buf;
+               srq_attr->srq_limit = be16_to_cpu(arbel_ctx->limit_watermark);
+       } else {
+               tavor_ctx = mailbox->buf;
+               srq_attr->srq_limit = be16_to_cpu(tavor_ctx->limit_watermark);
+       }
+
+       srq_attr->max_wr  = (mthca_is_memfree(dev)) ? srq->max - 1 : srq->max;
+       srq_attr->max_sge = srq->max_gs;
+
+out:
+       mthca_free_mailbox(dev, mailbox);
+
+       return err;
+}
+
 void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
                     enum ib_event_type event_type)
 {
index bb015c6494c4e0f37d1bf40f963c3172ca3bac49..02cc0a766f3ac767db1aba8333816ec58b402775 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
- * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -75,6 +75,11 @@ struct mthca_create_cq_resp {
        __u32 reserved;
 };
 
+struct mthca_resize_cq {
+       __u32 lkey;
+       __u32 reserved;
+};
+
 struct mthca_create_srq {
        __u32 lkey;
        __u32 db_index;
index 2f85a9a831b1a6b5787b58326270cd7f45c3e570..1251f86ec8568c66dc23d671748034f21927caef 100644 (file)
@@ -217,10 +217,16 @@ struct ipoib_neigh {
        struct list_head    list;
 };
 
+/*
+ * We stash a pointer to our private neighbour information after our
+ * hardware address in neigh->ha.  The ALIGN() expression here makes
+ * sure that this pointer is stored aligned so that an unaligned
+ * load is not needed to dereference it.
+ */
 static inline struct ipoib_neigh **to_ipoib_neigh(struct neighbour *neigh)
 {
-       return (struct ipoib_neigh **) (neigh->ha + 24 -
-                                       (offsetof(struct neighbour, ha) & 4));
+       return (void*) neigh + ALIGN(offsetof(struct neighbour, ha) +
+                                    INFINIBAND_ALEN, sizeof(void *));
 }
 
 extern struct workqueue_struct *ipoib_workqueue;
@@ -253,7 +259,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev);
 
 int ipoib_ib_dev_open(struct net_device *dev);
 int ipoib_ib_dev_up(struct net_device *dev);
-int ipoib_ib_dev_down(struct net_device *dev);
+int ipoib_ib_dev_down(struct net_device *dev, int flush);
 int ipoib_ib_dev_stop(struct net_device *dev);
 
 int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
index 86bcdd72a10706260bf2585fe5d3b5e8103e65e5..a1f5a05f2f363f7dcb6815c1ade4e635866109cc 100644 (file)
@@ -416,6 +416,7 @@ int ipoib_ib_dev_open(struct net_device *dev)
        ret = ipoib_ib_post_receives(dev);
        if (ret) {
                ipoib_warn(priv, "ipoib_ib_post_receives returned %d\n", ret);
+               ipoib_ib_dev_stop(dev);
                return -1;
        }
 
@@ -434,7 +435,7 @@ int ipoib_ib_dev_up(struct net_device *dev)
        return ipoib_mcast_start_thread(dev);
 }
 
-int ipoib_ib_dev_down(struct net_device *dev)
+int ipoib_ib_dev_down(struct net_device *dev, int flush)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
 
@@ -449,10 +450,11 @@ int ipoib_ib_dev_down(struct net_device *dev)
                set_bit(IPOIB_PKEY_STOP, &priv->flags);
                cancel_delayed_work(&priv->pkey_task);
                mutex_unlock(&pkey_mutex);
-               flush_workqueue(ipoib_workqueue);
+               if (flush)
+                       flush_workqueue(ipoib_workqueue);
        }
 
-       ipoib_mcast_stop_thread(dev, 1);
+       ipoib_mcast_stop_thread(dev, flush);
        ipoib_mcast_dev_flush(dev);
 
        ipoib_flush_paths(dev);
@@ -590,7 +592,7 @@ void ipoib_ib_dev_flush(void *_dev)
 
        ipoib_dbg(priv, "flushing\n");
 
-       ipoib_ib_dev_down(dev);
+       ipoib_ib_dev_down(dev, 0);
 
        /*
         * The device could have been brought down between the start and when
index c3b5f79d11681e2bd43cacad1bbdb73da88203a3..0ebacd558ff6508919631d214283b8e49fb38897 100644 (file)
@@ -133,7 +133,13 @@ static int ipoib_stop(struct net_device *dev)
 
        netif_stop_queue(dev);
 
-       ipoib_ib_dev_down(dev);
+       /*
+        * Now flush workqueue to make sure a scheduled task doesn't
+        * bring our internal state back up.
+        */
+       flush_workqueue(ipoib_workqueue);
+
+       ipoib_ib_dev_down(dev, 1);
        ipoib_ib_dev_stop(dev);
 
        if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
@@ -513,12 +519,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
                           be32_to_cpup((__be32 *) skb->dst->neighbour->ha));
        } else {
                neigh->ah  = NULL;
-               if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
-                       __skb_queue_tail(&neigh->queue, skb);
-               } else {
-                       ++priv->stats.tx_dropped;
-                       dev_kfree_skb_any(skb);
-               }
+               __skb_queue_tail(&neigh->queue, skb);
 
                if (!path->query && path_rec_start(dev, path))
                        goto err;
index a2408d7ec5986cb3e69b3988f9a6c5a35fbf118f..93c462eaf4fd781c2ae93411c04c55878cc37325 100644 (file)
@@ -115,7 +115,6 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
                if (neigh->ah)
                        ipoib_put_ah(neigh->ah);
                *to_ipoib_neigh(neigh->neighbour) = NULL;
-               neigh->neighbour->ops->destructor = NULL;
                kfree(neigh);
        }
 
@@ -213,6 +212,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
 {
        struct net_device *dev = mcast->dev;
        struct ipoib_dev_priv *priv = netdev_priv(dev);
+       struct ipoib_ah *ah;
        int ret;
 
        mcast->mcmember = *mcmember;
@@ -269,8 +269,8 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
                                av.static_rate, priv->local_rate,
                                ib_sa_rate_enum_to_int(mcast->mcmember.rate));
 
-               mcast->ah = ipoib_create_ah(dev, priv->pd, &av);
-               if (!mcast->ah) {
+               ah = ipoib_create_ah(dev, priv->pd, &av);
+               if (!ah) {
                        ipoib_warn(priv, "ib_address_create failed\n");
                } else {
                        ipoib_dbg_mcast(priv, "MGID " IPOIB_GID_FMT
@@ -280,6 +280,10 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
                                        be16_to_cpu(mcast->mcmember.mlid),
                                        mcast->mcmember.sl);
                }
+
+               spin_lock_irq(&priv->lock);
+               mcast->ah = ah;
+               spin_unlock_irq(&priv->lock);
        }
 
        /* actually send any queued packets */
@@ -432,9 +436,11 @@ static void ipoib_mcast_join_complete(int status,
        if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS)
                mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS;
 
+       mutex_lock(&mcast_mutex);
+
+       spin_lock_irq(&priv->lock);
        mcast->query = NULL;
 
-       mutex_lock(&mcast_mutex);
        if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) {
                if (status == -ETIMEDOUT)
                        queue_work(ipoib_workqueue, &priv->mcast_task);
@@ -443,6 +449,7 @@ static void ipoib_mcast_join_complete(int status,
                                           mcast->backoff * HZ);
        } else
                complete(&mcast->done);
+       spin_unlock_irq(&priv->lock);
        mutex_unlock(&mcast_mutex);
 
        return;
@@ -630,21 +637,27 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
        if (flush)
                flush_workqueue(ipoib_workqueue);
 
+       spin_lock_irq(&priv->lock);
        if (priv->broadcast && priv->broadcast->query) {
                ib_sa_cancel_query(priv->broadcast->query_id, priv->broadcast->query);
                priv->broadcast->query = NULL;
+               spin_unlock_irq(&priv->lock);
                ipoib_dbg_mcast(priv, "waiting for bcast\n");
                wait_for_completion(&priv->broadcast->done);
-       }
+       } else
+               spin_unlock_irq(&priv->lock);
 
        list_for_each_entry(mcast, &priv->multicast_list, list) {
+               spin_lock_irq(&priv->lock);
                if (mcast->query) {
                        ib_sa_cancel_query(mcast->query_id, mcast->query);
                        mcast->query = NULL;
+                       spin_unlock_irq(&priv->lock);
                        ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n",
                                        IPOIB_GID_ARG(mcast->mcmember.mgid));
                        wait_for_completion(&mcast->done);
-               }
+               } else
+                       spin_unlock_irq(&priv->lock);
        }
 
        return 0;
index faaf10e5fc7b0b7eaee6ccb1bd1ef217595d902d..18d2f53ec34cd0abad51a656b7f02ff469cf8e94 100644 (file)
@@ -255,6 +255,6 @@ void ipoib_event(struct ib_event_handler *handler,
            record->event == IB_EVENT_LID_CHANGE  ||
            record->event == IB_EVENT_SM_CHANGE) {
                ipoib_dbg(priv, "Port active event\n");
-               schedule_work(&priv->flush_task);
+               queue_work(ipoib_workqueue, &priv->flush_task);
        }
 }
index 960dae5c87d1d73d9b19fe24f094130df40ca1b4..a13dcdf90a4f11d4c886fa2b5486fc84d4c19b7b 100644 (file)
@@ -1237,6 +1237,87 @@ static int srp_reset_host(struct scsi_cmnd *scmnd)
        return ret;
 }
 
+static ssize_t show_id_ext(struct class_device *cdev, char *buf)
+{
+       struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+
+       if (target->state == SRP_TARGET_DEAD ||
+           target->state == SRP_TARGET_REMOVED)
+               return -ENODEV;
+
+       return sprintf(buf, "0x%016llx\n",
+                      (unsigned long long) be64_to_cpu(target->id_ext));
+}
+
+static ssize_t show_ioc_guid(struct class_device *cdev, char *buf)
+{
+       struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+
+       if (target->state == SRP_TARGET_DEAD ||
+           target->state == SRP_TARGET_REMOVED)
+               return -ENODEV;
+
+       return sprintf(buf, "0x%016llx\n",
+                      (unsigned long long) be64_to_cpu(target->ioc_guid));
+}
+
+static ssize_t show_service_id(struct class_device *cdev, char *buf)
+{
+       struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+
+       if (target->state == SRP_TARGET_DEAD ||
+           target->state == SRP_TARGET_REMOVED)
+               return -ENODEV;
+
+       return sprintf(buf, "0x%016llx\n",
+                      (unsigned long long) be64_to_cpu(target->service_id));
+}
+
+static ssize_t show_pkey(struct class_device *cdev, char *buf)
+{
+       struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+
+       if (target->state == SRP_TARGET_DEAD ||
+           target->state == SRP_TARGET_REMOVED)
+               return -ENODEV;
+
+       return sprintf(buf, "0x%04x\n", be16_to_cpu(target->path.pkey));
+}
+
+static ssize_t show_dgid(struct class_device *cdev, char *buf)
+{
+       struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+
+       if (target->state == SRP_TARGET_DEAD ||
+           target->state == SRP_TARGET_REMOVED)
+               return -ENODEV;
+
+       return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[0]),
+                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[1]),
+                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[2]),
+                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[3]),
+                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[4]),
+                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[5]),
+                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[6]),
+                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[7]));
+}
+
+static CLASS_DEVICE_ATTR(id_ext,       S_IRUGO, show_id_ext,           NULL);
+static CLASS_DEVICE_ATTR(ioc_guid,     S_IRUGO, show_ioc_guid,         NULL);
+static CLASS_DEVICE_ATTR(service_id,   S_IRUGO, show_service_id,       NULL);
+static CLASS_DEVICE_ATTR(pkey,         S_IRUGO, show_pkey,             NULL);
+static CLASS_DEVICE_ATTR(dgid,         S_IRUGO, show_dgid,             NULL);
+
+static struct class_device_attribute *srp_host_attrs[] = {
+       &class_device_attr_id_ext,
+       &class_device_attr_ioc_guid,
+       &class_device_attr_service_id,
+       &class_device_attr_pkey,
+       &class_device_attr_dgid,
+       NULL
+};
+
 static struct scsi_host_template srp_template = {
        .module                         = THIS_MODULE,
        .name                           = DRV_NAME,
@@ -1249,7 +1330,8 @@ static struct scsi_host_template srp_template = {
        .this_id                        = -1,
        .sg_tablesize                   = SRP_MAX_INDIRECT,
        .cmd_per_lun                    = SRP_SQ_SIZE,
-       .use_clustering                 = ENABLE_CLUSTERING
+       .use_clustering                 = ENABLE_CLUSTERING,
+       .shost_attrs                    = srp_host_attrs
 };
 
 static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
@@ -1366,6 +1448,7 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
                                strlcpy(dgid, p + i * 2, 3);
                                target->path.dgid.raw[i] = simple_strtoul(dgid, NULL, 16);
                        }
+                       kfree(p);
                        break;
 
                case SRP_OPT_PKEY:
index bd458cb9b4ea9c972ad13843a2ffabb5cc21f034..61b89617a9671589a3d83cacc24e69a44faca9f1 100644 (file)
@@ -1,5 +1,6 @@
 saa7146-objs    := saa7146_i2c.o saa7146_core.o
 saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
+ir-common-objs  := ir-functions.o ir-keymaps.o
 
 obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
 obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
deleted file mode 100644 (file)
index 97fa3fc..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- *
- * some common structs and functions to handle infrared remotes via
- * input layer ...
- *
- * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/string.h>
-#include <media/ir-common.h>
-
-/* -------------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
-MODULE_LICENSE("GPL");
-
-static int repeat = 1;
-module_param(repeat, int, 0444);
-MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
-
-static int debug = 0;    /* debug level (0,1,2) */
-module_param(debug, int, 0644);
-
-#define dprintk(level, fmt, arg...)    if (debug >= level) \
-       printk(KERN_DEBUG fmt , ## arg)
-
-/* -------------------------------------------------------------------------- */
-
-/* generic RC5 keytable                                          */
-/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
-/* used by old (black) Hauppauge remotes                         */
-IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = {
-       /* Keys 0 to 9 */
-       [ 0x00 ] = KEY_KP0,
-       [ 0x01 ] = KEY_KP1,
-       [ 0x02 ] = KEY_KP2,
-       [ 0x03 ] = KEY_KP3,
-       [ 0x04 ] = KEY_KP4,
-       [ 0x05 ] = KEY_KP5,
-       [ 0x06 ] = KEY_KP6,
-       [ 0x07 ] = KEY_KP7,
-       [ 0x08 ] = KEY_KP8,
-       [ 0x09 ] = KEY_KP9,
-
-       [ 0x0b ] = KEY_CHANNEL,         /* channel / program (japan: 11) */
-       [ 0x0c ] = KEY_POWER,           /* standby */
-       [ 0x0d ] = KEY_MUTE,            /* mute / demute */
-       [ 0x0f ] = KEY_TV,              /* display */
-       [ 0x10 ] = KEY_VOLUMEUP,
-       [ 0x11 ] = KEY_VOLUMEDOWN,
-       [ 0x12 ] = KEY_BRIGHTNESSUP,
-       [ 0x13 ] = KEY_BRIGHTNESSDOWN,
-       [ 0x1e ] = KEY_SEARCH,          /* search + */
-       [ 0x20 ] = KEY_CHANNELUP,       /* channel / program + */
-       [ 0x21 ] = KEY_CHANNELDOWN,     /* channel / program - */
-       [ 0x22 ] = KEY_CHANNEL,         /* alt / channel */
-       [ 0x23 ] = KEY_LANGUAGE,        /* 1st / 2nd language */
-       [ 0x26 ] = KEY_SLEEP,           /* sleeptimer */
-       [ 0x2e ] = KEY_MENU,            /* 2nd controls (USA: menu) */
-       [ 0x30 ] = KEY_PAUSE,
-       [ 0x32 ] = KEY_REWIND,
-       [ 0x33 ] = KEY_GOTO,
-       [ 0x35 ] = KEY_PLAY,
-       [ 0x36 ] = KEY_STOP,
-       [ 0x37 ] = KEY_RECORD,          /* recording */
-       [ 0x3c ] = KEY_TEXT,            /* teletext submode (Japan: 12) */
-       [ 0x3d ] = KEY_SUSPEND,         /* system standby */
-
-};
-EXPORT_SYMBOL_GPL(ir_codes_rc5_tv);
-
-/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
-IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
-       /* Keys 0 to 9 */
-       [ 18 ] = KEY_KP0,
-       [  5 ] = KEY_KP1,
-       [  6 ] = KEY_KP2,
-       [  7 ] = KEY_KP3,
-       [  9 ] = KEY_KP4,
-       [ 10 ] = KEY_KP5,
-       [ 11 ] = KEY_KP6,
-       [ 13 ] = KEY_KP7,
-       [ 14 ] = KEY_KP8,
-       [ 15 ] = KEY_KP9,
-
-       [  0 ] = KEY_POWER,
-       [  2 ] = KEY_TUNER,             /* TV/FM */
-       [ 30 ] = KEY_VIDEO,
-       [  4 ] = KEY_VOLUMEUP,
-       [  8 ] = KEY_VOLUMEDOWN,
-       [ 12 ] = KEY_CHANNELUP,
-       [ 16 ] = KEY_CHANNELDOWN,
-       [  3 ] = KEY_ZOOM,              /* fullscreen */
-       [ 31 ] = KEY_SUBTITLE,          /* closed caption/teletext */
-       [ 32 ] = KEY_SLEEP,
-       [ 20 ] = KEY_MUTE,
-       [ 43 ] = KEY_RED,
-       [ 44 ] = KEY_GREEN,
-       [ 45 ] = KEY_YELLOW,
-       [ 46 ] = KEY_BLUE,
-       [ 24 ] = KEY_KPPLUS,            /* fine tune + */
-       [ 25 ] = KEY_KPMINUS,           /* fine tune - */
-       [ 33 ] = KEY_KPDOT,
-       [ 19 ] = KEY_KPENTER,
-       [ 34 ] = KEY_BACK,
-       [ 35 ] = KEY_PLAYPAUSE,
-       [ 36 ] = KEY_NEXT,
-       [ 38 ] = KEY_STOP,
-       [ 39 ] = KEY_RECORD
-};
-EXPORT_SYMBOL_GPL(ir_codes_winfast);
-
-IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
-       [ 0x59 ] = KEY_MUTE,
-       [ 0x4a ] = KEY_POWER,
-
-       [ 0x18 ] = KEY_TEXT,
-       [ 0x26 ] = KEY_TV,
-       [ 0x3d ] = KEY_PRINT,
-
-       [ 0x48 ] = KEY_RED,
-       [ 0x04 ] = KEY_GREEN,
-       [ 0x11 ] = KEY_YELLOW,
-       [ 0x00 ] = KEY_BLUE,
-
-       [ 0x2d ] = KEY_VOLUMEUP,
-       [ 0x1e ] = KEY_VOLUMEDOWN,
-
-       [ 0x49 ] = KEY_MENU,
-
-       [ 0x16 ] = KEY_CHANNELUP,
-       [ 0x17 ] = KEY_CHANNELDOWN,
-
-       [ 0x20 ] = KEY_UP,
-       [ 0x21 ] = KEY_DOWN,
-       [ 0x22 ] = KEY_LEFT,
-       [ 0x23 ] = KEY_RIGHT,
-       [ 0x0d ] = KEY_SELECT,
-
-
-
-       [ 0x08 ] = KEY_BACK,
-       [ 0x07 ] = KEY_REFRESH,
-
-       [ 0x2f ] = KEY_ZOOM,
-       [ 0x29 ] = KEY_RECORD,
-
-       [ 0x4b ] = KEY_PAUSE,
-       [ 0x4d ] = KEY_REWIND,
-       [ 0x2e ] = KEY_PLAY,
-       [ 0x4e ] = KEY_FORWARD,
-       [ 0x53 ] = KEY_PREVIOUS,
-       [ 0x4c ] = KEY_STOP,
-       [ 0x54 ] = KEY_NEXT,
-
-       [ 0x69 ] = KEY_KP0,
-       [ 0x6a ] = KEY_KP1,
-       [ 0x6b ] = KEY_KP2,
-       [ 0x6c ] = KEY_KP3,
-       [ 0x6d ] = KEY_KP4,
-       [ 0x6e ] = KEY_KP5,
-       [ 0x6f ] = KEY_KP6,
-       [ 0x70 ] = KEY_KP7,
-       [ 0x71 ] = KEY_KP8,
-       [ 0x72 ] = KEY_KP9,
-
-       [ 0x74 ] = KEY_CHANNEL,
-       [ 0x0a ] = KEY_BACKSPACE,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_pinnacle);
-
-/* empty keytable, can be used as placeholder for not-yet created keytables */
-IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
-       [ 42 ] = KEY_COFFEE,
-};
-EXPORT_SYMBOL_GPL(ir_codes_empty);
-
-/* Hauppauge: the newer, gray remotes (seems there are multiple
- * slightly different versions), shipped with cx88+ivtv cards.
- * almost rc5 coding, but some non-standard keys */
-IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
-       /* Keys 0 to 9 */
-       [ 0x00 ] = KEY_KP0,
-       [ 0x01 ] = KEY_KP1,
-       [ 0x02 ] = KEY_KP2,
-       [ 0x03 ] = KEY_KP3,
-       [ 0x04 ] = KEY_KP4,
-       [ 0x05 ] = KEY_KP5,
-       [ 0x06 ] = KEY_KP6,
-       [ 0x07 ] = KEY_KP7,
-       [ 0x08 ] = KEY_KP8,
-       [ 0x09 ] = KEY_KP9,
-
-       [ 0x0a ] = KEY_TEXT,            /* keypad asterisk as well */
-       [ 0x0b ] = KEY_RED,             /* red button */
-       [ 0x0c ] = KEY_RADIO,
-       [ 0x0d ] = KEY_MENU,
-       [ 0x0e ] = KEY_SUBTITLE,        /* also the # key */
-       [ 0x0f ] = KEY_MUTE,
-       [ 0x10 ] = KEY_VOLUMEUP,
-       [ 0x11 ] = KEY_VOLUMEDOWN,
-       [ 0x12 ] = KEY_PREVIOUS,        /* previous channel */
-       [ 0x14 ] = KEY_UP,
-       [ 0x15 ] = KEY_DOWN,
-       [ 0x16 ] = KEY_LEFT,
-       [ 0x17 ] = KEY_RIGHT,
-       [ 0x18 ] = KEY_VIDEO,           /* Videos */
-       [ 0x19 ] = KEY_AUDIO,           /* Music */
-       /* 0x1a: Pictures - presume this means
-          "Multimedia Home Platform" -
-          no "PICTURES" key in input.h
-        */
-       [ 0x1a ] = KEY_MHP,
-
-       [ 0x1b ] = KEY_EPG,             /* Guide */
-       [ 0x1c ] = KEY_TV,
-       [ 0x1e ] = KEY_NEXTSONG,        /* skip >| */
-       [ 0x1f ] = KEY_EXIT,            /* back/exit */
-       [ 0x20 ] = KEY_CHANNELUP,       /* channel / program + */
-       [ 0x21 ] = KEY_CHANNELDOWN,     /* channel / program - */
-       [ 0x22 ] = KEY_CHANNEL,         /* source (old black remote) */
-       [ 0x24 ] = KEY_PREVIOUSSONG,    /* replay |< */
-       [ 0x25 ] = KEY_ENTER,           /* OK */
-       [ 0x26 ] = KEY_SLEEP,           /* minimize (old black remote) */
-       [ 0x29 ] = KEY_BLUE,            /* blue key */
-       [ 0x2e ] = KEY_GREEN,           /* green button */
-       [ 0x30 ] = KEY_PAUSE,           /* pause */
-       [ 0x32 ] = KEY_REWIND,          /* backward << */
-       [ 0x34 ] = KEY_FASTFORWARD,     /* forward >> */
-       [ 0x35 ] = KEY_PLAY,
-       [ 0x36 ] = KEY_STOP,
-       [ 0x37 ] = KEY_RECORD,          /* recording */
-       [ 0x38 ] = KEY_YELLOW,          /* yellow key */
-       [ 0x3b ] = KEY_SELECT,          /* top right button */
-       [ 0x3c ] = KEY_ZOOM,            /* full */
-       [ 0x3d ] = KEY_POWER,           /* system power (green button) */
-};
-EXPORT_SYMBOL(ir_codes_hauppauge_new);
-
-IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
-       [  2 ] = KEY_KP0,
-       [  1 ] = KEY_KP1,
-       [ 11 ] = KEY_KP2,
-       [ 27 ] = KEY_KP3,
-       [  5 ] = KEY_KP4,
-       [  9 ] = KEY_KP5,
-       [ 21 ] = KEY_KP6,
-       [  6 ] = KEY_KP7,
-       [ 10 ] = KEY_KP8,
-       [ 18 ] = KEY_KP9,
-
-       [  3 ] = KEY_TUNER,             /* TV/FM */
-       [  7 ] = KEY_SEARCH,            /* scan */
-       [ 28 ] = KEY_ZOOM,              /* full screen */
-       [ 30 ] = KEY_POWER,
-       [ 23 ] = KEY_VOLUMEDOWN,
-       [ 31 ] = KEY_VOLUMEUP,
-       [ 20 ] = KEY_CHANNELDOWN,
-       [ 22 ] = KEY_CHANNELUP,
-       [ 24 ] = KEY_MUTE,
-
-       [  0 ] = KEY_LIST,              /* source */
-       [ 19 ] = KEY_INFO,              /* loop */
-       [ 16 ] = KEY_LAST,              /* +100 */
-       [ 13 ] = KEY_CLEAR,             /* reset */
-       [ 12 ] = BTN_RIGHT,             /* fun++ */
-       [  4 ] = BTN_LEFT,              /* fun-- */
-       [ 14 ] = KEY_GOTO,              /* function */
-       [ 15 ] = KEY_STOP,              /* freeze */
-};
-EXPORT_SYMBOL(ir_codes_pixelview);
-
-/* -------------------------------------------------------------------------- */
-
-static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
-{
-       if (KEY_RESERVED == ir->keycode) {
-               printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n",
-                      dev->name,ir->ir_key,ir->ir_raw,ir->keypressed);
-               return;
-       }
-       dprintk(1,"%s: key event code=%d down=%d\n",
-               dev->name,ir->keycode,ir->keypressed);
-       input_report_key(dev,ir->keycode,ir->keypressed);
-       input_sync(dev);
-}
-
-/* -------------------------------------------------------------------------- */
-
-void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
-                  int ir_type, IR_KEYTAB_TYPE *ir_codes)
-{
-       int i;
-
-       ir->ir_type = ir_type;
-       if (ir_codes)
-               memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
-
-
-       dev->keycode     = ir->ir_codes;
-       dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
-       dev->keycodemax  = IR_KEYTAB_SIZE;
-       for (i = 0; i < IR_KEYTAB_SIZE; i++)
-               set_bit(ir->ir_codes[i], dev->keybit);
-       clear_bit(0, dev->keybit);
-
-       set_bit(EV_KEY, dev->evbit);
-       if (repeat)
-               set_bit(EV_REP, dev->evbit);
-}
-
-void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
-{
-       if (ir->keypressed) {
-               ir->keypressed = 0;
-               ir_input_key_event(dev,ir);
-       }
-}
-
-void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
-                     u32 ir_key, u32 ir_raw)
-{
-       u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key);
-
-       if (ir->keypressed && ir->keycode != keycode) {
-               ir->keypressed = 0;
-               ir_input_key_event(dev,ir);
-       }
-       if (!ir->keypressed) {
-               ir->ir_key  = ir_key;
-               ir->ir_raw  = ir_raw;
-               ir->keycode = keycode;
-               ir->keypressed = 1;
-               ir_input_key_event(dev,ir);
-       }
-}
-
-/* -------------------------------------------------------------------------- */
-
-u32 ir_extract_bits(u32 data, u32 mask)
-{
-       int mbit, vbit;
-       u32 value;
-
-       value = 0;
-       vbit  = 0;
-       for (mbit = 0; mbit < 32; mbit++) {
-               if (!(mask & ((u32)1 << mbit)))
-                       continue;
-               if (data & ((u32)1 << mbit))
-                       value |= (1 << vbit);
-               vbit++;
-       }
-       return value;
-}
-
-static int inline getbit(u32 *samples, int bit)
-{
-       return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
-}
-
-/* sump raw samples for visual debugging ;) */
-int ir_dump_samples(u32 *samples, int count)
-{
-       int i, bit, start;
-
-       printk(KERN_DEBUG "ir samples: ");
-       start = 0;
-       for (i = 0; i < count * 32; i++) {
-               bit = getbit(samples,i);
-               if (bit)
-                       start = 1;
-               if (0 == start)
-                       continue;
-               printk("%s", bit ? "#" : "_");
-       }
-       printk("\n");
-       return 0;
-}
-
-/* decode raw samples, pulse distance coding used by NEC remotes */
-int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
-{
-       int i,last,bit,len;
-       u32 curBit;
-       u32 value;
-
-       /* find start burst */
-       for (i = len = 0; i < count * 32; i++) {
-               bit = getbit(samples,i);
-               if (bit) {
-                       len++;
-               } else {
-                       if (len >= 29)
-                               break;
-                       len = 0;
-               }
-       }
-
-       /* start burst to short */
-       if (len < 29)
-               return 0xffffffff;
-
-       /* find start silence */
-       for (len = 0; i < count * 32; i++) {
-               bit = getbit(samples,i);
-               if (bit) {
-                       break;
-               } else {
-                       len++;
-               }
-       }
-
-       /* silence to short */
-       if (len < 7)
-               return 0xffffffff;
-
-       /* go decoding */
-       len   = 0;
-       last = 1;
-       value = 0; curBit = 1;
-       for (; i < count * 32; i++) {
-               bit  = getbit(samples,i);
-               if (last) {
-                       if(bit) {
-                               continue;
-                       } else {
-                               len = 1;
-                       }
-               } else {
-                       if (bit) {
-                               if (len > (low + high) /2)
-                                       value |= curBit;
-                               curBit <<= 1;
-                               if (curBit == 1)
-                                       break;
-                       } else {
-                               len++;
-                       }
-               }
-               last = bit;
-       }
-
-       return value;
-}
-
-/* decode raw samples, biphase coding, used by rc5 for example */
-int ir_decode_biphase(u32 *samples, int count, int low, int high)
-{
-       int i,last,bit,len,flips;
-       u32 value;
-
-       /* find start bit (1) */
-       for (i = 0; i < 32; i++) {
-               bit = getbit(samples,i);
-               if (bit)
-                       break;
-       }
-
-       /* go decoding */
-       len   = 0;
-       flips = 0;
-       value = 1;
-       for (; i < count * 32; i++) {
-               if (len > high)
-                       break;
-               if (flips > 1)
-                       break;
-               last = bit;
-               bit  = getbit(samples,i);
-               if (last == bit) {
-                       len++;
-                       continue;
-               }
-               if (len < low) {
-                       len++;
-                       flips++;
-                       continue;
-               }
-               value <<= 1;
-               value |= bit;
-               flips = 0;
-               len   = 1;
-       }
-       return value;
-}
-
-EXPORT_SYMBOL_GPL(ir_input_init);
-EXPORT_SYMBOL_GPL(ir_input_nokey);
-EXPORT_SYMBOL_GPL(ir_input_keydown);
-
-EXPORT_SYMBOL_GPL(ir_extract_bits);
-EXPORT_SYMBOL_GPL(ir_dump_samples);
-EXPORT_SYMBOL_GPL(ir_decode_biphase);
-EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
new file mode 100644 (file)
index 0000000..397cff8
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ *
+ * some common structs and functions to handle infrared remotes via
+ * input layer ...
+ *
+ * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <media/ir-common.h>
+
+/* -------------------------------------------------------------------------- */
+
+MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
+MODULE_LICENSE("GPL");
+
+static int repeat = 1;
+module_param(repeat, int, 0444);
+MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
+
+static int debug = 0;    /* debug level (0,1,2) */
+module_param(debug, int, 0644);
+
+#define dprintk(level, fmt, arg...)    if (debug >= level) \
+       printk(KERN_DEBUG fmt , ## arg)
+
+/* -------------------------------------------------------------------------- */
+
+static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
+{
+       if (KEY_RESERVED == ir->keycode) {
+               printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n",
+                      dev->name,ir->ir_key,ir->ir_raw,ir->keypressed);
+               return;
+       }
+       dprintk(1,"%s: key event code=%d down=%d\n",
+               dev->name,ir->keycode,ir->keypressed);
+       input_report_key(dev,ir->keycode,ir->keypressed);
+       input_sync(dev);
+}
+
+/* -------------------------------------------------------------------------- */
+
+void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
+                  int ir_type, IR_KEYTAB_TYPE *ir_codes)
+{
+       int i;
+
+       ir->ir_type = ir_type;
+       if (ir_codes)
+               memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
+
+
+       dev->keycode     = ir->ir_codes;
+       dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
+       dev->keycodemax  = IR_KEYTAB_SIZE;
+       for (i = 0; i < IR_KEYTAB_SIZE; i++)
+               set_bit(ir->ir_codes[i], dev->keybit);
+       clear_bit(0, dev->keybit);
+
+       set_bit(EV_KEY, dev->evbit);
+       if (repeat)
+               set_bit(EV_REP, dev->evbit);
+}
+
+void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
+{
+       if (ir->keypressed) {
+               ir->keypressed = 0;
+               ir_input_key_event(dev,ir);
+       }
+}
+
+void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
+                     u32 ir_key, u32 ir_raw)
+{
+       u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key);
+
+       if (ir->keypressed && ir->keycode != keycode) {
+               ir->keypressed = 0;
+               ir_input_key_event(dev,ir);
+       }
+       if (!ir->keypressed) {
+               ir->ir_key  = ir_key;
+               ir->ir_raw  = ir_raw;
+               ir->keycode = keycode;
+               ir->keypressed = 1;
+               ir_input_key_event(dev,ir);
+       }
+}
+
+/* -------------------------------------------------------------------------- */
+
+u32 ir_extract_bits(u32 data, u32 mask)
+{
+       int mbit, vbit;
+       u32 value;
+
+       value = 0;
+       vbit  = 0;
+       for (mbit = 0; mbit < 32; mbit++) {
+               if (!(mask & ((u32)1 << mbit)))
+                       continue;
+               if (data & ((u32)1 << mbit))
+                       value |= (1 << vbit);
+               vbit++;
+       }
+       return value;
+}
+
+static int inline getbit(u32 *samples, int bit)
+{
+       return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
+}
+
+/* sump raw samples for visual debugging ;) */
+int ir_dump_samples(u32 *samples, int count)
+{
+       int i, bit, start;
+
+       printk(KERN_DEBUG "ir samples: ");
+       start = 0;
+       for (i = 0; i < count * 32; i++) {
+               bit = getbit(samples,i);
+               if (bit)
+                       start = 1;
+               if (0 == start)
+                       continue;
+               printk("%s", bit ? "#" : "_");
+       }
+       printk("\n");
+       return 0;
+}
+
+/* decode raw samples, pulse distance coding used by NEC remotes */
+int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
+{
+       int i,last,bit,len;
+       u32 curBit;
+       u32 value;
+
+       /* find start burst */
+       for (i = len = 0; i < count * 32; i++) {
+               bit = getbit(samples,i);
+               if (bit) {
+                       len++;
+               } else {
+                       if (len >= 29)
+                               break;
+                       len = 0;
+               }
+       }
+
+       /* start burst to short */
+       if (len < 29)
+               return 0xffffffff;
+
+       /* find start silence */
+       for (len = 0; i < count * 32; i++) {
+               bit = getbit(samples,i);
+               if (bit) {
+                       break;
+               } else {
+                       len++;
+               }
+       }
+
+       /* silence to short */
+       if (len < 7)
+               return 0xffffffff;
+
+       /* go decoding */
+       len   = 0;
+       last = 1;
+       value = 0; curBit = 1;
+       for (; i < count * 32; i++) {
+               bit  = getbit(samples,i);
+               if (last) {
+                       if(bit) {
+                               continue;
+                       } else {
+                               len = 1;
+                       }
+               } else {
+                       if (bit) {
+                               if (len > (low + high) /2)
+                                       value |= curBit;
+                               curBit <<= 1;
+                               if (curBit == 1)
+                                       break;
+                       } else {
+                               len++;
+                       }
+               }
+               last = bit;
+       }
+
+       return value;
+}
+
+/* decode raw samples, biphase coding, used by rc5 for example */
+int ir_decode_biphase(u32 *samples, int count, int low, int high)
+{
+       int i,last,bit,len,flips;
+       u32 value;
+
+       /* find start bit (1) */
+       for (i = 0; i < 32; i++) {
+               bit = getbit(samples,i);
+               if (bit)
+                       break;
+       }
+
+       /* go decoding */
+       len   = 0;
+       flips = 0;
+       value = 1;
+       for (; i < count * 32; i++) {
+               if (len > high)
+                       break;
+               if (flips > 1)
+                       break;
+               last = bit;
+               bit  = getbit(samples,i);
+               if (last == bit) {
+                       len++;
+                       continue;
+               }
+               if (len < low) {
+                       len++;
+                       flips++;
+                       continue;
+               }
+               value <<= 1;
+               value |= bit;
+               flips = 0;
+               len   = 1;
+       }
+       return value;
+}
+
+EXPORT_SYMBOL_GPL(ir_input_init);
+EXPORT_SYMBOL_GPL(ir_input_nokey);
+EXPORT_SYMBOL_GPL(ir_input_keydown);
+
+EXPORT_SYMBOL_GPL(ir_extract_bits);
+EXPORT_SYMBOL_GPL(ir_dump_samples);
+EXPORT_SYMBOL_GPL(ir_decode_biphase);
+EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
new file mode 100644 (file)
index 0000000..a294d5c
--- /dev/null
@@ -0,0 +1,1415 @@
+/*
+
+
+    Keytables for supported remote controls. This file is part of
+    video4linux.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <linux/input.h>
+#include <media/ir-common.h>
+
+/* empty keytable, can be used as placeholder for not-yet created keytables */
+IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
+       [ 0x2a ] = KEY_COFFEE,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_empty);
+
+/* Matt Jesson <dvb@jesson.eclipse.co.uk */
+IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
+       [ 0x28 ] = KEY_0,         //'0' / 'enter'
+       [ 0x22 ] = KEY_1,         //'1'
+       [ 0x12 ] = KEY_2,         //'2' / 'up arrow'
+       [ 0x32 ] = KEY_3,         //'3'
+       [ 0x24 ] = KEY_4,         //'4' / 'left arrow'
+       [ 0x14 ] = KEY_5,         //'5'
+       [ 0x34 ] = KEY_6,         //'6' / 'right arrow'
+       [ 0x26 ] = KEY_7,         //'7'
+       [ 0x16 ] = KEY_8,         //'8' / 'down arrow'
+       [ 0x36 ] = KEY_9,         //'9'
+
+       [ 0x20 ] = KEY_LIST,        // 'source'
+       [ 0x10 ] = KEY_TEXT,        // 'teletext'
+       [ 0x00 ] = KEY_POWER,       // 'power'
+       [ 0x04 ] = KEY_AUDIO,       // 'audio'
+       [ 0x06 ] = KEY_ZOOM,        // 'full screen'
+       [ 0x18 ] = KEY_VIDEO,       // 'display'
+       [ 0x38 ] = KEY_SEARCH,      // 'loop'
+       [ 0x08 ] = KEY_INFO,        // 'preview'
+       [ 0x2a ] = KEY_REWIND,      // 'backward <<'
+       [ 0x1a ] = KEY_FASTFORWARD, // 'forward >>'
+       [ 0x3a ] = KEY_RECORD,      // 'capture'
+       [ 0x0a ] = KEY_MUTE,        // 'mute'
+       [ 0x2c ] = KEY_RECORD,      // 'record'
+       [ 0x1c ] = KEY_PAUSE,       // 'pause'
+       [ 0x3c ] = KEY_STOP,        // 'stop'
+       [ 0x0c ] = KEY_PLAY,        // 'play'
+       [ 0x2e ] = KEY_RED,         // 'red'
+       [ 0x01 ] = KEY_BLUE,        // 'blue' / 'cancel'
+       [ 0x0e ] = KEY_YELLOW,      // 'yellow' / 'ok'
+       [ 0x21 ] = KEY_GREEN,       // 'green'
+       [ 0x11 ] = KEY_CHANNELDOWN, // 'channel -'
+       [ 0x31 ] = KEY_CHANNELUP,   // 'channel +'
+       [ 0x1e ] = KEY_VOLUMEDOWN,  // 'volume -'
+       [ 0x3e ] = KEY_VOLUMEUP,    // 'volume +'
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt);
+
+/* Attila Kondoros <attila.kondoros@chello.hu> */
+IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
+
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+       [ 0x00 ] = KEY_0,
+       [ 0x17 ] = KEY_LAST,        // +100
+       [ 0x0a ] = KEY_LIST,        // recall
+
+
+       [ 0x1c ] = KEY_TUNER,       // TV/FM
+       [ 0x15 ] = KEY_SEARCH,      // scan
+       [ 0x12 ] = KEY_POWER,       // power
+       [ 0x1f ] = KEY_VOLUMEDOWN,  // vol up
+       [ 0x1b ] = KEY_VOLUMEUP,    // vol down
+       [ 0x1e ] = KEY_CHANNELDOWN, // chn up
+       [ 0x1a ] = KEY_CHANNELUP,   // chn down
+
+       [ 0x11 ] = KEY_VIDEO,       // video
+       [ 0x0f ] = KEY_ZOOM,        // full screen
+       [ 0x13 ] = KEY_MUTE,        // mute/unmute
+       [ 0x10 ] = KEY_TEXT,        // min
+
+       [ 0x0d ] = KEY_STOP,        // freeze
+       [ 0x0e ] = KEY_RECORD,      // record
+       [ 0x1d ] = KEY_PLAYPAUSE,   // stop
+       [ 0x19 ] = KEY_PLAY,        // play
+
+       [ 0x16 ] = KEY_GOTO,        // osd
+       [ 0x14 ] = KEY_REFRESH,     // default
+       [ 0x0c ] = KEY_KPPLUS,      // fine tune >>>>
+       [ 0x18 ] = KEY_KPMINUS      // fine tune <<<<
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp);
+
+/* ---------------------------------------------------------------------- */
+
+IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
+
+       [ 0x1e ] = KEY_POWER,       // power
+       [ 0x07 ] = KEY_MEDIA,       // source
+       [ 0x1c ] = KEY_SEARCH,      // scan
+
+/* FIXME: duplicate keycodes?
+ *
+ * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
+ * The GPIO values are
+ * 6397fb for both "Scan <" and "CH -",
+ * 639ffb for "Scan >" and "CH+",
+ * 6384fb for "Tune <" and "<<<",
+ * 638cfb for "Tune >" and ">>>", regardless of the mask.
+ *
+ *     [ 0x17 ] = KEY_BACK,        // fm scan <<
+ *     [ 0x1f ] = KEY_FORWARD,     // fm scan >>
+ *
+ *     [ 0x04 ] = KEY_LEFT,        // fm tuning <
+ *     [ 0x0c ] = KEY_RIGHT,       // fm tuning >
+ *
+ * For now, these four keys are disabled. Pressing them will generate
+ * the CH+/CH-/<<</>>> events
+ */
+
+       [ 0x03 ] = KEY_TUNER,       // TV/FM
+
+       [ 0x00 ] = KEY_RECORD,
+       [ 0x08 ] = KEY_STOP,
+       [ 0x11 ] = KEY_PLAY,
+
+       [ 0x1a ] = KEY_PLAYPAUSE,   // freeze
+       [ 0x19 ] = KEY_ZOOM,        // zoom
+       [ 0x0f ] = KEY_TEXT,        // min
+
+       [ 0x01 ] = KEY_1,
+       [ 0x0b ] = KEY_2,
+       [ 0x1b ] = KEY_3,
+       [ 0x05 ] = KEY_4,
+       [ 0x09 ] = KEY_5,
+       [ 0x15 ] = KEY_6,
+       [ 0x06 ] = KEY_7,
+       [ 0x0a ] = KEY_8,
+       [ 0x12 ] = KEY_9,
+       [ 0x02 ] = KEY_0,
+       [ 0x10 ] = KEY_LAST,        // +100
+       [ 0x13 ] = KEY_LIST,        // recall
+
+       [ 0x1f ] = KEY_CHANNELUP,   // chn down
+       [ 0x17 ] = KEY_CHANNELDOWN, // chn up
+       [ 0x16 ] = KEY_VOLUMEUP,    // vol down
+       [ 0x14 ] = KEY_VOLUMEDOWN,  // vol up
+
+       [ 0x04 ] = KEY_KPMINUS,     // <<<
+       [ 0x0e ] = KEY_SETUP,       // function
+       [ 0x0c ] = KEY_KPPLUS,      // >>>
+
+       [ 0x0d ] = KEY_GOTO,        // mts
+       [ 0x1d ] = KEY_REFRESH,     // reset
+       [ 0x18 ] = KEY_MUTE         // mute/unmute
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_pixelview);
+
+IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = {
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+       [ 0x0a ] = KEY_TV,
+       [ 0x0b ] = KEY_AUX,
+       [ 0x0c ] = KEY_DVD,
+       [ 0x0d ] = KEY_POWER,
+       [ 0x0e ] = KEY_MHP,     /* labelled 'Picture' */
+       [ 0x0f ] = KEY_AUDIO,
+       [ 0x10 ] = KEY_INFO,
+       [ 0x11 ] = KEY_F13,     /* 16:9 */
+       [ 0x12 ] = KEY_F14,     /* 14:9 */
+       [ 0x13 ] = KEY_EPG,
+       [ 0x14 ] = KEY_EXIT,
+       [ 0x15 ] = KEY_MENU,
+       [ 0x16 ] = KEY_UP,
+       [ 0x17 ] = KEY_DOWN,
+       [ 0x18 ] = KEY_LEFT,
+       [ 0x19 ] = KEY_RIGHT,
+       [ 0x1a ] = KEY_ENTER,
+       [ 0x1b ] = KEY_CHANNELUP,
+       [ 0x1c ] = KEY_CHANNELDOWN,
+       [ 0x1d ] = KEY_VOLUMEUP,
+       [ 0x1e ] = KEY_VOLUMEDOWN,
+       [ 0x1f ] = KEY_RED,
+       [ 0x20 ] = KEY_GREEN,
+       [ 0x21 ] = KEY_YELLOW,
+       [ 0x22 ] = KEY_BLUE,
+       [ 0x23 ] = KEY_SUBTITLE,
+       [ 0x24 ] = KEY_F15,     /* AD */
+       [ 0x25 ] = KEY_TEXT,
+       [ 0x26 ] = KEY_MUTE,
+       [ 0x27 ] = KEY_REWIND,
+       [ 0x28 ] = KEY_STOP,
+       [ 0x29 ] = KEY_PLAY,
+       [ 0x2a ] = KEY_FASTFORWARD,
+       [ 0x2b ] = KEY_F16,     /* chapter */
+       [ 0x2c ] = KEY_PAUSE,
+       [ 0x2d ] = KEY_PLAY,
+       [ 0x2e ] = KEY_RECORD,
+       [ 0x2f ] = KEY_F17,     /* picture in picture */
+       [ 0x30 ] = KEY_KPPLUS,  /* zoom in */
+       [ 0x31 ] = KEY_KPMINUS, /* zoom out */
+       [ 0x32 ] = KEY_F18,     /* capture */
+       [ 0x33 ] = KEY_F19,     /* web */
+       [ 0x34 ] = KEY_EMAIL,
+       [ 0x35 ] = KEY_PHONE,
+       [ 0x36 ] = KEY_PC
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_nebula);
+
+/* DigitalNow DNTV Live DVB-T Remote */
+IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = {
+       [ 0x00 ] = KEY_ESC,             /* 'go up a level?' */
+       /* Keys 0 to 9 */
+       [ 0x0a ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0b ] = KEY_TUNER,           /* tv/fm */
+       [ 0x0c ] = KEY_SEARCH,          /* scan */
+       [ 0x0d ] = KEY_STOP,
+       [ 0x0e ] = KEY_PAUSE,
+       [ 0x0f ] = KEY_LIST,            /* source */
+
+       [ 0x10 ] = KEY_MUTE,
+       [ 0x11 ] = KEY_REWIND,          /* backward << */
+       [ 0x12 ] = KEY_POWER,
+       [ 0x13 ] = KEY_S,                       /* snap */
+       [ 0x14 ] = KEY_AUDIO,           /* stereo */
+       [ 0x15 ] = KEY_CLEAR,           /* reset */
+       [ 0x16 ] = KEY_PLAY,
+       [ 0x17 ] = KEY_ENTER,
+       [ 0x18 ] = KEY_ZOOM,            /* full screen */
+       [ 0x19 ] = KEY_FASTFORWARD,     /* forward >> */
+       [ 0x1a ] = KEY_CHANNELUP,
+       [ 0x1b ] = KEY_VOLUMEUP,
+       [ 0x1c ] = KEY_INFO,            /* preview */
+       [ 0x1d ] = KEY_RECORD,          /* record */
+       [ 0x1e ] = KEY_CHANNELDOWN,
+       [ 0x1f ] = KEY_VOLUMEDOWN,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t);
+
+/* ---------------------------------------------------------------------- */
+
+/* IO-DATA BCTV7E Remote */
+IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = {
+       [ 0x40 ] = KEY_TV,
+       [ 0x20 ] = KEY_RADIO,           /* FM */
+       [ 0x60 ] = KEY_EPG,
+       [ 0x00 ] = KEY_POWER,
+
+       /* Keys 0 to 9 */
+       [ 0x44 ] = KEY_0,               /* 10 */
+       [ 0x50 ] = KEY_1,
+       [ 0x30 ] = KEY_2,
+       [ 0x70 ] = KEY_3,
+       [ 0x48 ] = KEY_4,
+       [ 0x28 ] = KEY_5,
+       [ 0x68 ] = KEY_6,
+       [ 0x58 ] = KEY_7,
+       [ 0x38 ] = KEY_8,
+       [ 0x78 ] = KEY_9,
+
+       [ 0x10 ] = KEY_L,                       /* Live */
+       [ 0x08 ] = KEY_T,                       /* Time Shift */
+
+       [ 0x18 ] = KEY_PLAYPAUSE,               /* Play */
+
+       [ 0x24 ] = KEY_ENTER,           /* 11 */
+       [ 0x64 ] = KEY_ESC,             /* 12 */
+       [ 0x04 ] = KEY_M,                       /* Multi */
+
+       [ 0x54 ] = KEY_VIDEO,
+       [ 0x34 ] = KEY_CHANNELUP,
+       [ 0x74 ] = KEY_VOLUMEUP,
+       [ 0x14 ] = KEY_MUTE,
+
+       [ 0x4c ] = KEY_S,                       /* SVIDEO */
+       [ 0x2c ] = KEY_CHANNELDOWN,
+       [ 0x6c ] = KEY_VOLUMEDOWN,
+       [ 0x0c ] = KEY_ZOOM,
+
+       [ 0x5c ] = KEY_PAUSE,
+       [ 0x3c ] = KEY_C,                       /* || (red) */
+       [ 0x7c ] = KEY_RECORD,          /* recording */
+       [ 0x1c ] = KEY_STOP,
+
+       [ 0x41 ] = KEY_REWIND,          /* backward << */
+       [ 0x21 ] = KEY_PLAY,
+       [ 0x61 ] = KEY_FASTFORWARD,     /* forward >> */
+       [ 0x01 ] = KEY_NEXT,            /* skip >| */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e);
+
+/* ---------------------------------------------------------------------- */
+
+/* ADS Tech Instant TV DVB-T PCI Remote */
+IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = {
+       /* Keys 0 to 9 */
+       [ 0x4d ] = KEY_0,
+       [ 0x57 ] = KEY_1,
+       [ 0x4f ] = KEY_2,
+       [ 0x53 ] = KEY_3,
+       [ 0x56 ] = KEY_4,
+       [ 0x4e ] = KEY_5,
+       [ 0x5e ] = KEY_6,
+       [ 0x54 ] = KEY_7,
+       [ 0x4c ] = KEY_8,
+       [ 0x5c ] = KEY_9,
+
+       [ 0x5b ] = KEY_POWER,
+       [ 0x5f ] = KEY_MUTE,
+       [ 0x55 ] = KEY_GOTO,
+       [ 0x5d ] = KEY_SEARCH,
+       [ 0x17 ] = KEY_EPG,             /* Guide */
+       [ 0x1f ] = KEY_MENU,
+       [ 0x0f ] = KEY_UP,
+       [ 0x46 ] = KEY_DOWN,
+       [ 0x16 ] = KEY_LEFT,
+       [ 0x1e ] = KEY_RIGHT,
+       [ 0x0e ] = KEY_SELECT,          /* Enter */
+       [ 0x5a ] = KEY_INFO,
+       [ 0x52 ] = KEY_EXIT,
+       [ 0x59 ] = KEY_PREVIOUS,
+       [ 0x51 ] = KEY_NEXT,
+       [ 0x58 ] = KEY_REWIND,
+       [ 0x50 ] = KEY_FORWARD,
+       [ 0x44 ] = KEY_PLAYPAUSE,
+       [ 0x07 ] = KEY_STOP,
+       [ 0x1b ] = KEY_RECORD,
+       [ 0x13 ] = KEY_TUNER,           /* Live */
+       [ 0x0a ] = KEY_A,
+       [ 0x12 ] = KEY_B,
+       [ 0x03 ] = KEY_PROG1,           /* 1 */
+       [ 0x01 ] = KEY_PROG2,           /* 2 */
+       [ 0x00 ] = KEY_PROG3,           /* 3 */
+       [ 0x06 ] = KEY_DVD,
+       [ 0x48 ] = KEY_AUX,             /* Photo */
+       [ 0x40 ] = KEY_VIDEO,
+       [ 0x19 ] = KEY_AUDIO,           /* Music */
+       [ 0x0b ] = KEY_CHANNELUP,
+       [ 0x08 ] = KEY_CHANNELDOWN,
+       [ 0x15 ] = KEY_VOLUMEUP,
+       [ 0x1c ] = KEY_VOLUMEDOWN,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci);
+
+/* ---------------------------------------------------------------------- */
+
+/* MSI TV@nywhere remote */
+IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
+       /* Keys 0 to 9 */
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0c ] = KEY_MUTE,
+       [ 0x0f ] = KEY_SCREEN,          /* Full Screen */
+       [ 0x10 ] = KEY_F,                       /* Funtion */
+       [ 0x11 ] = KEY_T,                       /* Time shift */
+       [ 0x12 ] = KEY_POWER,
+       [ 0x13 ] = KEY_MEDIA,           /* MTS */
+       [ 0x14 ] = KEY_SLOW,
+       [ 0x16 ] = KEY_REWIND,          /* backward << */
+       [ 0x17 ] = KEY_ENTER,           /* Return */
+       [ 0x18 ] = KEY_FASTFORWARD,     /* forward >> */
+       [ 0x1a ] = KEY_CHANNELUP,
+       [ 0x1b ] = KEY_VOLUMEUP,
+       [ 0x1e ] = KEY_CHANNELDOWN,
+       [ 0x1f ] = KEY_VOLUMEDOWN,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere);
+
+/* ---------------------------------------------------------------------- */
+
+/* Cinergy 1400 DVB-T */
+IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
+       [ 0x01 ] = KEY_POWER,
+       [ 0x02 ] = KEY_1,
+       [ 0x03 ] = KEY_2,
+       [ 0x04 ] = KEY_3,
+       [ 0x05 ] = KEY_4,
+       [ 0x06 ] = KEY_5,
+       [ 0x07 ] = KEY_6,
+       [ 0x08 ] = KEY_7,
+       [ 0x09 ] = KEY_8,
+       [ 0x0a ] = KEY_9,
+       [ 0x0c ] = KEY_0,
+
+       [ 0x0b ] = KEY_VIDEO,
+       [ 0x0d ] = KEY_REFRESH,
+       [ 0x0e ] = KEY_SELECT,
+       [ 0x0f ] = KEY_EPG,
+       [ 0x10 ] = KEY_UP,
+       [ 0x11 ] = KEY_LEFT,
+       [ 0x12 ] = KEY_OK,
+       [ 0x13 ] = KEY_RIGHT,
+       [ 0x14 ] = KEY_DOWN,
+       [ 0x15 ] = KEY_TEXT,
+       [ 0x16 ] = KEY_INFO,
+
+       [ 0x17 ] = KEY_RED,
+       [ 0x18 ] = KEY_GREEN,
+       [ 0x19 ] = KEY_YELLOW,
+       [ 0x1a ] = KEY_BLUE,
+
+       [ 0x1b ] = KEY_CHANNELUP,
+       [ 0x1c ] = KEY_VOLUMEUP,
+       [ 0x1d ] = KEY_MUTE,
+       [ 0x1e ] = KEY_VOLUMEDOWN,
+       [ 0x1f ] = KEY_CHANNELDOWN,
+
+       [ 0x40 ] = KEY_PAUSE,
+       [ 0x4c ] = KEY_PLAY,
+       [ 0x58 ] = KEY_RECORD,
+       [ 0x54 ] = KEY_PREVIOUS,
+       [ 0x48 ] = KEY_STOP,
+       [ 0x5c ] = KEY_NEXT,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400);
+
+/* ---------------------------------------------------------------------- */
+
+/* AVERTV STUDIO 303 Remote */
+IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = {
+       [ 0x2a ] = KEY_1,
+       [ 0x32 ] = KEY_2,
+       [ 0x3a ] = KEY_3,
+       [ 0x4a ] = KEY_4,
+       [ 0x52 ] = KEY_5,
+       [ 0x5a ] = KEY_6,
+       [ 0x6a ] = KEY_7,
+       [ 0x72 ] = KEY_8,
+       [ 0x7a ] = KEY_9,
+       [ 0x0e ] = KEY_0,
+
+       [ 0x02 ] = KEY_POWER,
+       [ 0x22 ] = KEY_VIDEO,
+       [ 0x42 ] = KEY_AUDIO,
+       [ 0x62 ] = KEY_ZOOM,
+       [ 0x0a ] = KEY_TV,
+       [ 0x12 ] = KEY_CD,
+       [ 0x1a ] = KEY_TEXT,
+
+       [ 0x16 ] = KEY_SUBTITLE,
+       [ 0x1e ] = KEY_REWIND,
+       [ 0x06 ] = KEY_PRINT,
+
+       [ 0x2e ] = KEY_SEARCH,
+       [ 0x36 ] = KEY_SLEEP,
+       [ 0x3e ] = KEY_SHUFFLE,
+       [ 0x26 ] = KEY_MUTE,
+
+       [ 0x4e ] = KEY_RECORD,
+       [ 0x56 ] = KEY_PAUSE,
+       [ 0x5e ] = KEY_STOP,
+       [ 0x46 ] = KEY_PLAY,
+
+       [ 0x6e ] = KEY_RED,
+       [ 0x0b ] = KEY_GREEN,
+       [ 0x66 ] = KEY_YELLOW,
+       [ 0x03 ] = KEY_BLUE,
+
+       [ 0x76 ] = KEY_LEFT,
+       [ 0x7e ] = KEY_RIGHT,
+       [ 0x13 ] = KEY_DOWN,
+       [ 0x1b ] = KEY_UP,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_avertv_303);
+
+/* ---------------------------------------------------------------------- */
+
+/* DigitalNow DNTV Live! DVB-T Pro Remote */
+IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = {
+       [ 0x16 ] = KEY_POWER,
+       [ 0x5b ] = KEY_HOME,
+
+       [ 0x55 ] = KEY_TV,              /* live tv */
+       [ 0x58 ] = KEY_TUNER,           /* digital Radio */
+       [ 0x5a ] = KEY_RADIO,           /* FM radio */
+       [ 0x59 ] = KEY_DVD,             /* dvd menu */
+       [ 0x03 ] = KEY_1,
+       [ 0x01 ] = KEY_2,
+       [ 0x06 ] = KEY_3,
+       [ 0x09 ] = KEY_4,
+       [ 0x1d ] = KEY_5,
+       [ 0x1f ] = KEY_6,
+       [ 0x0d ] = KEY_7,
+       [ 0x19 ] = KEY_8,
+       [ 0x1b ] = KEY_9,
+       [ 0x0c ] = KEY_CANCEL,
+       [ 0x15 ] = KEY_0,
+       [ 0x4a ] = KEY_CLEAR,
+       [ 0x13 ] = KEY_BACK,
+       [ 0x00 ] = KEY_TAB,
+       [ 0x4b ] = KEY_UP,
+       [ 0x4e ] = KEY_LEFT,
+       [ 0x4f ] = KEY_OK,
+       [ 0x52 ] = KEY_RIGHT,
+       [ 0x51 ] = KEY_DOWN,
+       [ 0x1e ] = KEY_VOLUMEUP,
+       [ 0x0a ] = KEY_VOLUMEDOWN,
+       [ 0x02 ] = KEY_CHANNELDOWN,
+       [ 0x05 ] = KEY_CHANNELUP,
+       [ 0x11 ] = KEY_RECORD,
+       [ 0x14 ] = KEY_PLAY,
+       [ 0x4c ] = KEY_PAUSE,
+       [ 0x1a ] = KEY_STOP,
+       [ 0x40 ] = KEY_REWIND,
+       [ 0x12 ] = KEY_FASTFORWARD,
+       [ 0x41 ] = KEY_PREVIOUSSONG,    /* replay |< */
+       [ 0x42 ] = KEY_NEXTSONG,        /* skip >| */
+       [ 0x54 ] = KEY_CAMERA,          /* capture */
+       [ 0x50 ] = KEY_LANGUAGE,        /* sap */
+       [ 0x47 ] = KEY_TV2,             /* pip */
+       [ 0x4d ] = KEY_SCREEN,
+       [ 0x43 ] = KEY_SUBTITLE,
+       [ 0x10 ] = KEY_MUTE,
+       [ 0x49 ] = KEY_AUDIO,           /* l/r */
+       [ 0x07 ] = KEY_SLEEP,
+       [ 0x08 ] = KEY_VIDEO,           /* a/v */
+       [ 0x0e ] = KEY_PREVIOUS,        /* recall */
+       [ 0x45 ] = KEY_ZOOM,            /* zoom + */
+       [ 0x46 ] = KEY_ANGLE,           /* zoom - */
+       [ 0x56 ] = KEY_RED,
+       [ 0x57 ] = KEY_GREEN,
+       [ 0x5c ] = KEY_YELLOW,
+       [ 0x5d ] = KEY_BLUE,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro);
+
+IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = {
+       [ 0x01 ] = KEY_CHANNEL,
+       [ 0x02 ] = KEY_SELECT,
+       [ 0x03 ] = KEY_MUTE,
+       [ 0x04 ] = KEY_POWER,
+       [ 0x05 ] = KEY_1,
+       [ 0x06 ] = KEY_2,
+       [ 0x07 ] = KEY_3,
+       [ 0x08 ] = KEY_CHANNELUP,
+       [ 0x09 ] = KEY_4,
+       [ 0x0a ] = KEY_5,
+       [ 0x0b ] = KEY_6,
+       [ 0x0c ] = KEY_CHANNELDOWN,
+       [ 0x0d ] = KEY_7,
+       [ 0x0e ] = KEY_8,
+       [ 0x0f ] = KEY_9,
+       [ 0x10 ] = KEY_VOLUMEUP,
+       [ 0x11 ] = KEY_0,
+       [ 0x12 ] = KEY_MENU,
+       [ 0x13 ] = KEY_PRINT,
+       [ 0x14 ] = KEY_VOLUMEDOWN,
+       [ 0x16 ] = KEY_PAUSE,
+       [ 0x18 ] = KEY_RECORD,
+       [ 0x19 ] = KEY_REWIND,
+       [ 0x1a ] = KEY_PLAY,
+       [ 0x1b ] = KEY_FORWARD,
+       [ 0x1c ] = KEY_BACKSPACE,
+       [ 0x1e ] = KEY_STOP,
+       [ 0x40 ] = KEY_ZOOM,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_em_terratec);
+
+IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = {
+       [ 0x3a ] = KEY_0,
+       [ 0x31 ] = KEY_1,
+       [ 0x32 ] = KEY_2,
+       [ 0x33 ] = KEY_3,
+       [ 0x34 ] = KEY_4,
+       [ 0x35 ] = KEY_5,
+       [ 0x36 ] = KEY_6,
+       [ 0x37 ] = KEY_7,
+       [ 0x38 ] = KEY_8,
+       [ 0x39 ] = KEY_9,
+
+       [ 0x2f ] = KEY_POWER,
+
+       [ 0x2e ] = KEY_P,
+       [ 0x1f ] = KEY_L,
+       [ 0x2b ] = KEY_I,
+
+       [ 0x2d ] = KEY_ZOOM,
+       [ 0x1e ] = KEY_ZOOM,
+       [ 0x1b ] = KEY_VOLUMEUP,
+       [ 0x0f ] = KEY_VOLUMEDOWN,
+       [ 0x17 ] = KEY_CHANNELUP,
+       [ 0x1c ] = KEY_CHANNELDOWN,
+       [ 0x25 ] = KEY_INFO,
+
+       [ 0x3c ] = KEY_MUTE,
+
+       [ 0x3d ] = KEY_LEFT,
+       [ 0x3b ] = KEY_RIGHT,
+
+       [ 0x3f ] = KEY_UP,
+       [ 0x3e ] = KEY_DOWN,
+       [ 0x1a ] = KEY_PAUSE,
+
+       [ 0x1d ] = KEY_MENU,
+       [ 0x19 ] = KEY_PLAY,
+       [ 0x16 ] = KEY_REWIND,
+       [ 0x13 ] = KEY_FORWARD,
+       [ 0x15 ] = KEY_PAUSE,
+       [ 0x0e ] = KEY_REWIND,
+       [ 0x0d ] = KEY_PLAY,
+       [ 0x0b ] = KEY_STOP,
+       [ 0x07 ] = KEY_FORWARD,
+       [ 0x27 ] = KEY_RECORD,
+       [ 0x26 ] = KEY_TUNER,
+       [ 0x29 ] = KEY_TEXT,
+       [ 0x2a ] = KEY_MEDIA,
+       [ 0x18 ] = KEY_EPG,
+       [ 0x27 ] = KEY_RECORD,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_em_pinnacle_usb);
+
+IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = {
+       [ 0x0f ] = KEY_0,
+       [ 0x03 ] = KEY_1,
+       [ 0x04 ] = KEY_2,
+       [ 0x05 ] = KEY_3,
+       [ 0x07 ] = KEY_4,
+       [ 0x08 ] = KEY_5,
+       [ 0x09 ] = KEY_6,
+       [ 0x0b ] = KEY_7,
+       [ 0x0c ] = KEY_8,
+       [ 0x0d ] = KEY_9,
+
+       [ 0x0e ] = KEY_MODE,         // Air/Cable
+       [ 0x11 ] = KEY_VIDEO,        // Video
+       [ 0x15 ] = KEY_AUDIO,        // Audio
+       [ 0x00 ] = KEY_POWER,        // Power
+       [ 0x18 ] = KEY_TUNER,        // AV Source
+       [ 0x02 ] = KEY_ZOOM,         // Fullscreen
+       [ 0x1a ] = KEY_LANGUAGE,     // Stereo
+       [ 0x1b ] = KEY_MUTE,         // Mute
+       [ 0x14 ] = KEY_VOLUMEUP,     // Volume +
+       [ 0x17 ] = KEY_VOLUMEDOWN,   // Volume -
+       [ 0x12 ] = KEY_CHANNELUP,    // Channel +
+       [ 0x13 ] = KEY_CHANNELDOWN,  // Channel -
+       [ 0x06 ] = KEY_AGAIN,        // Recall
+       [ 0x10 ] = KEY_ENTER,      // Enter
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_flyvideo);
+
+IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE] = {
+       [ 0x01 ] = KEY_ZOOM,            // Full Screen
+       [ 0x00 ] = KEY_POWER,           // Power
+
+       [ 0x03 ] = KEY_1,
+       [ 0x04 ] = KEY_2,
+       [ 0x05 ] = KEY_3,
+       [ 0x07 ] = KEY_4,
+       [ 0x08 ] = KEY_5,
+       [ 0x09 ] = KEY_6,
+       [ 0x0b ] = KEY_7,
+       [ 0x0c ] = KEY_8,
+       [ 0x0d ] = KEY_9,
+       [ 0x06 ] = KEY_AGAIN,           // Recall
+       [ 0x0f ] = KEY_0,
+       [ 0x10 ] = KEY_MUTE,            // Mute
+       [ 0x02 ] = KEY_RADIO,           // TV/Radio
+       [ 0x1b ] = KEY_LANGUAGE,                // SAP (Second Audio Program)
+
+       [ 0x14 ] = KEY_VOLUMEUP,                // VOL+
+       [ 0x17 ] = KEY_VOLUMEDOWN,      // VOL-
+       [ 0x12 ] = KEY_CHANNELUP,               // CH+
+       [ 0x13 ] = KEY_CHANNELDOWN,     // CH-
+       [ 0x1d ] = KEY_ENTER,           // Enter
+
+       [ 0x1a ] = KEY_MODE,            // PIP
+       [ 0x18 ] = KEY_TUNER,           // Source
+
+       [ 0x1e ] = KEY_RECORD,          // Record/Pause
+       [ 0x15 ] = KEY_ANGLE,           // Swap (no label on key)
+       [ 0x1c ] = KEY_PAUSE,           // Timeshift/Pause
+       [ 0x19 ] = KEY_BACK,            // Rewind <<
+       [ 0x0a ] = KEY_PLAYPAUSE,               // Play/Pause
+       [ 0x1f ] = KEY_FORWARD,         // Forward >>
+       [ 0x16 ] = KEY_PREVIOUS,                // Back |<<
+       [ 0x11 ] = KEY_STOP,            // Stop
+       [ 0x0e ] = KEY_NEXT,            // End >>|
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_flydvb);
+
+IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE] = {
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0a ] = KEY_POWER,
+       [ 0x0b ] = KEY_PROG1,           // app
+       [ 0x0c ] = KEY_ZOOM,            // zoom/fullscreen
+       [ 0x0d ] = KEY_CHANNELUP,       // channel
+       [ 0x0e ] = KEY_CHANNELDOWN,     // channel-
+       [ 0x0f ] = KEY_VOLUMEUP,
+       [ 0x10 ] = KEY_VOLUMEDOWN,
+       [ 0x11 ] = KEY_TUNER,           // AV
+       [ 0x12 ] = KEY_NUMLOCK,         // -/--
+       [ 0x13 ] = KEY_AUDIO,           // audio
+       [ 0x14 ] = KEY_MUTE,
+       [ 0x15 ] = KEY_UP,
+       [ 0x16 ] = KEY_DOWN,
+       [ 0x17 ] = KEY_LEFT,
+       [ 0x18 ] = KEY_RIGHT,
+       [ 0x19 ] = BTN_LEFT,
+       [ 0x1a ] = BTN_RIGHT,
+       [ 0x1b ] = KEY_WWW,             // text
+       [ 0x1c ] = KEY_REWIND,
+       [ 0x1d ] = KEY_FORWARD,
+       [ 0x1e ] = KEY_RECORD,
+       [ 0x1f ] = KEY_PLAY,
+       [ 0x20 ] = KEY_PREVIOUSSONG,
+       [ 0x21 ] = KEY_NEXTSONG,
+       [ 0x22 ] = KEY_PAUSE,
+       [ 0x23 ] = KEY_STOP,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_cinergy);
+
+/* Alfons Geser <a.geser@cox.net>
+ * updates from Job D. R. Borges <jobdrb@ig.com.br> */
+IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE] = {
+       [ 0x12 ] = KEY_POWER,
+       [ 0x01 ] = KEY_TV,             // DVR
+       [ 0x15 ] = KEY_DVD,            // DVD
+       [ 0x17 ] = KEY_AUDIO,          // music
+                                    // DVR mode / DVD mode / music mode
+
+       [ 0x1b ] = KEY_MUTE,           // mute
+       [ 0x02 ] = KEY_LANGUAGE,       // MTS/SAP / audio / autoseek
+       [ 0x1e ] = KEY_SUBTITLE,       // closed captioning / subtitle / seek
+       [ 0x16 ] = KEY_ZOOM,           // full screen
+       [ 0x1c ] = KEY_VIDEO,          // video source / eject / delall
+       [ 0x1d ] = KEY_RESTART,        // playback / angle / del
+       [ 0x2f ] = KEY_SEARCH,         // scan / menu / playlist
+       [ 0x30 ] = KEY_CHANNEL,        // CH surfing / bookmark / memo
+
+       [ 0x31 ] = KEY_HELP,           // help
+       [ 0x32 ] = KEY_MODE,           // num/memo
+       [ 0x33 ] = KEY_ESC,            // cancel
+
+       [ 0x0c ] = KEY_UP,             // up
+       [ 0x10 ] = KEY_DOWN,           // down
+       [ 0x08 ] = KEY_LEFT,           // left
+       [ 0x04 ] = KEY_RIGHT,          // right
+       [ 0x03 ] = KEY_SELECT,         // select
+
+       [ 0x1f ] = KEY_REWIND,         // rewind
+       [ 0x20 ] = KEY_PLAYPAUSE,      // play/pause
+       [ 0x29 ] = KEY_FORWARD,        // forward
+       [ 0x14 ] = KEY_AGAIN,          // repeat
+       [ 0x2b ] = KEY_RECORD,         // recording
+       [ 0x2c ] = KEY_STOP,           // stop
+       [ 0x2d ] = KEY_PLAY,           // play
+       [ 0x2e ] = KEY_SHUFFLE,        // snapshot / shuffle
+
+       [ 0x00 ] = KEY_0,
+       [ 0x05 ] = KEY_1,
+       [ 0x06 ] = KEY_2,
+       [ 0x07 ] = KEY_3,
+       [ 0x09 ] = KEY_4,
+       [ 0x0a ] = KEY_5,
+       [ 0x0b ] = KEY_6,
+       [ 0x0d ] = KEY_7,
+       [ 0x0e ] = KEY_8,
+       [ 0x0f ] = KEY_9,
+
+       [ 0x2a ] = KEY_VOLUMEUP,
+       [ 0x11 ] = KEY_VOLUMEDOWN,
+       [ 0x18 ] = KEY_CHANNELUP,      // CH.tracking up
+       [ 0x19 ] = KEY_CHANNELDOWN,    // CH.tracking down
+
+       [ 0x13 ] = KEY_ENTER,        // enter
+       [ 0x21 ] = KEY_DOT,          // . (decimal dot)
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_eztv);
+
+/* Alex Hermann <gaaf@gmx.net> */
+IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = {
+       [ 0x28 ] = KEY_1,
+       [ 0x18 ] = KEY_2,
+       [ 0x38 ] = KEY_3,
+       [ 0x24 ] = KEY_4,
+       [ 0x14 ] = KEY_5,
+       [ 0x34 ] = KEY_6,
+       [ 0x2c ] = KEY_7,
+       [ 0x1c ] = KEY_8,
+       [ 0x3c ] = KEY_9,
+       [ 0x22 ] = KEY_0,
+
+       [ 0x20 ] = KEY_TV,              /* TV/FM */
+       [ 0x10 ] = KEY_CD,              /* CD */
+       [ 0x30 ] = KEY_TEXT,            /* TELETEXT */
+       [ 0x00 ] = KEY_POWER,           /* POWER */
+
+       [ 0x08 ] = KEY_VIDEO,           /* VIDEO */
+       [ 0x04 ] = KEY_AUDIO,           /* AUDIO */
+       [ 0x0c ] = KEY_ZOOM,            /* FULL SCREEN */
+
+       [ 0x12 ] = KEY_SUBTITLE,        /* DISPLAY */
+       [ 0x32 ] = KEY_REWIND,          /* LOOP */
+       [ 0x02 ] = KEY_PRINT,           /* PREVIEW */
+
+       [ 0x2a ] = KEY_SEARCH,          /* AUTOSCAN */
+       [ 0x1a ] = KEY_SLEEP,           /* FREEZE */
+       [ 0x3a ] = KEY_SHUFFLE,         /* SNAPSHOT */
+       [ 0x0a ] = KEY_MUTE,            /* MUTE */
+
+       [ 0x26 ] = KEY_RECORD,          /* RECORD */
+       [ 0x16 ] = KEY_PAUSE,           /* PAUSE */
+       [ 0x36 ] = KEY_STOP,            /* STOP */
+       [ 0x06 ] = KEY_PLAY,            /* PLAY */
+
+       [ 0x2e ] = KEY_RED,             /* RED */
+       [ 0x21 ] = KEY_GREEN,           /* GREEN */
+       [ 0x0e ] = KEY_YELLOW,          /* YELLOW */
+       [ 0x01 ] = KEY_BLUE,            /* BLUE */
+
+       [ 0x1e ] = KEY_VOLUMEDOWN,      /* VOLUME- */
+       [ 0x3e ] = KEY_VOLUMEUP,        /* VOLUME+ */
+       [ 0x11 ] = KEY_CHANNELDOWN,     /* CHANNEL/PAGE- */
+       [ 0x31 ] = KEY_CHANNELUP        /* CHANNEL/PAGE+ */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_avermedia);
+
+IR_KEYTAB_TYPE ir_codes_videomate_tv_pvr[IR_KEYTAB_SIZE] = {
+       [ 0x14 ] = KEY_MUTE,
+       [ 0x24 ] = KEY_ZOOM,
+
+       [ 0x01 ] = KEY_DVD,
+       [ 0x23 ] = KEY_RADIO,
+       [ 0x00 ] = KEY_TV,
+
+       [ 0x0a ] = KEY_REWIND,
+       [ 0x08 ] = KEY_PLAYPAUSE,
+       [ 0x0f ] = KEY_FORWARD,
+
+       [ 0x02 ] = KEY_PREVIOUS,
+       [ 0x07 ] = KEY_STOP,
+       [ 0x06 ] = KEY_NEXT,
+
+       [ 0x0c ] = KEY_UP,
+       [ 0x0e ] = KEY_DOWN,
+       [ 0x0b ] = KEY_LEFT,
+       [ 0x0d ] = KEY_RIGHT,
+       [ 0x11 ] = KEY_OK,
+
+       [ 0x03 ] = KEY_MENU,
+       [ 0x09 ] = KEY_SETUP,
+       [ 0x05 ] = KEY_VIDEO,
+       [ 0x22 ] = KEY_CHANNEL,
+
+       [ 0x12 ] = KEY_VOLUMEUP,
+       [ 0x15 ] = KEY_VOLUMEDOWN,
+       [ 0x10 ] = KEY_CHANNELUP,
+       [ 0x13 ] = KEY_CHANNELDOWN,
+
+       [ 0x04 ] = KEY_RECORD,
+
+       [ 0x16 ] = KEY_1,
+       [ 0x17 ] = KEY_2,
+       [ 0x18 ] = KEY_3,
+       [ 0x19 ] = KEY_4,
+       [ 0x1a ] = KEY_5,
+       [ 0x1b ] = KEY_6,
+       [ 0x1c ] = KEY_7,
+       [ 0x1d ] = KEY_8,
+       [ 0x1e ] = KEY_9,
+       [ 0x1f ] = KEY_0,
+
+       [ 0x20 ] = KEY_LANGUAGE,
+       [ 0x21 ] = KEY_SLEEP,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr);
+
+/* Michael Tokarev <mjt@tls.msk.ru>
+   http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
+   keytable is used by MANLI MTV00[ 0x0c ] and BeholdTV 40[13] at
+   least, and probably other cards too.
+   The "ascii-art picture" below (in comments, first row
+   is the keycode in hex, and subsequent row(s) shows
+   the button labels (several variants when appropriate)
+   helps to descide which keycodes to assign to the buttons.
+ */
+IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = {
+
+       /*  0x1c            0x12  *
+        * FUNCTION         POWER *
+        *   FM              (|)  *
+        *                        */
+       [ 0x1c ] = KEY_RADIO,   /*XXX*/
+       [ 0x12 ] = KEY_POWER,
+
+       /*  0x01    0x02    0x03  *
+        *   1       2       3    *
+        *                        *
+        *  0x04    0x05    0x06  *
+        *   4       5       6    *
+        *                        *
+        *  0x07    0x08    0x09  *
+        *   7       8       9    *
+        *                        */
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       /*  0x0a    0x00    0x17  *
+        * RECALL    0      +100  *
+        *                  PLUS  *
+        *                        */
+       [ 0x0a ] = KEY_AGAIN,   /*XXX KEY_REWIND? */
+       [ 0x00 ] = KEY_0,
+       [ 0x17 ] = KEY_DIGITS,  /*XXX*/
+
+       /*  0x14            0x10  *
+        *  MENU            INFO  *
+        *  OSD                   */
+       [ 0x14 ] = KEY_MENU,
+       [ 0x10 ] = KEY_INFO,
+
+       /*          0x0b          *
+        *           Up           *
+        *                        *
+        *  0x18    0x16    0x0c  *
+        *  Left     Ok     Right *
+        *                        *
+        *         0x015          *
+        *         Down           *
+        *                        */
+       [ 0x0b ] = KEY_UP,      /*XXX KEY_SCROLLUP? */
+       [ 0x18 ] = KEY_LEFT,    /*XXX KEY_BACK? */
+       [ 0x16 ] = KEY_OK,      /*XXX KEY_SELECT? KEY_ENTER? */
+       [ 0x0c ] = KEY_RIGHT,   /*XXX KEY_FORWARD? */
+       [ 0x15 ] = KEY_DOWN,    /*XXX KEY_SCROLLDOWN? */
+
+       /*  0x11            0x0d  *
+        *  TV/AV           MODE  *
+        *  SOURCE         STEREO *
+        *                        */
+       [ 0x11 ] = KEY_TV,      /*XXX*/
+       [ 0x0d ] = KEY_MODE,    /*XXX there's no KEY_STEREO */
+
+       /*  0x0f    0x1b    0x1a  *
+        *  AUDIO   Vol+    Chan+ *
+        *        TIMESHIFT???    *
+        *                        *
+        *  0x0e    0x1f    0x1e  *
+        *  SLEEP   Vol-    Chan- *
+        *                        */
+       [ 0x0f ] = KEY_AUDIO,
+       [ 0x1b ] = KEY_VOLUMEUP,
+       [ 0x1a ] = KEY_CHANNELUP,
+       [ 0x0e ] = KEY_SLEEP,   /*XXX maybe KEY_PAUSE */
+       [ 0x1f ] = KEY_VOLUMEDOWN,
+       [ 0x1e ] = KEY_CHANNELDOWN,
+
+       /*         0x13     0x19  *
+        *         MUTE   SNAPSHOT*
+        *                        */
+       [ 0x13 ] = KEY_MUTE,
+       [ 0x19 ] = KEY_RECORD,  /*XXX*/
+
+       // 0x1d unused ?
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_manli);
+
+/* Mike Baikov <mike@baikov.com> */
+IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE] = {
+
+       [ 0x21 ] = KEY_POWER,
+       [ 0x69 ] = KEY_TV,
+       [ 0x33 ] = KEY_0,
+       [ 0x51 ] = KEY_1,
+       [ 0x31 ] = KEY_2,
+       [ 0x71 ] = KEY_3,
+       [ 0x3b ] = KEY_4,
+       [ 0x58 ] = KEY_5,
+       [ 0x41 ] = KEY_6,
+       [ 0x48 ] = KEY_7,
+       [ 0x30 ] = KEY_8,
+       [ 0x53 ] = KEY_9,
+       [ 0x73 ] = KEY_AGAIN, /* LOOP */
+       [ 0x0a ] = KEY_AUDIO,
+       [ 0x61 ] = KEY_PRINT, /* PREVIEW */
+       [ 0x7a ] = KEY_VIDEO,
+       [ 0x20 ] = KEY_CHANNELUP,
+       [ 0x40 ] = KEY_CHANNELDOWN,
+       [ 0x18 ] = KEY_VOLUMEDOWN,
+       [ 0x50 ] = KEY_VOLUMEUP,
+       [ 0x10 ] = KEY_MUTE,
+       [ 0x4a ] = KEY_SEARCH,
+       [ 0x7b ] = KEY_SHUFFLE, /* SNAPSHOT */
+       [ 0x22 ] = KEY_RECORD,
+       [ 0x62 ] = KEY_STOP,
+       [ 0x78 ] = KEY_PLAY,
+       [ 0x39 ] = KEY_REWIND,
+       [ 0x59 ] = KEY_PAUSE,
+       [ 0x19 ] = KEY_FORWARD,
+       [ 0x09 ] = KEY_ZOOM,
+
+       [ 0x52 ] = KEY_F21, /* LIVE TIMESHIFT */
+       [ 0x1a ] = KEY_F22, /* MIN TIMESHIFT */
+       [ 0x3a ] = KEY_F23, /* TIMESHIFT */
+       [ 0x70 ] = KEY_F24, /* NORMAL TIMESHIFT */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_gotview7135);
+
+IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
+       [ 0x03 ] = KEY_POWER,
+       [ 0x6f ] = KEY_MUTE,
+       [ 0x10 ] = KEY_BACKSPACE,       /* Recall */
+
+       [ 0x11 ] = KEY_0,
+       [ 0x04 ] = KEY_1,
+       [ 0x05 ] = KEY_2,
+       [ 0x06 ] = KEY_3,
+       [ 0x08 ] = KEY_4,
+       [ 0x09 ] = KEY_5,
+       [ 0x0a ] = KEY_6,
+       [ 0x0c ] = KEY_7,
+       [ 0x0d ] = KEY_8,
+       [ 0x0e ] = KEY_9,
+       [ 0x12 ] = KEY_DOT,           /* 100+ */
+
+       [ 0x07 ] = KEY_VOLUMEUP,
+       [ 0x0b ] = KEY_VOLUMEDOWN,
+       [ 0x1a ] = KEY_KPPLUS,
+       [ 0x18 ] = KEY_KPMINUS,
+       [ 0x15 ] = KEY_UP,
+       [ 0x1d ] = KEY_DOWN,
+       [ 0x0f ] = KEY_CHANNELUP,
+       [ 0x13 ] = KEY_CHANNELDOWN,
+       [ 0x48 ] = KEY_ZOOM,
+
+       [ 0x1b ] = KEY_VIDEO,           /* Video source */
+       [ 0x49 ] = KEY_LANGUAGE,        /* MTS Select */
+       [ 0x19 ] = KEY_SEARCH,          /* Auto Scan */
+
+       [ 0x4b ] = KEY_RECORD,
+       [ 0x46 ] = KEY_PLAY,
+       [ 0x45 ] = KEY_PAUSE,           /* Pause */
+       [ 0x44 ] = KEY_STOP,
+       [ 0x40 ] = KEY_FORWARD,         /* Forward ? */
+       [ 0x42 ] = KEY_REWIND,          /* Backward ? */
+
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_purpletv);
+
+/* Mapping for the 28 key remote control as seen at
+   http://www.sednacomputer.com/photo/cardbus-tv.jpg
+   Pavel Mihaylov <bin@bash.info> */
+IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE] = {
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0a ] = KEY_AGAIN,          /* Recall */
+       [ 0x0b ] = KEY_CHANNELUP,
+       [ 0x0c ] = KEY_VOLUMEUP,
+       [ 0x0d ] = KEY_MODE,           /* Stereo */
+       [ 0x0e ] = KEY_STOP,
+       [ 0x0f ] = KEY_PREVIOUSSONG,
+       [ 0x10 ] = KEY_ZOOM,
+       [ 0x11 ] = KEY_TUNER,          /* Source */
+       [ 0x12 ] = KEY_POWER,
+       [ 0x13 ] = KEY_MUTE,
+       [ 0x15 ] = KEY_CHANNELDOWN,
+       [ 0x18 ] = KEY_VOLUMEDOWN,
+       [ 0x19 ] = KEY_SHUFFLE,        /* Snapshot */
+       [ 0x1a ] = KEY_NEXTSONG,
+       [ 0x1b ] = KEY_TEXT,           /* Time Shift */
+       [ 0x1c ] = KEY_RADIO,          /* FM Radio */
+       [ 0x1d ] = KEY_RECORD,
+       [ 0x1e ] = KEY_PAUSE,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna);
+
+/* Mark Phalan <phalanm@o2.ie> */
+IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x12 ] = KEY_POWER,
+       [ 0x10 ] = KEY_MUTE,
+       [ 0x1f ] = KEY_VOLUMEDOWN,
+       [ 0x1b ] = KEY_VOLUMEUP,
+       [ 0x1a ] = KEY_CHANNELUP,
+       [ 0x1e ] = KEY_CHANNELDOWN,
+       [ 0x0e ] = KEY_PAGEUP,
+       [ 0x1d ] = KEY_PAGEDOWN,
+       [ 0x13 ] = KEY_SOUND,
+
+       [ 0x18 ] = KEY_KPPLUSMINUS,     /* CH +/- */
+       [ 0x16 ] = KEY_SUBTITLE,                /* CC */
+       [ 0x0d ] = KEY_TEXT,            /* TTX */
+       [ 0x0b ] = KEY_TV,              /* AIR/CBL */
+       [ 0x11 ] = KEY_PC,              /* PC/TV */
+       [ 0x17 ] = KEY_OK,              /* CH RTN */
+       [ 0x19 ] = KEY_MODE,            /* FUNC */
+       [ 0x0c ] = KEY_SEARCH,          /* AUTOSCAN */
+
+       /* Not sure what to do with these ones! */
+       [ 0x0f ] = KEY_SELECT,          /* SOURCE */
+       [ 0x0a ] = KEY_KPPLUS,          /* +100 */
+       [ 0x14 ] = KEY_EQUAL,           /* SYNC */
+       [ 0x1c ] = KEY_MEDIA,             /* PC/TV */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_pv951);
+
+/* generic RC5 keytable                                          */
+/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
+/* used by old (black) Hauppauge remotes                         */
+IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = {
+       /* Keys 0 to 9 */
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0b ] = KEY_CHANNEL,         /* channel / program (japan: 11) */
+       [ 0x0c ] = KEY_POWER,           /* standby */
+       [ 0x0d ] = KEY_MUTE,            /* mute / demute */
+       [ 0x0f ] = KEY_TV,              /* display */
+       [ 0x10 ] = KEY_VOLUMEUP,
+       [ 0x11 ] = KEY_VOLUMEDOWN,
+       [ 0x12 ] = KEY_BRIGHTNESSUP,
+       [ 0x13 ] = KEY_BRIGHTNESSDOWN,
+       [ 0x1e ] = KEY_SEARCH,          /* search + */
+       [ 0x20 ] = KEY_CHANNELUP,       /* channel / program + */
+       [ 0x21 ] = KEY_CHANNELDOWN,     /* channel / program - */
+       [ 0x22 ] = KEY_CHANNEL,         /* alt / channel */
+       [ 0x23 ] = KEY_LANGUAGE,        /* 1st / 2nd language */
+       [ 0x26 ] = KEY_SLEEP,           /* sleeptimer */
+       [ 0x2e ] = KEY_MENU,            /* 2nd controls (USA: menu) */
+       [ 0x30 ] = KEY_PAUSE,
+       [ 0x32 ] = KEY_REWIND,
+       [ 0x33 ] = KEY_GOTO,
+       [ 0x35 ] = KEY_PLAY,
+       [ 0x36 ] = KEY_STOP,
+       [ 0x37 ] = KEY_RECORD,          /* recording */
+       [ 0x3c ] = KEY_TEXT,            /* teletext submode (Japan: 12) */
+       [ 0x3d ] = KEY_SUSPEND,         /* system standby */
+
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_rc5_tv);
+
+/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
+IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
+       /* Keys 0 to 9 */
+       [ 0x12 ] = KEY_0,
+       [ 0x05 ] = KEY_1,
+       [ 0x06 ] = KEY_2,
+       [ 0x07 ] = KEY_3,
+       [ 0x09 ] = KEY_4,
+       [ 0x0a ] = KEY_5,
+       [ 0x0b ] = KEY_6,
+       [ 0x0d ] = KEY_7,
+       [ 0x0e ] = KEY_8,
+       [ 0x0f ] = KEY_9,
+
+       [ 0x00 ] = KEY_POWER,
+       [ 0x02 ] = KEY_TUNER,           /* TV/FM */
+       [ 0x1e ] = KEY_VIDEO,
+       [ 0x04 ] = KEY_VOLUMEUP,
+       [ 0x08 ] = KEY_VOLUMEDOWN,
+       [ 0x0c ] = KEY_CHANNELUP,
+       [ 0x10 ] = KEY_CHANNELDOWN,
+       [ 0x03 ] = KEY_ZOOM,            /* fullscreen */
+       [ 0x1f ] = KEY_SUBTITLE,                /* closed caption/teletext */
+       [ 0x20 ] = KEY_SLEEP,
+       [ 0x14 ] = KEY_MUTE,
+       [ 0x2b ] = KEY_RED,
+       [ 0x2c ] = KEY_GREEN,
+       [ 0x2d ] = KEY_YELLOW,
+       [ 0x2e ] = KEY_BLUE,
+       [ 0x18 ] = KEY_KPPLUS,          /* fine tune + */
+       [ 0x19 ] = KEY_KPMINUS,         /* fine tune - */
+       [ 0x21 ] = KEY_DOT,
+       [ 0x13 ] = KEY_ENTER,
+       [ 0x22 ] = KEY_BACK,
+       [ 0x23 ] = KEY_PLAYPAUSE,
+       [ 0x24 ] = KEY_NEXT,
+       [ 0x26 ] = KEY_STOP,
+       [ 0x27 ] = KEY_RECORD
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_winfast);
+
+IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
+       [ 0x59 ] = KEY_MUTE,
+       [ 0x4a ] = KEY_POWER,
+
+       [ 0x18 ] = KEY_TEXT,
+       [ 0x26 ] = KEY_TV,
+       [ 0x3d ] = KEY_PRINT,
+
+       [ 0x48 ] = KEY_RED,
+       [ 0x04 ] = KEY_GREEN,
+       [ 0x11 ] = KEY_YELLOW,
+       [ 0x00 ] = KEY_BLUE,
+
+       [ 0x2d ] = KEY_VOLUMEUP,
+       [ 0x1e ] = KEY_VOLUMEDOWN,
+
+       [ 0x49 ] = KEY_MENU,
+
+       [ 0x16 ] = KEY_CHANNELUP,
+       [ 0x17 ] = KEY_CHANNELDOWN,
+
+       [ 0x20 ] = KEY_UP,
+       [ 0x21 ] = KEY_DOWN,
+       [ 0x22 ] = KEY_LEFT,
+       [ 0x23 ] = KEY_RIGHT,
+       [ 0x0d ] = KEY_SELECT,
+
+
+
+       [ 0x08 ] = KEY_BACK,
+       [ 0x07 ] = KEY_REFRESH,
+
+       [ 0x2f ] = KEY_ZOOM,
+       [ 0x29 ] = KEY_RECORD,
+
+       [ 0x4b ] = KEY_PAUSE,
+       [ 0x4d ] = KEY_REWIND,
+       [ 0x2e ] = KEY_PLAY,
+       [ 0x4e ] = KEY_FORWARD,
+       [ 0x53 ] = KEY_PREVIOUS,
+       [ 0x4c ] = KEY_STOP,
+       [ 0x54 ] = KEY_NEXT,
+
+       [ 0x69 ] = KEY_0,
+       [ 0x6a ] = KEY_1,
+       [ 0x6b ] = KEY_2,
+       [ 0x6c ] = KEY_3,
+       [ 0x6d ] = KEY_4,
+       [ 0x6e ] = KEY_5,
+       [ 0x6f ] = KEY_6,
+       [ 0x70 ] = KEY_7,
+       [ 0x71 ] = KEY_8,
+       [ 0x72 ] = KEY_9,
+
+       [ 0x74 ] = KEY_CHANNEL,
+       [ 0x0a ] = KEY_BACKSPACE,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_pinnacle);
+
+/* Hauppauge: the newer, gray remotes (seems there are multiple
+ * slightly different versions), shipped with cx88+ivtv cards.
+ * almost rc5 coding, but some non-standard keys */
+IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
+       /* Keys 0 to 9 */
+       [ 0x00 ] = KEY_0,
+       [ 0x01 ] = KEY_1,
+       [ 0x02 ] = KEY_2,
+       [ 0x03 ] = KEY_3,
+       [ 0x04 ] = KEY_4,
+       [ 0x05 ] = KEY_5,
+       [ 0x06 ] = KEY_6,
+       [ 0x07 ] = KEY_7,
+       [ 0x08 ] = KEY_8,
+       [ 0x09 ] = KEY_9,
+
+       [ 0x0a ] = KEY_TEXT,            /* keypad asterisk as well */
+       [ 0x0b ] = KEY_RED,             /* red button */
+       [ 0x0c ] = KEY_RADIO,
+       [ 0x0d ] = KEY_MENU,
+       [ 0x0e ] = KEY_SUBTITLE,        /* also the # key */
+       [ 0x0f ] = KEY_MUTE,
+       [ 0x10 ] = KEY_VOLUMEUP,
+       [ 0x11 ] = KEY_VOLUMEDOWN,
+       [ 0x12 ] = KEY_PREVIOUS,        /* previous channel */
+       [ 0x14 ] = KEY_UP,
+       [ 0x15 ] = KEY_DOWN,
+       [ 0x16 ] = KEY_LEFT,
+       [ 0x17 ] = KEY_RIGHT,
+       [ 0x18 ] = KEY_VIDEO,           /* Videos */
+       [ 0x19 ] = KEY_AUDIO,           /* Music */
+       /* 0x1a: Pictures - presume this means
+          "Multimedia Home Platform" -
+          no "PICTURES" key in input.h
+        */
+       [ 0x1a ] = KEY_MHP,
+
+       [ 0x1b ] = KEY_EPG,             /* Guide */
+       [ 0x1c ] = KEY_TV,
+       [ 0x1e ] = KEY_NEXTSONG,        /* skip >| */
+       [ 0x1f ] = KEY_EXIT,            /* back/exit */
+       [ 0x20 ] = KEY_CHANNELUP,       /* channel / program + */
+       [ 0x21 ] = KEY_CHANNELDOWN,     /* channel / program - */
+       [ 0x22 ] = KEY_CHANNEL,         /* source (old black remote) */
+       [ 0x24 ] = KEY_PREVIOUSSONG,    /* replay |< */
+       [ 0x25 ] = KEY_ENTER,           /* OK */
+       [ 0x26 ] = KEY_SLEEP,           /* minimize (old black remote) */
+       [ 0x29 ] = KEY_BLUE,            /* blue key */
+       [ 0x2e ] = KEY_GREEN,           /* green button */
+       [ 0x30 ] = KEY_PAUSE,           /* pause */
+       [ 0x32 ] = KEY_REWIND,          /* backward << */
+       [ 0x34 ] = KEY_FASTFORWARD,     /* forward >> */
+       [ 0x35 ] = KEY_PLAY,
+       [ 0x36 ] = KEY_STOP,
+       [ 0x37 ] = KEY_RECORD,          /* recording */
+       [ 0x38 ] = KEY_YELLOW,          /* yellow key */
+       [ 0x3b ] = KEY_SELECT,          /* top right button */
+       [ 0x3c ] = KEY_ZOOM,            /* full */
+       [ 0x3d ] = KEY_POWER,           /* system power (green button) */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new);
+
index 04c1938b9c918f9330c27627f8dde1a7e21c3696..8cdd4d265ffa235bb69a57f7a57679b6e0827e72 100644 (file)
@@ -21,7 +21,7 @@
 #include <media/saa7146.h>
 
 LIST_HEAD(saa7146_devices);
-DECLARE_MUTEX(saa7146_devices_lock);
+DEFINE_MUTEX(saa7146_devices_lock);
 
 static int saa7146_num;
 
@@ -116,8 +116,7 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
                pg = vmalloc_to_page(virt);
                if (NULL == pg)
                        goto err;
-               if (PageHighMem(pg))
-                       BUG();
+               BUG_ON(PageHighMem(pg));
                sglist[i].page   = pg;
                sglist[i].length = PAGE_SIZE;
        }
@@ -402,11 +401,11 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
 
        pci_set_drvdata(pci, dev);
 
-       init_MUTEX(&dev->lock);
+       mutex_init(&dev->lock);
        spin_lock_init(&dev->int_slock);
        spin_lock_init(&dev->slock);
 
-       init_MUTEX(&dev->i2c_lock);
+       mutex_init(&dev->i2c_lock);
 
        dev->module = THIS_MODULE;
        init_waitqueue_head(&dev->i2c_wq);
index f8cf73ed49ad683e62119b34de9f5a857d44549d..3870fa948cc08356a5ec1a8a5bed2b7eadbb941d 100644 (file)
@@ -17,18 +17,18 @@ int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit)
        }
 
        /* is it free? */
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        if (vv->resources & bit) {
                DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit));
                /* no, someone else uses it */
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        }
        /* it's free, grab it */
        fh->resources  |= bit;
        vv->resources |= bit;
        DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources));
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
        return 1;
 }
 
@@ -37,14 +37,13 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
        struct saa7146_dev *dev = fh->dev;
        struct saa7146_vv *vv = dev->vv_data;
 
-       if ((fh->resources & bits) != bits)
-               BUG();
+       BUG_ON((fh->resources & bits) != bits);
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        fh->resources  &= ~bits;
        vv->resources &= ~bits;
        DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources));
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 }
 
 
@@ -55,8 +54,7 @@ void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf)
 {
        DEB_EE(("dev:%p, buf:%p\n",dev,buf));
 
-       if (in_interrupt())
-               BUG();
+       BUG_ON(in_interrupt());
 
        videobuf_waiton(&buf->vb,0,0);
        videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
@@ -204,7 +202,7 @@ static int fops_open(struct inode *inode, struct file *file)
 
        DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor));
 
-       if (down_interruptible(&saa7146_devices_lock))
+       if (mutex_lock_interruptible(&saa7146_devices_lock))
                return -ERESTARTSYS;
 
        list_for_each(list,&saa7146_devices) {
@@ -276,7 +274,7 @@ out:
                kfree(fh);
                file->private_data = NULL;
        }
-       up(&saa7146_devices_lock);
+       mutex_unlock(&saa7146_devices_lock);
        return result;
 }
 
@@ -287,7 +285,7 @@ static int fops_release(struct inode *inode, struct file *file)
 
        DEB_EE(("inode:%p, file:%p\n",inode,file));
 
-       if (down_interruptible(&saa7146_devices_lock))
+       if (mutex_lock_interruptible(&saa7146_devices_lock))
                return -ERESTARTSYS;
 
        if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
@@ -303,7 +301,7 @@ static int fops_release(struct inode *inode, struct file *file)
        file->private_data = NULL;
        kfree(fh);
 
-       up(&saa7146_devices_lock);
+       mutex_unlock(&saa7146_devices_lock);
 
        return 0;
 }
index 8aabdd8fb3c53a5b928fa78ff3e1a3b9d9fd19c1..d9953f7a8b6b924eb13964624021593252a850cb 100644 (file)
@@ -279,7 +279,7 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, in
        int address_err = 0;
        int short_delay = 0;
 
-       if (down_interruptible (&dev->i2c_lock))
+       if (mutex_lock_interruptible(&dev->i2c_lock))
                return -ERESTARTSYS;
 
        for(i=0;i<num;i++) {
@@ -366,7 +366,7 @@ out:
                }
        }
 
-       up(&dev->i2c_lock);
+       mutex_unlock(&dev->i2c_lock);
        return err;
 }
 
index 468d3c9590755bfa44bc7ec7fdcf2d20b3756071..500bd3f05e169b877090276e11e6a0c130ec7160 100644 (file)
@@ -410,7 +410,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
                            V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
                            sizeof(struct saa7146_buf),
                            file);
-       init_MUTEX(&fh->vbi_q.lock);
+       mutex_init(&fh->vbi_q.lock);
 
        init_timer(&fh->vbi_read_timeout);
        fh->vbi_read_timeout.function = vbi_read_timeout;
index 7ebac7949df3789aa165ba472a26d6fc319a9651..6b42713d97f49d853ef1e3e980af0f67ccaa03df 100644 (file)
@@ -378,20 +378,20 @@ static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
                err = try_win(dev,&f->fmt.win);
                if (0 != err)
                        return err;
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                fh->ov.win    = f->fmt.win;
                fh->ov.nclips = f->fmt.win.clipcount;
                if (fh->ov.nclips > 16)
                        fh->ov.nclips = 16;
                if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) {
-                       up(&dev->lock);
+                       mutex_unlock(&dev->lock);
                        return -EFAULT;
                }
 
                /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
                fh->ov.fh = fh;
 
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
 
                /* check if our current overlay is active */
                if (IS_OVERLAY_ACTIVE(fh) != 0) {
@@ -516,7 +516,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
                return -EINVAL;
        }
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
 
        switch (ctrl->type) {
        case V4L2_CTRL_TYPE_BOOLEAN:
@@ -560,7 +560,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
                /* fixme: we can support changing VFLIP and HFLIP here... */
                if (IS_CAPTURE_ACTIVE(fh) != 0) {
                        DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
-                       up(&dev->lock);
+                       mutex_unlock(&dev->lock);
                        return -EINVAL;
                }
                vv->hflip = c->value;
@@ -568,7 +568,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
        case V4L2_CID_VFLIP:
                if (IS_CAPTURE_ACTIVE(fh) != 0) {
                        DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
-                       up(&dev->lock);
+                       mutex_unlock(&dev->lock);
                        return -EINVAL;
                }
                vv->vflip = c->value;
@@ -577,7 +577,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
                return -EINVAL;
        }
        }
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 
        if (IS_OVERLAY_ACTIVE(fh) != 0) {
                saa7146_stop_preview(fh);
@@ -939,7 +939,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                        }
                }
 
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
 
                /* ok, accept it */
                vv->ov_fb = *fb;
@@ -948,7 +948,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                        vv->ov_fb.fmt.bytesperline =
                                vv->ov_fb.fmt.width*fmt->depth/8;
 
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
 
                return 0;
        }
@@ -1086,7 +1086,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                        }
                }
 
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
 
                for(i = 0; i < dev->ext_vv_data->num_stds; i++)
                        if (*id & dev->ext_vv_data->stds[i].id)
@@ -1098,7 +1098,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                        found = 1;
                }
 
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
 
                if (vv->ov_suspend != NULL) {
                        saa7146_start_preview(vv->ov_suspend);
@@ -1201,11 +1201,11 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                DEB_D(("VIDIOCGMBUF \n"));
 
                q = &fh->video_q;
-               down(&q->lock);
+               mutex_lock(&q->lock);
                err = videobuf_mmap_setup(q,gbuffers,gbufsize,
                                          V4L2_MEMORY_MMAP);
                if (err < 0) {
-                       up(&q->lock);
+                       mutex_unlock(&q->lock);
                        return err;
                }
                memset(mbuf,0,sizeof(*mbuf));
@@ -1213,7 +1213,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                mbuf->size   = gbuffers * gbufsize;
                for (i = 0; i < gbuffers; i++)
                        mbuf->offsets[i] = i * gbufsize;
-               up(&q->lock);
+               mutex_unlock(&q->lock);
                return 0;
        }
        default:
@@ -1414,7 +1414,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
                            sizeof(struct saa7146_buf),
                            file);
 
-       init_MUTEX(&fh->video_q.lock);
+       mutex_init(&fh->video_q.lock);
 
        return 0;
 }
index 7d7e1613c5a745036e47f9630a5fdf3026ba778c..b3dd0603cd9210ff1773c7e0f6a0b36ca0213b4d 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/pci.h>
+#include <linux/mutex.h>
 
 #include "flexcop-reg.h"
 
@@ -73,8 +74,7 @@ struct flexcop_device {
        int (*fe_sleep) (struct dvb_frontend *);
 
        struct i2c_adapter i2c_adap;
-       struct semaphore i2c_sem;
-
+       struct mutex i2c_mutex;
        struct module *owner;
 
        /* options and status */
index 56495cb6cd02d39a3ded4a581e3d732231c4c320..e0bd2d8f0f0c92e08235aa9e15db650d43723f21 100644 (file)
@@ -135,7 +135,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs
        struct flexcop_device *fc = i2c_get_adapdata(i2c_adap);
        int i, ret = 0;
 
-       if (down_interruptible(&fc->i2c_sem))
+       if (mutex_lock_interruptible(&fc->i2c_mutex))
                return -ERESTARTSYS;
 
        /* reading */
@@ -161,7 +161,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs
        else
                ret = num;
 
-       up(&fc->i2c_sem);
+       mutex_unlock(&fc->i2c_mutex);
 
        return ret;
 }
@@ -180,7 +180,7 @@ int flexcop_i2c_init(struct flexcop_device *fc)
 {
        int ret;
 
-       sema_init(&fc->i2c_sem,1);
+       mutex_init(&fc->i2c_mutex);
 
        memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter));
        strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",I2C_NAME_SIZE);
index d188e4c670b512f6667825a39117a14a6a843d08..9d197efb481d4a3f2f08cec1bda3f04882b0de83 100644 (file)
@@ -1,3 +1,3 @@
 obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
 
-EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video/bt8xx -Idrivers/media/dvb/frontends
index 356f447ee2ab917a818ab37ecdb207d6f099f9dc..5500f8a0ffe2c6fa1f0013bbc8dc8ccb810f93dd 100644 (file)
@@ -344,7 +344,7 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *
        int retval;
 
        retval = 0;
-       if (down_interruptible (&bt->gpio_lock))
+       if (mutex_lock_interruptible(&bt->gpio_lock))
                return -ERESTARTSYS;
        /* special gpio signal */
        switch (cmd) {
@@ -375,7 +375,7 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *
                retval = -EINVAL;
                break;
        }
-       up(&bt->gpio_lock);
+       mutex_unlock(&bt->gpio_lock);
        return retval;
 }
 
index 9faf93770d08f3e5c6cdd3ddf2b70d86eaa17b20..f685bc1296097846e7ed959342307fc75d048763 100644 (file)
@@ -25,6 +25,8 @@
 #include <linux/pci.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
+#include <linux/mutex.h>
+
 #include "bt848.h"
 #include "bttv.h"
 
@@ -108,7 +110,7 @@ struct cards {
 extern int bt878_num;
 
 struct bt878 {
-       struct semaphore  gpio_lock;
+       struct mutex gpio_lock;
        unsigned int nr;
        unsigned int bttv_nr;
        struct i2c_adapter *adapter;
index 0310e3dd07e60e0c41489aac538f3da89aecc78e..1cfa5e5035d830f9ca66d1679efa149df2a065ec 100644 (file)
@@ -910,7 +910,7 @@ static int dst_get_device_id(struct dst_state *state)
 
 static int dst_probe(struct dst_state *state)
 {
-       sema_init(&state->dst_mutex, 1);
+       mutex_init(&state->dst_mutex);
        if ((rdc_8820_reset(state)) < 0) {
                dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
                return -1;
@@ -962,7 +962,7 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
 {
        u8 reply;
 
-       down(&state->dst_mutex);
+       mutex_lock(&state->dst_mutex);
        if ((dst_comm_init(state)) < 0) {
                dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
                goto error;
@@ -1013,11 +1013,11 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
                dprintk(verbose, DST_INFO, 1, "checksum failure");
                goto error;
        }
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return 0;
 
 error:
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return -EIO;
 
 }
@@ -1128,7 +1128,7 @@ static int dst_write_tuna(struct dvb_frontend *fe)
                        dst_set_voltage(fe, SEC_VOLTAGE_13);
        }
        state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
-       down(&state->dst_mutex);
+       mutex_lock(&state->dst_mutex);
        if ((dst_comm_init(state)) < 0) {
                dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
                goto error;
@@ -1160,11 +1160,11 @@ static int dst_write_tuna(struct dvb_frontend *fe)
        state->diseq_flags |= ATTEMPT_TUNE;
        retval = dst_get_tuna(state);
 werr:
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return retval;
 
 error:
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return -EIO;
 }
 
index c650b4bf7f5f8caee597fb19455ad0dd70593290..f6b49a801eba92ae75e9d8d68ccc58000d1ff199 100644 (file)
@@ -81,7 +81,7 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8
 {
        u8 reply;
 
-       down(&state->dst_mutex);
+       mutex_lock(&state->dst_mutex);
        dst_comm_init(state);
        msleep(65);
 
@@ -110,11 +110,11 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8
                        goto error;
                }
        }
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return 0;
 
 error:
-       up(&state->dst_mutex);
+       mutex_unlock(&state->dst_mutex);
        return -EIO;
 }
 
index 81557f38fe3826aa0cfdc44ba0ac96f19de2eac6..51d4e043716c19f37899566ee0f3bf97539fb685 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/smp_lock.h>
 #include <linux/dvb/frontend.h>
 #include <linux/device.h>
+#include <linux/mutex.h>
 #include "bt878.h"
 
 #include "dst_ca.h"
@@ -121,7 +122,7 @@ struct dst_state {
        u8 vendor[8];
        u8 board_info[8];
 
-       struct semaphore dst_mutex;
+       struct mutex dst_mutex;
 };
 
 struct dst_types {
index ea27b15007e9352f2de20cd8918264c1b4c4d2a5..baa8227ef87c8d5e045f24ffb8defb011ef6cdaa 100644 (file)
@@ -76,13 +76,13 @@ static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
        if (!dvbdmx->dmx.frontend)
                return -EINVAL;
 
-       down(&card->lock);
+       mutex_lock(&card->lock);
        card->nfeeds++;
        rc = card->nfeeds;
        if (card->nfeeds == 1)
                bt878_start(card->bt, card->gpio_mode,
                            card->op_sync_orin, card->irq_err_ignore);
-       up(&card->lock);
+       mutex_unlock(&card->lock);
        return rc;
 }
 
@@ -96,11 +96,11 @@ static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
        if (!dvbdmx->dmx.frontend)
                return -EINVAL;
 
-       down(&card->lock);
+       mutex_lock(&card->lock);
        card->nfeeds--;
        if (card->nfeeds == 0)
                bt878_stop(card->bt);
-       up(&card->lock);
+       mutex_unlock(&card->lock);
 
        return 0;
 }
@@ -239,6 +239,20 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
 
 static int pinnsat_pll_init(struct dvb_frontend* fe)
 {
+       struct dvb_bt8xx_card *card = fe->dvb->priv;
+
+       bttv_gpio_enable(card->bttv_nr, 1, 1);  /* output */
+       bttv_write_gpio(card->bttv_nr, 1, 1);   /* relay on */
+
+       return 0;
+}
+
+static int pinnsat_pll_sleep(struct dvb_frontend* fe)
+{
+       struct dvb_bt8xx_card *card = fe->dvb->priv;
+
+       bttv_write_gpio(card->bttv_nr, 1, 0);   /* relay off */
+
        return 0;
 }
 
@@ -246,6 +260,7 @@ static struct cx24110_config pctvsat_config = {
        .demod_address = 0x55,
        .pll_init = pinnsat_pll_init,
        .pll_set = cx24108_pll_set,
+       .pll_sleep = pinnsat_pll_sleep,
 };
 
 static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -788,7 +803,7 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
        if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
                return -ENOMEM;
 
-       init_MUTEX(&card->lock);
+       mutex_init(&card->lock);
        card->bttv_nr = sub->core->nr;
        strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
        card->i2c_adapter = &sub->core->i2c_adap;
@@ -798,14 +813,14 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
                card->gpio_mode = 0x0400c060;
                /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
                              BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
-               card->op_sync_orin = 0;
-               card->irq_err_ignore = 0;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
                break;
 
        case BTTV_BOARD_DVICO_DVBT_LITE:
                card->gpio_mode = 0x0400C060;
-               card->op_sync_orin = 0;
-               card->irq_err_ignore = 0;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
                /* 26, 15, 14, 6, 5
                 * A_PWRDN  DA_DPM DA_SBR DA_IOM_DA
                 * DA_APP(parallel) */
@@ -820,15 +835,15 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
        case BTTV_BOARD_NEBULA_DIGITV:
        case BTTV_BOARD_AVDVBT_761:
                card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
-               card->op_sync_orin = 0;
-               card->irq_err_ignore = 0;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
                /* A_PWRDN DA_SBR DA_APP (high speed serial) */
                break;
 
        case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
                card->gpio_mode = 0x0400402B;
                card->op_sync_orin = BT878_RISC_SYNC_MASK;
-               card->irq_err_ignore = 0;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
                /* A_PWRDN DA_SBR  DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
                break;
 
@@ -852,8 +867,8 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
 
        case BTTV_BOARD_PC_HDTV:
                card->gpio_mode = 0x0100EC7B;
-               card->op_sync_orin = 0;
-               card->irq_err_ignore = 0;
+               card->op_sync_orin = BT878_RISC_SYNC_MASK;
+               card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
                break;
 
        default:
@@ -881,7 +896,7 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
                return -EFAULT;
        }
 
-       init_MUTEX(&card->bt->gpio_lock);
+       mutex_init(&card->bt->gpio_lock);
        card->bt->bttv_nr = sub->core->nr;
 
        if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) {
index cf035a80361ccb9cb596b62dc075a493beeb7065..00dd9fa54c82cbeefc3a07fbce4aa5b8843b69c5 100644 (file)
@@ -26,6 +26,7 @@
 #define DVB_BT8XX_H
 
 #include <linux/i2c.h>
+#include <linux/mutex.h>
 #include "dvbdev.h"
 #include "dvb_net.h"
 #include "bttv.h"
@@ -38,7 +39,7 @@
 #include "lgdt330x.h"
 
 struct dvb_bt8xx_card {
-       struct semaphore lock;
+       struct mutex lock;
        int nfeeds;
        char card_name[32];
        struct dvb_adapter dvb_adapter;
index c4b4c5b6b7c803d2ae7e8c7299901be9380a94fd..71b575dc22bdb2fbfe7a21261da549ffaa8f2cb6 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/input.h>
 #include <linux/dvb/frontend.h>
+#include <linux/mutex.h>
 
 #include "dmxdev.h"
 #include "dvb_demux.h"
@@ -116,7 +117,7 @@ static struct dvb_frontend_info cinergyt2_fe_info = {
 struct cinergyt2 {
        struct dvb_demux demux;
        struct usb_device *udev;
-       struct semaphore sem;
+       struct mutex sem;
        struct dvb_adapter adapter;
        struct dvb_device *fedev;
        struct dmxdev dmxdev;
@@ -345,14 +346,14 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed)
        struct dvb_demux *demux = dvbdmxfeed->demux;
        struct cinergyt2 *cinergyt2 = demux->priv;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (cinergyt2->streaming == 0)
                cinergyt2_start_stream_xfer(cinergyt2);
 
        cinergyt2->streaming++;
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
        return 0;
 }
 
@@ -361,13 +362,13 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
        struct dvb_demux *demux = dvbdmxfeed->demux;
        struct cinergyt2 *cinergyt2 = demux->priv;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (--cinergyt2->streaming == 0)
                cinergyt2_stop_stream_xfer(cinergyt2);
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
        return 0;
 }
 
@@ -483,11 +484,11 @@ static int cinergyt2_open (struct inode *inode, struct file *file)
        struct cinergyt2 *cinergyt2 = dvbdev->priv;
        int err = -ERESTARTSYS;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if ((err = dvb_generic_open(inode, file))) {
-               up(&cinergyt2->sem);
+               mutex_unlock(&cinergyt2->sem);
                return err;
        }
 
@@ -499,12 +500,15 @@ static int cinergyt2_open (struct inode *inode, struct file *file)
 
        atomic_inc(&cinergyt2->inuse);
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
        return 0;
 }
 
 static void cinergyt2_unregister(struct cinergyt2 *cinergyt2)
 {
+       dvb_net_release(&cinergyt2->dvbnet);
+       dvb_dmxdev_release(&cinergyt2->dmxdev);
+       dvb_dmx_release(&cinergyt2->demux);
        dvb_unregister_device(cinergyt2->fedev);
        dvb_unregister_adapter(&cinergyt2->adapter);
 
@@ -517,7 +521,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
        struct dvb_device *dvbdev = file->private_data;
        struct cinergyt2 *cinergyt2 = dvbdev->priv;
 
-       if (down_interruptible(&cinergyt2->sem))
+       if (mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
@@ -526,7 +530,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
                cinergyt2_sleep(cinergyt2, 1);
        }
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
 
        if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) {
                warn("delayed unregister in release");
@@ -541,12 +545,12 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct
        struct dvb_device *dvbdev = file->private_data;
        struct cinergyt2 *cinergyt2 = dvbdev->priv;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        poll_wait(file, &cinergyt2->poll_wq, wait);
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
 
        return (POLLIN | POLLRDNORM | POLLPRI);
 }
@@ -613,7 +617,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file,
                if (copy_from_user(&p, (void  __user*) arg, sizeof(p)))
                        return -EFAULT;
 
-               if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+               if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                        return -ERESTARTSYS;
 
                param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
@@ -629,7 +633,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file,
                                        (char *) param, sizeof(*param),
                                        NULL, 0);
 
-               up(&cinergyt2->sem);
+               mutex_unlock(&cinergyt2->sem);
 
                return (err < 0) ? err : 0;
        }
@@ -724,7 +728,7 @@ static void cinergyt2_query_rc (void *data)
        struct cinergyt2_rc_event rc_events[12];
        int n, len, i;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return;
 
        len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
@@ -784,7 +788,7 @@ out:
        schedule_delayed_work(&cinergyt2->rc_query_work,
                              msecs_to_jiffies(RC_QUERY_INTERVAL));
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
 }
 
 static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
@@ -849,7 +853,7 @@ static void cinergyt2_query (void *data)
        uint8_t lock_bits;
        uint32_t unc;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return;
 
        unc = s->uncorrected_block_count;
@@ -868,7 +872,7 @@ static void cinergyt2_query (void *data)
        schedule_delayed_work(&cinergyt2->query_work,
                              msecs_to_jiffies(QUERY_INTERVAL));
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
 }
 
 static int cinergyt2_probe (struct usb_interface *intf,
@@ -885,7 +889,7 @@ static int cinergyt2_probe (struct usb_interface *intf,
        memset (cinergyt2, 0, sizeof (struct cinergyt2));
        usb_set_intfdata (intf, (void *) cinergyt2);
 
-       init_MUTEX(&cinergyt2->sem);
+       mutex_init(&cinergyt2->sem);
        init_waitqueue_head (&cinergyt2->poll_wq);
        INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2);
 
@@ -937,6 +941,7 @@ static int cinergyt2_probe (struct usb_interface *intf,
        return 0;
 
 bailout:
+       dvb_net_release(&cinergyt2->dvbnet);
        dvb_dmxdev_release(&cinergyt2->dmxdev);
        dvb_dmx_release(&cinergyt2->demux);
        dvb_unregister_adapter(&cinergyt2->adapter);
@@ -967,7 +972,7 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
 {
        struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (state.event > PM_EVENT_ON) {
@@ -981,7 +986,7 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
                cinergyt2_sleep(cinergyt2, 1);
        }
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
        return 0;
 }
 
@@ -990,7 +995,7 @@ static int cinergyt2_resume (struct usb_interface *intf)
        struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
        struct dvbt_set_parameters_msg *param = &cinergyt2->param;
 
-       if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+       if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        if (!cinergyt2->sleeping) {
@@ -1003,7 +1008,7 @@ static int cinergyt2_resume (struct usb_interface *intf)
 
        cinergyt2_resume_rc(cinergyt2);
 
-       up(&cinergyt2->sem);
+       mutex_unlock(&cinergyt2->sem);
        return 0;
 }
 
index 7b8373ad121b051cccbcbd675ca32e4f9d16efaa..09e96e9ddbdfc5a093af5315d8ef83cdbe9d5075 100644 (file)
@@ -1,9 +1,8 @@
 /*
  * dmxdev.c - DVB demultiplexer device
  *
- * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de>
- *               & Marcus Metzler <marcus@convergence.de>
-                     for convergence integrated media GmbH
+ * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
+ *                   for convergence integrated media GmbH
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -32,7 +31,6 @@
 #include <linux/wait.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
-
 #include "dmxdev.h"
 
 static int debug;
@@ -42,177 +40,133 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
 
 #define dprintk        if (debug) printk
 
-static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer)
+static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf,
+                                  const u8 *src, size_t len)
 {
-       buffer->data=NULL;
-       buffer->size=8192;
-       buffer->pread=0;
-       buffer->pwrite=0;
-       buffer->error=0;
-       init_waitqueue_head(&buffer->queue);
-}
-
-static inline int dvb_dmxdev_buffer_write(struct dmxdev_buffer *buf, const u8 *src, int len)
-{
-       int split;
-       int free;
-       int todo;
+       ssize_t free;
 
        if (!len)
                return 0;
        if (!buf->data)
                return 0;
 
-       free=buf->pread-buf->pwrite;
-       split=0;
-       if (free<=0) {
-               free+=buf->size;
-               split=buf->size-buf->pwrite;
-       }
-       if (len>=free) {
+       free = dvb_ringbuffer_free(buf);
+       if (len > free) {
                dprintk("dmxdev: buffer overflow\n");
-               return -1;
+               return -EOVERFLOW;
        }
-       if (split>=len)
-               split=0;
-       todo=len;
-       if (split) {
-               memcpy(buf->data + buf->pwrite, src, split);
-               todo-=split;
-               buf->pwrite=0;
-       }
-       memcpy(buf->data + buf->pwrite, src+split, todo);
-       buf->pwrite=(buf->pwrite+todo)%buf->size;
-       return len;
+
+       return dvb_ringbuffer_write(buf, src, len);
 }
 
-static ssize_t dvb_dmxdev_buffer_read(struct dmxdev_buffer *src,
-               int non_blocking, char __user *buf, size_t count, loff_t *ppos)
+static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,
+                                     int non_blocking, char __user *buf,
+                                     size_t count, loff_t *ppos)
 {
-       unsigned long todo=count;
-       int split, avail, error;
+       size_t todo;
+       ssize_t avail;
+       ssize_t ret = 0;
 
        if (!src->data)
                return 0;
 
-       if ((error=src->error)) {
-               src->pwrite=src->pread;
-               src->error=0;
-               return error;
+       if (src->error) {
+               ret = src->error;
+               dvb_ringbuffer_flush(src);
+               return ret;
        }
 
-       if (non_blocking && (src->pwrite==src->pread))
-               return -EWOULDBLOCK;
-
-       while (todo>0) {
-               if (non_blocking && (src->pwrite==src->pread))
-                       return (count-todo) ? (count-todo) : -EWOULDBLOCK;
+       for (todo = count; todo > 0; todo -= ret) {
+               if (non_blocking && dvb_ringbuffer_empty(src)) {
+                       ret = -EWOULDBLOCK;
+                       break;
+               }
 
-               if (wait_event_interruptible(src->queue,
-                                            (src->pread!=src->pwrite) ||
-                                            (src->error))<0)
-                       return count-todo;
+               ret = wait_event_interruptible(src->queue,
+                                              !dvb_ringbuffer_empty(src) ||
+                                              (src->error != 0));
+               if (ret < 0)
+                       break;
 
-               if ((error=src->error)) {
-                       src->pwrite=src->pread;
-                       src->error=0;
-                       return error;
+               if (src->error) {
+                       ret = src->error;
+                       dvb_ringbuffer_flush(src);
+                       break;
                }
 
-               split=src->size;
-               avail=src->pwrite - src->pread;
-               if (avail<0) {
-                       avail+=src->size;
-                       split=src->size - src->pread;
-               }
-               if (avail>todo)
-                       avail=todo;
-               if (split<avail) {
-                       if (copy_to_user(buf, src->data+src->pread, split))
-                                 return -EFAULT;
-                       buf+=split;
-                       src->pread=0;
-                       todo-=split;
-                       avail-=split;
-               }
-               if (avail) {
-                       if (copy_to_user(buf, src->data+src->pread, avail))
-                               return -EFAULT;
-                       src->pread = (src->pread + avail) % src->size;
-                       todo-=avail;
-                       buf+=avail;
-               }
+               avail = dvb_ringbuffer_avail(src);
+               if (avail > todo)
+                       avail = todo;
+
+               ret = dvb_ringbuffer_read(src, buf, avail, 1);
+               if (ret < 0)
+                       break;
+
+               buf += ret;
        }
-       return count;
+
+       return (count - todo) ? (count - todo) : ret;
 }
 
-static struct dmx_frontend * get_fe(struct dmx_demux *demux, int type)
+static struct dmx_frontend *get_fe(struct dmx_demux *demux, int type)
 {
        struct list_head *head, *pos;
 
-       head=demux->get_frontends(demux);
+       head = demux->get_frontends(demux);
        if (!head)
                return NULL;
        list_for_each(pos, head)
-               if (DMX_FE_ENTRY(pos)->source==type)
+               if (DMX_FE_ENTRY(pos)->source == type)
                        return DMX_FE_ENTRY(pos);
 
        return NULL;
 }
 
-static inline void dvb_dmxdev_dvr_state_set(struct dmxdev_dvr *dmxdevdvr, int state)
-{
-       spin_lock_irq(&dmxdevdvr->dev->lock);
-       dmxdevdvr->state=state;
-       spin_unlock_irq(&dmxdevdvr->dev->lock);
-}
-
 static int dvb_dvr_open(struct inode *inode, struct file *file)
 {
        struct dvb_device *dvbdev = file->private_data;
        struct dmxdev *dmxdev = dvbdev->priv;
        struct dmx_frontend *front;
 
-       dprintk ("function : %s\n", __FUNCTION__);
+       dprintk("function : %s\n", __FUNCTION__);
 
-       if (down_interruptible (&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
-       if ((file->f_flags&O_ACCMODE)==O_RDWR) {
-               if (!(dmxdev->capabilities&DMXDEV_CAP_DUPLEX)) {
-                       up(&dmxdev->mutex);
+       if ((file->f_flags & O_ACCMODE) == O_RDWR) {
+               if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
+                       mutex_unlock(&dmxdev->mutex);
                        return -EOPNOTSUPP;
                }
        }
 
-       if ((file->f_flags&O_ACCMODE)==O_RDONLY) {
-             dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer);
-             dmxdev->dvr_buffer.size=DVR_BUFFER_SIZE;
-             dmxdev->dvr_buffer.data=vmalloc(DVR_BUFFER_SIZE);
-             if (!dmxdev->dvr_buffer.data) {
-                     up(&dmxdev->mutex);
-                     return -ENOMEM;
-             }
+       if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+               void *mem = vmalloc(DVR_BUFFER_SIZE);
+               if (!mem) {
+                       mutex_unlock(&dmxdev->mutex);
+                       return -ENOMEM;
+               }
+               dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
        }
 
-       if ((file->f_flags&O_ACCMODE)==O_WRONLY) {
-               dmxdev->dvr_orig_fe=dmxdev->demux->frontend;
+       if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
+               dmxdev->dvr_orig_fe = dmxdev->demux->frontend;
 
                if (!dmxdev->demux->write) {
-                       up(&dmxdev->mutex);
+                       mutex_unlock(&dmxdev->mutex);
                        return -EOPNOTSUPP;
                }
 
-               front=get_fe(dmxdev->demux, DMX_MEMORY_FE);
+               front = get_fe(dmxdev->demux, DMX_MEMORY_FE);
 
                if (!front) {
-                       up(&dmxdev->mutex);
+                       mutex_unlock(&dmxdev->mutex);
                        return -EINVAL;
                }
                dmxdev->demux->disconnect_frontend(dmxdev->demux);
                dmxdev->demux->connect_frontend(dmxdev->demux, front);
        }
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return 0;
 }
 
@@ -221,30 +175,30 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
        struct dvb_device *dvbdev = file->private_data;
        struct dmxdev *dmxdev = dvbdev->priv;
 
-       if (down_interruptible (&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
-       if ((file->f_flags&O_ACCMODE)==O_WRONLY) {
+       if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
                dmxdev->demux->disconnect_frontend(dmxdev->demux);
                dmxdev->demux->connect_frontend(dmxdev->demux,
                                                dmxdev->dvr_orig_fe);
        }
-       if ((file->f_flags&O_ACCMODE)==O_RDONLY) {
+       if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
                if (dmxdev->dvr_buffer.data) {
-                       void *mem=dmxdev->dvr_buffer.data;
+                       void *mem = dmxdev->dvr_buffer.data;
                        mb();
                        spin_lock_irq(&dmxdev->lock);
-                       dmxdev->dvr_buffer.data=NULL;
+                       dmxdev->dvr_buffer.data = NULL;
                        spin_unlock_irq(&dmxdev->lock);
                        vfree(mem);
                }
        }
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return 0;
 }
 
 static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
-               size_t count, loff_t *ppos)
+                            size_t count, loff_t *ppos)
 {
        struct dvb_device *dvbdev = file->private_data;
        struct dmxdev *dmxdev = dvbdev->priv;
@@ -252,60 +206,62 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
 
        if (!dmxdev->demux->write)
                return -EOPNOTSUPP;
-       if ((file->f_flags&O_ACCMODE)!=O_WRONLY)
+       if ((file->f_flags & O_ACCMODE) != O_WRONLY)
                return -EINVAL;
-       if (down_interruptible (&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
-       ret=dmxdev->demux->write(dmxdev->demux, buf, count);
-       up(&dmxdev->mutex);
+       ret = dmxdev->demux->write(dmxdev->demux, buf, count);
+       mutex_unlock(&dmxdev->mutex);
        return ret;
 }
 
 static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
-               loff_t *ppos)
+                           loff_t *ppos)
 {
        struct dvb_device *dvbdev = file->private_data;
        struct dmxdev *dmxdev = dvbdev->priv;
        int ret;
 
-       //down(&dmxdev->mutex);
-       ret= dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
-                             file->f_flags&O_NONBLOCK,
-                             buf, count, ppos);
-       //up(&dmxdev->mutex);
+       //mutex_lock(&dmxdev->mutex);
+       ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
+                                    file->f_flags & O_NONBLOCK,
+                                    buf, count, ppos);
+       //mutex_unlock(&dmxdev->mutex);
        return ret;
 }
 
-static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter *dmxdevfilter, int state)
+static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter
+                                              *dmxdevfilter, int state)
 {
        spin_lock_irq(&dmxdevfilter->dev->lock);
-       dmxdevfilter->state=state;
+       dmxdevfilter->state = state;
        spin_unlock_irq(&dmxdevfilter->dev->lock);
 }
 
-static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, unsigned long size)
+static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
+                                     unsigned long size)
 {
-       struct dmxdev_buffer *buf=&dmxdevfilter->buffer;
+       struct dvb_ringbuffer *buf = &dmxdevfilter->buffer;
        void *mem;
 
-       if (buf->size==size)
+       if (buf->size == size)
                return 0;
-       if (dmxdevfilter->state>=DMXDEV_STATE_GO)
+       if (dmxdevfilter->state >= DMXDEV_STATE_GO)
                return -EBUSY;
        spin_lock_irq(&dmxdevfilter->dev->lock);
-       mem=buf->data;
-       buf->data=NULL;
-       buf->size=size;
-       buf->pwrite=buf->pread=0;
+       mem = buf->data;
+       buf->data = NULL;
+       buf->size = size;
+       dvb_ringbuffer_flush(buf);
        spin_unlock_irq(&dmxdevfilter->dev->lock);
        vfree(mem);
 
        if (buf->size) {
-               mem=vmalloc(dmxdevfilter->buffer.size);
+               mem = vmalloc(dmxdevfilter->buffer.size);
                if (!mem)
                        return -ENOMEM;
                spin_lock_irq(&dmxdevfilter->dev->lock);
-               buf->data=mem;
+               buf->data = mem;
                spin_unlock_irq(&dmxdevfilter->dev->lock);
        }
        return 0;
@@ -313,31 +269,33 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, unsign
 
 static void dvb_dmxdev_filter_timeout(unsigned long data)
 {
-       struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *)data;
+       struct dmxdev_filter *dmxdevfilter = (struct dmxdev_filter *)data;
 
-       dmxdevfilter->buffer.error=-ETIMEDOUT;
+       dmxdevfilter->buffer.error = -ETIMEDOUT;
        spin_lock_irq(&dmxdevfilter->dev->lock);
-       dmxdevfilter->state=DMXDEV_STATE_TIMEDOUT;
+       dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT;
        spin_unlock_irq(&dmxdevfilter->dev->lock);
        wake_up(&dmxdevfilter->buffer.queue);
 }
 
 static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
 {
-       struct dmx_sct_filter_params *para=&dmxdevfilter->params.sec;
+       struct dmx_sct_filter_params *para = &dmxdevfilter->params.sec;
 
        del_timer(&dmxdevfilter->timer);
        if (para->timeout) {
-               dmxdevfilter->timer.function=dvb_dmxdev_filter_timeout;
-               dmxdevfilter->timer.data=(unsigned long) dmxdevfilter;
-               dmxdevfilter->timer.expires=jiffies+1+(HZ/2+HZ*para->timeout)/1000;
+               dmxdevfilter->timer.function = dvb_dmxdev_filter_timeout;
+               dmxdevfilter->timer.data = (unsigned long)dmxdevfilter;
+               dmxdevfilter->timer.expires =
+                   jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000;
                add_timer(&dmxdevfilter->timer);
        }
 }
 
 static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
-                           const u8 *buffer2, size_t buffer2_len,
-                           struct dmx_section_filter *filter, enum dmx_success success)
+                                      const u8 *buffer2, size_t buffer2_len,
+                                      struct dmx_section_filter *filter,
+                                      enum dmx_success success)
 {
        struct dmxdev_filter *dmxdevfilter = filter->priv;
        int ret;
@@ -347,68 +305,68 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
                return 0;
        }
        spin_lock(&dmxdevfilter->dev->lock);
-       if (dmxdevfilter->state!=DMXDEV_STATE_GO) {
+       if (dmxdevfilter->state != DMXDEV_STATE_GO) {
                spin_unlock(&dmxdevfilter->dev->lock);
                return 0;
        }
        del_timer(&dmxdevfilter->timer);
        dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n",
                buffer1[0], buffer1[1],
-               buffer1[2], buffer1[3],
-               buffer1[4], buffer1[5]);
-       ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, buffer1_len);
-       if (ret==buffer1_len) {
-               ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, buffer2_len);
+               buffer1[2], buffer1[3], buffer1[4], buffer1[5]);
+       ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1,
+                                     buffer1_len);
+       if (ret == buffer1_len) {
+               ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2,
+                                             buffer2_len);
        }
-       if (ret<0) {
-               dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread;
-               dmxdevfilter->buffer.error=-EOVERFLOW;
+       if (ret < 0) {
+               dvb_ringbuffer_flush(&dmxdevfilter->buffer);
+               dmxdevfilter->buffer.error = ret;
        }
-       if (dmxdevfilter->params.sec.flags&DMX_ONESHOT)
-               dmxdevfilter->state=DMXDEV_STATE_DONE;
+       if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
+               dmxdevfilter->state = DMXDEV_STATE_DONE;
        spin_unlock(&dmxdevfilter->dev->lock);
        wake_up(&dmxdevfilter->buffer.queue);
        return 0;
 }
 
 static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
-                      const u8 *buffer2, size_t buffer2_len,
-                      struct dmx_ts_feed *feed, enum dmx_success success)
+                                 const u8 *buffer2, size_t buffer2_len,
+                                 struct dmx_ts_feed *feed,
+                                 enum dmx_success success)
 {
        struct dmxdev_filter *dmxdevfilter = feed->priv;
-       struct dmxdev_buffer *buffer;
+       struct dvb_ringbuffer *buffer;
        int ret;
 
        spin_lock(&dmxdevfilter->dev->lock);
-       if (dmxdevfilter->params.pes.output==DMX_OUT_DECODER) {
+       if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
                spin_unlock(&dmxdevfilter->dev->lock);
                return 0;
        }
 
-       if (dmxdevfilter->params.pes.output==DMX_OUT_TAP)
-               buffer=&dmxdevfilter->buffer;
+       if (dmxdevfilter->params.pes.output == DMX_OUT_TAP)
+               buffer = &dmxdevfilter->buffer;
        else
-               buffer=&dmxdevfilter->dev->dvr_buffer;
+               buffer = &dmxdevfilter->dev->dvr_buffer;
        if (buffer->error) {
                spin_unlock(&dmxdevfilter->dev->lock);
                wake_up(&buffer->queue);
                return 0;
        }
-       ret=dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
-       if (ret==buffer1_len)
-               ret=dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
-       if (ret<0) {
-               buffer->pwrite=buffer->pread;
-               buffer->error=-EOVERFLOW;
+       ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
+       if (ret == buffer1_len)
+               ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
+       if (ret < 0) {
+               dvb_ringbuffer_flush(buffer);
+               buffer->error = ret;
        }
        spin_unlock(&dmxdevfilter->dev->lock);
        wake_up(&buffer->queue);
        return 0;
 }
 
-
 /* stop feed but only mark the specified filter as stopped (state set) */
-
 static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
 {
        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
@@ -427,20 +385,16 @@ static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
        return 0;
 }
 
-
 /* start feed associated with the specified filter */
-
 static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter)
 {
-       dvb_dmxdev_filter_state_set (filter, DMXDEV_STATE_GO);
+       dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
 
        switch (filter->type) {
        case DMXDEV_TYPE_SEC:
                return filter->feed.sec->start_filtering(filter->feed.sec);
-               break;
        case DMXDEV_TYPE_PES:
                return filter->feed.ts->start_filtering(filter->feed.ts);
-               break;
        default:
                return -EINVAL;
        }
@@ -448,32 +402,31 @@ static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter)
        return 0;
 }
 
-
 /* restart section feed if it has filters left associated with it,
    otherwise release the feed */
-
 static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter)
 {
        int i;
        struct dmxdev *dmxdev = filter->dev;
        u16 pid = filter->params.sec.pid;
 
-       for (i=0; i<dmxdev->filternum; i++)
-               if (dmxdev->filter[i].state>=DMXDEV_STATE_GO &&
-                   dmxdev->filter[i].type==DMXDEV_TYPE_SEC &&
-                   dmxdev->filter[i].pid==pid) {
+       for (i = 0; i < dmxdev->filternum; i++)
+               if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&
+                   dmxdev->filter[i].type == DMXDEV_TYPE_SEC &&
+                   dmxdev->filter[i].params.sec.pid == pid) {
                        dvb_dmxdev_feed_start(&dmxdev->filter[i]);
                        return 0;
                }
 
-       filter->dev->demux->release_section_feed(dmxdev->demux, filter->feed.sec);
+       filter->dev->demux->release_section_feed(dmxdev->demux,
+                                                filter->feed.sec);
 
        return 0;
 }
 
 static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
 {
-       if (dmxdevfilter->state<DMXDEV_STATE_GO)
+       if (dmxdevfilter->state < DMXDEV_STATE_GO)
                return 0;
 
        switch (dmxdevfilter->type) {
@@ -483,36 +436,36 @@ static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
                dvb_dmxdev_feed_stop(dmxdevfilter);
                if (dmxdevfilter->filter.sec)
                        dmxdevfilter->feed.sec->
-                               release_filter(dmxdevfilter->feed.sec,
-                                              dmxdevfilter->filter.sec);
+                           release_filter(dmxdevfilter->feed.sec,
+                                          dmxdevfilter->filter.sec);
                dvb_dmxdev_feed_restart(dmxdevfilter);
-               dmxdevfilter->feed.sec=NULL;
+               dmxdevfilter->feed.sec = NULL;
                break;
        case DMXDEV_TYPE_PES:
                if (!dmxdevfilter->feed.ts)
                        break;
                dvb_dmxdev_feed_stop(dmxdevfilter);
                dmxdevfilter->dev->demux->
-                       release_ts_feed(dmxdevfilter->dev->demux,
-                                       dmxdevfilter->feed.ts);
-               dmxdevfilter->feed.ts=NULL;
+                   release_ts_feed(dmxdevfilter->dev->demux,
+                                   dmxdevfilter->feed.ts);
+               dmxdevfilter->feed.ts = NULL;
                break;
        default:
-               if (dmxdevfilter->state==DMXDEV_STATE_ALLOCATED)
+               if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED)
                        return 0;
                return -EINVAL;
        }
-       dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread=0;
+
+       dvb_ringbuffer_flush(&dmxdevfilter->buffer);
        return 0;
 }
 
 static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter)
 {
-       if (dmxdevfilter->state<DMXDEV_STATE_SET)
+       if (dmxdevfilter->state < DMXDEV_STATE_SET)
                return 0;
 
-       dmxdevfilter->type=DMXDEV_TYPE_NONE;
-       dmxdevfilter->pid=0xffff;
+       dmxdevfilter->type = DMXDEV_TYPE_NONE;
        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
        return 0;
 }
@@ -529,32 +482,33 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
        if (filter->state >= DMXDEV_STATE_GO)
                dvb_dmxdev_filter_stop(filter);
 
-       if (!(mem = filter->buffer.data)) {
+       if (!filter->buffer.data) {
                mem = vmalloc(filter->buffer.size);
+               if (!mem)
+                       return -ENOMEM;
                spin_lock_irq(&filter->dev->lock);
-               filter->buffer.data=mem;
+               filter->buffer.data = mem;
                spin_unlock_irq(&filter->dev->lock);
-               if (!filter->buffer.data)
-                       return -ENOMEM;
        }
 
-       filter->buffer.pwrite = filter->buffer.pread = 0;
+       dvb_ringbuffer_flush(&filter->buffer);
 
        switch (filter->type) {
        case DMXDEV_TYPE_SEC:
        {
-               struct dmx_sct_filter_params *para=&filter->params.sec;
-               struct dmx_section_filter **secfilter=&filter->filter.sec;
-               struct dmx_section_feed **secfeed=&filter->feed.sec;
+               struct dmx_sct_filter_params *para = &filter->params.sec;
+               struct dmx_section_filter **secfilter = &filter->filter.sec;
+               struct dmx_section_feed **secfeed = &filter->feed.sec;
+
+               *secfilter = NULL;
+               *secfeed = NULL;
 
-               *secfilter=NULL;
-               *secfeed=NULL;
 
                /* find active filter/feed with same PID */
-               for (i=0; i<dmxdev->filternum; i++) {
+               for (i = 0; i < dmxdev->filternum; i++) {
                        if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&
-                           dmxdev->filter[i].pid == para->pid &&
-                           dmxdev->filter[i].type == DMXDEV_TYPE_SEC) {
+                           dmxdev->filter[i].type == DMXDEV_TYPE_SEC &&
+                           dmxdev->filter[i].params.sec.pid == para->pid) {
                                *secfeed = dmxdev->filter[i].feed.sec;
                                break;
                        }
@@ -562,21 +516,20 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
 
                /* if no feed found, try to allocate new one */
                if (!*secfeed) {
-                       ret=dmxdev->demux->allocate_section_feed(dmxdev->demux,
-                                                                secfeed,
-                                                  dvb_dmxdev_section_callback);
-                       if (ret<0) {
-                               printk ("DVB (%s): could not alloc feed\n",
-                                       __FUNCTION__);
+                       ret = dmxdev->demux->allocate_section_feed(dmxdev->demux,
+                                                                  secfeed,
+                                                                  dvb_dmxdev_section_callback);
+                       if (ret < 0) {
+                               printk("DVB (%s): could not alloc feed\n",
+                                      __FUNCTION__);
                                return ret;
                        }
 
-                       ret=(*secfeed)->set(*secfeed, para->pid, 32768,
-                                           (para->flags & DMX_CHECK_CRC) ? 1 : 0);
-
-                       if (ret<0) {
-                               printk ("DVB (%s): could not set feed\n",
-                                       __FUNCTION__);
+                       ret = (*secfeed)->set(*secfeed, para->pid, 32768,
+                                             (para->flags & DMX_CHECK_CRC) ? 1 : 0);
+                       if (ret < 0) {
+                               printk("DVB (%s): could not set feed\n",
+                                      __FUNCTION__);
                                dvb_dmxdev_feed_restart(filter);
                                return ret;
                        }
@@ -584,41 +537,38 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
                        dvb_dmxdev_feed_stop(filter);
                }
 
-               ret=(*secfeed)->allocate_filter(*secfeed, secfilter);
-
+               ret = (*secfeed)->allocate_filter(*secfeed, secfilter);
                if (ret < 0) {
                        dvb_dmxdev_feed_restart(filter);
                        filter->feed.sec->start_filtering(*secfeed);
-                       dprintk ("could not get filter\n");
+                       dprintk("could not get filter\n");
                        return ret;
                }
 
                (*secfilter)->priv = filter;
 
                memcpy(&((*secfilter)->filter_value[3]),
-                      &(para->filter.filter[1]), DMX_FILTER_SIZE-1);
+                      &(para->filter.filter[1]), DMX_FILTER_SIZE - 1);
                memcpy(&(*secfilter)->filter_mask[3],
-                      &para->filter.mask[1], DMX_FILTER_SIZE-1);
+                      &para->filter.mask[1], DMX_FILTER_SIZE - 1);
                memcpy(&(*secfilter)->filter_mode[3],
-                      &para->filter.mode[1], DMX_FILTER_SIZE-1);
+                      &para->filter.mode[1], DMX_FILTER_SIZE - 1);
 
-               (*secfilter)->filter_value[0]=para->filter.filter[0];
-               (*secfilter)->filter_mask[0]=para->filter.mask[0];
-               (*secfilter)->filter_mode[0]=para->filter.mode[0];
-               (*secfilter)->filter_mask[1]=0;
-               (*secfilter)->filter_mask[2]=0;
+               (*secfilter)->filter_value[0] = para->filter.filter[0];
+               (*secfilter)->filter_mask[0] = para->filter.mask[0];
+               (*secfilter)->filter_mode[0] = para->filter.mode[0];
+               (*secfilter)->filter_mask[1] = 0;
+               (*secfilter)->filter_mask[2] = 0;
 
                filter->todo = 0;
 
-               ret = filter->feed.sec->start_filtering (filter->feed.sec);
-
+               ret = filter->feed.sec->start_filtering(filter->feed.sec);
                if (ret < 0)
                        return ret;
 
                dvb_dmxdev_filter_timer(filter);
                break;
        }
-
        case DMXDEV_TYPE_PES:
        {
                struct timespec timeout = { 0 };
@@ -630,41 +580,41 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
                struct dmx_ts_feed **tsfeed = &filter->feed.ts;
 
                filter->feed.ts = NULL;
-               otype=para->output;
+               otype = para->output;
 
-               ts_pes=(enum dmx_ts_pes) para->pes_type;
+               ts_pes = (enum dmx_ts_pes)para->pes_type;
 
-               if (ts_pes<DMX_PES_OTHER)
-                       ts_type=TS_DECODER;
+               if (ts_pes < DMX_PES_OTHER)
+                       ts_type = TS_DECODER;
                else
-                       ts_type=0;
+                       ts_type = 0;
 
                if (otype == DMX_OUT_TS_TAP)
                        ts_type |= TS_PACKET;
 
                if (otype == DMX_OUT_TAP)
-                       ts_type |= TS_PAYLOAD_ONLY|TS_PACKET;
+                       ts_type |= TS_PAYLOAD_ONLY | TS_PACKET;
 
-               ret=dmxdev->demux->allocate_ts_feed(dmxdev->demux,
-                                                   tsfeed,
-                                                   dvb_dmxdev_ts_callback);
-               if (ret<0)
+               ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux,
+                                                     tsfeed,
+                                                     dvb_dmxdev_ts_callback);
+               if (ret < 0)
                        return ret;
 
-               (*tsfeed)->priv = (void *) filter;
+               (*tsfeed)->priv = filter;
 
                ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
                                     32768, timeout);
-
                if (ret < 0) {
-                       dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed);
+                       dmxdev->demux->release_ts_feed(dmxdev->demux,
+                                                      *tsfeed);
                        return ret;
                }
 
                ret = filter->feed.ts->start_filtering(filter->feed.ts);
-
                if (ret < 0) {
-                       dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed);
+                       dmxdev->demux->release_ts_feed(dmxdev->demux,
+                                                      *tsfeed);
                        return ret;
                }
 
@@ -688,41 +638,40 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
        if (!dmxdev->filter)
                return -EINVAL;
 
-       if (down_interruptible(&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
-       for (i=0; i<dmxdev->filternum; i++)
-               if (dmxdev->filter[i].state==DMXDEV_STATE_FREE)
+       for (i = 0; i < dmxdev->filternum; i++)
+               if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
                        break;
 
-       if (i==dmxdev->filternum) {
-               up(&dmxdev->mutex);
+       if (i == dmxdev->filternum) {
+               mutex_unlock(&dmxdev->mutex);
                return -EMFILE;
        }
 
-       dmxdevfilter=&dmxdev->filter[i];
-       sema_init(&dmxdevfilter->mutex, 1);
-       dmxdevfilter->dvbdev=dmxdev->dvbdev;
-       file->private_data=dmxdevfilter;
+       dmxdevfilter = &dmxdev->filter[i];
+       mutex_init(&dmxdevfilter->mutex);
+       file->private_data = dmxdevfilter;
 
-       dvb_dmxdev_buffer_init(&dmxdevfilter->buffer);
-       dmxdevfilter->type=DMXDEV_TYPE_NONE;
+       dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
+       dmxdevfilter->type = DMXDEV_TYPE_NONE;
        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
-       dmxdevfilter->feed.ts=NULL;
+       dmxdevfilter->feed.ts = NULL;
        init_timer(&dmxdevfilter->timer);
 
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return 0;
 }
 
-
-static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter)
+static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev,
+                                 struct dmxdev_filter *dmxdevfilter)
 {
-       if (down_interruptible(&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
-       if (down_interruptible(&dmxdevfilter->mutex)) {
-               up(&dmxdev->mutex);
+       if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+               mutex_unlock(&dmxdev->mutex);
                return -ERESTARTSYS;
        }
 
@@ -730,18 +679,18 @@ static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *d
        dvb_dmxdev_filter_reset(dmxdevfilter);
 
        if (dmxdevfilter->buffer.data) {
-               void *mem=dmxdevfilter->buffer.data;
+               void *mem = dmxdevfilter->buffer.data;
 
                spin_lock_irq(&dmxdev->lock);
-               dmxdevfilter->buffer.data=NULL;
+               dmxdevfilter->buffer.data = NULL;
                spin_unlock_irq(&dmxdev->lock);
                vfree(mem);
        }
 
        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE);
        wake_up(&dmxdevfilter->buffer.queue);
-       up(&dmxdevfilter->mutex);
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdevfilter->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return 0;
 }
 
@@ -749,173 +698,171 @@ static inline void invert_mode(dmx_filter_t *filter)
 {
        int i;
 
-       for (i=0; i<DMX_FILTER_SIZE; i++)
-               filter->mode[i]^=0xff;
+       for (i = 0; i < DMX_FILTER_SIZE; i++)
+               filter->mode[i] ^= 0xff;
 }
 
-
 static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
-               struct dmxdev_filter *dmxdevfilter,
-               struct dmx_sct_filter_params *params)
+                                struct dmxdev_filter *dmxdevfilter,
+                                struct dmx_sct_filter_params *params)
 {
-       dprintk ("function : %s\n", __FUNCTION__);
+       dprintk("function : %s\n", __FUNCTION__);
 
        dvb_dmxdev_filter_stop(dmxdevfilter);
 
-       dmxdevfilter->type=DMXDEV_TYPE_SEC;
-       dmxdevfilter->pid=params->pid;
+       dmxdevfilter->type = DMXDEV_TYPE_SEC;
        memcpy(&dmxdevfilter->params.sec,
               params, sizeof(struct dmx_sct_filter_params));
        invert_mode(&dmxdevfilter->params.sec.filter);
        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
 
-       if (params->flags&DMX_IMMEDIATE_START)
+       if (params->flags & DMX_IMMEDIATE_START)
                return dvb_dmxdev_filter_start(dmxdevfilter);
 
        return 0;
 }
 
 static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
-                  struct dmxdev_filter *dmxdevfilter,
-                  struct dmx_pes_filter_params *params)
+                                    struct dmxdev_filter *dmxdevfilter,
+                                    struct dmx_pes_filter_params *params)
 {
        dvb_dmxdev_filter_stop(dmxdevfilter);
 
-       if (params->pes_type>DMX_PES_OTHER || params->pes_type<0)
+       if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0)
                return -EINVAL;
 
-       dmxdevfilter->type=DMXDEV_TYPE_PES;
-       dmxdevfilter->pid=params->pid;
-       memcpy(&dmxdevfilter->params, params, sizeof(struct dmx_pes_filter_params));
+       dmxdevfilter->type = DMXDEV_TYPE_PES;
+       memcpy(&dmxdevfilter->params, params,
+              sizeof(struct dmx_pes_filter_params));
 
        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
 
-       if (params->flags&DMX_IMMEDIATE_START)
+       if (params->flags & DMX_IMMEDIATE_START)
                return dvb_dmxdev_filter_start(dmxdevfilter);
 
        return 0;
 }
 
 static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil,
-               struct file *file, char __user *buf, size_t count, loff_t *ppos)
+                                  struct file *file, char __user *buf,
+                                  size_t count, loff_t *ppos)
 {
        int result, hcount;
-       int done=0;
-
-       if (dfil->todo<=0) {
-               hcount=3+dfil->todo;
-               if (hcount>count)
-                       hcount=count;
-               result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK,
-                                       buf, hcount, ppos);
-               if (result<0) {
-                       dfil->todo=0;
+       int done = 0;
+
+       if (dfil->todo <= 0) {
+               hcount = 3 + dfil->todo;
+               if (hcount > count)
+                       hcount = count;
+               result = dvb_dmxdev_buffer_read(&dfil->buffer,
+                                               file->f_flags & O_NONBLOCK,
+                                               buf, hcount, ppos);
+               if (result < 0) {
+                       dfil->todo = 0;
                        return result;
                }
-               if (copy_from_user(dfil->secheader-dfil->todo, buf, result))
+               if (copy_from_user(dfil->secheader - dfil->todo, buf, result))
                        return -EFAULT;
-               buf+=result;
-               done=result;
-               count-=result;
-               dfil->todo-=result;
-               if (dfil->todo>-3)
+               buf += result;
+               done = result;
+               count -= result;
+               dfil->todo -= result;
+               if (dfil->todo > -3)
                        return done;
-               dfil->todo=((dfil->secheader[1]<<8)|dfil->secheader[2])&0xfff;
+               dfil->todo = ((dfil->secheader[1] << 8) | dfil->secheader[2]) & 0xfff;
                if (!count)
                        return done;
        }
-       if (count>dfil->todo)
-               count=dfil->todo;
-       result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK,
-                               buf, count, ppos);
-       if (result<0)
+       if (count > dfil->todo)
+               count = dfil->todo;
+       result = dvb_dmxdev_buffer_read(&dfil->buffer,
+                                       file->f_flags & O_NONBLOCK,
+                                       buf, count, ppos);
+       if (result < 0)
                return result;
-       dfil->todo-=result;
-       return (result+done);
+       dfil->todo -= result;
+       return (result + done);
 }
 
-
 static ssize_t
-dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+dvb_demux_read(struct file *file, char __user *buf, size_t count,
+              loff_t *ppos)
 {
-       struct dmxdev_filter *dmxdevfilter= file->private_data;
-       int ret=0;
+       struct dmxdev_filter *dmxdevfilter = file->private_data;
+       int ret;
 
-       if (down_interruptible(&dmxdevfilter->mutex))
+       if (mutex_lock_interruptible(&dmxdevfilter->mutex))
                return -ERESTARTSYS;
 
-       if (dmxdevfilter->type==DMXDEV_TYPE_SEC)
-               ret=dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos);
+       if (dmxdevfilter->type == DMXDEV_TYPE_SEC)
+               ret = dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos);
        else
-               ret=dvb_dmxdev_buffer_read(&dmxdevfilter->buffer,
-                                    file->f_flags&O_NONBLOCK,
-                                    buf, count, ppos);
+               ret = dvb_dmxdev_buffer_read(&dmxdevfilter->buffer,
+                                            file->f_flags & O_NONBLOCK,
+                                            buf, count, ppos);
 
-       up(&dmxdevfilter->mutex);
+       mutex_unlock(&dmxdevfilter->mutex);
        return ret;
 }
 
-
 static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
                              unsigned int cmd, void *parg)
 {
        struct dmxdev_filter *dmxdevfilter = file->private_data;
-       struct dmxdev *dmxdev=dmxdevfilter->dev;
-       unsigned long arg=(unsigned long) parg;
-       int ret=0;
+       struct dmxdev *dmxdev = dmxdevfilter->dev;
+       unsigned long arg = (unsigned long)parg;
+       int ret = 0;
 
-       if (down_interruptible (&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
        switch (cmd) {
        case DMX_START:
-               if (down_interruptible(&dmxdevfilter->mutex)) {
-                       up(&dmxdev->mutex);
+               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+                       mutex_unlock(&dmxdev->mutex);
                        return -ERESTARTSYS;
                }
-               if (dmxdevfilter->state<DMXDEV_STATE_SET)
+               if (dmxdevfilter->state < DMXDEV_STATE_SET)
                        ret = -EINVAL;
                else
                        ret = dvb_dmxdev_filter_start(dmxdevfilter);
-               up(&dmxdevfilter->mutex);
+               mutex_unlock(&dmxdevfilter->mutex);
                break;
 
        case DMX_STOP:
-               if (down_interruptible(&dmxdevfilter->mutex)) {
-                       up(&dmxdev->mutex);
+               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+                       mutex_unlock(&dmxdev->mutex);
                        return -ERESTARTSYS;
                }
-               ret=dvb_dmxdev_filter_stop(dmxdevfilter);
-               up(&dmxdevfilter->mutex);
+               ret = dvb_dmxdev_filter_stop(dmxdevfilter);
+               mutex_unlock(&dmxdevfilter->mutex);
                break;
 
        case DMX_SET_FILTER:
-               if (down_interruptible(&dmxdevfilter->mutex)) {
-                       up(&dmxdev->mutex);
+               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+                       mutex_unlock(&dmxdev->mutex);
                        return -ERESTARTSYS;
                }
-               ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter,
-                                   (struct dmx_sct_filter_params *)parg);
-               up(&dmxdevfilter->mutex);
+               ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, parg);
+               mutex_unlock(&dmxdevfilter->mutex);
                break;
 
        case DMX_SET_PES_FILTER:
-               if (down_interruptible(&dmxdevfilter->mutex)) {
-                       up(&dmxdev->mutex);
+               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+                       mutex_unlock(&dmxdev->mutex);
                        return -ERESTARTSYS;
                }
-               ret=dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter,
-                                              (struct dmx_pes_filter_params *)parg);
-               up(&dmxdevfilter->mutex);
+               ret = dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, parg);
+               mutex_unlock(&dmxdevfilter->mutex);
                break;
 
        case DMX_SET_BUFFER_SIZE:
-               if (down_interruptible(&dmxdevfilter->mutex)) {
-                       up(&dmxdev->mutex);
+               if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+                       mutex_unlock(&dmxdev->mutex);
                        return -ERESTARTSYS;
                }
-               ret=dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);
-               up(&dmxdevfilter->mutex);
+               ret = dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);
+               mutex_unlock(&dmxdevfilter->mutex);
                break;
 
        case DMX_GET_EVENT:
@@ -923,10 +870,10 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
 
        case DMX_GET_PES_PIDS:
                if (!dmxdev->demux->get_pes_pids) {
-                       ret=-EINVAL;
+                       ret = -EINVAL;
                        break;
                }
-               dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg);
+               dmxdev->demux->get_pes_pids(dmxdev->demux, parg);
                break;
 
        case DMX_GET_CAPS:
@@ -947,19 +894,20 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
 
        case DMX_GET_STC:
                if (!dmxdev->demux->get_stc) {
-                       ret=-EINVAL;
+                       ret = -EINVAL;
                        break;
                }
                ret = dmxdev->demux->get_stc(dmxdev->demux,
-                               ((struct dmx_stc *)parg)->num,
-                               &((struct dmx_stc *)parg)->stc,
-                               &((struct dmx_stc *)parg)->base);
+                                            ((struct dmx_stc *)parg)->num,
+                                            &((struct dmx_stc *)parg)->stc,
+                                            &((struct dmx_stc *)parg)->base);
                break;
 
        default:
-               ret=-EINVAL;
+               ret = -EINVAL;
+               break;
        }
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return ret;
 }
 
@@ -969,8 +917,7 @@ static int dvb_demux_ioctl(struct inode *inode, struct file *file,
        return dvb_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl);
 }
 
-
-static unsigned int dvb_demux_poll (struct file *file, poll_table *wait)
+static unsigned int dvb_demux_poll(struct file *file, poll_table *wait)
 {
        struct dmxdev_filter *dmxdevfilter = file->private_data;
        unsigned int mask = 0;
@@ -988,13 +935,12 @@ static unsigned int dvb_demux_poll (struct file *file, poll_table *wait)
        if (dmxdevfilter->buffer.error)
                mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
 
-       if (dmxdevfilter->buffer.pread != dmxdevfilter->buffer.pwrite)
+       if (!dvb_ringbuffer_empty(&dmxdevfilter->buffer))
                mask |= (POLLIN | POLLRDNORM | POLLPRI);
 
        return mask;
 }
 
-
 static int dvb_demux_release(struct inode *inode, struct file *file)
 {
        struct dmxdev_filter *dmxdevfilter = file->private_data;
@@ -1003,72 +949,67 @@ static int dvb_demux_release(struct inode *inode, struct file *file)
        return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
 }
 
-
 static struct file_operations dvb_demux_fops = {
-       .owner          = THIS_MODULE,
-       .read           = dvb_demux_read,
-       .ioctl          = dvb_demux_ioctl,
-       .open           = dvb_demux_open,
-       .release        = dvb_demux_release,
-       .poll           = dvb_demux_poll,
+       .owner = THIS_MODULE,
+       .read = dvb_demux_read,
+       .ioctl = dvb_demux_ioctl,
+       .open = dvb_demux_open,
+       .release = dvb_demux_release,
+       .poll = dvb_demux_poll,
 };
 
-
 static struct dvb_device dvbdev_demux = {
-       .priv           = NULL,
-       .users          = 1,
-       .writers        = 1,
-       .fops           = &dvb_demux_fops
+       .priv = NULL,
+       .users = 1,
+       .writers = 1,
+       .fops = &dvb_demux_fops
 };
 
-
 static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
-                    unsigned int cmd, void *parg)
+                           unsigned int cmd, void *parg)
 {
        struct dvb_device *dvbdev = file->private_data;
        struct dmxdev *dmxdev = dvbdev->priv;
+       int ret;
 
-       int ret=0;
-
-       if (down_interruptible (&dmxdev->mutex))
+       if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
        switch (cmd) {
        case DMX_SET_BUFFER_SIZE:
                // FIXME: implement
-               ret=0;
+               ret = 0;
                break;
 
        default:
-               ret=-EINVAL;
+               ret = -EINVAL;
+               break;
        }
-       up(&dmxdev->mutex);
+       mutex_unlock(&dmxdev->mutex);
        return ret;
 }
 
-
 static int dvb_dvr_ioctl(struct inode *inode, struct file *file,
-                 unsigned int cmd, unsigned long arg)
+                        unsigned int cmd, unsigned long arg)
 {
        return dvb_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl);
 }
 
-
-static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait)
+static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
 {
        struct dvb_device *dvbdev = file->private_data;
        struct dmxdev *dmxdev = dvbdev->priv;
        unsigned int mask = 0;
 
-       dprintk ("function : %s\n", __FUNCTION__);
+       dprintk("function : %s\n", __FUNCTION__);
 
        poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
 
-       if ((file->f_flags&O_ACCMODE) == O_RDONLY) {
+       if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
                if (dmxdev->dvr_buffer.error)
                        mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
 
-               if (dmxdev->dvr_buffer.pread!=dmxdev->dvr_buffer.pwrite)
+               if (!dvb_ringbuffer_empty(&dmxdev->dvr_buffer))
                        mask |= (POLLIN | POLLRDNORM | POLLPRI);
        } else
                mask |= (POLLOUT | POLLWRNORM | POLLPRI);
@@ -1076,73 +1017,63 @@ static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait)
        return mask;
 }
 
-
 static struct file_operations dvb_dvr_fops = {
-       .owner          = THIS_MODULE,
-       .read           = dvb_dvr_read,
-       .write          = dvb_dvr_write,
-       .ioctl          = dvb_dvr_ioctl,
-       .open           = dvb_dvr_open,
-       .release        = dvb_dvr_release,
-       .poll           = dvb_dvr_poll,
+       .owner = THIS_MODULE,
+       .read = dvb_dvr_read,
+       .write = dvb_dvr_write,
+       .ioctl = dvb_dvr_ioctl,
+       .open = dvb_dvr_open,
+       .release = dvb_dvr_release,
+       .poll = dvb_dvr_poll,
 };
 
 static struct dvb_device dvbdev_dvr = {
-       .priv           = NULL,
-       .users          = 1,
-       .writers        = 1,
-       .fops           = &dvb_dvr_fops
+       .priv = NULL,
+       .users = 1,
+       .writers = 1,
+       .fops = &dvb_dvr_fops
 };
 
-int
-dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
+int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
 {
        int i;
 
        if (dmxdev->demux->open(dmxdev->demux) < 0)
                return -EUSERS;
 
-       dmxdev->filter = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_filter));
+       dmxdev->filter = vmalloc(dmxdev->filternum * sizeof(struct dmxdev_filter));
        if (!dmxdev->filter)
                return -ENOMEM;
 
-       dmxdev->dvr = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_dvr));
-       if (!dmxdev->dvr) {
-               vfree(dmxdev->filter);
-               dmxdev->filter = NULL;
-               return -ENOMEM;
-       }
-
-       sema_init(&dmxdev->mutex, 1);
+       mutex_init(&dmxdev->mutex);
        spin_lock_init(&dmxdev->lock);
-       for (i=0; i<dmxdev->filternum; i++) {
-               dmxdev->filter[i].dev=dmxdev;
-               dmxdev->filter[i].buffer.data=NULL;
-               dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
-               dmxdev->dvr[i].dev=dmxdev;
-               dmxdev->dvr[i].buffer.data=NULL;
-               dvb_dmxdev_dvr_state_set(&dmxdev->dvr[i], DMXDEV_STATE_FREE);
+       for (i = 0; i < dmxdev->filternum; i++) {
+               dmxdev->filter[i].dev = dmxdev;
+               dmxdev->filter[i].buffer.data = NULL;
+               dvb_dmxdev_filter_state_set(&dmxdev->filter[i],
+                                           DMXDEV_STATE_FREE);
        }
 
-       dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, DVB_DEVICE_DEMUX);
-       dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, dmxdev, DVB_DEVICE_DVR);
+       dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
+                           DVB_DEVICE_DEMUX);
+       dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
+                           dmxdev, DVB_DEVICE_DVR);
 
-       dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer);
+       dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
 
        return 0;
 }
+
 EXPORT_SYMBOL(dvb_dmxdev_init);
 
-void
-dvb_dmxdev_release(struct dmxdev *dmxdev)
+void dvb_dmxdev_release(struct dmxdev *dmxdev)
 {
        dvb_unregister_device(dmxdev->dvbdev);
        dvb_unregister_device(dmxdev->dvr_dvbdev);
 
        vfree(dmxdev->filter);
-       dmxdev->filter=NULL;
-       vfree(dmxdev->dvr);
-       dmxdev->dvr=NULL;
+       dmxdev->filter = NULL;
        dmxdev->demux->close(dmxdev->demux);
 }
+
 EXPORT_SYMBOL(dvb_dmxdev_release);
index fd72920c21998586cab856d1796f543460d2968d..d2bee9ffe43cff81421bba33846c42cae9234f92 100644 (file)
 #include <linux/wait.h>
 #include <linux/fs.h>
 #include <linux/string.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #include <linux/dvb/dmx.h>
 
 #include "dvbdev.h"
 #include "demux.h"
+#include "dvb_ringbuffer.h"
 
-enum dmxdevype {
+enum dmxdev_type {
        DMXDEV_TYPE_NONE,
        DMXDEV_TYPE_SEC,
        DMXDEV_TYPE_PES,
@@ -52,18 +53,7 @@ enum dmxdev_state {
        DMXDEV_STATE_TIMEDOUT
 };
 
-struct dmxdev_buffer {
-       u8 *data;
-       int size;
-       int pread;
-       int pwrite;
-       wait_queue_head_t queue;
-       int error;
-};
-
 struct dmxdev_filter {
-       struct dvb_device *dvbdev;
-
        union {
                struct dmx_section_filter *sec;
        } filter;
@@ -78,26 +68,17 @@ struct dmxdev_filter {
                struct dmx_pes_filter_params pes;
        } params;
 
-       int type;
+       enum dmxdev_type type;
        enum dmxdev_state state;
        struct dmxdev *dev;
-       struct dmxdev_buffer buffer;
+       struct dvb_ringbuffer buffer;
 
-       struct semaphore mutex;
+       struct mutex mutex;
 
        /* only for sections */
        struct timer_list timer;
        int todo;
        u8 secheader[3];
-
-       u16 pid;
-};
-
-
-struct dmxdev_dvr {
-       int state;
-       struct dmxdev *dev;
-       struct dmxdev_buffer buffer;
 };
 
 
@@ -106,7 +87,6 @@ struct dmxdev {
        struct dvb_device *dvr_dvbdev;
 
        struct dmxdev_filter *filter;
-       struct dmxdev_dvr *dvr;
        struct dmx_demux *demux;
 
        int filternum;
@@ -114,10 +94,10 @@ struct dmxdev {
 #define DMXDEV_CAP_DUPLEX 1
        struct dmx_frontend *dvr_orig_fe;
 
-       struct dmxdev_buffer dvr_buffer;
+       struct dvb_ringbuffer dvr_buffer;
 #define DVR_BUFFER_SIZE (10*188*1024)
 
-       struct semaphore mutex;
+       struct mutex mutex;
        spinlock_t lock;
 };
 
index b4c899b15959c62d016388926b00ea2f83624670..83ec5e06c48287ea538ae31920c978b0e3c83a53 100644 (file)
@@ -589,18 +589,18 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
        if (pid > DMX_MAX_PID)
                return -EINVAL;
 
-       if (down_interruptible(&demux->mutex))
+       if (mutex_lock_interruptible(&demux->mutex))
                return -ERESTARTSYS;
 
        if (ts_type & TS_DECODER) {
                if (pes_type >= DMX_TS_PES_OTHER) {
-                       up(&demux->mutex);
+                       mutex_unlock(&demux->mutex);
                        return -EINVAL;
                }
 
                if (demux->pesfilter[pes_type] &&
                    demux->pesfilter[pes_type] != feed) {
-                       up(&demux->mutex);
+                       mutex_unlock(&demux->mutex);
                        return -EINVAL;
                }
 
@@ -622,14 +622,14 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
 #else
                feed->buffer = vmalloc(feed->buffer_size);
                if (!feed->buffer) {
-                       up(&demux->mutex);
+                       mutex_unlock(&demux->mutex);
                        return -ENOMEM;
                }
 #endif
        }
 
        feed->state = DMX_STATE_READY;
-       up(&demux->mutex);
+       mutex_unlock(&demux->mutex);
 
        return 0;
 }
@@ -640,21 +640,21 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed)
        struct dvb_demux *demux = feed->demux;
        int ret;
 
-       if (down_interruptible(&demux->mutex))
+       if (mutex_lock_interruptible(&demux->mutex))
                return -ERESTARTSYS;
 
        if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -EINVAL;
        }
 
        if (!demux->start_feed) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -ENODEV;
        }
 
        if ((ret = demux->start_feed(feed)) < 0) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return ret;
        }
 
@@ -662,7 +662,7 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed)
        ts_feed->is_filtering = 1;
        feed->state = DMX_STATE_GO;
        spin_unlock_irq(&demux->lock);
-       up(&demux->mutex);
+       mutex_unlock(&demux->mutex);
 
        return 0;
 }
@@ -673,16 +673,16 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed)
        struct dvb_demux *demux = feed->demux;
        int ret;
 
-       if (down_interruptible(&demux->mutex))
+       if (mutex_lock_interruptible(&demux->mutex))
                return -ERESTARTSYS;
 
        if (feed->state < DMX_STATE_GO) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -EINVAL;
        }
 
        if (!demux->stop_feed) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -ENODEV;
        }
 
@@ -692,7 +692,7 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed)
        ts_feed->is_filtering = 0;
        feed->state = DMX_STATE_ALLOCATED;
        spin_unlock_irq(&demux->lock);
-       up(&demux->mutex);
+       mutex_unlock(&demux->mutex);
 
        return ret;
 }
@@ -704,11 +704,11 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
        struct dvb_demux *demux = (struct dvb_demux *)dmx;
        struct dvb_demux_feed *feed;
 
-       if (down_interruptible(&demux->mutex))
+       if (mutex_lock_interruptible(&demux->mutex))
                return -ERESTARTSYS;
 
        if (!(feed = dvb_dmx_feed_alloc(demux))) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -EBUSY;
        }
 
@@ -729,7 +729,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
 
        if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
                feed->state = DMX_STATE_FREE;
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -EBUSY;
        }
 
@@ -737,7 +737,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
        feed->filter->feed = feed;
        feed->filter->state = DMX_STATE_READY;
 
-       up(&demux->mutex);
+       mutex_unlock(&demux->mutex);
 
        return 0;
 }
@@ -748,11 +748,11 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
        struct dvb_demux *demux = (struct dvb_demux *)dmx;
        struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
 
-       if (down_interruptible(&demux->mutex))
+       if (mutex_lock_interruptible(&demux->mutex))
                return -ERESTARTSYS;
 
        if (feed->state == DMX_STATE_FREE) {
-               up(&demux->mutex);
+               mutex_unlock(&demux->mutex);
                return -EINVAL;
        }
 #ifndef NOBUFS
@@ -770,7 +770,7 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
        if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER)
                demux->pesfilter[feed->pes_type] = NULL;
 
-       up(&demux->mutex);
+       mutex_unlock(&demux->mutex);
        return 0;
 }
 
@@ -785,12 +785,12 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed,
        struct dvb_demux *dvbdemux = dvbdmxfeed->demux;
        struct dvb_demux_filter *dvbdmxfilter;
 
-       if (down_interruptible(&dvbdemux->mutex))
+       if (mutex_lock_interruptible(&dvbdemux->mutex))
                return -ERESTARTSYS;
 
        dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux);
        if (!dvbdmxfilter) {
-               up(&dvbdemux->mutex);
+               mutex_unlock(&dvbdemux->mutex);
                return -EBUSY;
        }
 
@@ -805,7 +805,7 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed,
        dvbdmxfeed->filter = dvbdmxfilter;
        spin_unlock_irq(&dvbdemux->lock);
 
-       up(&dvbdemux->mutex);
+       mutex_unlock(&dvbdemux->mutex);
        return 0;
 }
 
@@ -819,7 +819,7 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed,
        if (pid > 0x1fff)
                return -EINVAL;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        dvb_demux_feed_add(dvbdmxfeed);
@@ -833,13 +833,13 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed,
 #else
        dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size);
        if (!dvbdmxfeed->buffer) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -ENOMEM;
        }
 #endif
 
        dvbdmxfeed->state = DMX_STATE_READY;
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return 0;
 }
 
@@ -871,16 +871,16 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
        struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
        int ret;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        if (feed->is_filtering) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -EBUSY;
        }
 
        if (!dvbdmxfeed->filter) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -EINVAL;
        }
 
@@ -890,14 +890,14 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
        dvbdmxfeed->feed.sec.seclen = 0;
 
        if (!dvbdmx->start_feed) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -ENODEV;
        }
 
        prepare_secfilters(dvbdmxfeed);
 
        if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return ret;
        }
 
@@ -906,7 +906,7 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
        dvbdmxfeed->state = DMX_STATE_GO;
        spin_unlock_irq(&dvbdmx->lock);
 
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return 0;
 }
 
@@ -916,11 +916,11 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
        struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
        int ret;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        if (!dvbdmx->stop_feed) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -ENODEV;
        }
 
@@ -931,7 +931,7 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
        feed->is_filtering = 0;
        spin_unlock_irq(&dvbdmx->lock);
 
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return ret;
 }
 
@@ -942,11 +942,11 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
        struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
        struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        if (dvbdmxfilter->feed != dvbdmxfeed) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -EINVAL;
        }
 
@@ -966,7 +966,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
 
        dvbdmxfilter->state = DMX_STATE_FREE;
        spin_unlock_irq(&dvbdmx->lock);
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return 0;
 }
 
@@ -977,11 +977,11 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
        struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
        struct dvb_demux_feed *dvbdmxfeed;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -EBUSY;
        }
 
@@ -1006,7 +1006,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
        (*feed)->stop_filtering = dmx_section_feed_stop_filtering;
        (*feed)->release_filter = dmx_section_feed_release_filter;
 
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return 0;
 }
 
@@ -1016,11 +1016,11 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
        struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
        struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
 
-       if (down_interruptible(&dvbdmx->mutex))
+       if (mutex_lock_interruptible(&dvbdmx->mutex))
                return -ERESTARTSYS;
 
        if (dvbdmxfeed->state == DMX_STATE_FREE) {
-               up(&dvbdmx->mutex);
+               mutex_unlock(&dvbdmx->mutex);
                return -EINVAL;
        }
 #ifndef NOBUFS
@@ -1033,7 +1033,7 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
 
        dvbdmxfeed->pid = 0xffff;
 
-       up(&dvbdmx->mutex);
+       mutex_unlock(&dvbdmx->mutex);
        return 0;
 }
 
@@ -1071,10 +1071,10 @@ static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
        if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
                return -EINVAL;
 
-       if (down_interruptible(&dvbdemux->mutex))
+       if (mutex_lock_interruptible(&dvbdemux->mutex))
                return -ERESTARTSYS;
        dvb_dmx_swfilter(dvbdemux, buf, count);
-       up(&dvbdemux->mutex);
+       mutex_unlock(&dvbdemux->mutex);
 
        if (signal_pending(current))
                return -EINTR;
@@ -1126,11 +1126,11 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux,
        if (demux->frontend)
                return -EINVAL;
 
-       if (down_interruptible(&dvbdemux->mutex))
+       if (mutex_lock_interruptible(&dvbdemux->mutex))
                return -ERESTARTSYS;
 
        demux->frontend = frontend;
-       up(&dvbdemux->mutex);
+       mutex_unlock(&dvbdemux->mutex);
        return 0;
 }
 
@@ -1138,11 +1138,11 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
 {
        struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
 
-       if (down_interruptible(&dvbdemux->mutex))
+       if (mutex_lock_interruptible(&dvbdemux->mutex))
                return -ERESTARTSYS;
 
        demux->frontend = NULL;
-       up(&dvbdemux->mutex);
+       mutex_unlock(&dvbdemux->mutex);
        return 0;
 }
 
@@ -1215,7 +1215,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
        dmx->disconnect_frontend = dvbdmx_disconnect_frontend;
        dmx->get_pes_pids = dvbdmx_get_pes_pids;
 
-       sema_init(&dvbdemux->mutex, 1);
+       mutex_init(&dvbdemux->mutex);
        spin_lock_init(&dvbdemux->lock);
 
        return 0;
index 0cc888339d52e0894effd9e227756bc340057165..2c5f915329ca9c5658e68628208f57c58c856364 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/time.h>
 #include <linux/timer.h>
 #include <linux/spinlock.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #include "demux.h"
 
@@ -125,7 +125,7 @@ struct dvb_demux {
        u8 tsbuf[204];
        int tsbufp;
 
-       struct semaphore mutex;
+       struct mutex mutex;
        spinlock_t lock;
 };
 
index 771f32d889e6261de8b8c77d10fad85b55da20a4..2c3ea8f95dcd4106c084fc99c3cf2a543d82256a 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/suspend.h>
 #include <linux/jiffies.h>
 #include <asm/processor.h>
-#include <asm/semaphore.h>
 
 #include "dvb_frontend.h"
 #include "dvbdev.h"
@@ -50,13 +49,13 @@ static int dvb_powerdown_on_sleep = 1;
 
 module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
 MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off).");
-module_param(dvb_shutdown_timeout, int, 0444);
+module_param(dvb_shutdown_timeout, int, 0644);
 MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");
-module_param(dvb_force_auto_inversion, int, 0444);
+module_param(dvb_force_auto_inversion, int, 0644);
 MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always");
-module_param(dvb_override_tune_delay, int, 0444);
+module_param(dvb_override_tune_delay, int, 0644);
 MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
-module_param(dvb_powerdown_on_sleep, int, 0444);
+module_param(dvb_powerdown_on_sleep, int, 0644);
 MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)");
 
 #define dprintk if (dvb_frontend_debug) printk
@@ -88,7 +87,7 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB vola
  * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
  */
 
-static DECLARE_MUTEX(frontend_mutex);
+static DEFINE_MUTEX(frontend_mutex);
 
 struct dvb_frontend_private {
 
@@ -1021,12 +1020,12 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
 
        dprintk ("%s\n", __FUNCTION__);
 
-       if (down_interruptible (&frontend_mutex))
+       if (mutex_lock_interruptible(&frontend_mutex))
                return -ERESTARTSYS;
 
        fe->frontend_priv = kzalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL);
        if (fe->frontend_priv == NULL) {
-               up(&frontend_mutex);
+               mutex_unlock(&frontend_mutex);
                return -ENOMEM;
        }
        fepriv = fe->frontend_priv;
@@ -1045,7 +1044,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
        dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
                             fe, DVB_DEVICE_FRONTEND);
 
-       up (&frontend_mutex);
+       mutex_unlock(&frontend_mutex);
        return 0;
 }
 EXPORT_SYMBOL(dvb_register_frontend);
@@ -1055,7 +1054,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
        struct dvb_frontend_private *fepriv = fe->frontend_priv;
        dprintk ("%s\n", __FUNCTION__);
 
-       down (&frontend_mutex);
+       mutex_lock(&frontend_mutex);
        dvb_unregister_device (fepriv->dvbdev);
        dvb_frontend_stop (fe);
        if (fe->ops->release)
@@ -1064,7 +1063,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
                printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name);
        /* fe is invalid now */
        kfree(fepriv);
-       up (&frontend_mutex);
+       mutex_unlock(&frontend_mutex);
        return 0;
 }
 EXPORT_SYMBOL(dvb_unregister_frontend);
index 70a6d14efda72dddb4b2cb9b92127e77534ce853..d5aee5ad67a0f819877b09b61a69de2963591530 100644 (file)
@@ -104,6 +104,7 @@ struct dvb_frontend {
        struct dvb_adapter *dvb;
        void* demodulator_priv;
        void* frontend_priv;
+       void* misc_priv;
 };
 
 extern int dvb_register_frontend(struct dvb_adapter* dvb,
index 6711eb6a058c9bc6548bb323c684785e549a3466..2f0f35811bf7710c2a95e63bbeaa37c2900be0af 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/uio.h>
 #include <asm/uaccess.h>
 #include <linux/crc32.h>
+#include <linux/mutex.h>
 
 #include "dvb_demux.h"
 #include "dvb_net.h"
@@ -151,8 +152,7 @@ struct dvb_net_priv {
        unsigned char ule_bridged;              /* Whether the ULE_BRIDGED extension header was found. */
        int ule_sndu_remain;                    /* Nr. of bytes still required for current ULE SNDU. */
        unsigned long ts_count;                 /* Current ts cell counter. */
-
-       struct semaphore mutex;
+       struct mutex mutex;
 };
 
 
@@ -889,7 +889,7 @@ static int dvb_net_feed_start(struct net_device *dev)
        unsigned char *mac = (unsigned char *) dev->dev_addr;
 
        dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode);
-       down(&priv->mutex);
+       mutex_lock(&priv->mutex);
        if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
                printk("%s: BUG %d\n", __FUNCTION__, __LINE__);
 
@@ -974,7 +974,7 @@ static int dvb_net_feed_start(struct net_device *dev)
                ret = -EINVAL;
 
 error:
-       up(&priv->mutex);
+       mutex_unlock(&priv->mutex);
        return ret;
 }
 
@@ -984,7 +984,7 @@ static int dvb_net_feed_stop(struct net_device *dev)
        int i, ret = 0;
 
        dprintk("%s\n", __FUNCTION__);
-       down(&priv->mutex);
+       mutex_lock(&priv->mutex);
        if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
                if (priv->secfeed) {
                        if (priv->secfeed->is_filtering) {
@@ -1026,7 +1026,7 @@ static int dvb_net_feed_stop(struct net_device *dev)
                        printk("%s: no ts feed to stop\n", dev->name);
        } else
                ret = -EINVAL;
-       up(&priv->mutex);
+       mutex_unlock(&priv->mutex);
        return ret;
 }
 
@@ -1208,7 +1208,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
 
        INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);
        INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);
-       init_MUTEX(&priv->mutex);
+       mutex_init(&priv->mutex);
 
        net->base_addr = pid;
 
index 77ad2410f4d3cd29cfb3a63a72c6dd6512c22cba..c972fe014c58283bdbca41f584cb76be583b0b61 100644 (file)
@@ -45,6 +45,7 @@ void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len)
        rbuf->pread=rbuf->pwrite=0;
        rbuf->data=data;
        rbuf->size=len;
+       rbuf->error=0;
 
        init_waitqueue_head(&rbuf->queue);
 
@@ -87,6 +88,7 @@ ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf)
 void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
 {
        rbuf->pread = rbuf->pwrite;
+       rbuf->error = 0;
 }
 
 
index 6d25609727719df623adfd83fde491fb1d071cf2..d97714e757362b6ee62204de6444b68337faaede 100644 (file)
@@ -35,6 +35,7 @@ struct dvb_ringbuffer {
        ssize_t           size;
        ssize_t           pread;
        ssize_t           pwrite;
+       int               error;
 
        wait_queue_head_t queue;
        spinlock_t        lock;
index 162f9795cd899268056f830b45f67ce6ad5c6b70..e14bf43941e33874554e7d39fc87c5525859f126 100644 (file)
@@ -77,7 +77,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
        int i;
 
-       if (down_interruptible(&d->i2c_sem) < 0)
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
                return -EAGAIN;
 
        if (num > 2)
@@ -126,7 +126,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
                }
        }
 
-       up(&d->i2c_sem);
+       mutex_unlock(&d->i2c_mutex);
        return i;
 }
 
index 269d899da488336024e70286a8773b48cff65c77..2d52b76671d35a729eea31b3bb16cf3f50b97953 100644 (file)
@@ -128,7 +128,7 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
        int i;
 
-       if (down_interruptible(&d->i2c_sem) < 0)
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
                return -EAGAIN;
 
        if (num > 2)
@@ -146,7 +146,7 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
                                break;
        }
 
-       up(&d->i2c_sem);
+       mutex_unlock(&d->i2c_mutex);
        return i;
 }
 
index caa1346e3063076c74b5a17dcc1e5f905a254a9a..91136c00ce9ddf5bf3b5d1957601c05d0148decc 100644 (file)
@@ -48,7 +48,7 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
        int i;
 
-       if (down_interruptible(&d->i2c_sem) < 0)
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
                return -EAGAIN;
 
        if (num > 2)
@@ -67,7 +67,7 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
                                break;
        }
 
-       up(&d->i2c_sem);
+       mutex_unlock(&d->i2c_mutex);
        return i;
 }
 
index ce34a55e5c243095ca8853f4e382f93fdd2047dc..a1705ecb9a544ac8c99872daa9f658a0f4051815 100644 (file)
@@ -42,8 +42,8 @@ static int dvb_usb_init(struct dvb_usb_device *d)
 {
        int ret = 0;
 
-       sema_init(&d->usb_sem, 1);
-       sema_init(&d->i2c_sem, 1);
+       mutex_init(&d->usb_mutex);
+       mutex_init(&d->i2c_mutex);
 
        d->state = DVB_USB_STATE_INIT;
 
index ee821974dc604a97d9fed5ffa084f620e2c14a60..9002f35aa952822f7144b15bfeddf76fff08c2b8 100644 (file)
@@ -21,7 +21,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
        if (wbuf == NULL || wlen == 0)
                return -EINVAL;
 
-       if ((ret = down_interruptible(&d->usb_sem)))
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
                return ret;
 
        deb_xfer(">>> ");
@@ -53,7 +53,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
                }
        }
 
-       up(&d->usb_sem);
+       mutex_unlock(&d->usb_mutex);
        return ret;
 }
 EXPORT_SYMBOL(dvb_usb_generic_rw);
index d4909e5c67e063f89a92d3f7dd184d209ffea800..fead958a57e3d0758461cec8317bef45bdb41e80 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/input.h>
 #include <linux/usb.h>
 #include <linux/firmware.h>
+#include <linux/mutex.h>
 
 #include "dvb_frontend.h"
 #include "dvb_demux.h"
@@ -227,8 +228,8 @@ struct dvb_usb_properties {
  * @feedcount: number of reqested feeds (used for streaming-activation)
  * @pid_filtering: is hardware pid_filtering used or not.
  *
- * @usb_sem: semaphore of USB control messages (reading needs two messages)
- * @i2c_sem: semaphore for i2c-transfers
+ * @usb_mutex: semaphore of USB control messages (reading needs two messages)
+ * @i2c_mutex: semaphore for i2c-transfers
  *
  * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
  * @pll_addr: I2C address of the tuner for programming
@@ -283,10 +284,10 @@ struct dvb_usb_device {
        int pid_filtering;
 
        /* locking */
-       struct semaphore usb_sem;
+       struct mutex usb_mutex;
 
        /* i2c */
-       struct semaphore i2c_sem;
+       struct mutex i2c_mutex;
        struct i2c_adapter i2c_adap;
 
        /* tuner programming information */
index 4a95eca81c5cc28bef8354bbeca4ad5d6d1d6774..b2f098a2d5f7ee31f8baa891fcd784a0d2497532 100644 (file)
@@ -75,7 +75,7 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il
 {
        int ret;
 
-       if ((ret = down_interruptible(&d->usb_sem)))
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
                return ret;
 
        if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0)
@@ -84,7 +84,7 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il
        ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen);
 
 unlock:
-       up(&d->usb_sem);
+       mutex_unlock(&d->usb_mutex);
 
        return ret;
 }
index 3835235b68dff0f18793c0b711af42c3160ed6cd..8ea3834a6cf8a2091d9908081c6e5f85ee69d618 100644 (file)
@@ -38,7 +38,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
        deb_xfer("out buffer: ");
        debug_dump(outbuf,outlen+1,deb_xfer);
 
-       if ((ret = down_interruptible(&d->usb_sem)))
+       if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
                return ret;
 
        if (usb_control_msg(d->udev,
@@ -68,7 +68,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
                memcpy(in,&inbuf[1],inlen);
 
 unlock:
-       up(&d->usb_sem);
+       mutex_unlock(&d->usb_mutex);
 
        return ret;
 }
index c676b1e23ab0d1cb2d3ef2d6c4ead09a9dbf73d4..94233168d2415ab1d4d45d3e16c01ab2b33ff0aa 100644 (file)
@@ -116,6 +116,12 @@ config DVB_MT352
        help
          A DVB-T tuner module. Say Y when you want to support this frontend.
 
+config DVB_ZL10353
+       tristate "Zarlink ZL10353 based"
+       depends on DVB_CORE
+       help
+         A DVB-T tuner module. Say Y when you want to support this frontend.
+
 config DVB_DIB3000MB
        tristate "DiBcom 3000M-B"
        depends on DVB_CORE
@@ -155,7 +161,7 @@ comment "ATSC (North American/Korean Terresterial DTV) frontends"
        depends on DVB_CORE
 
 config DVB_NXT200X
-       tristate "Nextwave NXT2002/NXT2004 based"
+       tristate "NxtWave Communications NXT2002/NXT2004 based"
        depends on DVB_CORE
        select FW_LOADER
        help
@@ -169,14 +175,14 @@ config DVB_NXT200X
          or /lib/firmware (depending on configuration of firmware hotplug).
 
 config DVB_OR51211
-       tristate "or51211 based (pcHDTV HD2000 card)"
+       tristate "Oren OR51211 based"
        depends on DVB_CORE
        select FW_LOADER
        help
          An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
 
 config DVB_OR51132
-       tristate "OR51132 based (pcHDTV HD3000 card)"
+       tristate "Oren OR51132 based"
        depends on DVB_CORE
        select FW_LOADER
        help
index 1af769cd90c021d16d2e3e969306c0df4f508f8d..d09b6071fbaf23763400135137f3fcd87b64af2c 100644 (file)
@@ -20,6 +20,7 @@ obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
 obj-$(CONFIG_DVB_SP887X) += sp887x.o
 obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
 obj-$(CONFIG_DVB_MT352) += mt352.o
+obj-$(CONFIG_DVB_ZL10353) += zl10353.o
 obj-$(CONFIG_DVB_CX22702) += cx22702.o
 obj-$(CONFIG_DVB_TDA10021) += tda10021.o
 obj-$(CONFIG_DVB_STV0297) += stv0297.o
index caaee893ca7674d048ba91b16c084c09b5934fd8..1708a1d4893e4a7c9a9173d88555caef7016a171 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/jiffies.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/mutex.h>
 
 #include "dvb_frontend.h"
 #include "bcm3510.h"
@@ -52,7 +53,7 @@ struct bcm3510_state {
        struct dvb_frontend frontend;
 
        /* demodulator private data */
-       struct semaphore hab_sem;
+       struct mutex hab_mutex;
        u8 firmware_loaded:1;
 
        unsigned long next_status_check;
@@ -213,7 +214,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob
        dbufout(ob,olen+2,deb_hab);
        deb_hab("\n");
 
-       if (down_interruptible(&st->hab_sem) < 0)
+       if (mutex_lock_interruptible(&st->hab_mutex) < 0)
                return -EAGAIN;
 
        if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
@@ -226,7 +227,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob
 
        memcpy(ibuf,&ib[2],ilen);
 error:
-       up(&st->hab_sem);
+       mutex_unlock(&st->hab_mutex);
        return ret;
 }
 
@@ -796,7 +797,7 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
        state->frontend.ops = &state->ops;
        state->frontend.demodulator_priv = state;
 
-       sema_init(&state->hab_sem, 1);
+       mutex_init(&state->hab_mutex);
 
        if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
                goto error;
diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h
new file mode 100644 (file)
index 0000000..78573b2
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * bsbe1.h - ALPS BSBE1 tuner support (moved from av7110.c)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef BSBE1_H
+#define BSBE1_H
+
+static u8 alps_bsbe1_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x30,
+       0x03, 0x00,
+       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
+       0x06, 0x40,   /* DAC not used, set to high impendance mode */
+       0x07, 0x00,   /* DAC LSB */
+       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
+       0x09, 0x00,   /* FIFO */
+       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
+       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
+       0x10, 0x3f,   // AGC2  0x3d
+       0x11, 0x84,
+       0x12, 0xb9,
+       0x15, 0xc9,   // lock detector threshold
+       0x16, 0x00,
+       0x17, 0x00,
+       0x18, 0x00,
+       0x19, 0x00,
+       0x1a, 0x00,
+       0x1f, 0x50,
+       0x20, 0x00,
+       0x21, 0x00,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
+       0x29, 0x1e,  // 1/2 threshold
+       0x2a, 0x14,  // 2/3 threshold
+       0x2b, 0x0f,  // 3/4 threshold
+       0x2c, 0x09,  // 5/6 threshold
+       0x2d, 0x05,  // 7/8 threshold
+       0x2e, 0x01,
+       0x31, 0x1f,  // test all FECs
+       0x32, 0x19,  // viterbi and synchro search
+       0x33, 0xfc,  // rs control
+       0x34, 0x93,  // error control
+       0x0f, 0x92,
+       0xff, 0xff
+};
+
+
+static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
+{
+       u8 aclk = 0;
+       u8 bclk = 0;
+
+       if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
+       else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
+       else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
+       else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
+       else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
+       else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
+
+       stv0299_writereg(fe, 0x13, aclk);
+       stv0299_writereg(fe, 0x14, bclk);
+       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+       stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
+       stv0299_writereg(fe, 0x21, (ratio      ) & 0xf0);
+
+       return 0;
+}
+
+static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
+{
+       int ret;
+       u8 data[4];
+       u32 div;
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+       if ((params->frequency < 950000) || (params->frequency > 2150000))
+               return -EINVAL;
+
+       div = (params->frequency + (125 - 1)) / 125; // round correctly
+       data[0] = (div >> 8) & 0x7f;
+       data[1] = div & 0xff;
+       data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
+       data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
+
+       ret = i2c_transfer(i2c, &msg, 1);
+       return (ret != 1) ? -EIO : 0;
+}
+
+static struct stv0299_config alps_bsbe1_config = {
+       .demod_address = 0x68,
+       .inittab = alps_bsbe1_inittab,
+       .mclk = 88000000UL,
+       .invert = 1,
+       .skip_reinit = 0,
+       .min_delay_ms = 100,
+       .set_symbol_rate = alps_bsbe1_set_symbol_rate,
+       .pll_set = alps_bsbe1_pll_set,
+};
+
+#endif
diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h
new file mode 100644 (file)
index 0000000..2a5366c
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * bsru6.h - ALPS BSRU6 tuner support (moved from budget-ci.c)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef BSRU6_H
+#define BSRU6_H
+
+static u8 alps_bsru6_inittab[] = {
+       0x01, 0x15,
+       0x02, 0x00,
+       0x03, 0x00,
+       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
+       0x06, 0x40,   /* DAC not used, set to high impendance mode */
+       0x07, 0x00,   /* DAC LSB */
+       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
+       0x09, 0x00,   /* FIFO */
+       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
+       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
+       0x10, 0x3f,   // AGC2  0x3d
+       0x11, 0x84,
+       0x12, 0xb9,
+       0x15, 0xc9,   // lock detector threshold
+       0x16, 0x00,
+       0x17, 0x00,
+       0x18, 0x00,
+       0x19, 0x00,
+       0x1a, 0x00,
+       0x1f, 0x50,
+       0x20, 0x00,
+       0x21, 0x00,
+       0x22, 0x00,
+       0x23, 0x00,
+       0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
+       0x29, 0x1e,  // 1/2 threshold
+       0x2a, 0x14,  // 2/3 threshold
+       0x2b, 0x0f,  // 3/4 threshold
+       0x2c, 0x09,  // 5/6 threshold
+       0x2d, 0x05,  // 7/8 threshold
+       0x2e, 0x01,
+       0x31, 0x1f,  // test all FECs
+       0x32, 0x19,  // viterbi and synchro search
+       0x33, 0xfc,  // rs control
+       0x34, 0x93,  // error control
+       0x0f, 0x52,
+       0xff, 0xff
+};
+
+static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
+{
+       u8 aclk = 0;
+       u8 bclk = 0;
+
+       if (srate < 1500000) {
+               aclk = 0xb7;
+               bclk = 0x47;
+       } else if (srate < 3000000) {
+               aclk = 0xb7;
+               bclk = 0x4b;
+       } else if (srate < 7000000) {
+               aclk = 0xb7;
+               bclk = 0x4f;
+       } else if (srate < 14000000) {
+               aclk = 0xb7;
+               bclk = 0x53;
+       } else if (srate < 30000000) {
+               aclk = 0xb6;
+               bclk = 0x53;
+       } else if (srate < 45000000) {
+               aclk = 0xb4;
+               bclk = 0x51;
+       }
+
+       stv0299_writereg(fe, 0x13, aclk);
+       stv0299_writereg(fe, 0x14, bclk);
+       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+       stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
+       stv0299_writereg(fe, 0x21, ratio & 0xf0);
+
+       return 0;
+}
+
+static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params)
+{
+       u8 buf[4];
+       u32 div;
+       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
+
+       if ((params->frequency < 950000) || (params->frequency > 2150000))
+               return -EINVAL;
+
+       div = (params->frequency + (125 - 1)) / 125;    // round correctly
+       buf[0] = (div >> 8) & 0x7f;
+       buf[1] = div & 0xff;
+       buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
+       buf[3] = 0xC4;
+
+       if (params->frequency > 1530000)
+               buf[3] = 0xc0;
+
+       if (i2c_transfer(i2c, &msg, 1) != 1)
+               return -EIO;
+       return 0;
+}
+
+static struct stv0299_config alps_bsru6_config = {
+       .demod_address = 0x68,
+       .inittab = alps_bsru6_inittab,
+       .mclk = 88000000UL,
+       .invert = 1,
+       .skip_reinit = 0,
+       .lock_output = STV0229_LOCKOUTPUT_1,
+       .volt13_op0_op1 = STV0299_VOLT13_OP1,
+       .min_delay_ms = 100,
+       .set_symbol_rate = alps_bsru6_set_symbol_rate,
+       .pll_set = alps_bsru6_pll_set,
+};
+
+#endif
index d15d32c51dc5dd466f133bbad301b1cc3824cb2f..f3edf8b517dd274c0e0bd9cfdc2405d175c72355 100644 (file)
@@ -371,6 +371,15 @@ static int cx24110_initfe(struct dvb_frontend* fe)
        return 0;
 }
 
+static int cx24110_sleep(struct dvb_frontend *fe)
+{
+       struct cx24110_state *state = fe->demodulator_priv;
+
+       if (state->config->pll_sleep)
+                 return state->config->pll_sleep(fe);
+       return 0;
+}
+
 static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
        struct cx24110_state *state = fe->demodulator_priv;
@@ -418,6 +427,9 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
        struct cx24110_state *state = fe->demodulator_priv;
        unsigned long timeout;
 
+       if (cmd->msg_len < 3 || cmd->msg_len > 6)
+               return -EINVAL;  /* not implemented */
+
        for (i = 0; i < cmd->msg_len; i++)
                cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
 
@@ -639,6 +651,7 @@ static struct dvb_frontend_ops cx24110_ops = {
        .release = cx24110_release,
 
        .init = cx24110_initfe,
+       .sleep = cx24110_sleep,
        .set_frontend = cx24110_set_frontend,
        .get_frontend = cx24110_get_frontend,
        .read_status = cx24110_read_status,
index b63ecf26421a08003ca7fced3ce278e6be5ff98b..609ac642b406ad748c791cfd441b825460cb9080 100644 (file)
@@ -35,6 +35,7 @@ struct cx24110_config
        /* PLL maintenance */
        int (*pll_init)(struct dvb_frontend* fe);
        int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
+       int (*pll_sleep)(struct dvb_frontend* fe);
 };
 
 extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
index 4dcb6050d4fad659f04af92fc82bf23319892f19..b6e2c387a04cc06f05405871b088bfa78cce1ae6 100644 (file)
@@ -362,6 +362,63 @@ struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
 };
 EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261);
 
+/*
+ * Philips TD1316 Tuner.
+ */
+static void td1316_bw(u8 *buf, u32 freq, int bandwidth)
+{
+       u8 band;
+
+       /* determine band */
+       if (freq < 161000000)
+               band = 1;
+       else if (freq < 444000000)
+               band = 2;
+       else
+               band = 4;
+
+       buf[3] |= band;
+
+       /* setup PLL filter */
+       if (bandwidth == BANDWIDTH_8_MHZ)
+               buf[3] |= 1 << 3;
+}
+
+struct dvb_pll_desc dvb_pll_philips_td1316 = {
+       .name  = "Philips TD1316",
+       .min   =  87000000,
+       .max   = 895000000,
+       .setbw = td1316_bw,
+       .count = 9,
+       .entries = {
+               {  93834000, 36166000, 166666, 0xca, 0x60},
+               { 123834000, 36166000, 166666, 0xca, 0xa0},
+               { 163834000, 36166000, 166666, 0xca, 0xc0},
+               { 253834000, 36166000, 166666, 0xca, 0x60},
+               { 383834000, 36166000, 166666, 0xca, 0xa0},
+               { 443834000, 36166000, 166666, 0xca, 0xc0},
+               { 583834000, 36166000, 166666, 0xca, 0x60},
+               { 793834000, 36166000, 166666, 0xca, 0xa0},
+               { 858834000, 36166000, 166666, 0xca, 0xe0},
+       },
+};
+EXPORT_SYMBOL(dvb_pll_philips_td1316);
+
+/* FE6600 used on DViCO Hybrid */
+struct dvb_pll_desc dvb_pll_thomson_fe6600 = {
+       .name = "Thomson FE6600",
+       .min =  44250000,
+       .max = 858000000,
+       .count = 4,
+       .entries = {
+               { 250000000, 36213333, 166667, 0xb4, 0x12 },
+               { 455000000, 36213333, 166667, 0xfe, 0x11 },
+               { 775500000, 36213333, 166667, 0xbc, 0x18 },
+               { 999999999, 36213333, 166667, 0xf4, 0x18 },
+       }
+};
+EXPORT_SYMBOL(dvb_pll_thomson_fe6600);
+
 /* ----------------------------------------------------------- */
 /* code                                                        */
 
@@ -391,8 +448,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
        div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize;
        buf[0] = div >> 8;
        buf[1] = div & 0xff;
-       buf[2] = desc->entries[i].cb1;
-       buf[3] = desc->entries[i].cb2;
+       buf[2] = desc->entries[i].config;
+       buf[3] = desc->entries[i].cb;
 
        if (desc->setbw)
                desc->setbw(buf, freq, bandwidth);
index bb8d4b4eb183fcb8e33228658419a620fabe0b7f..2b84617849899cb5cc96d91017638ad5670f7989 100644 (file)
@@ -15,8 +15,8 @@ struct dvb_pll_desc {
                u32 limit;
                u32 offset;
                u32 stepsize;
-               u8  cb1;
-               u8  cb2;
+               u8  config;
+               u8  cb;
        } entries[12];
 };
 
@@ -40,6 +40,9 @@ extern struct dvb_pll_desc dvb_pll_tuv1236d;
 extern struct dvb_pll_desc dvb_pll_tdhu2;
 extern struct dvb_pll_desc dvb_pll_samsung_tbmv;
 extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261;
+extern struct dvb_pll_desc dvb_pll_philips_td1316;
+
+extern struct dvb_pll_desc dvb_pll_thomson_fe6600;
 
 int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
                      u32 freq, int bandwidth);
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
new file mode 100644 (file)
index 0000000..0dcbe61
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * lnbp21.h - driver for lnb supply and control ic lnbp21
+ *
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef _LNBP21_H
+#define _LNBP21_H
+
+/* system register */
+#define LNBP21_OLF     0x01
+#define LNBP21_OTF     0x02
+#define LNBP21_EN      0x04
+#define LNBP21_VSEL    0x08
+#define LNBP21_LLC     0x10
+#define LNBP21_TEN     0x20
+#define LNBP21_ISEL    0x40
+#define LNBP21_PCL     0x80
+
+struct lnbp21 {
+       u8                      config;
+       u8                      override_or;
+       u8                      override_and;
+       struct i2c_adapter      *i2c;
+       void                    (*release_chain)(struct dvb_frontend* fe);
+};
+
+static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
+       struct i2c_msg msg = {  .addr = 0x08, .flags = 0,
+                               .buf = &lnbp21->config,
+                               .len = sizeof(lnbp21->config) };
+
+       lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
+
+       switch(voltage) {
+       case SEC_VOLTAGE_OFF:
+               break;
+       case SEC_VOLTAGE_13:
+               lnbp21->config |= LNBP21_EN;
+               break;
+       case SEC_VOLTAGE_18:
+               lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
+               break;
+       default:
+               return -EINVAL;
+       };
+
+       lnbp21->config |= lnbp21->override_or;
+       lnbp21->config &= lnbp21->override_and;
+
+       return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
+{
+       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
+       struct i2c_msg msg = {  .addr = 0x08, .flags = 0,
+                               .buf = &lnbp21->config,
+                               .len = sizeof(lnbp21->config) };
+
+       if (arg)
+               lnbp21->config |= LNBP21_LLC;
+       else
+               lnbp21->config &= ~LNBP21_LLC;
+
+       lnbp21->config |= lnbp21->override_or;
+       lnbp21->config &= lnbp21->override_and;
+
+       return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static void lnbp21_exit(struct dvb_frontend *fe)
+{
+       struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
+
+       /* LNBP power off */
+       lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+       /* free data & call next release routine */
+       fe->ops->release = lnbp21->release_chain;
+       kfree(fe->misc_priv);
+       fe->misc_priv = NULL;
+       if (fe->ops->release)
+               fe->ops->release(fe);
+}
+
+static int lnbp21_init(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+{
+       struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
+
+       if (!lnbp21)
+               return -ENOMEM;
+
+       /* default configuration */
+       lnbp21->config = LNBP21_ISEL;
+
+       /* bits which should be forced to '1' */
+       lnbp21->override_or = override_set;
+
+       /* bits which should be forced to '0' */
+       lnbp21->override_and = ~override_clear;
+
+       /* install release callback */
+       lnbp21->release_chain = fe->ops->release;
+       fe->ops->release = lnbp21_exit;
+
+       /* override frontend ops */
+       fe->ops->set_voltage = lnbp21_set_voltage;
+       fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+
+       lnbp21->i2c = i2c;
+       fe->misc_priv = lnbp21;
+
+       return lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
+}
+
+#endif
index c63e9a5084eb7ffcb1c50b9efebee1a0f85b946c..8e8df7b4ca0e595f8d28f710a273357ab37da3ad 100644 (file)
@@ -229,7 +229,7 @@ static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
        dprintk("%s\n", __FUNCTION__);
 
        result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
-       msleep(1);
+       msleep(20);
        return result;
 }
 
@@ -502,7 +502,12 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
        const struct firmware *fw;
 
        /* reset + wake up chip */
-       tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
+       if (state->config->xtal_freq == TDA10046_XTAL_4M) {
+               tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
+       } else {
+               dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __FUNCTION__);
+               tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
+       }
        tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
        /* let the clocks recover from sleep */
        msleep(5);
@@ -651,7 +656,7 @@ static int tda10046_init(struct dvb_frontend* fe)
        // tda setup
        tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
        tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87);    // 100 ppm crystal, select HP stream
-       tda1004x_write_byteI(state, TDA1004X_CONFC1, 8);      // disable pulse killer
+       tda1004x_write_byteI(state, TDA1004X_CONFC1, 0x88);      // enable pulse killer
 
        switch (state->config->agc_config) {
        case TDA10046_AGC_DEFAULT:
@@ -672,6 +677,12 @@ static int tda10046_init(struct dvb_frontend* fe)
                tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
                tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
                break;
+       case TDA10046_AGC_TDA827X_GPL:
+               tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02);   // AGC setup
+               tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70);    // AGC Threshold
+               tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
+               tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+               break;
        }
        tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
        tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
@@ -683,6 +694,7 @@ static int tda10046_init(struct dvb_frontend* fe)
        tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
        tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
        tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
+       // tda1004x_write_mask(state, 0x50, 0x80, 0x80);         // handle out of guard echoes
        tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
 
        state->initialised = 1;
@@ -1027,6 +1039,7 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
                if (status == -1)
                        return -EIO;
                cber |= (status << 8);
+               // The address 0x20 should be read to cope with a TDA10046 bug
                tda1004x_read_byte(state, TDA1004X_CBER_RESET);
 
                if (cber != 65535)
@@ -1047,7 +1060,8 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
                status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
                if (status == -1)
                        return -EIO;
-               vber |= ((status << 16) & 0x0f);
+               vber |= (status & 0x0f) << 16;
+               // The CVBER_LUT should be read to cope with TDA10046 hardware bug
                tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
 
                // if RS has passed some valid TS packets, then we must be
@@ -1161,6 +1175,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
        if (tmp < 0)
                return -EIO;
        *ber |= (tmp << 9);
+       // The address 0x20 should be read to cope with a TDA10046 bug
        tda1004x_read_byte(state, TDA1004X_CBER_RESET);
 
        dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);
@@ -1187,6 +1202,8 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
                                tda1004x_disable_tuner_i2c(state);
                        }
                }
+               /* set outputs to tristate */
+               tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
                tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
                break;
        }
index 8659c52647adf839139a7e1ae38e95071ff800a5..cc0c4af64067037312fde708aef5dea56c9b5459 100644 (file)
@@ -35,7 +35,8 @@ enum tda10046_agc {
        TDA10046_AGC_DEFAULT,           /* original configuration */
        TDA10046_AGC_IFO_AUTO_NEG,      /* IF AGC only, automatic, negtive */
        TDA10046_AGC_IFO_AUTO_POS,      /* IF AGC only, automatic, positive */
-       TDA10046_AGC_TDA827X,       /* IF AGC only, special setup for tda827x */
+       TDA10046_AGC_TDA827X,           /* IF AGC only, special setup for tda827x */
+       TDA10046_AGC_TDA827X_GPL,       /* same as above, but GPIOs 0 */
 };
 
 enum tda10046_if {
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
new file mode 100644 (file)
index 0000000..d7d9f59
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Driver for Zarlink DVB-T ZL10353 demodulator
+ *
+ * Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "zl10353_priv.h"
+#include "zl10353.h"
+
+struct zl10353_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend frontend;
+       struct dvb_frontend_ops ops;
+
+       struct zl10353_config config;
+};
+
+static int debug_regs = 0;
+
+static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0,
+                              .buf = buf, .len = 2 };
+       int err = i2c_transfer(state->i2c, &msg, 1);
+       if (err != 1) {
+               printk("zl10353: write to reg %x failed (err = %d)!\n", reg, err);
+               return err;
+       }
+       return 0;
+}
+
+int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen)
+{
+       int err, i;
+       for (i = 0; i < ilen - 1; i++)
+               if ((err = zl10353_single_write(fe, ibuf[0] + i, ibuf[i + 1])))
+                       return err;
+
+       return 0;
+}
+
+static int zl10353_read_register(struct zl10353_state *state, u8 reg)
+{
+       int ret;
+       u8 b0[1] = { reg };
+       u8 b1[1] = { 0 };
+       struct i2c_msg msg[2] = { { .addr = state->config.demod_address,
+                                   .flags = 0,
+                                   .buf = b0, .len = 1 },
+                                 { .addr = state->config.demod_address,
+                                   .flags = I2C_M_RD,
+                                   .buf = b1, .len = 1 } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2) {
+               printk("%s: readreg error (reg=%d, ret==%i)\n",
+                      __FUNCTION__, reg, ret);
+               return ret;
+       }
+
+       return b1[0];
+}
+
+static void zl10353_dump_regs(struct dvb_frontend *fe)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       char buf[52], buf2[4];
+       int ret;
+       u8 reg;
+
+       /* Dump all registers. */
+       for (reg = 0; ; reg++) {
+               if (reg % 16 == 0) {
+                       if (reg)
+                               printk(KERN_DEBUG "%s\n", buf);
+                       sprintf(buf, "%02x: ", reg);
+               }
+               ret = zl10353_read_register(state, reg);
+               if (ret >= 0)
+                       sprintf(buf2, "%02x ", (u8)ret);
+               else
+                       strcpy(buf2, "-- ");
+               strcat(buf, buf2);
+               if (reg == 0xff)
+                       break;
+       }
+       printk(KERN_DEBUG "%s\n", buf);
+}
+
+static int zl10353_sleep(struct dvb_frontend *fe)
+{
+       static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 };
+
+       zl10353_write(fe, zl10353_softdown, sizeof(zl10353_softdown));
+       return 0;
+}
+
+static int zl10353_set_parameters(struct dvb_frontend *fe,
+                                 struct dvb_frontend_parameters *param)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 pllbuf[6] = { 0x67 };
+
+       /* These settings set "auto-everything" and start the FSM. */
+       zl10353_single_write(fe, 0x55, 0x80);
+       udelay(200);
+       zl10353_single_write(fe, 0xEA, 0x01);
+       udelay(200);
+       zl10353_single_write(fe, 0xEA, 0x00);
+
+       zl10353_single_write(fe, 0x56, 0x28);
+       zl10353_single_write(fe, 0x89, 0x20);
+       zl10353_single_write(fe, 0x5E, 0x00);
+       zl10353_single_write(fe, 0x65, 0x5A);
+       zl10353_single_write(fe, 0x66, 0xE9);
+       zl10353_single_write(fe, 0x62, 0x0A);
+
+       state->config.pll_set(fe, param, pllbuf + 1);
+       zl10353_write(fe, pllbuf, sizeof(pllbuf));
+
+       zl10353_single_write(fe, 0x70, 0x01);
+       udelay(250);
+       zl10353_single_write(fe, 0xE4, 0x00);
+       zl10353_single_write(fe, 0xE5, 0x2A);
+       zl10353_single_write(fe, 0xE9, 0x02);
+       zl10353_single_write(fe, 0xE7, 0x40);
+       zl10353_single_write(fe, 0xE8, 0x10);
+
+       return 0;
+}
+
+static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       int s6, s7, s8;
+
+       if ((s6 = zl10353_read_register(state, STATUS_6)) < 0)
+               return -EREMOTEIO;
+       if ((s7 = zl10353_read_register(state, STATUS_7)) < 0)
+               return -EREMOTEIO;
+       if ((s8 = zl10353_read_register(state, STATUS_8)) < 0)
+               return -EREMOTEIO;
+
+       *status = 0;
+       if (s6 & (1 << 2))
+               *status |= FE_HAS_CARRIER;
+       if (s6 & (1 << 1))
+               *status |= FE_HAS_VITERBI;
+       if (s6 & (1 << 5))
+               *status |= FE_HAS_LOCK;
+       if (s7 & (1 << 4))
+               *status |= FE_HAS_SYNC;
+       if (s8 & (1 << 6))
+               *status |= FE_HAS_SIGNAL;
+
+       if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
+           (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
+               *status &= ~FE_HAS_LOCK;
+
+       return 0;
+}
+
+static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 _snr;
+
+       if (debug_regs)
+               zl10353_dump_regs(fe);
+
+       _snr = zl10353_read_register(state, SNR);
+       *snr = (_snr << 8) | _snr;
+
+       return 0;
+}
+
+static int zl10353_get_tune_settings(struct dvb_frontend *fe,
+                                    struct dvb_frontend_tune_settings
+                                        *fe_tune_settings)
+{
+       fe_tune_settings->min_delay_ms = 1000;
+       fe_tune_settings->step_size = 0;
+       fe_tune_settings->max_drift = 0;
+
+       return 0;
+}
+
+static int zl10353_init(struct dvb_frontend *fe)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+       u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F };
+       int rc = 0;
+
+       if (debug_regs)
+               zl10353_dump_regs(fe);
+
+       /* Do a "hard" reset if not already done */
+       if (zl10353_read_register(state, 0x50) != 0x03) {
+               rc = zl10353_write(fe, zl10353_reset_attach,
+                                  sizeof(zl10353_reset_attach));
+               if (debug_regs)
+                       zl10353_dump_regs(fe);
+       }
+
+       return 0;
+}
+
+static void zl10353_release(struct dvb_frontend *fe)
+{
+       struct zl10353_state *state = fe->demodulator_priv;
+
+       kfree(state);
+}
+
+static struct dvb_frontend_ops zl10353_ops;
+
+struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
+                                   struct i2c_adapter *i2c)
+{
+       struct zl10353_state *state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->i2c = i2c;
+       memcpy(&state->config, config, sizeof(struct zl10353_config));
+       memcpy(&state->ops, &zl10353_ops, sizeof(struct dvb_frontend_ops));
+
+       /* check if the demod is there */
+       if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353)
+               goto error;
+
+       /* create dvb_frontend */
+       state->frontend.ops = &state->ops;
+       state->frontend.demodulator_priv = state;
+
+       return &state->frontend;
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops zl10353_ops = {
+
+       .info = {
+               .name                   = "Zarlink ZL10353 DVB-T",
+               .type                   = FE_OFDM,
+               .frequency_min          = 174000000,
+               .frequency_max          = 862000000,
+               .frequency_stepsize     = 166667,
+               .frequency_tolerance    = 0,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+                       FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+                       FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
+                       FE_CAN_MUTE_TS
+       },
+
+       .release = zl10353_release,
+
+       .init = zl10353_init,
+       .sleep = zl10353_sleep,
+
+       .set_frontend = zl10353_set_parameters,
+       .get_tune_settings = zl10353_get_tune_settings,
+
+       .read_status = zl10353_read_status,
+       .read_snr = zl10353_read_snr,
+};
+
+module_param(debug_regs, int, 0644);
+MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off).");
+
+MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver");
+MODULE_AUTHOR("Chris Pascoe");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(zl10353_attach);
+EXPORT_SYMBOL(zl10353_write);
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
new file mode 100644 (file)
index 0000000..5cc4ae7
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  Driver for Zarlink DVB-T ZL10353 demodulator
+ *
+ *  Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef ZL10353_H
+#define ZL10353_H
+
+#include <linux/dvb/frontend.h>
+
+struct zl10353_config
+{
+       /* demodulator's I2C address */
+       u8 demod_address;
+
+       /* function which configures the PLL buffer (for secondary I2C
+        * connected tuner) or tunes the PLL (for direct connected tuner) */
+       int (*pll_set)(struct dvb_frontend *fe,
+                      struct dvb_frontend_parameters *params, u8 *pllbuf);
+};
+
+extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
+                                          struct i2c_adapter *i2c);
+
+extern int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen);
+
+#endif /* ZL10353_H */
diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h
new file mode 100644 (file)
index 0000000..b72224b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Driver for Zarlink DVB-T ZL10353 demodulator
+ *
+ *  Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef _ZL10353_PRIV_
+#define _ZL10353_PRIV_
+
+#define ID_ZL10353     0x14
+
+enum zl10353_reg_addr {
+       INTERRUPT_0     = 0x00,
+       INTERRUPT_1     = 0x01,
+       INTERRUPT_2     = 0x02,
+       INTERRUPT_3     = 0x03,
+       INTERRUPT_4     = 0x04,
+       INTERRUPT_5     = 0x05,
+       STATUS_6        = 0x06,
+       STATUS_7        = 0x07,
+       STATUS_8        = 0x08,
+       STATUS_9        = 0x09,
+       SNR             = 0x10,
+       CHIP_ID         = 0x7F,
+};
+
+#endif                          /* _ZL10353_PRIV_ */
index 7c6ccb96b1574dd4e8d24bcc9159a3ecb093d803..840efec32cb621c7d0c723b8e675b197ca02d5cf 100644 (file)
@@ -54,7 +54,6 @@
 #include <linux/i2c.h>
 
 #include <asm/system.h>
-#include <asm/semaphore.h>
 
 #include <linux/dvb/frontend.h>
 
 #include "av7110_ca.h"
 #include "av7110_ipack.h"
 
+#include "bsbe1.h"
+#include "lnbp21.h"
+#include "bsru6.h"
+
 #define TS_WIDTH  376
 #define TS_HEIGHT 512
 #define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
@@ -82,6 +85,8 @@ static int hw_sections;
 static int rgb_on;
 static int volume = 255;
 static int budgetpatch;
+static int wss_cfg_4_3 = 0x4008;
+static int wss_cfg_16_9 = 0x0007;
 
 module_param_named(debug, av7110_debug, int, 0644);
 MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
@@ -100,6 +105,10 @@ module_param(volume, int, 0444);
 MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
 module_param(budgetpatch, int, 0444);
 MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)");
+module_param(wss_cfg_4_3, int, 0444);
+MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data");
+module_param(wss_cfg_16_9, int, 0444);
+MODULE_PARM_DESC(wss_cfg_16_9, "WSS 16:9 - default 0x0007 - bit 15: disable, 14: burst mode, 13..0: wss data");
 
 static void restart_feeds(struct av7110 *av7110);
 
@@ -125,6 +134,13 @@ static void init_av7110_av(struct av7110 *av7110)
        if (ret < 0)
                printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
 
+       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 2, wss_cfg_4_3);
+       if (ret < 0)
+               printk("dvb-ttpci: unable to configure 4:3 wss\n");
+       ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 3, wss_cfg_16_9);
+       if (ret < 0)
+               printk("dvb-ttpci: unable to configure 16:9 wss\n");
+
        ret = av7710_set_video_mode(av7110, vidmode);
        if (ret < 0)
                printk("dvb-ttpci:cannot set video mode:%d\n",ret);
@@ -242,10 +258,10 @@ static int arm_thread(void *data)
                if (!av7110->arm_ready)
                        continue;
 
-               if (down_interruptible(&av7110->dcomlock))
+               if (mutex_lock_interruptible(&av7110->dcomlock))
                        break;
                newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
-               up(&av7110->dcomlock);
+               mutex_unlock(&av7110->dcomlock);
 
                if (newloops == av7110->arm_loops || av7110->arm_errors > 3) {
                        printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
@@ -253,10 +269,10 @@ static int arm_thread(void *data)
 
                        recover_arm(av7110);
 
-                       if (down_interruptible(&av7110->dcomlock))
+                       if (mutex_lock_interruptible(&av7110->dcomlock))
                                break;
                        newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                }
                av7110->arm_loops = newloops;
                av7110->arm_errors = 0;
@@ -741,7 +757,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
        int ret = 0;
        dprintk(4, "%p\n", av7110);
 
-       if (down_interruptible(&av7110->pid_mutex))
+       if (mutex_lock_interruptible(&av7110->pid_mutex))
                return -ERESTARTSYS;
 
        if (!(vpid & 0x8000))
@@ -760,7 +776,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
                ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
        }
 
-       up(&av7110->pid_mutex);
+       mutex_unlock(&av7110->pid_mutex);
        return ret;
 }
 
@@ -1088,11 +1104,9 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
        struct av7110 *av7110;
 
        /* pointer casting paranoia... */
-       if (!demux)
-               BUG();
+       BUG_ON(!demux);
        dvbdemux = (struct dvb_demux *) demux->priv;
-       if (!dvbdemux)
-               BUG();
+       BUG_ON(!dvbdemux);
        av7110 = (struct av7110 *) dvbdemux->priv;
 
        dprintk(4, "%p\n", av7110);
@@ -1570,208 +1584,6 @@ static struct ves1x93_config alps_bsrv2_config = {
        .pll_set = alps_bsrv2_pll_set,
 };
 
-
-static u8 alps_bsru6_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x40,   /* DAC not used, set to high impendance mode */
-       0x07, 0x00,   /* DAC LSB */
-       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
-       0x09, 0x00,   /* FIFO */
-       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
-       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
-       0x10, 0x3f,   // AGC2  0x3d
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,   // lock detector threshold
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
-       0x29, 0x1e,  // 1/2 threshold
-       0x2a, 0x14,  // 2/3 threshold
-       0x2b, 0x0f,  // 3/4 threshold
-       0x2c, 0x09,  // 5/6 threshold
-       0x2d, 0x05,  // 7/8 threshold
-       0x2e, 0x01,
-       0x31, 0x1f,  // test all FECs
-       0x32, 0x19,  // viterbi and synchro search
-       0x33, 0xfc,  // rs control
-       0x34, 0x93,  // error control
-       0x0f, 0x52,
-       0xff, 0xff
-};
-
-static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
-{
-       u8 aclk = 0;
-       u8 bclk = 0;
-
-       if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
-       else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
-       else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
-       else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
-       else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
-       else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
-
-       stv0299_writereg(fe, 0x13, aclk);
-       stv0299_writereg(fe, 0x14, bclk);
-       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
-       stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
-       stv0299_writereg(fe, 0x21, (ratio      ) & 0xf0);
-
-       return 0;
-}
-
-static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
-{
-       int ret;
-       u8 data[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       if ((params->frequency < 950000) || (params->frequency > 2150000))
-               return -EINVAL;
-
-       div = (params->frequency + (125 - 1)) / 125; // round correctly
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-       data[3] = 0xC4;
-
-       if (params->frequency > 1530000) data[3] = 0xc0;
-
-       ret = i2c_transfer(i2c, &msg, 1);
-       if (ret != 1)
-               return -EIO;
-       return 0;
-}
-
-static struct stv0299_config alps_bsru6_config = {
-
-       .demod_address = 0x68,
-       .inittab = alps_bsru6_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .lock_output = STV0229_LOCKOUTPUT_1,
-       .volt13_op0_op1 = STV0299_VOLT13_OP1,
-       .min_delay_ms = 100,
-       .set_symbol_rate = alps_bsru6_set_symbol_rate,
-       .pll_set = alps_bsru6_pll_set,
-};
-
-
-static u8 alps_bsbe1_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x40,   /* DAC not used, set to high impendance mode */
-       0x07, 0x00,   /* DAC LSB */
-       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
-       0x09, 0x00,   /* FIFO */
-       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
-       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
-       0x10, 0x3f,   // AGC2  0x3d
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,   // lock detector threshold
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
-       0x29, 0x1e,  // 1/2 threshold
-       0x2a, 0x14,  // 2/3 threshold
-       0x2b, 0x0f,  // 3/4 threshold
-       0x2c, 0x09,  // 5/6 threshold
-       0x2d, 0x05,  // 7/8 threshold
-       0x2e, 0x01,
-       0x31, 0x1f,  // test all FECs
-       0x32, 0x19,  // viterbi and synchro search
-       0x33, 0xfc,  // rs control
-       0x34, 0x93,  // error control
-       0x0f, 0x92,
-       0xff, 0xff
-};
-
-static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
-{
-       int ret;
-       u8 data[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       if ((params->frequency < 950000) || (params->frequency > 2150000))
-               return -EINVAL;
-
-       div = (params->frequency + (125 - 1)) / 125; // round correctly
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-       data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
-
-       ret = i2c_transfer(i2c, &msg, 1);
-       return (ret != 1) ? -EIO : 0;
-}
-
-static struct stv0299_config alps_bsbe1_config = {
-       .demod_address = 0x68,
-       .inittab = alps_bsbe1_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .min_delay_ms = 100,
-       .set_symbol_rate = alps_bsru6_set_symbol_rate,
-       .pll_set = alps_bsbe1_pll_set,
-};
-
-static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
-       int ret;
-       u8 data[1];
-       struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       switch(voltage) {
-       case SEC_VOLTAGE_OFF:
-               data[0] = 0x00;
-               break;
-       case SEC_VOLTAGE_13:
-               data[0] = 0x44;
-               break;
-       case SEC_VOLTAGE_18:
-               data[0] = 0x4c;
-               break;
-       default:
-               return -EINVAL;
-       };
-
-       ret = i2c_transfer(&av7110->i2c_adap, &msg, 1);
-       return (ret != 1) ? -EIO : 0;
-}
-
-
 static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
 {
        struct av7110* av7110 = fe->dvb->priv;
@@ -2096,7 +1908,7 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
        if (av7110->playing)
                return 0;
 
-       if (down_interruptible(&av7110->pid_mutex))
+       if (mutex_lock_interruptible(&av7110->pid_mutex))
                return -ERESTARTSYS;
 
        if (synced) {
@@ -2118,7 +1930,7 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
        if (!ret)
                av7110->fe_synced = synced;
 
-       up(&av7110->pid_mutex);
+       mutex_unlock(&av7110->pid_mutex);
        return ret;
 }
 
@@ -2374,9 +2186,15 @@ static int frontend_init(struct av7110 *av7110)
                        /* ALPS BSBE1 */
                        av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
                        if (av7110->fe) {
-                               av7110->fe->ops->set_voltage = lnbp21_set_voltage;
-                               av7110->fe->ops->dishnetwork_send_legacy_command = NULL;
-                               av7110->recover = dvb_s_recover;
+                               if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) {
+                                       printk("dvb-ttpci: LNBP21 not found!\n");
+                                       if (av7110->fe->ops->release)
+                                               av7110->fe->ops->release(av7110->fe);
+                                       av7110->fe = NULL;
+                               } else {
+                                       av7110->fe->ops->dishnetwork_send_legacy_command = NULL;
+                                       av7110->recover = dvb_s_recover;
+                               }
                        }
                        break;
                }
@@ -2714,16 +2532,16 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
        tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
        tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
 
-       sema_init(&av7110->pid_mutex, 1);
+       mutex_init(&av7110->pid_mutex);
 
        /* locks for data transfers from/to AV7110 */
        spin_lock_init(&av7110->debilock);
-       sema_init(&av7110->dcomlock, 1);
+       mutex_init(&av7110->dcomlock);
        av7110->debitype = -1;
 
        /* default OSD window */
        av7110->osdwin = 1;
-       sema_init(&av7110->osd_sema, 1);
+       mutex_init(&av7110->osd_mutex);
 
        /* ARM "watchdog" */
        init_waitqueue_head(&av7110->arm_wait);
index fafd25fab83593e483245f47d17ae175495d9259..3e2e12124bae0228bd91a69fee9183129fe2bc32 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/dvb/ca.h>
 #include <linux/dvb/osd.h>
 #include <linux/dvb/net.h>
+#include <linux/mutex.h>
 
 #include "dvbdev.h"
 #include "demux.h"
@@ -127,7 +128,7 @@ struct av7110 {
        /* DEBI and polled command interface */
 
        spinlock_t              debilock;
-       struct semaphore        dcomlock;
+       struct mutex            dcomlock;
        volatile int            debitype;
        volatile int            debilen;
 
@@ -146,7 +147,7 @@ struct av7110 {
 
        int                     osdwin;      /* currently active window */
        u16                     osdbpp[8];
-       struct semaphore        osd_sema;
+       struct mutex            osd_mutex;
 
        /* CA */
 
@@ -172,7 +173,7 @@ struct av7110 {
        struct tasklet_struct   vpe_tasklet;
 
        int                     fe_synced;
-       struct semaphore        pid_mutex;
+       struct mutex            pid_mutex;
 
        int                     video_blank;
        struct video_status     videostate;
index 0bb6e74ae7f0f83edaf538bd45f5cc682a843461..75736f2fe83864bb6bf48e7204a28c6a9930e806 100644 (file)
@@ -327,10 +327,10 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
        start = jiffies;
        for (;;) {
                err = time_after(jiffies, start + ARM_WAIT_FREE);
-               if (down_interruptible(&av7110->dcomlock))
+               if (mutex_lock_interruptible(&av7110->dcomlock))
                        return -ERESTARTSYS;
                stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
-               up(&av7110->dcomlock);
+               mutex_unlock(&av7110->dcomlock);
                if ((stat & flags) == 0)
                        break;
                if (err) {
@@ -487,11 +487,11 @@ static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
                dprintk(1, "arm not ready.\n");
                return -1;
        }
-       if (down_interruptible(&av7110->dcomlock))
+       if (mutex_lock_interruptible(&av7110->dcomlock))
                return -ERESTARTSYS;
 
        ret = __av7110_send_fw_cmd(av7110, buf, length);
-       up(&av7110->dcomlock);
+       mutex_unlock(&av7110->dcomlock);
        if (ret && ret!=-ERESTARTSYS)
                printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
                       __FUNCTION__, ret);
@@ -563,11 +563,11 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
                return -1;
        }
 
-       if (down_interruptible(&av7110->dcomlock))
+       if (mutex_lock_interruptible(&av7110->dcomlock))
                return -ERESTARTSYS;
 
        if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
-               up(&av7110->dcomlock);
+               mutex_unlock(&av7110->dcomlock);
                printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err);
                return err;
        }
@@ -579,7 +579,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
                        break;
                if (err) {
                        printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                        return -ETIMEDOUT;
                }
 #ifdef _NOHANDSHAKE
@@ -595,7 +595,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
                        break;
                if (err) {
                        printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                        return -ETIMEDOUT;
                }
                msleep(1);
@@ -606,12 +606,12 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
        stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
        if (stat & GPMQOver) {
                printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__);
-               up(&av7110->dcomlock);
+               mutex_unlock(&av7110->dcomlock);
                return -1;
        }
        else if (stat & OSDQOver) {
                printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__);
-               up(&av7110->dcomlock);
+               mutex_unlock(&av7110->dcomlock);
                return -1;
        }
 #endif
@@ -619,7 +619,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
        for (i = 0; i < reply_buf_len; i++)
                reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2);
 
-       up(&av7110->dcomlock);
+       mutex_unlock(&av7110->dcomlock);
        return 0;
 }
 
@@ -735,7 +735,7 @@ static int FlushText(struct av7110 *av7110)
        unsigned long start;
        int err;
 
-       if (down_interruptible(&av7110->dcomlock))
+       if (mutex_lock_interruptible(&av7110->dcomlock))
                return -ERESTARTSYS;
        start = jiffies;
        while (1) {
@@ -745,12 +745,12 @@ static int FlushText(struct av7110 *av7110)
                if (err) {
                        printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
                               __FUNCTION__);
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                        return -ETIMEDOUT;
                }
                msleep(1);
        }
-       up(&av7110->dcomlock);
+       mutex_unlock(&av7110->dcomlock);
        return 0;
 }
 
@@ -761,7 +761,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
        int length = strlen(buf) + 1;
        u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y };
 
-       if (down_interruptible(&av7110->dcomlock))
+       if (mutex_lock_interruptible(&av7110->dcomlock))
                return -ERESTARTSYS;
 
        start = jiffies;
@@ -772,7 +772,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
                if (ret) {
                        printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
                               __FUNCTION__);
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                        return -ETIMEDOUT;
                }
                msleep(1);
@@ -786,7 +786,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
                if (ret) {
                        printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
                               __FUNCTION__);
-                       up(&av7110->dcomlock);
+                       mutex_unlock(&av7110->dcomlock);
                        return -ETIMEDOUT;
                }
                msleep(1);
@@ -798,7 +798,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
        if (length & 1)
                wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
        ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
-       up(&av7110->dcomlock);
+       mutex_unlock(&av7110->dcomlock);
        if (ret && ret!=-ERESTARTSYS)
                printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
        return ret;
@@ -1062,7 +1062,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
 {
        int ret;
 
-       if (down_interruptible(&av7110->osd_sema))
+       if (mutex_lock_interruptible(&av7110->osd_mutex))
                return -ERESTARTSYS;
 
        switch (dc->cmd) {
@@ -1198,7 +1198,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
                break;
        }
 
-       up(&av7110->osd_sema);
+       mutex_unlock(&av7110->osd_mutex);
        if (ret==-ERESTARTSYS)
                dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd);
        else if (ret)
index 94cf38c7e8a809f8f5cf5ce2bba99c9f160aea0d..2f23ceab8d446491c73a3d832ec2c824733eb951 100644 (file)
@@ -579,14 +579,11 @@ static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size
                return -EFAULT;
        if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23)
                return -EINVAL;
-       if (d.id) {
+       if (d.id)
                av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0];
-               rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig,
-                                  2, 1, av7110->wssData);
-       } else {
-               av7110->wssData = 0;
-               rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
-       }
+       else
+               av7110->wssData = 0x8000;
+       rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 1, av7110->wssData);
        return (rc < 0) ? rc : count;
 }
 
index 1465c04e49aa843fd7c127201afecba0790b0370..9dd4745f53123826b78707ee12118f119cbd6146 100644 (file)
@@ -1000,6 +1000,7 @@ static u8 read_pwm(struct budget_av *budget_av)
 
 #define SUBID_DVBS_TV_STAR     0x0014
 #define SUBID_DVBS_TV_STAR_CI  0x0016
+#define SUBID_DVBS_EASYWATCH   0x001e
 #define SUBID_DVBC_KNC1                0x0020
 #define SUBID_DVBC_KNC1_PLUS   0x0021
 #define SUBID_DVBC_CINERGY1200 0x1156
@@ -1038,6 +1039,7 @@ static void frontend_init(struct budget_av *budget_av)
        case SUBID_DVBS_TV_STAR:
        case SUBID_DVBS_TV_STAR_CI:
        case SUBID_DVBS_CYNERGY1200N:
+       case SUBID_DVBS_EASYWATCH:
                fe = stv0299_attach(&philips_sd1878_config,
                                &budget_av->budget.i2c_adap);
                break;
@@ -1285,6 +1287,7 @@ MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
 MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
 MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
 MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
+MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
 MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
 MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
 MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
@@ -1300,6 +1303,7 @@ static struct pci_device_id pci_tbl[] = {
        MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
        MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
        MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
+       MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
        MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
        MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
        MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
index b9b3cd9c0369c16c5521d40d97be29dbc0df39d6..5f91036f5b874af9a7bf4a80a841897d5a5a7ed3 100644 (file)
@@ -42,6 +42,9 @@
 #include "stv0299.h"
 #include "stv0297.h"
 #include "tda1004x.h"
+#include "lnbp21.h"
+#include "bsbe1.h"
+#include "bsru6.h"
 
 #define DEBIADDR_IR            0x1234
 #define DEBIADDR_CICONTROL     0x0000
@@ -474,123 +477,6 @@ static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
                tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
 }
 
-
-static u8 alps_bsru6_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x00,
-       0x03, 0x00,
-       0x04, 0x7d,             /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x35,             /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x40,             /* DAC not used, set to high impendance mode */
-       0x07, 0x00,             /* DAC LSB */
-       0x08, 0x40,             /* DiSEqC off, LNB power on OP2/LOCK pin on */
-       0x09, 0x00,             /* FIFO */
-       0x0c, 0x51,             /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-       0x0d, 0x82,             /* DC offset compensation = ON, beta_agc1 = 2 */
-       0x0e, 0x23,             /* alpha_tmg = 2, beta_tmg = 3 */
-       0x10, 0x3f,             // AGC2  0x3d
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,             // lock detector threshold
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00,             // out imp: normal  out type: parallel FEC mode:0
-       0x29, 0x1e,             // 1/2 threshold
-       0x2a, 0x14,             // 2/3 threshold
-       0x2b, 0x0f,             // 3/4 threshold
-       0x2c, 0x09,             // 5/6 threshold
-       0x2d, 0x05,             // 7/8 threshold
-       0x2e, 0x01,
-       0x31, 0x1f,             // test all FECs
-       0x32, 0x19,             // viterbi and synchro search
-       0x33, 0xfc,             // rs control
-       0x34, 0x93,             // error control
-       0x0f, 0x52,
-       0xff, 0xff
-};
-
-static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
-{
-       u8 aclk = 0;
-       u8 bclk = 0;
-
-       if (srate < 1500000) {
-               aclk = 0xb7;
-               bclk = 0x47;
-       } else if (srate < 3000000) {
-               aclk = 0xb7;
-               bclk = 0x4b;
-       } else if (srate < 7000000) {
-               aclk = 0xb7;
-               bclk = 0x4f;
-       } else if (srate < 14000000) {
-               aclk = 0xb7;
-               bclk = 0x53;
-       } else if (srate < 30000000) {
-               aclk = 0xb6;
-               bclk = 0x53;
-       } else if (srate < 45000000) {
-               aclk = 0xb4;
-               bclk = 0x51;
-       }
-
-       stv0299_writereg(fe, 0x13, aclk);
-       stv0299_writereg(fe, 0x14, bclk);
-       stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
-       stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
-       stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
-
-       return 0;
-}
-
-static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params)
-{
-       u8 buf[4];
-       u32 div;
-       struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
-
-       if ((params->frequency < 950000) || (params->frequency > 2150000))
-               return -EINVAL;
-
-       div = (params->frequency + (125 - 1)) / 125;    // round correctly
-       buf[0] = (div >> 8) & 0x7f;
-       buf[1] = div & 0xff;
-       buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-       buf[3] = 0xC4;
-
-       if (params->frequency > 1530000)
-               buf[3] = 0xc0;
-
-       if (i2c_transfer(i2c, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
-static struct stv0299_config alps_bsru6_config = {
-
-       .demod_address = 0x68,
-       .inittab = alps_bsru6_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .lock_output = STV0229_LOCKOUTPUT_1,
-       .volt13_op0_op1 = STV0299_VOLT13_OP1,
-       .min_delay_ms = 100,
-       .set_symbol_rate = alps_bsru6_set_symbol_rate,
-       .pll_set = alps_bsru6_pll_set,
-};
-
-
-
-
 static u8 philips_su1278_tt_inittab[] = {
        0x01, 0x0f,
        0x02, 0x30,
@@ -1069,6 +955,20 @@ static void frontend_init(struct budget_ci *budget_ci)
                        break;
                }
                break;
+
+       case 0x1017:            // TT S-1500 PCI
+               budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap);
+               if (budget_ci->budget.dvb_frontend) {
+                       budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
+                       if (lnbp21_init(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) {
+                               printk("%s: No LNBP21 found!\n", __FUNCTION__);
+                               if (budget_ci->budget.dvb_frontend->ops->release)
+                                       budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend);
+                               budget_ci->budget.dvb_frontend = NULL;
+                       }
+               }
+
+               break;
        }
 
        if (budget_ci->budget.dvb_frontend == NULL) {
@@ -1146,6 +1046,7 @@ static int budget_ci_detach(struct saa7146_dev *dev)
 
 static struct saa7146_extension budget_extension;
 
+MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
 MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
 MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T         PCI", BUDGET_TT);
 MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
@@ -1157,6 +1058,7 @@ static struct pci_device_id pci_tbl[] = {
        MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
        MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
        MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
+       MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
        {
         .vendor = 0,
         }
index fc416cf5253ca7dacee87fb17fb76d081f8b048e..9fc9185a842690b8c42bb2aae665b6231358384c 100644 (file)
@@ -37,6 +37,8 @@
 #include "ves1x93.h"
 #include "tda8083.h"
 
+#include "bsru6.h"
+
 #define budget_patch budget
 
 static struct saa7146_extension budget_extension;
@@ -290,103 +292,6 @@ static struct ves1x93_config alps_bsrv2_config = {
        .pll_set = alps_bsrv2_pll_set,
 };
 
-static u8 alps_bsru6_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x00,
-       0x03, 0x00,
-       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x40,   /* DAC not used, set to high impendance mode */
-       0x07, 0x00,   /* DAC LSB */
-       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
-       0x09, 0x00,   /* FIFO */
-       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
-       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
-       0x10, 0x3f,   // AGC2  0x3d
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,   // lock detector threshold
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
-       0x29, 0x1e,  // 1/2 threshold
-       0x2a, 0x14,  // 2/3 threshold
-       0x2b, 0x0f,  // 3/4 threshold
-       0x2c, 0x09,  // 5/6 threshold
-       0x2d, 0x05,  // 7/8 threshold
-       0x2e, 0x01,
-       0x31, 0x1f,  // test all FECs
-       0x32, 0x19,  // viterbi and synchro search
-       0x33, 0xfc,  // rs control
-       0x34, 0x93,  // error control
-       0x0f, 0x52,
-       0xff, 0xff
-};
-
-static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
-{
-       u8 aclk = 0;
-       u8 bclk = 0;
-
-       if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
-       else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
-       else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
-       else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
-       else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
-       else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
-
-       stv0299_writereg (fe, 0x13, aclk);
-       stv0299_writereg (fe, 0x14, bclk);
-       stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
-       stv0299_writereg (fe, 0x20, (ratio >>  8) & 0xff);
-       stv0299_writereg (fe, 0x21, (ratio      ) & 0xf0);
-
-       return 0;
-}
-
-static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
-{
-       u8 data[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL;
-
-       div = (params->frequency + (125 - 1)) / 125; // round correctly
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-       data[3] = 0xC4;
-
-       if (params->frequency > 1530000) data[3] = 0xc0;
-
-       if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO;
-       return 0;
-}
-
-static struct stv0299_config alps_bsru6_config = {
-
-       .demod_address = 0x68,
-       .inittab = alps_bsru6_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .lock_output = STV0229_LOCKOUTPUT_1,
-       .volt13_op0_op1 = STV0299_VOLT13_OP1,
-       .min_delay_ms = 100,
-       .set_symbol_rate = alps_bsru6_set_symbol_rate,
-       .pll_set = alps_bsru6_pll_set,
-};
-
 static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
 {
        struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
index 238c77b52f89f7f0f759ec4dc99acd3487a240ae..c23c02d95641867d8b6163c2fa99dca218bd0299 100644 (file)
@@ -41,6 +41,8 @@
 #include "l64781.h"
 #include "tda8083.h"
 #include "s5h1420.h"
+#include "lnbp21.h"
+#include "bsru6.h"
 
 static void Set22K (struct budget *budget, int state)
 {
@@ -184,64 +186,6 @@ static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t m
        return 0;
 }
 
-static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-       u8 buf;
-       struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
-
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-
-       switch(voltage) {
-       case SEC_VOLTAGE_13:
-               buf = (buf & 0xf7) | 0x04;
-               break;
-
-       case SEC_VOLTAGE_18:
-               buf = (buf & 0xf7) | 0x0c;
-               break;
-
-       case SEC_VOLTAGE_OFF:
-               buf = buf & 0xf0;
-               break;
-       }
-
-       msg.flags = 0;
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-
-       return 0;
-}
-
-static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, long arg)
-{
-       struct budget* budget = (struct budget*) fe->dvb->priv;
-       u8 buf;
-       struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
-
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-
-       if (arg) {
-               buf = buf | 0x10;
-       } else {
-               buf = buf & 0xef;
-       }
-
-       msg.flags = 0;
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
-
-       return 0;
-}
-
-static int lnbp21_init(struct budget* budget)
-{
-       u8 buf = 0x00;
-       struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) };
-
-       if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
-               return -EIO;
-       return 0;
-}
-
 static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
 {
        struct budget* budget = (struct budget*) fe->dvb->priv;
@@ -277,176 +221,6 @@ static struct ves1x93_config alps_bsrv2_config =
        .pll_set = alps_bsrv2_pll_set,
 };
 
-static u8 alps_bsru6_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x00,
-       0x03, 0x00,
-       0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x40,   /* DAC not used, set to high impendance mode */
-       0x07, 0x00,   /* DAC LSB */
-       0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
-       0x09, 0x00,   /* FIFO */
-       0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-       0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
-       0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
-       0x10, 0x3f,   // AGC2  0x3d
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,   // lock detector threshold
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
-       0x29, 0x1e,  // 1/2 threshold
-       0x2a, 0x14,  // 2/3 threshold
-       0x2b, 0x0f,  // 3/4 threshold
-       0x2c, 0x09,  // 5/6 threshold
-       0x2d, 0x05,  // 7/8 threshold
-       0x2e, 0x01,
-       0x31, 0x1f,  // test all FECs
-       0x32, 0x19,  // viterbi and synchro search
-       0x33, 0xfc,  // rs control
-       0x34, 0x93,  // error control
-       0x0f, 0x52,
-       0xff, 0xff
-};
-
-static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
-{
-       u8 aclk = 0;
-       u8 bclk = 0;
-
-       if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
-       else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
-       else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
-       else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
-       else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
-       else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
-
-       stv0299_writereg (fe, 0x13, aclk);
-       stv0299_writereg (fe, 0x14, bclk);
-       stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
-       stv0299_writereg (fe, 0x20, (ratio >>  8) & 0xff);
-       stv0299_writereg (fe, 0x21, (ratio      ) & 0xf0);
-
-       return 0;
-}
-
-static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
-{
-       u8 data[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL;
-
-       div = (params->frequency + (125 - 1)) / 125; // round correctly
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-       data[3] = 0xC4;
-
-       if (params->frequency > 1530000) data[3] = 0xc0;
-
-       if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO;
-       return 0;
-}
-
-static struct stv0299_config alps_bsru6_config = {
-
-       .demod_address = 0x68,
-       .inittab = alps_bsru6_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .lock_output = STV0229_LOCKOUTPUT_1,
-       .volt13_op0_op1 = STV0299_VOLT13_OP1,
-       .min_delay_ms = 100,
-       .set_symbol_rate = alps_bsru6_set_symbol_rate,
-       .pll_set = alps_bsru6_pll_set,
-};
-
-static u8 alps_bsbe1_inittab[] = {
-       0x01, 0x15,
-       0x02, 0x30,
-       0x03, 0x00,
-       0x04, 0x7d,  /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-       0x05, 0x35,  /* I2CT = 0, SCLT = 1, SDAT = 1 */
-       0x06, 0x40,  /* DAC not used, set to high impendance mode */
-       0x07, 0x00,  /* DAC LSB */
-       0x08, 0x40,  /* DiSEqC off, LNB power on OP2/LOCK pin on */
-       0x09, 0x00,  /* FIFO */
-       0x0c, 0x51,  /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-       0x0d, 0x82,  /* DC offset compensation = ON, beta_agc1 = 2 */
-       0x0e, 0x23,  /* alpha_tmg = 2, beta_tmg = 3 */
-       0x10, 0x3f,  // AGC2 0x3d
-       0x11, 0x84,
-       0x12, 0xb9,
-       0x15, 0xc9,  // lock detector threshold
-       0x16, 0x00,
-       0x17, 0x00,
-       0x18, 0x00,
-       0x19, 0x00,
-       0x1a, 0x00,
-       0x1f, 0x50,
-       0x20, 0x00,
-       0x21, 0x00,
-       0x22, 0x00,
-       0x23, 0x00,
-       0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
-       0x29, 0x1e, // 1/2 threshold
-       0x2a, 0x14, // 2/3 threshold
-       0x2b, 0x0f, // 3/4 threshold
-       0x2c, 0x09, // 5/6 threshold
-       0x2d, 0x05, // 7/8 threshold
-       0x2e, 0x01,
-       0x31, 0x1f, // test all FECs
-       0x32, 0x19, // viterbi and synchro search
-       0x33, 0xfc, // rs control
-       0x34, 0x93, // error control
-       0x0f, 0x92, // 0x80 = inverse AGC
-       0xff, 0xff
-};
-
-static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
-{
-       int ret;
-       u8 data[4];
-       u32 div;
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
-       if ((params->frequency < 950000) || (params->frequency > 2150000))
-               return -EINVAL;
-
-       div = (params->frequency + (125 - 1)) / 125; // round correctly
-       data[0] = (div >> 8) & 0x7f;
-       data[1] = div & 0xff;
-       data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-       data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
-
-       ret = i2c_transfer(i2c, &msg, 1);
-       return (ret != 1) ? -EIO : 0;
-}
-
-static struct stv0299_config alps_bsbe1_config = {
-       .demod_address = 0x68,
-       .inittab = alps_bsbe1_inittab,
-       .mclk = 88000000UL,
-       .invert = 1,
-       .skip_reinit = 0,
-       .min_delay_ms = 100,
-       .set_symbol_rate = alps_bsru6_set_symbol_rate,
-       .pll_set = alps_bsbe1_pll_set,
-};
-
 static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
 {
        struct budget* budget = (struct budget*) fe->dvb->priv;
@@ -580,20 +354,6 @@ static u8 read_pwm(struct budget* budget)
 static void frontend_init(struct budget *budget)
 {
        switch(budget->dev->pci->subsystem_device) {
-       case 0x1017:
-               // try the ALPS BSBE1 now
-               budget->dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget->i2c_adap);
-               if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
-                       budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
-                       budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
-                       if (lnbp21_init(budget)) {
-                               printk("%s: No LNBP21 found!\n", __FUNCTION__);
-                               goto error_out;
-                       }
-               }
-
-               break;
        case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
        case 0x1013:
                // try the ALPS BSRV2 first of all
@@ -646,9 +406,7 @@ static void frontend_init(struct budget *budget)
        case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260))
                budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap);
                if (budget->dvb_frontend) {
-                       budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
-                       budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
-                       if (lnbp21_init(budget)) {
+                       if (lnbp21_init(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) {
                                printk("%s: No LNBP21 found!\n", __FUNCTION__);
                                goto error_out;
                        }
@@ -719,7 +477,6 @@ static int budget_detach (struct saa7146_dev* dev)
 
 static struct saa7146_extension budget_extension;
 
-MAKE_BUDGET_INFO(ttbs2, "TT-Budget/WinTV-NOVA-S PCI (rev AL/alps bsbe1 lnbp21 frontend)", BUDGET_TT);
 MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S  PCI",  BUDGET_TT);
 MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C  PCI",  BUDGET_TT);
 MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T  PCI",  BUDGET_TT);
@@ -732,7 +489,6 @@ static struct pci_device_id pci_tbl[] = {
        MAKE_EXTENSION_PCI(ttbc,  0x13c2, 0x1004),
        MAKE_EXTENSION_PCI(ttbt,  0x13c2, 0x1005),
        MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
-       MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
        MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1016),
        MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
        MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
index c7bb63c4d98dc086253fc2f377408a0ec8c95fda..4ac0f4d080252c537379716ba34c44c4c36087f1 100644 (file)
@@ -10,6 +10,8 @@
 #include "dvb_net.h"
 
 #include <linux/module.h>
+#include <linux/mutex.h>
+
 #include <media/saa7146.h>
 
 extern int budget_debug;
@@ -51,7 +53,7 @@ struct budget {
        struct dmx_frontend mem_frontend;
 
        int fe_synced;
-       struct semaphore pid_mutex;
+       struct mutex pid_mutex;
 
        int ci_present;
        int video_port;
index 5a13c4744f616d9799af9e6858f51c9ce5ce141e..248fdc7accfb123d52c37460cc057faec7e2ca52 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/jiffies.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #include "dvb_frontend.h"
 #include "dmxdev.h"
@@ -35,7 +35,6 @@
 #include <linux/dvb/dmx.h>
 #include <linux/pci.h>
 
-
 /*
   TTUSB_HWSECTIONS:
     the DSP supports filtering in hardware, however, since the "muxstream"
@@ -83,8 +82,8 @@ struct ttusb {
        struct dvb_net dvbnet;
 
        /* and one for USB access. */
-       struct semaphore semi2c;
-       struct semaphore semusb;
+       struct mutex semi2c;
+       struct mutex semusb;
 
        struct dvb_adapter adapter;
        struct usb_device *dev;
@@ -150,7 +149,7 @@ static int ttusb_cmd(struct ttusb *ttusb,
        printk("\n");
 #endif
 
-       if (down_interruptible(&ttusb->semusb) < 0)
+       if (mutex_lock_interruptible(&ttusb->semusb) < 0)
                return -EAGAIN;
 
        err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
@@ -158,13 +157,13 @@ static int ttusb_cmd(struct ttusb *ttusb,
        if (err != 0) {
                dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
                        __FUNCTION__, err);
-               up(&ttusb->semusb);
+               mutex_unlock(&ttusb->semusb);
                return err;
        }
        if (actual_len != len) {
                dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__,
                        actual_len, len);
-               up(&ttusb->semusb);
+               mutex_unlock(&ttusb->semusb);
                return -1;
        }
 
@@ -174,7 +173,7 @@ static int ttusb_cmd(struct ttusb *ttusb,
        if (err != 0) {
                printk("%s: failed, receive error %d\n", __FUNCTION__,
                       err);
-               up(&ttusb->semusb);
+               mutex_unlock(&ttusb->semusb);
                return err;
        }
 #if DEBUG >= 3
@@ -185,14 +184,14 @@ static int ttusb_cmd(struct ttusb *ttusb,
        printk("\n");
 #endif
        if (!needresult)
-               up(&ttusb->semusb);
+               mutex_unlock(&ttusb->semusb);
        return 0;
 }
 
 static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
 {
        memcpy(data, ttusb->last_result, len);
-       up(&ttusb->semusb);
+       mutex_unlock(&ttusb->semusb);
        return 0;
 }
 
@@ -250,7 +249,7 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num
        int i = 0;
        int inc;
 
-       if (down_interruptible(&ttusb->semi2c) < 0)
+       if (mutex_lock_interruptible(&ttusb->semi2c) < 0)
                return -EAGAIN;
 
        while (i < num) {
@@ -284,7 +283,7 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num
                i += inc;
        }
 
-       up(&ttusb->semi2c);
+       mutex_unlock(&ttusb->semi2c);
        return i;
 }
 
@@ -689,8 +688,7 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
                                memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
                                       data, avail);
                                ttusb->muxpack_ptr += avail;
-                               if (ttusb->muxpack_ptr > 264)
-                                       BUG();
+                               BUG_ON(ttusb->muxpack_ptr > 264);
                                data += avail;
                                len -= avail;
                                /* determine length */
@@ -1495,8 +1493,11 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
        ttusb->dev = udev;
        ttusb->c = 0;
        ttusb->mux_state = 0;
-       sema_init(&ttusb->semi2c, 0);
-       sema_init(&ttusb->semusb, 1);
+       mutex_init(&ttusb->semi2c);
+
+       mutex_lock(&ttusb->semi2c);
+
+       mutex_init(&ttusb->semusb);
 
        ttusb_setup_interfaces(ttusb);
 
@@ -1504,7 +1505,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
        if (ttusb_init_controller(ttusb))
                printk("ttusb_init_controller: error\n");
 
-       up(&ttusb->semi2c);
+       mutex_unlock(&ttusb->semi2c);
 
        dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE);
        ttusb->adapter.priv = ttusb;
index df831171e03ca3ba92e65fac70e78a8f9c6cc08e..44dea32118483e9dbf14868dd927b84fdfad7ea1 100644 (file)
@@ -20,7 +20,8 @@
  *
  */
 
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -115,7 +116,7 @@ struct ttusb_dec {
        unsigned int                    out_pipe;
        unsigned int                    irq_pipe;
        enum ttusb_dec_interface        interface;
-       struct semaphore                usb_sem;
+       struct mutex                    usb_mutex;
 
        void                    *irq_buffer;
        struct urb              *irq_urb;
@@ -124,7 +125,7 @@ struct ttusb_dec {
        dma_addr_t              iso_dma_handle;
        struct urb              *iso_urb[ISO_BUF_COUNT];
        int                     iso_stream_count;
-       struct semaphore        iso_sem;
+       struct mutex            iso_mutex;
 
        u8                              packet[MAX_PVA_LENGTH + 4];
        enum ttusb_dec_packet_type      packet_type;
@@ -273,9 +274,9 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
        if (!b)
                return -ENOMEM;
 
-       if ((result = down_interruptible(&dec->usb_sem))) {
+       if ((result = mutex_lock_interruptible(&dec->usb_mutex))) {
                kfree(b);
-               printk("%s: Failed to down usb semaphore.\n", __FUNCTION__);
+               printk("%s: Failed to lock usb mutex.\n", __FUNCTION__);
                return result;
        }
 
@@ -300,7 +301,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
        if (result) {
                printk("%s: command bulk message failed: error %d\n",
                       __FUNCTION__, result);
-               up(&dec->usb_sem);
+               mutex_unlock(&dec->usb_mutex);
                kfree(b);
                return result;
        }
@@ -311,7 +312,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
        if (result) {
                printk("%s: result bulk message failed: error %d\n",
                       __FUNCTION__, result);
-               up(&dec->usb_sem);
+               mutex_unlock(&dec->usb_mutex);
                kfree(b);
                return result;
        } else {
@@ -327,7 +328,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
                if (cmd_result && b[3] > 0)
                        memcpy(cmd_result, &b[4], b[3]);
 
-               up(&dec->usb_sem);
+               mutex_unlock(&dec->usb_mutex);
 
                kfree(b);
                return 0;
@@ -835,7 +836,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
 
        dprintk("%s\n", __FUNCTION__);
 
-       if (down_interruptible(&dec->iso_sem))
+       if (mutex_lock_interruptible(&dec->iso_mutex))
                return;
 
        dec->iso_stream_count--;
@@ -845,7 +846,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
                        usb_kill_urb(dec->iso_urb[i]);
        }
 
-       up(&dec->iso_sem);
+       mutex_unlock(&dec->iso_mutex);
 }
 
 /* Setting the interface of the DEC tends to take down the USB communications
@@ -890,7 +891,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
 
        dprintk("%s\n", __FUNCTION__);
 
-       if (down_interruptible(&dec->iso_sem))
+       if (mutex_lock_interruptible(&dec->iso_mutex))
                return -EAGAIN;
 
        if (!dec->iso_stream_count) {
@@ -911,7 +912,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
                                        i--;
                                }
 
-                               up(&dec->iso_sem);
+                               mutex_unlock(&dec->iso_mutex);
                                return result;
                        }
                }
@@ -919,7 +920,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
 
        dec->iso_stream_count++;
 
-       up(&dec->iso_sem);
+       mutex_unlock(&dec->iso_mutex);
 
        return 0;
 }
@@ -1229,8 +1230,8 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec)
 {
        dprintk("%s\n", __FUNCTION__);
 
-       sema_init(&dec->usb_sem, 1);
-       sema_init(&dec->iso_sem, 1);
+       mutex_init(&dec->usb_mutex);
+       mutex_init(&dec->iso_mutex);
 
        dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
        dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
index a917a90cb5dc8cd3a4154621605b7404bb95f67b..b602c73e2309ea9cf3313f225d32628599175025 100644 (file)
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
 #include <asm/io.h>
 #include "../../../sound/oss/aci.h"
 #include "miropcm20-rds-core.h"
 
 #define DEBUG 0
 
-static struct semaphore aci_rds_sem;
+static struct mutex aci_rds_mutex;
 
 #define RDS_DATASHIFT          2   /* Bit 2 */
 #define RDS_DATAMASK        (1 << RDS_DATASHIFT)
@@ -181,7 +182,7 @@ int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize)
 {
        int ret;
 
-       if (down_interruptible(&aci_rds_sem))
+       if (mutex_lock_interruptible(&aci_rds_mutex))
                return -EINTR;
 
        rds_write(cmd);
@@ -192,7 +193,7 @@ int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize)
        else
                ret = 0;
 
-       up(&aci_rds_sem);
+       mutex_unlock(&aci_rds_mutex);
        
        return ret;
 }
@@ -200,7 +201,7 @@ EXPORT_SYMBOL(aci_rds_cmd);
 
 int __init attach_aci_rds(void)
 {
-       init_MUTEX(&aci_rds_sem);
+       mutex_init(&aci_rds_mutex);
        return 0;
 }
 
index 914deab4e04440c462e28a28998ff2c8c2e92141..557fb5c4af38ea59c5fad2cc3ae80cc29e125760 100644 (file)
@@ -43,7 +43,7 @@
 
 static int io = CONFIG_RADIO_RTRACK_PORT; 
 static int radio_nr = -1;
-static struct semaphore lock;
+static struct mutex lock;
 
 struct rt_device
 {
@@ -83,23 +83,23 @@ static void rt_incvol(void)
 static void rt_mute(struct rt_device *dev)
 {
        dev->muted = 1;
-       down(&lock);
+       mutex_lock(&lock);
        outb(0xd0, io);                 /* volume steady, off           */
-       up(&lock);
+       mutex_unlock(&lock);
 }
 
 static int rt_setvol(struct rt_device *dev, int vol)
 {
        int i;
 
-       down(&lock);
+       mutex_lock(&lock);
        
        if(vol == dev->curvol) {        /* requested volume = current */
                if (dev->muted) {       /* user is unmuting the card  */
                        dev->muted = 0;
                        outb (0xd8, io);        /* enable card */
                }       
-               up(&lock);
+               mutex_unlock(&lock);
                return 0;
        }
 
@@ -108,7 +108,7 @@ static int rt_setvol(struct rt_device *dev, int vol)
                sleep_delay(2000000);   /* make sure it's totally down  */
                outb(0xd0, io);         /* volume steady, off           */
                dev->curvol = 0;        /* track the volume state!      */
-               up(&lock);
+               mutex_unlock(&lock);
                return 0;
        }
 
@@ -121,7 +121,7 @@ static int rt_setvol(struct rt_device *dev, int vol)
                        rt_decvol();
 
        dev->curvol = vol;
-       up(&lock);
+       mutex_unlock(&lock);
        return 0;
 }
 
@@ -168,7 +168,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
        freq += 171200;                 /* Add 10.7 MHz IF              */
        freq /= 800;                    /* Convert to 50 kHz units      */
        
-       down(&lock);                    /* Stop other ops interfering */
+       mutex_lock(&lock);                      /* Stop other ops interfering */
         
        send_0_byte (io, dev);          /*  0: LSB of frequency         */
 
@@ -196,7 +196,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
        else
                outb (0xd8, io);        /* volume steady + sigstr + on */
                
-       up(&lock);
+       mutex_unlock(&lock);
 
        return 0;
 }
@@ -337,7 +337,7 @@ static int __init rtrack_init(void)
 
        /* Set up the I/O locking */
        
-       init_MUTEX(&lock);
+       mutex_init(&lock);
        
        /* mute card - prevents noisy bootups */
 
index 523be820f9c64c3f6fd48fa226aebea16f5489ae..83bdae23417d930386d600850df4f51ecab1d4b4 100644 (file)
@@ -42,7 +42,7 @@
 static int io = CONFIG_RADIO_AZTECH_PORT; 
 static int radio_nr = -1;
 static int radio_wait_time = 1000;
-static struct semaphore lock;
+static struct mutex lock;
 
 struct az_device
 {
@@ -87,9 +87,9 @@ static void send_1_byte (struct az_device *dev)
 
 static int az_setvol(struct az_device *dev, int vol)
 {
-       down(&lock);
+       mutex_lock(&lock);
        outb (volconvert(vol), io);
-       up(&lock);
+       mutex_unlock(&lock);
        return 0;
 }
 
@@ -122,7 +122,7 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency)
        frequency += 171200;            /* Add 10.7 MHz IF              */
        frequency /= 800;               /* Convert to 50 kHz units      */
                                        
-       down(&lock);
+       mutex_lock(&lock);
        
        send_0_byte (dev);              /*  0: LSB of frequency       */
 
@@ -152,7 +152,7 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency)
        udelay (radio_wait_time);
        outb_p(128+64+volconvert(dev->curvol), io);
        
-       up(&lock);
+       mutex_unlock(&lock);
 
        return 0;
 }
@@ -283,7 +283,7 @@ static int __init aztech_init(void)
                return -EBUSY;
        }
 
-       init_MUTEX(&lock);
+       mutex_init(&lock);
        aztech_radio.priv=&aztech_unit;
        
        if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1)
index 36c9f5bf8cdd09a0931b863aa770e7454276fdf2..39c1d9118636af1a03804a42cde2f0559d2ca173 100644 (file)
 #include <linux/sched.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 #include <linux/pci.h>
 #include <linux/videodev.h>
 
+
 #define DRIVER_VERSION "0.05"
 
 #define GPIO_DATA      0x60   /* port offset from ESS_IO_BASE */
@@ -104,7 +105,7 @@ struct radio_device {
                muted,  /* VIDEO_AUDIO_MUTE */
                stereo, /* VIDEO_TUNER_STEREO_ON */     
                tuned;  /* signal strength (0 or 0xffff) */
-       struct  semaphore lock;
+       struct mutex lock;
 };
 
 static u32 radio_bits_get(struct radio_device *dev)
@@ -258,9 +259,9 @@ static int radio_ioctl(struct inode *inode, struct file *file,
        struct radio_device *card = video_get_drvdata(dev);
        int ret;
 
-       down(&card->lock);
+       mutex_lock(&card->lock);
        ret = video_usercopy(inode, file, cmd, arg, radio_function);
-       up(&card->lock);
+       mutex_unlock(&card->lock);
 
        return ret;
 }
@@ -311,7 +312,7 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
        }
 
        radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA;
-       init_MUTEX(&radio_unit->lock);
+       mutex_init(&radio_unit->lock);
 
        maestro_radio_inst = video_device_alloc();
        if (maestro_radio_inst == NULL) {
index c975ddd86cd5257e9b8959a2f29e46381661bb1c..f0bf47bcb64cfd3859b98625b9041761f46458e2 100644 (file)
@@ -37,7 +37,8 @@
 #include <linux/sched.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
 #include <linux/pci.h>
 #include <linux/videodev.h>
 
@@ -101,7 +102,7 @@ static struct radio_device
                
        unsigned long freq;
        
-       struct  semaphore lock;
+       struct mutex lock;
 } radio_unit = {0, 0, 0, 0, };
 
 
@@ -267,9 +268,9 @@ static int radio_ioctl(struct inode *inode, struct file *file,
        struct radio_device *card=dev->priv;
        int ret;
        
-       down(&card->lock);
+       mutex_lock(&card->lock);
        ret = video_usercopy(inode, file, cmd, arg, radio_function);
-       up(&card->lock);
+       mutex_unlock(&card->lock);
        return ret;
 }
 
@@ -290,7 +291,7 @@ static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_d
                goto err_out_free_region;
 
        radio_unit.io = pci_resource_start(pdev, 0);
-       init_MUTEX(&radio_unit.lock);
+       mutex_init(&radio_unit.lock);
        maxiradio_radio.priv = &radio_unit;
 
        if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) {
index 0229f792a05969717a7271356a03a1a6c51da3ce..53073b424107ba5972478f6773bb096c11e7b554 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/isapnp.h>
 #include <asm/io.h>            /* outb, outb_p                 */
 #include <asm/uaccess.h>       /* copy to/from user            */
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 struct fmi_device
 {
@@ -37,7 +37,7 @@ struct fmi_device
 static int io = -1; 
 static int radio_nr = -1;
 static struct pnp_dev *dev = NULL;
-static struct semaphore lock;
+static struct mutex lock;
 
 /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
 /* It is only useful to give freq in intervall of 800 (=0.05Mhz),
@@ -68,16 +68,16 @@ static void outbits(int bits, unsigned int data, int port)
 
 static inline void fmi_mute(int port)
 {
-       down(&lock);
+       mutex_lock(&lock);
        outb(0x00, port);
-       up(&lock);
+       mutex_unlock(&lock);
 }
 
 static inline void fmi_unmute(int port)
 {
-       down(&lock);
+       mutex_lock(&lock);
        outb(0x08, port);
-       up(&lock);
+       mutex_unlock(&lock);
 }
 
 static inline int fmi_setfreq(struct fmi_device *dev)
@@ -85,12 +85,12 @@ static inline int fmi_setfreq(struct fmi_device *dev)
        int myport = dev->port;
        unsigned long freq = dev->curfreq;
 
-       down(&lock);
+       mutex_lock(&lock);
 
        outbits(16, RSF16_ENCODE(freq), myport);
        outbits(8, 0xC0, myport);
        msleep(143);            /* was schedule_timeout(HZ/7) */
-       up(&lock);
+       mutex_unlock(&lock);
        if (dev->curvol) fmi_unmute(myport);
        return 0;
 }
@@ -102,7 +102,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev)
        int myport = dev->port;
 
        
-       down(&lock);
+       mutex_lock(&lock);
        val = dev->curvol ? 0x08 : 0x00;        /* unmute/mute */
        outb(val, myport);
        outb(val | 0x10, myport);
@@ -110,7 +110,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev)
        res = (int)inb(myport+1);
        outb(val, myport);
        
-       up(&lock);
+       mutex_unlock(&lock);
        return (res & 2) ? 0 : 0xFFFF;
 }
 
@@ -296,7 +296,7 @@ static int __init fmi_init(void)
        fmi_unit.flags = VIDEO_TUNER_LOW;
        fmi_radio.priv = &fmi_unit;
        
-       init_MUTEX(&lock);
+       mutex_init(&lock);
        
        if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) {
                release_region(io, 2);
index 099ffb3b9c710e5d242d29f630d74eed8a61c5dc..bcebd8cb19ad43e0accfb4aa97088d27781837d1 100644 (file)
@@ -19,9 +19,9 @@
 #include <asm/io.h>            /* outb, outb_p                 */
 #include <asm/uaccess.h>       /* copy to/from user            */
 #include <linux/videodev.h>    /* kernel radio structs         */
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
-static struct semaphore lock;
+static struct mutex lock;
 
 #undef DEBUG
 //#define DEBUG 1
@@ -238,9 +238,9 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file,
                        if (fmr2->mute)
                                v->flags |= VIDEO_AUDIO_MUTE;
                        v->mode=VIDEO_MODE_AUTO;
-                       down(&lock);
+                       mutex_lock(&lock);
                        v->signal = fmr2_getsigstr(fmr2);
-                       up(&lock);
+                       mutex_unlock(&lock);
                        return 0;
                }
                case VIDIOCSTUNER:
@@ -274,9 +274,9 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file,
                        /* set card freq (if not muted) */
                        if (fmr2->curvol && !fmr2->mute)
                        {
-                               down(&lock);
+                               mutex_lock(&lock);
                                fmr2_setfreq(fmr2);
-                               up(&lock);
+                               mutex_unlock(&lock);
                        }
                        return 0;
                }
@@ -318,14 +318,14 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file,
                        else
                                printk(KERN_DEBUG "mute\n");
 #endif
-                       down(&lock);
+                       mutex_lock(&lock);
                        if (fmr2->curvol && !fmr2->mute)
                        {
                                fmr2_setvolume(fmr2);
                                fmr2_setfreq(fmr2);
                        }
                        else fmr2_mute(fmr2->port);
-                       up(&lock);
+                       mutex_unlock(&lock);
                        return 0;
                }
                case VIDIOCGUNIT:
@@ -380,7 +380,7 @@ static int __init fmr2_init(void)
        fmr2_unit.card_type = 0;
        fmr2_radio.priv = &fmr2_unit;
 
-       init_MUTEX(&lock);
+       mutex_init(&lock);
 
        if (request_region(io, 2, "sf16fmr2"))
        {
@@ -397,10 +397,10 @@ static int __init fmr2_init(void)
        printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io);
        debug_print((KERN_DEBUG "Mute %d Low %d\n",VIDEO_AUDIO_MUTE,VIDEO_TUNER_LOW));
        /* mute card - prevents noisy bootups */
-       down(&lock);
+       mutex_lock(&lock);
        fmr2_mute(io);
        fmr2_product_info(&fmr2_unit);
-       up(&lock);
+       mutex_unlock(&lock);
        debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type));
        return 0;
 }
index 8ac9a8ef909441e98171dbb4b4f4e65d5c16b749..e50955836d6b1a829dc273846157a443866c9d76 100644 (file)
@@ -59,7 +59,7 @@ struct typhoon_device {
        int muted;
        unsigned long curfreq;
        unsigned long mutefreq;
-       struct semaphore lock;
+       struct mutex lock;
 };
 
 static void typhoon_setvol_generic(struct typhoon_device *dev, int vol);
@@ -77,12 +77,12 @@ static int typhoon_get_info(char *buf, char **start, off_t offset, int len);
 
 static void typhoon_setvol_generic(struct typhoon_device *dev, int vol)
 {
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        vol >>= 14;                             /* Map 16 bit to 2 bit */
        vol &= 3;
        outb_p(vol / 2, dev->iobase);           /* Set the volume, high bit. */
        outb_p(vol % 2, dev->iobase + 2);       /* Set the volume, low bit. */
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 }
 
 static int typhoon_setfreq_generic(struct typhoon_device *dev,
@@ -102,7 +102,7 @@ static int typhoon_setfreq_generic(struct typhoon_device *dev,
         *
         */
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        x = frequency / 160;
        outval = (x * x + 2500) / 5000;
        outval = (outval * x + 5000) / 10000;
@@ -112,7 +112,7 @@ static int typhoon_setfreq_generic(struct typhoon_device *dev,
        outb_p((outval >> 8) & 0x01, dev->iobase + 4);
        outb_p(outval >> 9, dev->iobase + 6);
        outb_p(outval & 0xff, dev->iobase + 8);
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 
        return 0;
 }
@@ -337,7 +337,7 @@ static int __init typhoon_init(void)
 #endif /* MODULE */
 
        printk(KERN_INFO BANNER);
-       init_MUTEX(&typhoon_unit.lock);
+       mutex_init(&typhoon_unit.lock);
        io = typhoon_unit.iobase;
        if (!request_region(io, 8, "typhoon")) {
                printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n",
index d590e80c922e336a69d610f26f18f3cf28898652..7bf1a4264891deca514dd6a5465497b46e02919d 100644 (file)
@@ -48,7 +48,7 @@ struct zol_device {
        unsigned long curfreq;
        int muted;
        unsigned int stereo;
-       struct semaphore lock;
+       struct mutex lock;
 };
 
 static int zol_setvol(struct zol_device *dev, int vol)
@@ -57,30 +57,30 @@ static int zol_setvol(struct zol_device *dev, int vol)
        if (dev->muted)
                return 0;
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        if (vol == 0) {
                outb(0, io);
                outb(0, io);
                inb(io + 3);    /* Zoltrix needs to be read to confirm */
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        }
 
        outb(dev->curvol-1, io);
        msleep(10);
        inb(io + 2);
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
        return 0;
 }
 
 static void zol_mute(struct zol_device *dev)
 {
        dev->muted = 1;
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        outb(0, io);
        outb(0, io);
        inb(io + 3);            /* Zoltrix needs to be read to confirm */
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 }
 
 static void zol_unmute(struct zol_device *dev)
@@ -104,7 +104,7 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
        bitmask = 0xc480402c10080000ull;
        i = 45;
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        
        outb(0, io);
        outb(0, io);
@@ -149,7 +149,7 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
                udelay(1000);
        }
        
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
        
        if(!dev->muted)
        {
@@ -164,7 +164,7 @@ static int zol_getsigstr(struct zol_device *dev)
 {
        int a, b;
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        outb(0x00, io);         /* This stuff I found to do nothing */
        outb(dev->curvol, io);
        msleep(20);
@@ -173,7 +173,7 @@ static int zol_getsigstr(struct zol_device *dev)
        msleep(10);
        b = inb(io);
 
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
        
        if (a != b)
                return (0);
@@ -188,7 +188,7 @@ static int zol_is_stereo (struct zol_device *dev)
 {
        int x1, x2;
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        
        outb(0x00, io);
        outb(dev->curvol, io);
@@ -198,7 +198,7 @@ static int zol_is_stereo (struct zol_device *dev)
        msleep(10);
        x2 = inb(io);
 
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
        
        if ((x1 == x2) && (x1 == 0xcf))
                return 1;
@@ -350,7 +350,7 @@ static int __init zoltrix_init(void)
        }
        printk(KERN_INFO "Zoltrix Radio Plus card driver.\n");
 
-       init_MUTEX(&zoltrix_unit.lock);
+       mutex_init(&zoltrix_unit.lock);
        
        /* mute card - prevents noisy bootups */
 
index d82c8a30ba44373e137ba43b7fe8f0067d156119..c622a4da5663a0d87db2335f49fcdbbd5d3c5c91 100644 (file)
@@ -26,6 +26,7 @@ config VIDEO_BT848
        select VIDEO_IR
        select VIDEO_TUNER
        select VIDEO_TVEEPROM
+       select VIDEO_MSP3400
        ---help---
          Support for BT848 based frame grabber/overlay boards. This includes
          the Miro, Hauppauge and STB boards. Please read the material in
@@ -142,6 +143,8 @@ config VIDEO_CPIA_USB
          otherwise say N. This will not work with the Creative Webcam III.
          It is also available as a module (cpia_usb).
 
+source "drivers/media/video/cpia2/Kconfig"
+
 config VIDEO_SAA5246A
        tristate "SAA5246A, SAA5281 Teletext processor"
        depends on VIDEO_DEV && I2C
@@ -339,18 +342,53 @@ config VIDEO_M32R_AR_M64278
          Say Y here to use the Renesas M64278E-800 camera module,
          which supports VGA(640x480 pixcels) size of images.
 
-config VIDEO_AUDIO_DECODER
-       tristate "Add support for additional audio chipsets"
+config VIDEO_MSP3400
+       tristate "Micronas MSP34xx audio decoders"
+       depends on VIDEO_DEV && I2C
+       ---help---
+         Support for the Micronas MSP34xx series of audio decoders.
+
+         To compile this driver as a module, choose M here: the
+         module will be called msp3400
+
+config VIDEO_CS53L32A
+       tristate "Cirrus Logic CS53L32A audio ADC"
        depends on VIDEO_DEV && I2C && EXPERIMENTAL
        ---help---
-         Say Y here to compile drivers for WM8775 and CS53L32A audio
-         decoders.
+         Support for the Cirrus Logic CS53L32A low voltage
+         stereo A/D converter.
 
-config VIDEO_DECODER
-       tristate "Add support for additional video chipsets"
+         To compile this driver as a module, choose M here: the
+         module will be called cs53l32a
+
+config VIDEO_WM8775
+       tristate "Wolfson Microelectronics WM8775 audio ADC"
        depends on VIDEO_DEV && I2C && EXPERIMENTAL
        ---help---
-         Say Y here to compile drivers for SAA7115, SAA7127 and CX25840
-         video decoders.
+         Support for the Wolfson Microelectronics WM8775
+         high performance stereo A/D Converter.
+
+         To compile this driver as a module, choose M here: the
+         module will be called wm8775
+
+source "drivers/media/video/cx25840/Kconfig"
+
+config VIDEO_SAA711X
+       tristate "Philips SAA7113/4/5 video decoders"
+       depends on VIDEO_DEV && I2C && EXPERIMENTAL
+       ---help---
+         Support for the Philips SAA7113/4/5 video decoders.
+
+         To compile this driver as a module, choose M here: the
+         module will be called saa7115
+
+config VIDEO_SAA7127
+       tristate "Philips SAA7127/9 digital video encoders"
+       depends on VIDEO_DEV && I2C && EXPERIMENTAL
+       ---help---
+         Support for the Philips SAA7127/9 digital video encoders.
+
+         To compile this driver as a module, choose M here: the
+         module will be called saa7127
 
 endmenu
index faf728366c4e4e57655939d8540b2908b8fd1691..f2bd4c0c4f10f5f0215a18d14d6533d88e6f8664 100644 (file)
@@ -15,7 +15,7 @@ msp3400-objs  :=      msp3400-driver.o msp3400-kthreads.o
 
 obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o
 
-obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
+obj-$(CONFIG_VIDEO_BT848) += bttv.o tvaudio.o \
        tda7432.o tda9875.o ir-kbd-i2c.o
 obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
 
@@ -44,10 +44,13 @@ obj-$(CONFIG_VIDEO_MEYE) += meye.o
 obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/
 obj-$(CONFIG_VIDEO_CX88) += cx88/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
-obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o
-obj-$(CONFIG_VIDEO_AUDIO_DECODER) += wm8775.o cs53l32a.o
+obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o
+obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
+obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
+obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
 obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
-obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
+obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
+obj-$(CONFIG_VIDEO_MXB) += saa7111.o tda9840.o tea6415c.o tea6420.o mxb.o
 obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
 obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
 obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o
@@ -61,6 +64,8 @@ obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
 
 obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
 
-obj-$(CONFIG_VIDEO_DECODER)     += saa7115.o cx25840/ saa7127.o
+obj-$(CONFIG_VIDEO_CX25840) += cx25840/
+obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
+obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
 
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
index 994b75fe165ab8d63f5a1f7ff036a58d8a9c14e5..c586f64b6b7f20fb7d1e38016c4a90ed983bae16 100644 (file)
@@ -31,8 +31,8 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/videodev.h>
+#include <linux/mutex.h>
 
-#include <asm/semaphore.h>
 #include <asm/uaccess.h>
 #include <asm/m32r.h>
 #include <asm/io.h>
@@ -117,7 +117,7 @@ struct ar_device {
        int width, height;
        int frame_bytes, line_bytes;
        wait_queue_head_t wait;
-       struct semaphore lock;
+       struct mutex lock;
 };
 
 static int video_nr = -1;      /* video device number (first free) */
@@ -288,7 +288,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
        if (ar->mode == AR_MODE_NORMAL)
                arvcr1 |= ARVCR1_NORMAL;
 
-       down(&ar->lock);
+       mutex_lock(&ar->lock);
 
 #if USE_INT
        local_irq_save(flags);
@@ -392,7 +392,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
        }
        DEBUG(1, "ret = %d\n", ret);
 out_up:
-       up(&ar->lock);
+       mutex_unlock(&ar->lock);
        return ret;
 }
 
@@ -456,7 +456,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file,
                    (w->width != AR_WIDTH_QVGA || w->height != AR_HEIGHT_QVGA))
                                return -EINVAL;
 
-               down(&ar->lock);
+               mutex_lock(&ar->lock);
                ar->width = w->width;
                ar->height = w->height;
                if (ar->width == AR_WIDTH_VGA) {
@@ -473,7 +473,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file,
                        ar->line_bytes = AR_LINE_BYTES_QVGA;
                        ar->mode = AR_MODE_INTERLACE;
                }
-               up(&ar->lock);
+               mutex_unlock(&ar->lock);
                return 0;
        }
        case VIDIOCGFBUF:
@@ -734,7 +734,7 @@ static int ar_initialize(struct video_device *dev)
 void ar_release(struct video_device *vfd)
 {
        struct ar_device *ar = vfd->priv;
-       down(&ar->lock);
+       mutex_lock(&ar->lock);
        video_device_release(vfd);
 }
 
@@ -824,7 +824,7 @@ static int __init ar_init(void)
                ar->line_bytes  = AR_LINE_BYTES_QVGA;
                ar->mode        = AR_MODE_INTERLACE;
        }
-       init_MUTEX(&ar->lock);
+       mutex_init(&ar->lock);
        init_waitqueue_head(&ar->wait);
 
 #if USE_INT
index 9749d6ed623184d42b2e5220980e2a60821e7cbf..abfa6ad857a0b89f8e33b581a0d92bc721732bf7 100644 (file)
@@ -137,6 +137,8 @@ MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a li
 MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
 MODULE_PARM_DESC(tuner,"specify installed tuner type");
 MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)");
+MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
+               " [some VIA/SIS chipsets are known to have problem with overlay]");
 
 /* ----------------------------------------------------------------------- */
 /* list of card IDs for bt878+ cards                                       */
@@ -275,7 +277,6 @@ static struct CARD {
        { 0x03116000, BTTV_BOARD_SENSORAY311,   "Sensoray 311" },
        { 0x00790e11, BTTV_BOARD_WINDVR,        "Canopus WinDVR PCI" },
        { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX,       "Face to Face Tvmax" },
-       { 0x20007063, BTTV_BOARD_PC_HDTV,       "pcHDTV HD-2000 TV"},
        { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" },
        { 0x146caa0c, BTTV_BOARD_PV951,         "ituner spectra8" },
        { 0x200a1295, BTTV_BOARD_PXC200,        "ImageNation PXC200A" },
@@ -297,13 +298,14 @@ static struct CARD {
        * { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB,  "Hauppauge ImpactVCB" }, */
 
        /* DVB cards (using pci function .1 for mpeg data xfer) */
-       { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
-       { 0x07611461, BTTV_BOARD_AVDVBT_761,    "AverMedia AverTV DVB-T 761" },
        { 0x001c11bd, BTTV_BOARD_PINNACLESAT,   "Pinnacle PCTV Sat" },
+       { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
+       { 0x20007063, BTTV_BOARD_PC_HDTV,       "pcHDTV HD-2000 TV"},
        { 0x002611bd, BTTV_BOARD_TWINHAN_DST,   "Pinnacle PCTV SAT CI" },
        { 0x00011822, BTTV_BOARD_TWINHAN_DST,   "Twinhan VisionPlus DVB" },
        { 0xfc00270f, BTTV_BOARD_TWINHAN_DST,   "ChainTech digitop DST-1000 DVB-S" },
        { 0x07711461, BTTV_BOARD_AVDVBT_771,    "AVermedia AverTV DVB-T 771" },
+       { 0x07611461, BTTV_BOARD_AVDVBT_761,    "AverMedia AverTV DVB-T 761" },
        { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE,    "DViCO FusionHDTV DVB-T Lite" },
        { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE,    "DViCO FusionHDTV 5 Lite" },
 
@@ -4944,12 +4946,14 @@ void __devinit bttv_check_chipset(void)
        if (vsfx)
                printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n");
        if (pcipci_fail) {
-               printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n");
+               printk(KERN_INFO "bttv: bttv and your chipset may not work "
+                                                       "together.\n");
                if (!no_overlay) {
-                       printk(KERN_WARNING "bttv: overlay will be disabled.\n");
+                       printk(KERN_INFO "bttv: overlay will be disabled.\n");
                        no_overlay = 1;
                } else {
-                       printk(KERN_WARNING "bttv: overlay forced. Use this option at your own risk.\n");
+                       printk(KERN_INFO "bttv: overlay forced. Use this "
+                                               "option at your own risk.\n");
                }
        }
        if (UNSET != latency)
index 578b20085082a54df29077b2b517e946a30482f0..c0415d6e7fee2164bda6731e15fccea8ff58a259 100644 (file)
@@ -1965,7 +1965,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
                BUG();
        }
 
-       down(&fh->cap.lock);
+       mutex_lock(&fh->cap.lock);
                kfree(fh->ov.clips);
        fh->ov.clips    = clips;
        fh->ov.nclips   = n;
@@ -1986,7 +1986,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
                bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
                retval = bttv_switch_overlay(btv,fh,new);
        }
-       up(&fh->cap.lock);
+       mutex_unlock(&fh->cap.lock);
        return retval;
 }
 
@@ -2166,7 +2166,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
                fmt = format_by_fourcc(f->fmt.pix.pixelformat);
 
                /* update our state informations */
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                fh->fmt              = fmt;
                fh->cap.field        = f->fmt.pix.field;
                fh->cap.last         = V4L2_FIELD_NONE;
@@ -2175,7 +2175,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
                btv->init.fmt        = fmt;
                btv->init.width      = f->fmt.pix.width;
                btv->init.height     = f->fmt.pix.height;
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
 
                return 0;
        }
@@ -2282,7 +2282,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                fmt = format_by_palette(pic->palette);
                if (NULL == fmt)
                        return -EINVAL;
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                if (fmt->depth != pic->depth) {
                        retval = -EINVAL;
                        goto fh_unlock_and_return;
@@ -2313,7 +2313,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                bt848_contrast(btv,pic->contrast);
                bt848_hue(btv,pic->hue);
                bt848_sat(btv,pic->colour);
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return 0;
        }
 
@@ -2379,7 +2379,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                        return -EPERM;
                end = (unsigned long)fbuf->base +
                        fbuf->height * fbuf->bytesperline;
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                retval = -EINVAL;
 
                switch (fbuf->depth) {
@@ -2417,7 +2417,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                        btv->fbuf.fmt.bytesperline = fbuf->bytesperline;
                else
                        btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fbuf->depth/8;
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return 0;
        }
 
@@ -2440,7 +2440,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY))
                        return -EBUSY;
 
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                if (*on) {
                        fh->ov.tvnorm = btv->tvnorm;
                        new = videobuf_alloc(sizeof(*new));
@@ -2451,7 +2451,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
 
                /* switch over */
                retval = bttv_switch_overlay(btv,fh,new);
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return retval;
        }
 
@@ -2460,7 +2460,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                struct video_mbuf *mbuf = arg;
                unsigned int i;
 
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize,
                                             V4L2_MEMORY_MMAP);
                if (retval < 0)
@@ -2470,7 +2470,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                mbuf->size   = gbuffers * gbufsize;
                for (i = 0; i < gbuffers; i++)
                        mbuf->offsets[i] = i * gbufsize;
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return 0;
        }
        case VIDIOCMCAPTURE:
@@ -2482,7 +2482,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                if (vm->frame >= VIDEO_MAX_FRAME)
                        return -EINVAL;
 
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                retval = -EINVAL;
                buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame];
                if (NULL == buf)
@@ -2504,7 +2504,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                spin_lock_irqsave(&btv->s_lock,flags);
                buffer_queue(&fh->cap,&buf->vb);
                spin_unlock_irqrestore(&btv->s_lock,flags);
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return 0;
        }
        case VIDIOCSYNC:
@@ -2515,7 +2515,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                if (*frame >= VIDEO_MAX_FRAME)
                        return -EINVAL;
 
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                retval = -EINVAL;
                buf = (struct bttv_buffer *)fh->cap.bufs[*frame];
                if (NULL == buf)
@@ -2535,7 +2535,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                        retval = -EINVAL;
                        break;
                }
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return retval;
        }
 
@@ -2719,7 +2719,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                if (0 == (fmt->flags & FORMAT_FLAGS_PACKED))
                        return -EINVAL;
 
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                retval = -EINVAL;
                if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
                        if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth)
@@ -2759,7 +2759,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                                retval = bttv_switch_overlay(btv,fh,new);
                        }
                }
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                return retval;
        }
 
@@ -2890,7 +2890,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
        return 0;
 
  fh_unlock_and_return:
-       up(&fh->cap.lock);
+       mutex_unlock(&fh->cap.lock);
        return retval;
 }
 
@@ -2957,16 +2957,16 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
                buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
        } else {
                /* read() capture */
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                if (NULL == fh->cap.read_buf) {
                        /* need to capture a new frame */
                        if (locked_btres(fh->btv,RESOURCE_VIDEO)) {
-                               up(&fh->cap.lock);
+                               mutex_unlock(&fh->cap.lock);
                                return POLLERR;
                        }
                        fh->cap.read_buf = videobuf_alloc(fh->cap.msize);
                        if (NULL == fh->cap.read_buf) {
-                               up(&fh->cap.lock);
+                               mutex_unlock(&fh->cap.lock);
                                return POLLERR;
                        }
                        fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
@@ -2974,13 +2974,13 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
                        if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
                                kfree (fh->cap.read_buf);
                                fh->cap.read_buf = NULL;
-                               up(&fh->cap.lock);
+                               mutex_unlock(&fh->cap.lock);
                                return POLLERR;
                        }
                        fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
                        fh->cap.read_off = 0;
                }
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                buf = (struct bttv_buffer*)fh->cap.read_buf;
        }
 
index 221b36e7f3922d0cac81da1ae06490a2a0d50cb3..69efa0e5174d58ffb113d97479f8b82180490b65 100644 (file)
 #include "bttv.h"
 #include "bttvp.h"
 
-/* ---------------------------------------------------------------------- */
-
-static IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = {
-       [ 34 ] = KEY_KP0,
-       [ 40 ] = KEY_KP1,
-       [ 24 ] = KEY_KP2,
-       [ 56 ] = KEY_KP3,
-       [ 36 ] = KEY_KP4,
-       [ 20 ] = KEY_KP5,
-       [ 52 ] = KEY_KP6,
-       [ 44 ] = KEY_KP7,
-       [ 28 ] = KEY_KP8,
-       [ 60 ] = KEY_KP9,
-
-       [ 48 ] = KEY_EJECTCD,     // Unmarked on my controller
-       [  0 ] = KEY_POWER,
-       [ 18 ] = BTN_LEFT,        // DISPLAY/L
-       [ 50 ] = BTN_RIGHT,       // LOOP/R
-       [ 10 ] = KEY_MUTE,
-       [ 38 ] = KEY_RECORD,
-       [ 22 ] = KEY_PAUSE,
-       [ 54 ] = KEY_STOP,
-       [ 30 ] = KEY_VOLUMEDOWN,
-       [ 62 ] = KEY_VOLUMEUP,
-
-       [ 32 ] = KEY_TUNER,       // TV/FM
-       [ 16 ] = KEY_CD,
-       [  8 ] = KEY_VIDEO,
-       [  4 ] = KEY_AUDIO,
-       [ 12 ] = KEY_ZOOM,        // full screen
-       [  2 ] = KEY_INFO,        // preview
-       [ 42 ] = KEY_SEARCH,      // autoscan
-       [ 26 ] = KEY_STOP,        // freeze
-       [ 58 ] = KEY_RECORD,      // capture
-       [  6 ] = KEY_PLAY,        // unmarked
-       [ 46 ] = KEY_RED,         // unmarked
-       [ 14 ] = KEY_GREEN,       // unmarked
-
-       [ 33 ] = KEY_YELLOW,      // unmarked
-       [ 17 ] = KEY_CHANNELDOWN,
-       [ 49 ] = KEY_CHANNELUP,
-       [  1 ] = KEY_BLUE,        // unmarked
-};
-
-/* Matt Jesson <dvb@jesson.eclipse.co.uk */
-static IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
-       [ 0x28 ] = KEY_KP0,         //'0' / 'enter'
-       [ 0x22 ] = KEY_KP1,         //'1'
-       [ 0x12 ] = KEY_KP2,         //'2' / 'up arrow'
-       [ 0x32 ] = KEY_KP3,         //'3'
-       [ 0x24 ] = KEY_KP4,         //'4' / 'left arrow'
-       [ 0x14 ] = KEY_KP5,         //'5'
-       [ 0x34 ] = KEY_KP6,         //'6' / 'right arrow'
-       [ 0x26 ] = KEY_KP7,         //'7'
-       [ 0x16 ] = KEY_KP8,         //'8' / 'down arrow'
-       [ 0x36 ] = KEY_KP9,         //'9'
-
-       [ 0x20 ] = KEY_LIST,        // 'source'
-       [ 0x10 ] = KEY_TEXT,        // 'teletext'
-       [ 0x00 ] = KEY_POWER,       // 'power'
-       [ 0x04 ] = KEY_AUDIO,       // 'audio'
-       [ 0x06 ] = KEY_ZOOM,        // 'full screen'
-       [ 0x18 ] = KEY_VIDEO,       // 'display'
-       [ 0x38 ] = KEY_SEARCH,      // 'loop'
-       [ 0x08 ] = KEY_INFO,        // 'preview'
-       [ 0x2a ] = KEY_REWIND,      // 'backward <<'
-       [ 0x1a ] = KEY_FASTFORWARD, // 'forward >>'
-       [ 0x3a ] = KEY_RECORD,      // 'capture'
-       [ 0x0a ] = KEY_MUTE,        // 'mute'
-       [ 0x2c ] = KEY_RECORD,      // 'record'
-       [ 0x1c ] = KEY_PAUSE,       // 'pause'
-       [ 0x3c ] = KEY_STOP,        // 'stop'
-       [ 0x0c ] = KEY_PLAY,        // 'play'
-       [ 0x2e ] = KEY_RED,         // 'red'
-       [ 0x01 ] = KEY_BLUE,        // 'blue' / 'cancel'
-       [ 0x0e ] = KEY_YELLOW,      // 'yellow' / 'ok'
-       [ 0x21 ] = KEY_GREEN,       // 'green'
-       [ 0x11 ] = KEY_CHANNELDOWN, // 'channel -'
-       [ 0x31 ] = KEY_CHANNELUP,   // 'channel +'
-       [ 0x1e ] = KEY_VOLUMEDOWN,  // 'volume -'
-       [ 0x3e ] = KEY_VOLUMEUP,    // 'volume +'
-};
-
-/* Attila Kondoros <attila.kondoros@chello.hu> */
-static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
-
-       [  1 ] = KEY_KP1,
-       [  2 ] = KEY_KP2,
-       [  3 ] = KEY_KP3,
-       [  4 ] = KEY_KP4,
-       [  5 ] = KEY_KP5,
-       [  6 ] = KEY_KP6,
-       [  7 ] = KEY_KP7,
-       [  8 ] = KEY_KP8,
-       [  9 ] = KEY_KP9,
-       [  0 ] = KEY_KP0,
-       [ 23 ] = KEY_LAST,        // +100
-       [ 10 ] = KEY_LIST,        // recall
-
-
-       [ 28 ] = KEY_TUNER,       // TV/FM
-       [ 21 ] = KEY_SEARCH,      // scan
-       [ 18 ] = KEY_POWER,       // power
-       [ 31 ] = KEY_VOLUMEDOWN,  // vol up
-       [ 27 ] = KEY_VOLUMEUP,    // vol down
-       [ 30 ] = KEY_CHANNELDOWN, // chn up
-       [ 26 ] = KEY_CHANNELUP,   // chn down
-
-       [ 17 ] = KEY_VIDEO,       // video
-       [ 15 ] = KEY_ZOOM,        // full screen
-       [ 19 ] = KEY_MUTE,        // mute/unmute
-       [ 16 ] = KEY_TEXT,        // min
-
-       [ 13 ] = KEY_STOP,        // freeze
-       [ 14 ] = KEY_RECORD,      // record
-       [ 29 ] = KEY_PLAYPAUSE,   // stop
-       [ 25 ] = KEY_PLAY,        // play
-
-       [ 22 ] = KEY_GOTO,        // osd
-       [ 20 ] = KEY_REFRESH,     // default
-       [ 12 ] = KEY_KPPLUS,      // fine tune >>>>
-       [ 24 ] = KEY_KPMINUS      // fine tune <<<<
-};
-
-/* ---------------------------------------------------------------------- */
-
-static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
-
-       [ 30 ] = KEY_POWER,       // power
-       [ 7  ] = KEY_MEDIA,       // source
-       [ 28 ] = KEY_SEARCH,      // scan
-
-/* FIXME: duplicate keycodes?
- *
- * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
- * The GPIO values are
- * 6397fb for both "Scan <" and "CH -",
- * 639ffb for "Scan >" and "CH+",
- * 6384fb for "Tune <" and "<<<",
- * 638cfb for "Tune >" and ">>>", regardless of the mask.
- *
- *     [ 23 ] = KEY_BACK,        // fm scan <<
- *     [ 31 ] = KEY_FORWARD,     // fm scan >>
- *
- *     [ 4  ] = KEY_LEFT,        // fm tuning <
- *     [ 12 ] = KEY_RIGHT,       // fm tuning >
- *
- * For now, these four keys are disabled. Pressing them will generate
- * the CH+/CH-/<<</>>> events
- */
-
-       [ 3  ] = KEY_TUNER,       // TV/FM
-
-       [ 0  ] = KEY_RECORD,
-       [ 8  ] = KEY_STOP,
-       [ 17 ] = KEY_PLAY,
-
-       [ 26 ] = KEY_PLAYPAUSE,   // freeze
-       [ 25 ] = KEY_ZOOM,        // zoom
-       [ 15 ] = KEY_TEXT,        // min
-
-       [ 1  ] = KEY_KP1,
-       [ 11 ] = KEY_KP2,
-       [ 27 ] = KEY_KP3,
-       [ 5  ] = KEY_KP4,
-       [ 9  ] = KEY_KP5,
-       [ 21 ] = KEY_KP6,
-       [ 6  ] = KEY_KP7,
-       [ 10 ] = KEY_KP8,
-       [ 18 ] = KEY_KP9,
-       [ 2  ] = KEY_KP0,
-       [ 16 ] = KEY_LAST,        // +100
-       [ 19 ] = KEY_LIST,        // recall
-
-       [ 31 ] = KEY_CHANNELUP,   // chn down
-       [ 23 ] = KEY_CHANNELDOWN, // chn up
-       [ 22 ] = KEY_VOLUMEUP,    // vol down
-       [ 20 ] = KEY_VOLUMEDOWN,  // vol up
-
-       [ 4  ] = KEY_KPMINUS,     // <<<
-       [ 14 ] = KEY_SETUP,       // function
-       [ 12 ] = KEY_KPPLUS,      // >>>
-
-       [ 13 ] = KEY_GOTO,        // mts
-       [ 29 ] = KEY_REFRESH,     // reset
-       [ 24 ] = KEY_MUTE         // mute/unmute
-};
-
-static IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = {
-       [0x00] = KEY_KP0,
-       [0x01] = KEY_KP1,
-       [0x02] = KEY_KP2,
-       [0x03] = KEY_KP3,
-       [0x04] = KEY_KP4,
-       [0x05] = KEY_KP5,
-       [0x06] = KEY_KP6,
-       [0x07] = KEY_KP7,
-       [0x08] = KEY_KP8,
-       [0x09] = KEY_KP9,
-       [0x0a] = KEY_TV,
-       [0x0b] = KEY_AUX,
-       [0x0c] = KEY_DVD,
-       [0x0d] = KEY_POWER,
-       [0x0e] = KEY_MHP,       /* labelled 'Picture' */
-       [0x0f] = KEY_AUDIO,
-       [0x10] = KEY_INFO,
-       [0x11] = KEY_F13,       /* 16:9 */
-       [0x12] = KEY_F14,       /* 14:9 */
-       [0x13] = KEY_EPG,
-       [0x14] = KEY_EXIT,
-       [0x15] = KEY_MENU,
-       [0x16] = KEY_UP,
-       [0x17] = KEY_DOWN,
-       [0x18] = KEY_LEFT,
-       [0x19] = KEY_RIGHT,
-       [0x1a] = KEY_ENTER,
-       [0x1b] = KEY_CHANNELUP,
-       [0x1c] = KEY_CHANNELDOWN,
-       [0x1d] = KEY_VOLUMEUP,
-       [0x1e] = KEY_VOLUMEDOWN,
-       [0x1f] = KEY_RED,
-       [0x20] = KEY_GREEN,
-       [0x21] = KEY_YELLOW,
-       [0x22] = KEY_BLUE,
-       [0x23] = KEY_SUBTITLE,
-       [0x24] = KEY_F15,       /* AD */
-       [0x25] = KEY_TEXT,
-       [0x26] = KEY_MUTE,
-       [0x27] = KEY_REWIND,
-       [0x28] = KEY_STOP,
-       [0x29] = KEY_PLAY,
-       [0x2a] = KEY_FASTFORWARD,
-       [0x2b] = KEY_F16,       /* chapter */
-       [0x2c] = KEY_PAUSE,
-       [0x2d] = KEY_PLAY,
-       [0x2e] = KEY_RECORD,
-       [0x2f] = KEY_F17,       /* picture in picture */
-       [0x30] = KEY_KPPLUS,    /* zoom in */
-       [0x31] = KEY_KPMINUS,   /* zoom out */
-       [0x32] = KEY_F18,       /* capture */
-       [0x33] = KEY_F19,       /* web */
-       [0x34] = KEY_EMAIL,
-       [0x35] = KEY_PHONE,
-       [0x36] = KEY_PC
-};
 
 static int debug;
 module_param(debug, int, 0644);    /* debug level (0,1,2) */
@@ -573,7 +328,8 @@ int bttv_input_init(struct bttv *btv)
                ir->polling      = 50; // ms
                break;
        case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
-               ir_codes         = ir_codes_conceptronic;
+       case BTTV_BOARD_CONTVFMI:
+               ir_codes         = ir_codes_pixelview;
                ir->mask_keycode = 0x001F00;
                ir->mask_keyup   = 0x006000;
                ir->polling      = 50; // ms
index b40e9734bf0885d83724b29b4b5d7683964fe01f..344f84e9af0462899f8a6f62ddac7315ed720cb0 100644 (file)
@@ -51,8 +51,10 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
        int rc;
 
        /* estimate risc mem: worst case is one write per page border +
-          one write per scan line + sync + jump (all 2 dwords) */
-       instructions  = (bpl * lines) / PAGE_SIZE + lines;
+          one write per scan line + sync + jump (all 2 dwords).  padding
+          can cause next bpl to start close to a page border.  First DMA
+          region may be smaller than PAGE_SIZE */
+       instructions  = 1 + ((bpl + padding) * lines) / PAGE_SIZE + lines;
        instructions += 2;
        if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0)
                return rc;
@@ -104,7 +106,7 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
 
        /* save pointer to jmp instruction address */
        risc->jmp = rp;
-       BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
+       BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
        return 0;
 }
 
@@ -222,7 +224,7 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
 
        /* save pointer to jmp instruction address */
        risc->jmp = rp;
-       BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
+       BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
        return 0;
 }
 
@@ -274,6 +276,8 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
                if (line > maxy)
                        btcx_calc_skips(line, ov->w.width, &maxy,
                                        skips, &nskips, ov->clips, ov->nclips);
+               else
+                       nskips = 0;
 
                /* write out risc code */
                for (start = 0, skip = 0; start < ov->w.width; start = end) {
@@ -307,7 +311,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
 
        /* save pointer to jmp instruction address */
        risc->jmp = rp;
-       BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
+       BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
        kfree(skips);
        return 0;
 }
@@ -507,8 +511,7 @@ bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
 void
 bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf)
 {
-       if (in_interrupt())
-               BUG();
+       BUG_ON(in_interrupt());
        videobuf_waiton(&buf->vb,0,0);
        videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma);
        videobuf_dma_free(&buf->vb.dma);
index 6bad93ef969fd402d6131a1a9c0d0a594c769d3b..d97b7d8ac33d687f9f7d0a46f32f069096d0e5c0 100644 (file)
@@ -73,7 +73,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include <linux/parport.h>
 #include <linux/sched.h>
 #include <linux/videodev.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 #include <asm/uaccess.h>
 
 #include "bw-qcam.h"
@@ -168,7 +168,7 @@ static struct qcam_device *qcam_init(struct parport *port)
        
        memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
        
-       init_MUTEX(&q->lock);
+       mutex_init(&q->lock);
 
        q->port_mode = (QC_ANY | QC_NOTSET);
        q->width = 320;
@@ -772,9 +772,9 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
                        qcam->whitebal = p->whiteness>>8;
                        qcam->bpp = p->depth;
 
-                       down(&qcam->lock);                      
+                       mutex_lock(&qcam->lock);
                        qc_setscanmode(qcam);
-                       up(&qcam->lock);
+                       mutex_unlock(&qcam->lock);
                        qcam->status |= QC_PARAM_CHANGE;
 
                        return 0;
@@ -805,9 +805,9 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
                                qcam->height = 240;
                                qcam->transfer_scale = 1;
                        }
-                       down(&qcam->lock);
+                       mutex_lock(&qcam->lock);
                        qc_setscanmode(qcam);
-                       up(&qcam->lock);
+                       mutex_unlock(&qcam->lock);
                        
                        /* We must update the camera before we grab. We could
                           just have changed the grab size */
@@ -854,7 +854,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
        int len;
        parport_claim_or_block(qcam->pdev);
        
-       down(&qcam->lock);
+       mutex_lock(&qcam->lock);
        
        qc_reset(qcam);
 
@@ -864,7 +864,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
 
        len=qc_capture(qcam, buf,count);
        
-       up(&qcam->lock);
+       mutex_unlock(&qcam->lock);
        
        parport_release(qcam->pdev);
        return len;
index 723e8ad9e56ac52f49998a44b959ea3b567d189b..6701dafbc0da82deca9579837464c94e3db426e0 100644 (file)
@@ -55,7 +55,7 @@ struct qcam_device {
        struct video_device vdev;
        struct pardevice *pdev;
        struct parport *pport;
-       struct semaphore lock;
+       struct mutex lock;
        int width, height;
        int bpp;
        int mode;
index 9976db4f6da8f77d6f41961bc6115a23c82a25f2..8211fd8d7cbfabc587f14cf7e99a19986e465ffc 100644 (file)
@@ -34,7 +34,8 @@
 #include <linux/parport.h>
 #include <linux/sched.h>
 #include <linux/videodev.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
 #include <asm/uaccess.h>
 
 struct qcam_device {
@@ -47,7 +48,7 @@ struct qcam_device {
        int contrast, brightness, whitebal;
        int top, left;
        unsigned int bidirectional;
-       struct semaphore lock;
+       struct mutex lock;
 };
 
 /* cameras maximum */
@@ -581,11 +582,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
                        qcam->contrast = p->contrast>>8;
                        qcam->whitebal = p->whiteness>>8;
 
-                       down(&qcam->lock);                      
+                       mutex_lock(&qcam->lock);
                        parport_claim_or_block(qcam->pdev);
                        qc_setup(qcam); 
                        parport_release(qcam->pdev);
-                       up(&qcam->lock);
+                       mutex_unlock(&qcam->lock);
                        return 0;
                }
                case VIDIOCSWIN:
@@ -628,11 +629,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
 #endif
                        /* Ok we figured out what to use from our 
                           wide choice */
-                       down(&qcam->lock);
+                       mutex_lock(&qcam->lock);
                        parport_claim_or_block(qcam->pdev);
                        qc_setup(qcam);
                        parport_release(qcam->pdev);
-                       up(&qcam->lock);
+                       mutex_unlock(&qcam->lock);
                        return 0;
                }
                case VIDIOCGWIN:
@@ -672,12 +673,12 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
        struct qcam_device *qcam=(struct qcam_device *)v;
        int len;
 
-       down(&qcam->lock);
+       mutex_lock(&qcam->lock);
        parport_claim_or_block(qcam->pdev);
        /* Probably should have a semaphore against multiple users */
        len = qc_capture(qcam, buf,count); 
        parport_release(qcam->pdev);
-       up(&qcam->lock);
+       mutex_unlock(&qcam->lock);
        return len;
 }
 
@@ -727,7 +728,7 @@ static struct qcam_device *qcam_init(struct parport *port)
        
        memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
 
-       init_MUTEX(&q->lock);
+       mutex_init(&q->lock);
        q->width = q->ccd_width = 320;
        q->height = q->ccd_height = 240;
        q->mode = QC_MILLIONS | QC_DECIMATION_1;
index 85d964b5b33c5e55bd5e99506ba25774b3fc267c..d93a561e6b80dbe6817ec6fd91d3771194ee0c47 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/pagemap.h>
 #include <linux/delay.h>
 #include <asm/io.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
@@ -622,7 +622,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf,
        
        buffer = page;
        
-       if (down_interruptible(&cam->param_lock))
+       if (mutex_lock_interruptible(&cam->param_lock))
                return -ERESTARTSYS;
        
        /*
@@ -1350,7 +1350,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf,
        } else
                DBG("error: %d\n", retval);
        
-       up(&cam->param_lock);
+       mutex_unlock(&cam->param_lock);
        
 out:
        free_page((unsigned long)page);
@@ -1664,7 +1664,7 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
        case CPIA_COMMAND_GetColourParams:
        case CPIA_COMMAND_GetColourBalance:
        case CPIA_COMMAND_GetExposure:
-               down(&cam->param_lock);
+               mutex_lock(&cam->param_lock);
                datasize=8;
                break;
        case CPIA_COMMAND_ReadMCPorts: 
@@ -1691,7 +1691,7 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
                if (command == CPIA_COMMAND_GetColourParams ||
                    command == CPIA_COMMAND_GetColourBalance ||
                    command == CPIA_COMMAND_GetExposure)
-                       up(&cam->param_lock);
+                       mutex_unlock(&cam->param_lock);
        } else {
                switch(command) {
                case CPIA_COMMAND_GetCPIAVersion:
@@ -1726,13 +1726,13 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
                        cam->params.colourParams.brightness = data[0];
                        cam->params.colourParams.contrast = data[1];
                        cam->params.colourParams.saturation = data[2];
-                       up(&cam->param_lock);
+                       mutex_unlock(&cam->param_lock);
                        break;
                case CPIA_COMMAND_GetColourBalance:
                        cam->params.colourBalance.redGain = data[0];
                        cam->params.colourBalance.greenGain = data[1];
                        cam->params.colourBalance.blueGain = data[2];
-                       up(&cam->param_lock);
+                       mutex_unlock(&cam->param_lock);
                        break;
                case CPIA_COMMAND_GetExposure:
                        cam->params.exposure.gain = data[0];
@@ -1743,7 +1743,7 @@ static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
                        cam->params.exposure.green1Comp = data[5];
                        cam->params.exposure.green2Comp = data[6];
                        cam->params.exposure.blueComp = data[7];
-                       up(&cam->param_lock);
+                       mutex_unlock(&cam->param_lock);
                        break;
 
                case CPIA_COMMAND_ReadMCPorts: 
@@ -2059,7 +2059,7 @@ static int parse_picture(struct cam_data *cam, int size)
        int rows, cols, linesize, subsample_422;
 
        /* make sure params don't change while we are decoding */
-       down(&cam->param_lock);
+       mutex_lock(&cam->param_lock);
 
        obuf = cam->decompressed_frame.data;
        end_obuf = obuf+CPIA_MAX_FRAME_SIZE;
@@ -2069,26 +2069,26 @@ static int parse_picture(struct cam_data *cam, int size)
 
        if ((ibuf[0] != MAGIC_0) || (ibuf[1] != MAGIC_1)) {
                LOG("header not found\n");
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
                return -1;
        }
 
        if ((ibuf[16] != VIDEOSIZE_QCIF) && (ibuf[16] != VIDEOSIZE_CIF)) {
                LOG("wrong video size\n");
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
                return -1;
        }
        
        if (ibuf[17] != SUBSAMPLE_420 && ibuf[17] != SUBSAMPLE_422) {
                LOG("illegal subtype %d\n",ibuf[17]);
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
                return -1;
        }
        subsample_422 = ibuf[17] == SUBSAMPLE_422;
        
        if (ibuf[18] != YUVORDER_YUYV && ibuf[18] != YUVORDER_UYVY) {
                LOG("illegal yuvorder %d\n",ibuf[18]);
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
                return -1;
        }
        in_uyvy = ibuf[18] == YUVORDER_UYVY;
@@ -2098,7 +2098,7 @@ static int parse_picture(struct cam_data *cam, int size)
            (ibuf[26] != cam->params.roi.rowStart) ||
            (ibuf[27] != cam->params.roi.rowEnd)) {
                LOG("ROI mismatch\n");
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
                return -1;
        }
        cols = 8*(ibuf[25] - ibuf[24]);
@@ -2107,14 +2107,14 @@ static int parse_picture(struct cam_data *cam, int size)
        
        if ((ibuf[28] != NOT_COMPRESSED) && (ibuf[28] != COMPRESSED)) {
                LOG("illegal compression %d\n",ibuf[28]);
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
                return -1;
        }
        compressed = (ibuf[28] == COMPRESSED);
        
        if (ibuf[29] != NO_DECIMATION && ibuf[29] != DECIMATION_ENAB) {
                LOG("illegal decimation %d\n",ibuf[29]);
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
                return -1;
        }
        decimation = (ibuf[29] == DECIMATION_ENAB);     
@@ -2130,7 +2130,7 @@ static int parse_picture(struct cam_data *cam, int size)
        cam->params.status.vpStatus = ibuf[38];
        cam->params.status.errorCode = ibuf[39];
        cam->fps = ibuf[41];
-       up(&cam->param_lock);
+       mutex_unlock(&cam->param_lock);
        
        linesize = skipcount(cols, out_fmt);
        ibuf += FRAME_HEADER_SIZE;
@@ -2271,9 +2271,9 @@ static int find_over_exposure(int brightness)
 /* update various camera modes and settings */
 static void dispatch_commands(struct cam_data *cam)
 {
-       down(&cam->param_lock);
+       mutex_lock(&cam->param_lock);
        if (cam->cmd_queue==COMMAND_NONE) {
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
                return;
        }
        DEB_BYTE(cam->cmd_queue);
@@ -2415,7 +2415,7 @@ static void dispatch_commands(struct cam_data *cam)
          }
 
        cam->cmd_queue = COMMAND_NONE;
-       up(&cam->param_lock);
+       mutex_unlock(&cam->param_lock);
        return;
 }
 
@@ -2562,7 +2562,7 @@ static void monitor_exposure(struct cam_data *cam)
        gain = data[2];
        coarseL = data[3];
 
-       down(&cam->param_lock);
+       mutex_lock(&cam->param_lock);
        light_exp = cam->params.colourParams.brightness +
                    TC - 50 + EXP_ACC_LIGHT;
        if(light_exp > 255)
@@ -2762,7 +2762,7 @@ static void monitor_exposure(struct cam_data *cam)
                        LOG("Automatically increasing sensor_fps\n");
                }
        }
-       up(&cam->param_lock);
+       mutex_unlock(&cam->param_lock);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2778,10 +2778,10 @@ static void restart_flicker(struct cam_data *cam)
        int cam_exposure, old_exp;
        if(!FIRMWARE_VERSION(1,2))
                return;
-       down(&cam->param_lock);
+       mutex_lock(&cam->param_lock);
        if(cam->params.flickerControl.flickerMode == 0 ||
           cam->raw_image[39] == 0) {
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
                return;
        }
        cam_exposure = cam->raw_image[39]*2;
@@ -2810,7 +2810,7 @@ static void restart_flicker(struct cam_data *cam)
                        cam->exposure_status = EXPOSURE_NORMAL;
 
        }
-       up(&cam->param_lock);
+       mutex_unlock(&cam->param_lock);
 }
 #undef FIRMWARE_VERSION
 
@@ -3186,7 +3186,7 @@ static int cpia_open(struct inode *inode, struct file *file)
        if (!try_module_get(cam->ops->owner))
                return -ENODEV;
 
-       down(&cam->busy_lock);
+       mutex_lock(&cam->busy_lock);
        err = -ENOMEM;
        if (!cam->raw_image) {
                cam->raw_image = rvmalloc(CPIA_MAX_IMAGE_SIZE);
@@ -3227,7 +3227,7 @@ static int cpia_open(struct inode *inode, struct file *file)
        
        ++cam->open_count;
        file->private_data = dev;
-       up(&cam->busy_lock);
+       mutex_unlock(&cam->busy_lock);
        return 0;
 
  oops:
@@ -3239,7 +3239,7 @@ static int cpia_open(struct inode *inode, struct file *file)
                rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
                cam->raw_image = NULL;
        }
-       up(&cam->busy_lock);
+       mutex_unlock(&cam->busy_lock);
        put_cam(cam->ops);
        return err;
 }
@@ -3303,24 +3303,24 @@ static ssize_t cpia_read(struct file *file, char __user *buf,
        int err;
 
        /* make this _really_ smp and multithread-safe */
-       if (down_interruptible(&cam->busy_lock))
+       if (mutex_lock_interruptible(&cam->busy_lock))
                return -EINTR;
 
        if (!buf) {
                DBG("buf NULL\n");
-               up(&cam->busy_lock);
+               mutex_unlock(&cam->busy_lock);
                return -EINVAL;
        }
 
        if (!count) {
                DBG("count 0\n");
-               up(&cam->busy_lock);
+               mutex_unlock(&cam->busy_lock);
                return 0;
        }
 
        if (!cam->ops) {
                DBG("ops NULL\n");
-               up(&cam->busy_lock);
+               mutex_unlock(&cam->busy_lock);
                return -ENODEV;
        }
 
@@ -3329,7 +3329,7 @@ static ssize_t cpia_read(struct file *file, char __user *buf,
        cam->mmap_kludge=0;
        if((err = fetch_frame(cam)) != 0) {
                DBG("ERROR from fetch_frame: %d\n", err);
-               up(&cam->busy_lock);
+               mutex_unlock(&cam->busy_lock);
                return err;
        }
        cam->decompressed_frame.state = FRAME_UNUSED;
@@ -3338,17 +3338,17 @@ static ssize_t cpia_read(struct file *file, char __user *buf,
        if (cam->decompressed_frame.count > count) {
                DBG("count wrong: %d, %lu\n", cam->decompressed_frame.count,
                    (unsigned long) count);
-               up(&cam->busy_lock);
+               mutex_unlock(&cam->busy_lock);
                return -EFAULT;
        }
        if (copy_to_user(buf, cam->decompressed_frame.data,
                        cam->decompressed_frame.count)) {
                DBG("copy_to_user failed\n");
-               up(&cam->busy_lock);
+               mutex_unlock(&cam->busy_lock);
                return -EFAULT;
        }
 
-       up(&cam->busy_lock);
+       mutex_unlock(&cam->busy_lock);
        return cam->decompressed_frame.count;
 }
 
@@ -3363,7 +3363,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
                return -ENODEV;
        
        /* make this _really_ smp-safe */
-       if (down_interruptible(&cam->busy_lock))
+       if (mutex_lock_interruptible(&cam->busy_lock))
                return -EINTR;
 
        //DBG("cpia_ioctl: %u\n", ioctlnr);
@@ -3439,7 +3439,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
                        break;
                }
 
-               down(&cam->param_lock);
+               mutex_lock(&cam->param_lock);
                /* brightness, colour, contrast need no check 0-65535 */
                cam->vp = *vp;
                /* update cam->params.colourParams */
@@ -3466,7 +3466,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
 
                /* queue command to update camera */
                cam->cmd_queue |= COMMAND_SETCOLOURPARAMS;
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
                DBG("VIDIOCSPICT: %d / %d // %d / %d / %d / %d\n",
                    vp->depth, vp->palette, vp->brightness, vp->hue, vp->colour,
                    vp->contrast);
@@ -3501,13 +3501,13 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
                /* we set the video window to something smaller or equal to what
                * is requested by the user???
                */
-               down(&cam->param_lock);
+               mutex_lock(&cam->param_lock);
                if (vw->width != cam->vw.width || vw->height != cam->vw.height) {
                        int video_size = match_videosize(vw->width, vw->height);
 
                        if (video_size < 0) {
                                retval = -EINVAL;
-                               up(&cam->param_lock);
+                               mutex_unlock(&cam->param_lock);
                                break;
                        }
                        cam->video_size = video_size;
@@ -3520,7 +3520,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
                        cam->cmd_queue |= COMMAND_SETFORMAT;
                }
 
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
 
                /* setformat ignored by camera during streaming,
                 * so stop/dispatch/start */
@@ -3682,7 +3682,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
 
                DBG("%d,%d/%dx%d\n", vc->x,vc->y,vc->width, vc->height);
                
-               down(&cam->param_lock);
+               mutex_lock(&cam->param_lock);
                
                cam->vc.x      = vc->x;
                cam->vc.y      = vc->y;
@@ -3692,7 +3692,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
                set_vw_size(cam);
                cam->cmd_queue |= COMMAND_SETFORMAT;
 
-               up(&cam->param_lock);
+               mutex_unlock(&cam->param_lock);
 
                /* setformat ignored by camera during streaming,
                 * so stop/dispatch/start */
@@ -3736,7 +3736,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file,
                break;
        }
 
-       up(&cam->busy_lock);
+       mutex_unlock(&cam->busy_lock);
        return retval;
 } 
 
@@ -3769,12 +3769,12 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma)
                return -ENODEV;
        
        /* make this _really_ smp-safe */
-       if (down_interruptible(&cam->busy_lock))
+       if (mutex_lock_interruptible(&cam->busy_lock))
                return -EINTR;
 
        if (!cam->frame_buf) {  /* we do lazy allocation */
                if ((retval = allocate_frame_buf(cam))) {
-                       up(&cam->busy_lock);
+                       mutex_unlock(&cam->busy_lock);
                        return retval;
                }
        }
@@ -3783,7 +3783,7 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma)
        while (size > 0) {
                page = vmalloc_to_pfn((void *)pos);
                if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
-                       up(&cam->busy_lock);
+                       mutex_unlock(&cam->busy_lock);
                        return -EAGAIN;
                }
                start += PAGE_SIZE;
@@ -3795,7 +3795,7 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma)
        }
 
        DBG("cpia_mmap: %ld\n", size);
-       up(&cam->busy_lock);
+       mutex_unlock(&cam->busy_lock);
 
        return 0;
 }
@@ -3936,8 +3936,8 @@ static void init_camera_struct(struct cam_data *cam,
        memset(cam, 0, sizeof(struct cam_data));
 
        cam->ops = ops;
-       init_MUTEX(&cam->param_lock);
-       init_MUTEX(&cam->busy_lock);
+       mutex_init(&cam->param_lock);
+       mutex_init(&cam->busy_lock);
 
        reset_camera_struct(cam);
 
index f629b693ee656e704993496eeb08e818483d8384..de6678200a57ee13c52f59f1e4ddfd4a38636a20 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/videodev.h>
 #include <linux/list.h>
 #include <linux/smp_lock.h>
+#include <linux/mutex.h>
 
 struct cpia_camera_ops
 {
@@ -246,7 +247,7 @@ enum v4l_camstates {
 struct cam_data {
        struct list_head cam_data_list;
 
-        struct semaphore busy_lock;     /* guard against SMP multithreading */
+        struct mutex busy_lock;     /* guard against SMP multithreading */
        struct cpia_camera_ops *ops;    /* lowlevel driver operations */
        void *lowlevel_data;            /* private data for lowlevel driver */
        u8 *raw_image;                  /* buffer for raw image data */
@@ -261,7 +262,7 @@ struct cam_data {
        u8 mainsFreq;                   /* for flicker control */
 
                                /* proc interface */
-       struct semaphore param_lock;    /* params lock for this camera */
+       struct mutex param_lock;        /* params lock for this camera */
        struct cam_params params;       /* camera settings */
        struct proc_dir_entry *proc_entry;      /* /proc/cpia/videoX */
        
diff --git a/drivers/media/video/cpia2/Kconfig b/drivers/media/video/cpia2/Kconfig
new file mode 100644 (file)
index 0000000..513cc09
--- /dev/null
@@ -0,0 +1,9 @@
+config VIDEO_CPIA2
+       tristate "CPiA2 Video For Linux"
+       depends on VIDEO_DEV && USB
+       ---help---
+         This is the video4linux driver for cameras based on Vision's CPiA2
+         (Colour Processor Interface ASIC), such as the Digital Blue QX5
+         Microscope. If you have one of these cameras, say Y here
+
+         This driver is also available as a module (cpia2).
diff --git a/drivers/media/video/cpia2/Makefile b/drivers/media/video/cpia2/Makefile
new file mode 100644 (file)
index 0000000..828cf1b
--- /dev/null
@@ -0,0 +1,3 @@
+cpia2-objs     := cpia2_v4l.o cpia2_usb.o cpia2_core.o
+
+obj-$(CONFIG_VIDEO_CPIA2) += cpia2.o
diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h
new file mode 100644 (file)
index 0000000..95d3afa
--- /dev/null
@@ -0,0 +1,497 @@
+/****************************************************************************
+ *
+ *  Filename: cpia2.h
+ *
+ *  Copyright 2001, STMicrolectronics, Inc.
+ *
+ *  Contact:  steve.miller@st.com
+ *
+ *  Description:
+ *     This is a USB driver for CPiA2 based video cameras.
+ *
+ *     This driver is modelled on the cpia usb driver by
+ *     Jochen Scharrlach and Johannes Erdfeldt.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ****************************************************************************/
+
+#ifndef __CPIA2_H__
+#define __CPIA2_H__
+
+#include <linux/version.h>
+#include <linux/videodev.h>
+#include <linux/usb.h>
+#include <linux/poll.h>
+
+#include "cpia2dev.h"
+#include "cpia2_registers.h"
+
+/* define for verbose debug output */
+//#define _CPIA2_DEBUG_
+
+#define CPIA2_MAJ_VER  2
+#define CPIA2_MIN_VER   0
+#define CPIA2_PATCH_VER        0
+
+/***
+ * Image defines
+ ***/
+#ifndef true
+#define true 1
+#define false 0
+#endif
+
+/*  Misc constants */
+#define ALLOW_CORRUPT 0                /* Causes collater to discard checksum */
+
+/* USB Transfer mode */
+#define XFER_ISOC 0
+#define XFER_BULK 1
+
+/* USB Alternates */
+#define USBIF_CMDONLY 0
+#define USBIF_BULK 1
+#define USBIF_ISO_1 2  /*  128 bytes/ms */
+#define USBIF_ISO_2 3  /*  384 bytes/ms */
+#define USBIF_ISO_3 4  /*  640 bytes/ms */
+#define USBIF_ISO_4 5  /*  768 bytes/ms */
+#define USBIF_ISO_5 6  /*  896 bytes/ms */
+#define USBIF_ISO_6 7  /* 1023 bytes/ms */
+
+/* Flicker Modes */
+#define NEVER_FLICKER   0
+#define ANTI_FLICKER_ON 1
+#define FLICKER_60      60
+#define FLICKER_50      50
+
+/* Debug flags */
+#define DEBUG_NONE          0
+#define DEBUG_REG           0x00000001
+#define DEBUG_DUMP_PATCH    0x00000002
+#define DEBUG_DUMP_REGS     0x00000004
+
+/***
+ * Video frame sizes
+ ***/
+enum {
+       VIDEOSIZE_VGA = 0,      /* 640x480 */
+       VIDEOSIZE_CIF,          /* 352x288 */
+       VIDEOSIZE_QVGA,         /* 320x240 */
+       VIDEOSIZE_QCIF,         /* 176x144 */
+       VIDEOSIZE_288_216,
+       VIDEOSIZE_256_192,
+       VIDEOSIZE_224_168,
+       VIDEOSIZE_192_144,
+};
+
+#define STV_IMAGE_CIF_ROWS    288
+#define STV_IMAGE_CIF_COLS    352
+
+#define STV_IMAGE_QCIF_ROWS   144
+#define STV_IMAGE_QCIF_COLS   176
+
+#define STV_IMAGE_VGA_ROWS    480
+#define STV_IMAGE_VGA_COLS    640
+
+#define STV_IMAGE_QVGA_ROWS   240
+#define STV_IMAGE_QVGA_COLS   320
+
+#define JPEG_MARKER_COM (1<<6) /* Comment segment */
+
+/***
+ * Enums
+ ***/
+/* Sensor types available with cpia2 asics */
+enum sensors {
+       CPIA2_SENSOR_410,
+       CPIA2_SENSOR_500
+};
+
+/* Asic types available in the CPiA2 architecture */
+#define  CPIA2_ASIC_672 0x67
+
+/* Device types (stv672, stv676, etc) */
+#define  DEVICE_STV_672   0x0001
+#define  DEVICE_STV_676   0x0002
+
+enum frame_status {
+       FRAME_EMPTY,
+       FRAME_READING,          /* In the process of being grabbed into */
+       FRAME_READY,            /* Ready to be read */
+       FRAME_ERROR,
+};
+
+/***
+ * Register access (for USB request byte)
+ ***/
+enum {
+       CAMERAACCESS_SYSTEM = 0,
+       CAMERAACCESS_VC,
+       CAMERAACCESS_VP,
+       CAMERAACCESS_IDATA
+};
+
+#define CAMERAACCESS_TYPE_BLOCK    0x00
+#define CAMERAACCESS_TYPE_RANDOM   0x04
+#define CAMERAACCESS_TYPE_MASK     0x08
+#define CAMERAACCESS_TYPE_REPEAT   0x0C
+
+#define TRANSFER_READ 0
+#define TRANSFER_WRITE 1
+
+#define DEFAULT_ALT   USBIF_ISO_6
+#define DEFAULT_BRIGHTNESS 0x46
+#define DEFAULT_CONTRAST 0x93
+#define DEFAULT_SATURATION 0x7f
+#define DEFAULT_TARGET_KB 0x30
+
+/* Power state */
+#define HI_POWER_MODE CPIA2_SYSTEM_CONTROL_HIGH_POWER
+#define LO_POWER_MODE CPIA2_SYSTEM_CONTROL_LOW_POWER
+
+
+/********
+ * Commands
+ *******/
+enum {
+       CPIA2_CMD_NONE = 0,
+       CPIA2_CMD_GET_VERSION,
+       CPIA2_CMD_GET_PNP_ID,
+       CPIA2_CMD_GET_ASIC_TYPE,
+       CPIA2_CMD_GET_SENSOR,
+       CPIA2_CMD_GET_VP_DEVICE,
+       CPIA2_CMD_GET_VP_BRIGHTNESS,
+       CPIA2_CMD_SET_VP_BRIGHTNESS,
+       CPIA2_CMD_GET_CONTRAST,
+       CPIA2_CMD_SET_CONTRAST,
+       CPIA2_CMD_GET_VP_SATURATION,
+       CPIA2_CMD_SET_VP_SATURATION,
+       CPIA2_CMD_GET_VP_GPIO_DIRECTION,
+       CPIA2_CMD_SET_VP_GPIO_DIRECTION,
+       CPIA2_CMD_GET_VP_GPIO_DATA,
+       CPIA2_CMD_SET_VP_GPIO_DATA,
+       CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION,
+       CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
+       CPIA2_CMD_GET_VC_MP_GPIO_DATA,
+       CPIA2_CMD_SET_VC_MP_GPIO_DATA,
+       CPIA2_CMD_ENABLE_PACKET_CTRL,
+       CPIA2_CMD_GET_FLICKER_MODES,
+       CPIA2_CMD_SET_FLICKER_MODES,
+       CPIA2_CMD_RESET_FIFO,   /* clear fifo and enable stream block */
+       CPIA2_CMD_SET_HI_POWER,
+       CPIA2_CMD_SET_LOW_POWER,
+       CPIA2_CMD_CLEAR_V2W_ERR,
+       CPIA2_CMD_SET_USER_MODE,
+       CPIA2_CMD_GET_USER_MODE,
+       CPIA2_CMD_FRAMERATE_REQ,
+       CPIA2_CMD_SET_COMPRESSION_STATE,
+       CPIA2_CMD_GET_WAKEUP,
+       CPIA2_CMD_SET_WAKEUP,
+       CPIA2_CMD_GET_PW_CONTROL,
+       CPIA2_CMD_SET_PW_CONTROL,
+       CPIA2_CMD_GET_SYSTEM_CTRL,
+       CPIA2_CMD_SET_SYSTEM_CTRL,
+       CPIA2_CMD_GET_VP_SYSTEM_STATE,
+       CPIA2_CMD_GET_VP_SYSTEM_CTRL,
+       CPIA2_CMD_SET_VP_SYSTEM_CTRL,
+       CPIA2_CMD_GET_VP_EXP_MODES,
+       CPIA2_CMD_SET_VP_EXP_MODES,
+       CPIA2_CMD_GET_DEVICE_CONFIG,
+       CPIA2_CMD_SET_DEVICE_CONFIG,
+       CPIA2_CMD_SET_SERIAL_ADDR,
+       CPIA2_CMD_SET_SENSOR_CR1,
+       CPIA2_CMD_GET_VC_CONTROL,
+       CPIA2_CMD_SET_VC_CONTROL,
+       CPIA2_CMD_SET_TARGET_KB,
+       CPIA2_CMD_SET_DEF_JPEG_OPT,
+       CPIA2_CMD_REHASH_VP4,
+       CPIA2_CMD_GET_USER_EFFECTS,
+       CPIA2_CMD_SET_USER_EFFECTS
+};
+
+enum user_cmd {
+       COMMAND_NONE = 0x00000001,
+       COMMAND_SET_FPS = 0x00000002,
+       COMMAND_SET_COLOR_PARAMS = 0x00000004,
+       COMMAND_GET_COLOR_PARAMS = 0x00000008,
+       COMMAND_SET_FORMAT = 0x00000010,        /* size, etc */
+       COMMAND_SET_FLICKER = 0x00000020
+};
+
+/***
+ * Some defines specific to the 676 chip
+ ***/
+#define CAMACC_CIF      0x01
+#define CAMACC_VGA      0x02
+#define CAMACC_QCIF     0x04
+#define CAMACC_QVGA     0x08
+
+
+struct cpia2_register {
+       u8 index;
+       u8 value;
+};
+
+struct cpia2_reg_mask {
+       u8 index;
+       u8 and_mask;
+       u8 or_mask;
+       u8 fill;
+};
+
+struct cpia2_command {
+       u32 command;
+       u8 req_mode;            /* (Block or random) | registerBank */
+       u8 reg_count;
+       u8 direction;
+       u8 start;
+       union reg_types {
+               struct cpia2_register registers[32];
+               struct cpia2_reg_mask masks[16];
+               u8 block_data[64];
+               u8 *patch_data; /* points to function defined block */
+       } buffer;
+};
+
+struct camera_params {
+       struct {
+               u8 firmware_revision_hi; /* For system register set (bank 0) */
+               u8 firmware_revision_lo;
+               u8 asic_id;     /* Video Compressor set (bank 1) */
+               u8 asic_rev;
+               u8 vp_device_hi;        /* Video Processor set (bank 2) */
+               u8 vp_device_lo;
+               u8 sensor_flags;
+               u8 sensor_rev;
+       } version;
+
+       struct {
+               u32 device_type;     /* enumerated from vendor/product ids.
+                                     * Currently, either STV_672 or STV_676 */
+               u16 vendor;
+               u16 product;
+               u16 device_revision;
+       } pnp_id;
+
+       struct {
+               u8 brightness;  /* CPIA2_VP_EXPOSURE_TARGET */
+               u8 contrast;    /* Note: this is CPIA2_VP_YRANGE */
+               u8 saturation;  /*  CPIA2_VP_SATURATION */
+       } color_params;
+
+       struct {
+               u8 cam_register;
+               u8 flicker_mode_req;    /* 1 if flicker on, else never flicker */
+               int mains_frequency;
+       } flicker_control;
+
+       struct {
+               u8 jpeg_options;
+               u8 creep_period;
+               u8 user_squeeze;
+               u8 inhibit_htables;
+       } compression;
+
+       struct {
+               u8 ohsize;      /* output image size */
+               u8 ovsize;
+               u8 hcrop;       /* cropping start_pos/4 */
+               u8 vcrop;
+               u8 hphase;      /* scaling registers */
+               u8 vphase;
+               u8 hispan;
+               u8 vispan;
+               u8 hicrop;
+               u8 vicrop;
+               u8 hifraction;
+               u8 vifraction;
+       } image_size;
+
+       struct {
+               int width;      /* actual window width */
+               int height;     /* actual window height */
+       } roi;
+
+       struct {
+               u8 video_mode;
+               u8 frame_rate;
+               u8 video_size;  /* Not a register, just a convenience for cropped sizes */
+               u8 gpio_direction;
+               u8 gpio_data;
+               u8 system_ctrl;
+               u8 system_state;
+               u8 lowlight_boost;      /* Bool: 0 = off, 1 = on */
+               u8 device_config;
+               u8 exposure_modes;
+               u8 user_effects;
+       } vp_params;
+
+       struct {
+               u8 pw_control;
+               u8 wakeup;
+               u8 vc_control;
+               u8 vc_mp_direction;
+               u8 vc_mp_data;
+               u8 target_kb;
+       } vc_params;
+
+       struct {
+               u8 power_mode;
+               u8 system_ctrl;
+               u8 stream_mode; /* This is the current alternate for usb drivers */
+               u8 allow_corrupt;
+       } camera_state;
+};
+
+#define NUM_SBUF    2
+
+struct cpia2_sbuf {
+       char *data;
+       struct urb *urb;
+};
+
+struct framebuf {
+       struct timeval timestamp;
+       unsigned long seq;
+       int num;
+       int length;
+       int max_length;
+       volatile enum frame_status status;
+       u8 *data;
+       struct framebuf *next;
+};
+
+struct cpia2_fh {
+       enum v4l2_priority prio;
+       u8 mmapped;
+};
+
+struct camera_data {
+       /* locks */
+       struct semaphore busy_lock;     /* guard against SMP multithreading */
+       struct v4l2_prio_state prio;
+
+       /* camera status */
+       volatile int present;   /* Is the camera still present? */
+       int open_count;         /* # of process that have camera open */
+       int first_image_seen;
+       u8 mains_freq;          /* for flicker control */
+       enum sensors sensor_type;
+       u8 flush;
+       u8 mmapped;
+       int streaming;          /* 0 = no, 1 = yes */
+       int xfer_mode;          /* XFER_BULK or XFER_ISOC */
+       struct camera_params params;    /* camera settings */
+
+       /* v4l */
+       int video_size;                 /* VIDEO_SIZE_ */
+       struct video_device *vdev;      /* v4l videodev */
+       struct video_picture vp;        /* v4l camera settings */
+       struct video_window vw;         /* v4l capture area */
+       __u32 pixelformat;       /* Format fourcc      */
+
+       /* USB */
+       struct usb_device *dev;
+       unsigned char iface;
+       unsigned int cur_alt;
+       unsigned int old_alt;
+       struct cpia2_sbuf sbuf[NUM_SBUF];       /* Double buffering */
+
+       wait_queue_head_t wq_stream;
+
+       /* Buffering */
+       u32 frame_size;
+       int num_frames;
+       unsigned long frame_count;
+       u8 *frame_buffer;       /* frame buffer data */
+       struct framebuf *buffers;
+       struct framebuf * volatile curbuff;
+       struct framebuf *workbuff;
+
+       /* MJPEG Extension */
+       int APPn;               /* Number of APP segment to be written, must be 0..15 */
+       int APP_len;            /* Length of data in JPEG APPn segment */
+       char APP_data[60];      /* Data in the JPEG APPn segment. */
+
+       int COM_len;            /* Length of data in JPEG COM segment */
+       char COM_data[60];      /* Data in JPEG COM segment */
+};
+
+/* v4l */
+int cpia2_register_camera(struct camera_data *cam);
+void cpia2_unregister_camera(struct camera_data *cam);
+
+/* core */
+int cpia2_reset_camera(struct camera_data *cam);
+int cpia2_set_low_power(struct camera_data *cam);
+void cpia2_dbg_dump_registers(struct camera_data *cam);
+int cpia2_match_video_size(int width, int height);
+void cpia2_set_camera_state(struct camera_data *cam);
+void cpia2_save_camera_state(struct camera_data *cam);
+void cpia2_set_color_params(struct camera_data *cam);
+void cpia2_set_brightness(struct camera_data *cam, unsigned char value);
+void cpia2_set_contrast(struct camera_data *cam, unsigned char value);
+void cpia2_set_saturation(struct camera_data *cam, unsigned char value);
+int cpia2_set_flicker_mode(struct camera_data *cam, int mode);
+void cpia2_set_format(struct camera_data *cam);
+int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd);
+int cpia2_do_command(struct camera_data *cam,
+                    unsigned int command,
+                    unsigned char direction, unsigned char param);
+struct camera_data *cpia2_init_camera_struct(void);
+int cpia2_init_camera(struct camera_data *cam);
+int cpia2_allocate_buffers(struct camera_data *cam);
+void cpia2_free_buffers(struct camera_data *cam);
+long cpia2_read(struct camera_data *cam,
+               char *buf, unsigned long count, int noblock);
+unsigned int cpia2_poll(struct camera_data *cam,
+                       struct file *filp, poll_table *wait);
+int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma);
+void cpia2_set_property_flip(struct camera_data *cam, int prop_val);
+void cpia2_set_property_mirror(struct camera_data *cam, int prop_val);
+int cpia2_set_target_kb(struct camera_data *cam, unsigned char value);
+int cpia2_set_gpio(struct camera_data *cam, unsigned char setting);
+int cpia2_set_fps(struct camera_data *cam, int framerate);
+
+/* usb */
+int cpia2_usb_init(void);
+void cpia2_usb_cleanup(void);
+int cpia2_usb_transfer_cmd(struct camera_data *cam, void *registers,
+                          u8 request, u8 start, u8 count, u8 direction);
+int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate);
+int cpia2_usb_stream_stop(struct camera_data *cam);
+int cpia2_usb_stream_pause(struct camera_data *cam);
+int cpia2_usb_stream_resume(struct camera_data *cam);
+int cpia2_usb_change_streaming_alternate(struct camera_data *cam,
+                                        unsigned int alt);
+
+
+/* ----------------------- debug functions ---------------------- */
+#ifdef _CPIA2_DEBUG_
+#define ALOG(lev, fmt, args...) printk(lev "%s:%d %s(): " fmt, __FILE__, __LINE__, __func__, ## args)
+#define LOG(fmt, args...) ALOG(KERN_INFO, fmt, ## args)
+#define ERR(fmt, args...) ALOG(KERN_ERR, fmt, ## args)
+#define DBG(fmt, args...) ALOG(KERN_DEBUG, fmt, ## args)
+#else
+#define ALOG(fmt,args...) printk(fmt,##args)
+#define LOG(fmt,args...) ALOG(KERN_INFO "cpia2: "fmt,##args)
+#define ERR(fmt,args...) ALOG(KERN_ERR "cpia2: "fmt,##args)
+#define DBG(fmn,args...) do {} while(0)
+#endif
+/* No function or lineno, for shorter lines */
+#define KINFO(fmt, args...) printk(KERN_INFO fmt,##args)
+
+#endif
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c
new file mode 100644 (file)
index 0000000..5dfb242
--- /dev/null
@@ -0,0 +1,2525 @@
+/****************************************************************************
+ *
+ *  Filename: cpia2_core.c
+ *
+ *  Copyright 2001, STMicrolectronics, Inc.
+ *      Contact:  steve.miller@st.com
+ *
+ *  Description:
+ *     This is a USB driver for CPia2 based video cameras.
+ *     The infrastructure of this driver is based on the cpia usb driver by
+ *     Jochen Scharrlach and Johannes Erdfeldt.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Stripped of 2.4 stuff ready for main kernel submit by
+ *             Alan Cox <alan@redhat.com>
+ *
+ ****************************************************************************/
+
+#include "cpia2.h"
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+//#define _CPIA2_DEBUG_
+
+#include "cpia2patch.h"
+
+#ifdef _CPIA2_DEBUG_
+
+static const char *block_name[] = {
+       "System",
+       "VC",
+       "VP",
+       "IDATA"
+};
+#endif
+
+static unsigned int debugs_on = 0;//DEBUG_REG;
+
+
+/******************************************************************************
+ *
+ *  Forward Declarations
+ *
+ *****************************************************************************/
+static int apply_vp_patch(struct camera_data *cam);
+static int set_default_user_mode(struct camera_data *cam);
+static int set_vw_size(struct camera_data *cam, int size);
+static int configure_sensor(struct camera_data *cam,
+                           int reqwidth, int reqheight);
+static int config_sensor_410(struct camera_data *cam,
+                           int reqwidth, int reqheight);
+static int config_sensor_500(struct camera_data *cam,
+                           int reqwidth, int reqheight);
+static int set_all_properties(struct camera_data *cam);
+static void get_color_params(struct camera_data *cam);
+static void wake_system(struct camera_data *cam);
+static void set_lowlight_boost(struct camera_data *cam);
+static void reset_camera_struct(struct camera_data *cam);
+static int cpia2_set_high_power(struct camera_data *cam);
+
+/* Here we want the physical address of the memory.
+ * This is used when initializing the contents of the
+ * area and marking the pages as reserved.
+ */
+static inline unsigned long kvirt_to_pa(unsigned long adr)
+{
+       unsigned long kva, ret;
+
+       kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
+       kva |= adr & (PAGE_SIZE-1); /* restore the offset */
+       ret = __pa(kva);
+       return ret;
+}
+
+static void *rvmalloc(unsigned long size)
+{
+       void *mem;
+       unsigned long adr;
+
+       /* Round it off to PAGE_SIZE */
+       size = PAGE_ALIGN(size);
+
+       mem = vmalloc_32(size);
+       if (!mem)
+               return NULL;
+
+       memset(mem, 0, size);   /* Clear the ram out, no junk to the user */
+       adr = (unsigned long) mem;
+
+       while ((long)size > 0) {
+               SetPageReserved(vmalloc_to_page((void *)adr));
+               adr += PAGE_SIZE;
+               size -= PAGE_SIZE;
+       }
+       return mem;
+}
+
+static void rvfree(void *mem, unsigned long size)
+{
+       unsigned long adr;
+
+       if (!mem)
+               return;
+
+       size = PAGE_ALIGN(size);
+
+       adr = (unsigned long) mem;
+       while ((long)size > 0) {
+               ClearPageReserved(vmalloc_to_page((void *)adr));
+               adr += PAGE_SIZE;
+               size -= PAGE_SIZE;
+       }
+       vfree(mem);
+}
+
+/******************************************************************************
+ *
+ *  cpia2_do_command
+ *
+ *  Send an arbitrary command to the camera.  For commands that read from
+ *  the camera, copy the buffers into the proper param structures.
+ *****************************************************************************/
+int cpia2_do_command(struct camera_data *cam,
+                    u32 command, u8 direction, u8 param)
+{
+       int retval = 0;
+       struct cpia2_command cmd;
+       unsigned int device = cam->params.pnp_id.device_type;
+
+       cmd.command = command;
+       cmd.reg_count = 2;      /* default */
+       cmd.direction = direction;
+
+       /***
+        * Set up the command.
+        ***/
+       switch (command) {
+       case CPIA2_CMD_GET_VERSION:
+               cmd.req_mode =
+                   CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
+               cmd.start = CPIA2_SYSTEM_DEVICE_HI;
+               break;
+       case CPIA2_CMD_GET_PNP_ID:
+               cmd.req_mode =
+                   CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
+               cmd.reg_count = 8;
+               cmd.start = CPIA2_SYSTEM_DESCRIP_VID_HI;
+               break;
+       case CPIA2_CMD_GET_ASIC_TYPE:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
+               cmd.start = CPIA2_VC_ASIC_ID;
+               break;
+       case CPIA2_CMD_GET_SENSOR:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.start = CPIA2_VP_SENSOR_FLAGS;
+               break;
+       case CPIA2_CMD_GET_VP_DEVICE:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.start = CPIA2_VP_DEVICEH;
+               break;
+       case CPIA2_CMD_SET_VP_BRIGHTNESS:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_VP_BRIGHTNESS:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               if (device == DEVICE_STV_672)
+                       cmd.start = CPIA2_VP4_EXPOSURE_TARGET;
+               else
+                       cmd.start = CPIA2_VP5_EXPOSURE_TARGET;
+               break;
+       case CPIA2_CMD_SET_CONTRAST:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_CONTRAST:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VP_YRANGE;
+               break;
+       case CPIA2_CMD_SET_VP_SATURATION:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_VP_SATURATION:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               if (device == DEVICE_STV_672)
+                       cmd.start = CPIA2_VP_SATURATION;
+               else
+                       cmd.start = CPIA2_VP5_MCUVSATURATION;
+               break;
+       case CPIA2_CMD_SET_VP_GPIO_DATA:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_VP_GPIO_DATA:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VP_GPIO_DATA;
+               break;
+       case CPIA2_CMD_SET_VP_GPIO_DIRECTION:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_VP_GPIO_DIRECTION:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VP_GPIO_DIRECTION;
+               break;
+       case CPIA2_CMD_SET_VC_MP_GPIO_DATA:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_VC_MP_GPIO_DATA:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VC_MP_DATA;
+               break;
+       case CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VC_MP_DIR;
+               break;
+       case CPIA2_CMD_ENABLE_PACKET_CTRL:
+               cmd.req_mode =
+                   CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
+               cmd.start = CPIA2_SYSTEM_INT_PACKET_CTRL;
+               cmd.reg_count = 1;
+               cmd.buffer.block_data[0] = param;
+               break;
+       case CPIA2_CMD_SET_FLICKER_MODES:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_FLICKER_MODES:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VP_FLICKER_MODES;
+               break;
+       case CPIA2_CMD_RESET_FIFO:      /* clear fifo and enable stream block */
+               cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
+               cmd.reg_count = 2;
+               cmd.start = 0;
+               cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL;
+               cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC |
+                   CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT;
+               cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL;
+               cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC |
+                   CPIA2_VC_ST_CTRL_DST_USB |
+                   CPIA2_VC_ST_CTRL_EOF_DETECT |
+                   CPIA2_VC_ST_CTRL_FIFO_ENABLE;
+               break;
+       case CPIA2_CMD_SET_HI_POWER:
+               cmd.req_mode =
+                   CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM;
+               cmd.reg_count = 2;
+               cmd.buffer.registers[0].index =
+                   CPIA2_SYSTEM_SYSTEM_CONTROL;
+               cmd.buffer.registers[1].index =
+                   CPIA2_SYSTEM_SYSTEM_CONTROL;
+               cmd.buffer.registers[0].value = CPIA2_SYSTEM_CONTROL_CLEAR_ERR;
+               cmd.buffer.registers[1].value =
+                   CPIA2_SYSTEM_CONTROL_HIGH_POWER;
+               break;
+       case CPIA2_CMD_SET_LOW_POWER:
+               cmd.req_mode =
+                   CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL;
+               cmd.buffer.block_data[0] = 0;
+               break;
+       case CPIA2_CMD_CLEAR_V2W_ERR:
+               cmd.req_mode =
+                   CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL;
+               cmd.buffer.block_data[0] = CPIA2_SYSTEM_CONTROL_CLEAR_ERR;
+               break;
+       case CPIA2_CMD_SET_USER_MODE:   /* Then fall through */
+               cmd.buffer.block_data[0] = param;
+       case CPIA2_CMD_GET_USER_MODE:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               if (device == DEVICE_STV_672)
+                       cmd.start = CPIA2_VP4_USER_MODE;
+               else
+                       cmd.start = CPIA2_VP5_USER_MODE;
+               break;
+       case CPIA2_CMD_FRAMERATE_REQ:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               if (device == DEVICE_STV_672)
+                       cmd.start = CPIA2_VP4_FRAMERATE_REQUEST;
+               else
+                       cmd.start = CPIA2_VP5_FRAMERATE_REQUEST;
+               cmd.buffer.block_data[0] = param;
+               break;
+       case CPIA2_CMD_SET_WAKEUP:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_WAKEUP:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VC_WAKEUP;
+               break;
+       case CPIA2_CMD_SET_PW_CONTROL:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_PW_CONTROL:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VC_PW_CTRL;
+               break;
+       case CPIA2_CMD_GET_VP_SYSTEM_STATE:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VP_SYSTEMSTATE;
+               break;
+       case CPIA2_CMD_SET_SYSTEM_CTRL:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_SYSTEM_CTRL:
+               cmd.req_mode =
+                   CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_SYSTEM_SYSTEM_CONTROL;
+               break;
+       case CPIA2_CMD_SET_VP_SYSTEM_CTRL:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_VP_SYSTEM_CTRL:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VP_SYSTEMCTRL;
+               break;
+       case CPIA2_CMD_SET_VP_EXP_MODES:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_VP_EXP_MODES:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VP_EXPOSURE_MODES;
+               break;
+       case CPIA2_CMD_SET_DEVICE_CONFIG:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_DEVICE_CONFIG:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VP_DEVICE_CONFIG;
+               break;
+       case CPIA2_CMD_SET_SERIAL_ADDR:
+               cmd.buffer.block_data[0] = param;
+               cmd.req_mode =
+                   CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_SYSTEM_VP_SERIAL_ADDR;
+               break;
+       case CPIA2_CMD_SET_SENSOR_CR1:
+               cmd.buffer.block_data[0] = param;
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_SENSOR_CR1;
+               break;
+       case CPIA2_CMD_SET_VC_CONTROL:
+               cmd.buffer.block_data[0] = param;       /* Then fall through */
+       case CPIA2_CMD_GET_VC_CONTROL:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VC_VC_CTRL;
+               break;
+       case CPIA2_CMD_SET_TARGET_KB:
+               cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
+               cmd.reg_count = 1;
+               cmd.buffer.registers[0].index = CPIA2_VC_VC_TARGET_KB;
+               cmd.buffer.registers[0].value = param;
+               break;
+       case CPIA2_CMD_SET_DEF_JPEG_OPT:
+               cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
+               cmd.reg_count = 4;
+               cmd.buffer.registers[0].index = CPIA2_VC_VC_JPEG_OPT;
+               cmd.buffer.registers[0].value =
+                   CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE;
+               cmd.buffer.registers[1].index = CPIA2_VC_VC_USER_SQUEEZE;
+               cmd.buffer.registers[1].value = 20;
+               cmd.buffer.registers[2].index = CPIA2_VC_VC_CREEP_PERIOD;
+               cmd.buffer.registers[2].value = 2;
+               cmd.buffer.registers[3].index = CPIA2_VC_VC_JPEG_OPT;
+               cmd.buffer.registers[3].value = CPIA2_VC_VC_JPEG_OPT_DEFAULT;
+               break;
+       case CPIA2_CMD_REHASH_VP4:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VP_REHASH_VALUES;
+               cmd.buffer.block_data[0] = param;
+               break;
+       case CPIA2_CMD_SET_USER_EFFECTS:  /* Note: Be careful with this as
+                                            this register can also affect
+                                            flicker modes */
+               cmd.buffer.block_data[0] = param;      /* Then fall through */
+       case CPIA2_CMD_GET_USER_EFFECTS:
+               cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+               cmd.reg_count = 1;
+               if (device == DEVICE_STV_672)
+                       cmd.start = CPIA2_VP4_USER_EFFECTS;
+               else
+                       cmd.start = CPIA2_VP5_USER_EFFECTS;
+               break;
+       default:
+               LOG("DoCommand received invalid command\n");
+               return -EINVAL;
+       }
+
+       retval = cpia2_send_command(cam, &cmd);
+       if (retval) {
+               return retval;
+       }
+
+       /***
+        * Now copy any results from a read into the appropriate param struct.
+        ***/
+       switch (command) {
+       case CPIA2_CMD_GET_VERSION:
+               cam->params.version.firmware_revision_hi =
+                   cmd.buffer.block_data[0];
+               cam->params.version.firmware_revision_lo =
+                   cmd.buffer.block_data[1];
+               break;
+       case CPIA2_CMD_GET_PNP_ID:
+               cam->params.pnp_id.vendor = (cmd.buffer.block_data[0] << 8) |
+                                           cmd.buffer.block_data[1];
+               cam->params.pnp_id.product = (cmd.buffer.block_data[2] << 8) |
+                                            cmd.buffer.block_data[3];
+               cam->params.pnp_id.device_revision =
+                       (cmd.buffer.block_data[4] << 8) |
+                       cmd.buffer.block_data[5];
+               if (cam->params.pnp_id.vendor == 0x553) {
+                       if (cam->params.pnp_id.product == 0x100) {
+                               cam->params.pnp_id.device_type = DEVICE_STV_672;
+                       } else if (cam->params.pnp_id.product == 0x140 ||
+                                  cam->params.pnp_id.product == 0x151) {
+                               cam->params.pnp_id.device_type = DEVICE_STV_676;
+                       }
+               }
+               break;
+       case CPIA2_CMD_GET_ASIC_TYPE:
+               cam->params.version.asic_id = cmd.buffer.block_data[0];
+               cam->params.version.asic_rev = cmd.buffer.block_data[1];
+               break;
+       case CPIA2_CMD_GET_SENSOR:
+               cam->params.version.sensor_flags = cmd.buffer.block_data[0];
+               cam->params.version.sensor_rev = cmd.buffer.block_data[1];
+               break;
+       case CPIA2_CMD_GET_VP_DEVICE:
+               cam->params.version.vp_device_hi = cmd.buffer.block_data[0];
+               cam->params.version.vp_device_lo = cmd.buffer.block_data[1];
+               break;
+       case CPIA2_CMD_GET_VP_BRIGHTNESS:
+               cam->params.color_params.brightness = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_CONTRAST:
+               cam->params.color_params.contrast = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_VP_SATURATION:
+               cam->params.color_params.saturation = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_VP_GPIO_DATA:
+               cam->params.vp_params.gpio_data = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_VP_GPIO_DIRECTION:
+               cam->params.vp_params.gpio_direction = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION:
+               cam->params.vc_params.vc_mp_direction =cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_VC_MP_GPIO_DATA:
+               cam->params.vc_params.vc_mp_data = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_FLICKER_MODES:
+               cam->params.flicker_control.cam_register =
+                       cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_WAKEUP:
+               cam->params.vc_params.wakeup = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_PW_CONTROL:
+               cam->params.vc_params.pw_control = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_SYSTEM_CTRL:
+               cam->params.camera_state.system_ctrl = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_VP_SYSTEM_STATE:
+               cam->params.vp_params.system_state = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_VP_SYSTEM_CTRL:
+               cam->params.vp_params.system_ctrl = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_VP_EXP_MODES:
+               cam->params.vp_params.exposure_modes = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_DEVICE_CONFIG:
+               cam->params.vp_params.device_config = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_VC_CONTROL:
+               cam->params.vc_params.vc_control = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_USER_MODE:
+               cam->params.vp_params.video_mode = cmd.buffer.block_data[0];
+               break;
+       case CPIA2_CMD_GET_USER_EFFECTS:
+               cam->params.vp_params.user_effects = cmd.buffer.block_data[0];
+               break;
+       default:
+               break;
+       }
+       return retval;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_send_command
+ *
+ *****************************************************************************/
+int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd)
+{
+       u8 count;
+       u8 start;
+       u8 block_index;
+       u8 *buffer;
+       int retval;
+       const char* dir;
+
+       if (cmd->direction == TRANSFER_WRITE) {
+               dir = "Write";
+       } else {
+               dir = "Read";
+       }
+
+       block_index = cmd->req_mode & 0x03;
+
+       switch (cmd->req_mode & 0x0c) {
+       case CAMERAACCESS_TYPE_RANDOM:
+               count = cmd->reg_count * sizeof(struct cpia2_register);
+               start = 0;
+               buffer = (u8 *) & cmd->buffer;
+               if (debugs_on & DEBUG_REG)
+                       DBG("%s Random: Register block %s\n", dir,
+                           block_name[block_index]);
+               break;
+       case CAMERAACCESS_TYPE_BLOCK:
+               count = cmd->reg_count;
+               start = cmd->start;
+               buffer = cmd->buffer.block_data;
+               if (debugs_on & DEBUG_REG)
+                       DBG("%s Block: Register block %s\n", dir,
+                           block_name[block_index]);
+               break;
+       case CAMERAACCESS_TYPE_MASK:
+               count = cmd->reg_count * sizeof(struct cpia2_reg_mask);
+               start = 0;
+               buffer = (u8 *) & cmd->buffer;
+               if (debugs_on & DEBUG_REG)
+                       DBG("%s Mask: Register block %s\n", dir,
+                           block_name[block_index]);
+               break;
+       case CAMERAACCESS_TYPE_REPEAT:  /* For patch blocks only */
+               count = cmd->reg_count;
+               start = cmd->start;
+               buffer = cmd->buffer.block_data;
+               if (debugs_on & DEBUG_REG)
+                       DBG("%s Repeat: Register block %s\n", dir,
+                           block_name[block_index]);
+               break;
+       default:
+               LOG("%s: invalid request mode\n",__FUNCTION__);
+               return -EINVAL;
+       }
+
+       retval = cpia2_usb_transfer_cmd(cam,
+                                       buffer,
+                                       cmd->req_mode,
+                                       start, count, cmd->direction);
+#ifdef _CPIA2_DEBUG_
+       if (debugs_on & DEBUG_REG) {
+               int i;
+               for (i = 0; i < cmd->reg_count; i++) {
+                       if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_BLOCK)
+                               KINFO("%s Block: [0x%02X] = 0x%02X\n",
+                                   dir, start + i, buffer[i]);
+                       if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_RANDOM)
+                               KINFO("%s Random: [0x%02X] = 0x%02X\n",
+                                   dir, cmd->buffer.registers[i].index,
+                                   cmd->buffer.registers[i].value);
+               }
+       }
+#endif
+
+       return retval;
+};
+
+/*************
+ * Functions to implement camera functionality
+ *************/
+/******************************************************************************
+ *
+ *  cpia2_get_version_info
+ *
+ *****************************************************************************/
+static void cpia2_get_version_info(struct camera_data *cam)
+{
+       cpia2_do_command(cam, CPIA2_CMD_GET_VERSION, TRANSFER_READ, 0);
+       cpia2_do_command(cam, CPIA2_CMD_GET_PNP_ID, TRANSFER_READ, 0);
+       cpia2_do_command(cam, CPIA2_CMD_GET_ASIC_TYPE, TRANSFER_READ, 0);
+       cpia2_do_command(cam, CPIA2_CMD_GET_SENSOR, TRANSFER_READ, 0);
+       cpia2_do_command(cam, CPIA2_CMD_GET_VP_DEVICE, TRANSFER_READ, 0);
+}
+
+/******************************************************************************
+ *
+ *  cpia2_reset_camera
+ *
+ *  Called at least during the open process, sets up initial params.
+ *****************************************************************************/
+int cpia2_reset_camera(struct camera_data *cam)
+{
+       u8 tmp_reg;
+       int retval = 0;
+       int i;
+       struct cpia2_command cmd;
+
+       /***
+        * VC setup
+        ***/
+       retval = configure_sensor(cam,
+                                 cam->params.roi.width,
+                                 cam->params.roi.height);
+       if (retval < 0) {
+               ERR("Couldn't configure sensor, error=%d\n", retval);
+               return retval;
+       }
+
+       /* Clear FIFO and route/enable stream block */
+       cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
+       cmd.direction = TRANSFER_WRITE;
+       cmd.reg_count = 2;
+       cmd.buffer.registers[0].index = CPIA2_VC_ST_CTRL;
+       cmd.buffer.registers[0].value = CPIA2_VC_ST_CTRL_SRC_VC |
+               CPIA2_VC_ST_CTRL_DST_USB | CPIA2_VC_ST_CTRL_EOF_DETECT;
+       cmd.buffer.registers[1].index = CPIA2_VC_ST_CTRL;
+       cmd.buffer.registers[1].value = CPIA2_VC_ST_CTRL_SRC_VC |
+               CPIA2_VC_ST_CTRL_DST_USB |
+               CPIA2_VC_ST_CTRL_EOF_DETECT | CPIA2_VC_ST_CTRL_FIFO_ENABLE;
+
+       cpia2_send_command(cam, &cmd);
+
+       cpia2_set_high_power(cam);
+
+       if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
+               /* Enable button notification */
+               cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_SYSTEM;
+               cmd.buffer.registers[0].index = CPIA2_SYSTEM_INT_PACKET_CTRL;
+               cmd.buffer.registers[0].value =
+                       CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX;
+               cmd.reg_count = 1;
+               cpia2_send_command(cam, &cmd);
+       }
+
+       current->state = TASK_INTERRUPTIBLE;
+       schedule_timeout(100 * HZ / 1000);      /* wait for 100 msecs */
+
+       if (cam->params.pnp_id.device_type == DEVICE_STV_672)
+               retval = apply_vp_patch(cam);
+
+       /* wait for vp to go to sleep */
+       current->state = TASK_INTERRUPTIBLE;
+       schedule_timeout(100 * HZ / 1000);      /* wait for 100 msecs */
+
+       /***
+        * If this is a 676, apply VP5 fixes before we start streaming
+        ***/
+       if (cam->params.pnp_id.device_type == DEVICE_STV_676) {
+               cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
+
+               /* The following writes improve the picture */
+               cmd.buffer.registers[0].index = CPIA2_VP5_MYBLACK_LEVEL;
+               cmd.buffer.registers[0].value = 0; /* reduce from the default
+                                                   * rec 601 pedestal of 16 */
+               cmd.buffer.registers[1].index = CPIA2_VP5_MCYRANGE;
+               cmd.buffer.registers[1].value = 0x92; /* increase from 100% to
+                                                      * (256/256 - 31) to fill
+                                                      * available range */
+               cmd.buffer.registers[2].index = CPIA2_VP5_MYCEILING;
+               cmd.buffer.registers[2].value = 0xFF; /* Increase from the
+                                                      * default rec 601 ceiling
+                                                      * of 240 */
+               cmd.buffer.registers[3].index = CPIA2_VP5_MCUVSATURATION;
+               cmd.buffer.registers[3].value = 0xFF; /* Increase from the rec
+                                                      * 601 100% level (128)
+                                                      * to 145-192 */
+               cmd.buffer.registers[4].index = CPIA2_VP5_ANTIFLKRSETUP;
+               cmd.buffer.registers[4].value = 0x80;  /* Inhibit the
+                                                       * anti-flicker */
+
+               /* The following 4 writes are a fix to allow QVGA to work at 30 fps */
+               cmd.buffer.registers[5].index = CPIA2_VP_RAM_ADDR_H;
+               cmd.buffer.registers[5].value = 0x01;
+               cmd.buffer.registers[6].index = CPIA2_VP_RAM_ADDR_L;
+               cmd.buffer.registers[6].value = 0xE3;
+               cmd.buffer.registers[7].index = CPIA2_VP_RAM_DATA;
+               cmd.buffer.registers[7].value = 0x02;
+               cmd.buffer.registers[8].index = CPIA2_VP_RAM_DATA;
+               cmd.buffer.registers[8].value = 0xFC;
+
+               cmd.direction = TRANSFER_WRITE;
+               cmd.reg_count = 9;
+
+               cpia2_send_command(cam, &cmd);
+       }
+
+       /* Activate all settings and start the data stream */
+       /* Set user mode */
+       set_default_user_mode(cam);
+
+       /* Give VP time to wake up */
+       current->state = TASK_INTERRUPTIBLE;
+       schedule_timeout(100 * HZ / 1000);      /* wait for 100 msecs */
+
+       set_all_properties(cam);
+
+       cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0);
+       DBG("After SetAllProperties(cam), user mode is 0x%0X\n",
+           cam->params.vp_params.video_mode);
+
+       /***
+        * Set audio regulator off.  This and the code to set the compresison
+        * state are too complex to form a CPIA2_CMD_, and seem to be somewhat
+        * intertwined.  This stuff came straight from the windows driver.
+        ***/
+       /* Turn AutoExposure off in VP and enable the serial bridge to the sensor */
+       cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0);
+       tmp_reg = cam->params.vp_params.system_ctrl;
+       cmd.buffer.registers[0].value = tmp_reg &
+               (tmp_reg & (CPIA2_VP_SYSTEMCTRL_HK_CONTROL ^ 0xFF));
+
+       cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0);
+       cmd.buffer.registers[1].value = cam->params.vp_params.device_config |
+                                       CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE;
+       cmd.buffer.registers[0].index = CPIA2_VP_SYSTEMCTRL;
+       cmd.buffer.registers[1].index = CPIA2_VP_DEVICE_CONFIG;
+       cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
+       cmd.reg_count = 2;
+       cmd.direction = TRANSFER_WRITE;
+       cmd.start = 0;
+       cpia2_send_command(cam, &cmd);
+
+       /* Set the correct I2C address in the CPiA-2 system register */
+       cpia2_do_command(cam,
+                        CPIA2_CMD_SET_SERIAL_ADDR,
+                        TRANSFER_WRITE,
+                        CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR);
+
+       /* Now have sensor access - set bit to turn the audio regulator off */
+       cpia2_do_command(cam,
+                        CPIA2_CMD_SET_SENSOR_CR1,
+                        TRANSFER_WRITE, CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR);
+
+       /* Set the correct I2C address in the CPiA-2 system register */
+       if (cam->params.pnp_id.device_type == DEVICE_STV_672)
+               cpia2_do_command(cam,
+                                CPIA2_CMD_SET_SERIAL_ADDR,
+                                TRANSFER_WRITE,
+                                CPIA2_SYSTEM_VP_SERIAL_ADDR_VP); // 0x88
+       else
+               cpia2_do_command(cam,
+                                CPIA2_CMD_SET_SERIAL_ADDR,
+                                TRANSFER_WRITE,
+                                CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP); // 0x8a
+
+       /* increase signal drive strength */
+       if (cam->params.pnp_id.device_type == DEVICE_STV_676)
+               cpia2_do_command(cam,
+                                CPIA2_CMD_SET_VP_EXP_MODES,
+                                TRANSFER_WRITE,
+                                CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP);
+
+       /* Start autoexposure */
+       cpia2_do_command(cam, CPIA2_CMD_GET_DEVICE_CONFIG, TRANSFER_READ, 0);
+       cmd.buffer.registers[0].value = cam->params.vp_params.device_config &
+                                 (CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE ^ 0xFF);
+
+       cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_CTRL, TRANSFER_READ, 0);
+       cmd.buffer.registers[1].value =
+           cam->params.vp_params.system_ctrl | CPIA2_VP_SYSTEMCTRL_HK_CONTROL;
+
+       cmd.buffer.registers[0].index = CPIA2_VP_DEVICE_CONFIG;
+       cmd.buffer.registers[1].index = CPIA2_VP_SYSTEMCTRL;
+       cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VP;
+       cmd.reg_count = 2;
+       cmd.direction = TRANSFER_WRITE;
+
+       cpia2_send_command(cam, &cmd);
+
+       /* Set compression state */
+       cpia2_do_command(cam, CPIA2_CMD_GET_VC_CONTROL, TRANSFER_READ, 0);
+       if (cam->params.compression.inhibit_htables) {
+               tmp_reg = cam->params.vc_params.vc_control |
+                         CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES;
+       } else  {
+               tmp_reg = cam->params.vc_params.vc_control &
+                         ~CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES;
+       }
+       cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg);
+
+       /* Set target size (kb) on vc */
+       cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB,
+                        TRANSFER_WRITE, cam->params.vc_params.target_kb);
+
+       /* Wiggle VC Reset */
+       /***
+        * First read and wait a bit.
+        ***/
+       for (i = 0; i < 50; i++) {
+               cpia2_do_command(cam, CPIA2_CMD_GET_PW_CONTROL,
+                                TRANSFER_READ, 0);
+       }
+
+       tmp_reg = cam->params.vc_params.pw_control;
+       tmp_reg &= ~CPIA2_VC_PW_CTRL_VC_RESET_N;
+
+       cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg);
+
+       tmp_reg |= CPIA2_VC_PW_CTRL_VC_RESET_N;
+       cpia2_do_command(cam, CPIA2_CMD_SET_PW_CONTROL, TRANSFER_WRITE,tmp_reg);
+
+       cpia2_do_command(cam, CPIA2_CMD_SET_DEF_JPEG_OPT, TRANSFER_WRITE, 0);
+
+       cpia2_do_command(cam, CPIA2_CMD_GET_USER_MODE, TRANSFER_READ, 0);
+       DBG("After VC RESET, user mode is 0x%0X\n",
+           cam->params.vp_params.video_mode);
+
+       return retval;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_high_power
+ *
+ *****************************************************************************/
+static int cpia2_set_high_power(struct camera_data *cam)
+{
+       int i;
+       for (i = 0; i <= 50; i++) {
+               /* Read system status */
+               cpia2_do_command(cam,CPIA2_CMD_GET_SYSTEM_CTRL,TRANSFER_READ,0);
+
+               /* If there is an error, clear it */
+               if(cam->params.camera_state.system_ctrl &
+                  CPIA2_SYSTEM_CONTROL_V2W_ERR)
+                       cpia2_do_command(cam, CPIA2_CMD_CLEAR_V2W_ERR,
+                                        TRANSFER_WRITE, 0);
+
+               /* Try to set high power mode */
+               cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL,
+                                TRANSFER_WRITE, 1);
+
+               /* Try to read something in VP to check if everything is awake */
+               cpia2_do_command(cam, CPIA2_CMD_GET_VP_SYSTEM_STATE,
+                                TRANSFER_READ, 0);
+               if (cam->params.vp_params.system_state &
+                   CPIA2_VP_SYSTEMSTATE_HK_ALIVE) {
+                       break;
+               } else if (i == 50) {
+                       cam->params.camera_state.power_mode = LO_POWER_MODE;
+                       ERR("Camera did not wake up\n");
+                       return -EIO;
+               }
+       }
+
+       DBG("System now in high power state\n");
+       cam->params.camera_state.power_mode = HI_POWER_MODE;
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_low_power
+ *
+ *****************************************************************************/
+int cpia2_set_low_power(struct camera_data *cam)
+{
+       cam->params.camera_state.power_mode = LO_POWER_MODE;
+       cpia2_do_command(cam, CPIA2_CMD_SET_SYSTEM_CTRL, TRANSFER_WRITE, 0);
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  apply_vp_patch
+ *
+ *****************************************************************************/
+static int apply_vp_patch(struct camera_data *cam)
+{
+       int i, j;
+       struct cpia2_command cmd;
+
+       cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP;
+       cmd.direction = TRANSFER_WRITE;
+
+       for (i = 0; i < PATCH_DATA_SIZE; i++) {
+               for (j = 0; j < patch_data[i].count; j++) {
+                       cmd.buffer.block_data[j] = patch_data[i].data[j];
+               }
+
+               cmd.start = patch_data[i].reg;
+               cmd.reg_count = patch_data[i].count;
+               cpia2_send_command(cam, &cmd);
+       }
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  set_default_user_mode
+ *
+ *****************************************************************************/
+static int set_default_user_mode(struct camera_data *cam)
+{
+       unsigned char user_mode;
+       unsigned char frame_rate;
+       int width = cam->params.roi.width;
+       int height = cam->params.roi.height;
+
+       switch (cam->params.version.sensor_flags) {
+       case CPIA2_VP_SENSOR_FLAGS_404:
+       case CPIA2_VP_SENSOR_FLAGS_407:
+       case CPIA2_VP_SENSOR_FLAGS_409:
+       case CPIA2_VP_SENSOR_FLAGS_410:
+               if ((width > STV_IMAGE_QCIF_COLS)
+                   || (height > STV_IMAGE_QCIF_ROWS)) {
+                       user_mode = CPIA2_VP_USER_MODE_CIF;
+               } else {
+                       user_mode = CPIA2_VP_USER_MODE_QCIFDS;
+               }
+               frame_rate = CPIA2_VP_FRAMERATE_30;
+               break;
+       case CPIA2_VP_SENSOR_FLAGS_500:
+               if ((width > STV_IMAGE_CIF_COLS)
+                   || (height > STV_IMAGE_CIF_ROWS)) {
+                       user_mode = CPIA2_VP_USER_MODE_VGA;
+               } else {
+                       user_mode = CPIA2_VP_USER_MODE_QVGADS;
+               }
+               if (cam->params.pnp_id.device_type == DEVICE_STV_672)
+                       frame_rate = CPIA2_VP_FRAMERATE_15;
+               else
+                       frame_rate = CPIA2_VP_FRAMERATE_30;
+               break;
+       default:
+               LOG("%s: Invalid sensor flag value 0x%0X\n",__FUNCTION__,
+                   cam->params.version.sensor_flags);
+               return -EINVAL;
+       }
+
+       DBG("Sensor flag = 0x%0x, user mode = 0x%0x, frame rate = 0x%X\n",
+           cam->params.version.sensor_flags, user_mode, frame_rate);
+       cpia2_do_command(cam, CPIA2_CMD_SET_USER_MODE, TRANSFER_WRITE,
+                        user_mode);
+       if(cam->params.vp_params.frame_rate > 0 &&
+          frame_rate > cam->params.vp_params.frame_rate)
+               frame_rate = cam->params.vp_params.frame_rate;
+
+       cpia2_set_fps(cam, frame_rate);
+
+//     if (cam->params.pnp_id.device_type == DEVICE_STV_676)
+//             cpia2_do_command(cam,
+//                              CPIA2_CMD_SET_VP_SYSTEM_CTRL,
+//                              TRANSFER_WRITE,
+//                              CPIA2_VP_SYSTEMCTRL_HK_CONTROL |
+//                              CPIA2_VP_SYSTEMCTRL_POWER_CONTROL);
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_match_video_size
+ *
+ *  return the best match, where 'best' is as always
+ *  the largest that is not bigger than what is requested.
+ *****************************************************************************/
+int cpia2_match_video_size(int width, int height)
+{
+       if (width >= STV_IMAGE_VGA_COLS && height >= STV_IMAGE_VGA_ROWS)
+               return VIDEOSIZE_VGA;
+
+       if (width >= STV_IMAGE_CIF_COLS && height >= STV_IMAGE_CIF_ROWS)
+               return VIDEOSIZE_CIF;
+
+       if (width >= STV_IMAGE_QVGA_COLS && height >= STV_IMAGE_QVGA_ROWS)
+               return VIDEOSIZE_QVGA;
+
+       if (width >= 288 && height >= 216)
+               return VIDEOSIZE_288_216;
+
+       if (width >= 256 && height >= 192)
+               return VIDEOSIZE_256_192;
+
+       if (width >= 224 && height >= 168)
+               return VIDEOSIZE_224_168;
+
+       if (width >= 192 && height >= 144)
+               return VIDEOSIZE_192_144;
+
+       if (width >= STV_IMAGE_QCIF_COLS && height >= STV_IMAGE_QCIF_ROWS)
+               return VIDEOSIZE_QCIF;
+
+       return -1;
+}
+
+/******************************************************************************
+ *
+ *  SetVideoSize
+ *
+ *****************************************************************************/
+static int set_vw_size(struct camera_data *cam, int size)
+{
+       int retval = 0;
+
+       cam->params.vp_params.video_size = size;
+
+       switch (size) {
+       case VIDEOSIZE_VGA:
+               DBG("Setting size to VGA\n");
+               cam->params.roi.width = STV_IMAGE_VGA_COLS;
+               cam->params.roi.height = STV_IMAGE_VGA_ROWS;
+               cam->vw.width = STV_IMAGE_VGA_COLS;
+               cam->vw.height = STV_IMAGE_VGA_ROWS;
+               break;
+       case VIDEOSIZE_CIF:
+               DBG("Setting size to CIF\n");
+               cam->params.roi.width = STV_IMAGE_CIF_COLS;
+               cam->params.roi.height = STV_IMAGE_CIF_ROWS;
+               cam->vw.width = STV_IMAGE_CIF_COLS;
+               cam->vw.height = STV_IMAGE_CIF_ROWS;
+               break;
+       case VIDEOSIZE_QVGA:
+               DBG("Setting size to QVGA\n");
+               cam->params.roi.width = STV_IMAGE_QVGA_COLS;
+               cam->params.roi.height = STV_IMAGE_QVGA_ROWS;
+               cam->vw.width = STV_IMAGE_QVGA_COLS;
+               cam->vw.height = STV_IMAGE_QVGA_ROWS;
+               break;
+       case VIDEOSIZE_288_216:
+               cam->params.roi.width = 288;
+               cam->params.roi.height = 216;
+               cam->vw.width = 288;
+               cam->vw.height = 216;
+               break;
+       case VIDEOSIZE_256_192:
+               cam->vw.width = 256;
+               cam->vw.height = 192;
+               cam->params.roi.width = 256;
+               cam->params.roi.height = 192;
+               break;
+       case VIDEOSIZE_224_168:
+               cam->vw.width = 224;
+               cam->vw.height = 168;
+               cam->params.roi.width = 224;
+               cam->params.roi.height = 168;
+               break;
+       case VIDEOSIZE_192_144:
+               cam->vw.width = 192;
+               cam->vw.height = 144;
+               cam->params.roi.width = 192;
+               cam->params.roi.height = 144;
+               break;
+       case VIDEOSIZE_QCIF:
+               DBG("Setting size to QCIF\n");
+               cam->params.roi.width = STV_IMAGE_QCIF_COLS;
+               cam->params.roi.height = STV_IMAGE_QCIF_ROWS;
+               cam->vw.width = STV_IMAGE_QCIF_COLS;
+               cam->vw.height = STV_IMAGE_QCIF_ROWS;
+               break;
+       default:
+               retval = -EINVAL;
+       }
+       return retval;
+}
+
+/******************************************************************************
+ *
+ *  configure_sensor
+ *
+ *****************************************************************************/
+static int configure_sensor(struct camera_data *cam,
+                           int req_width, int req_height)
+{
+       int retval;
+
+       switch (cam->params.version.sensor_flags) {
+       case CPIA2_VP_SENSOR_FLAGS_404:
+       case CPIA2_VP_SENSOR_FLAGS_407:
+       case CPIA2_VP_SENSOR_FLAGS_409:
+       case CPIA2_VP_SENSOR_FLAGS_410:
+               retval = config_sensor_410(cam, req_width, req_height);
+               break;
+       case CPIA2_VP_SENSOR_FLAGS_500:
+               retval = config_sensor_500(cam, req_width, req_height);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return retval;
+}
+
+/******************************************************************************
+ *
+ *  config_sensor_410
+ *
+ *****************************************************************************/
+static int config_sensor_410(struct camera_data *cam,
+                           int req_width, int req_height)
+{
+       struct cpia2_command cmd;
+       int i = 0;
+       int image_size;
+       int image_type;
+       int width = req_width;
+       int height = req_height;
+
+       /***
+        *  Make sure size doesn't exceed CIF.
+        ***/
+       if (width > STV_IMAGE_CIF_COLS)
+               width = STV_IMAGE_CIF_COLS;
+       if (height > STV_IMAGE_CIF_ROWS)
+               height = STV_IMAGE_CIF_ROWS;
+
+       image_size = cpia2_match_video_size(width, height);
+
+       DBG("Config 410: width = %d, height = %d\n", width, height);
+       DBG("Image size returned is %d\n", image_size);
+       if (image_size >= 0) {
+               set_vw_size(cam, image_size);
+               width = cam->params.roi.width;
+               height = cam->params.roi.height;
+
+               DBG("After set_vw_size(), width = %d, height = %d\n",
+                   width, height);
+               if (width <= 176 && height <= 144) {
+                       DBG("image type = VIDEOSIZE_QCIF\n");
+                       image_type = VIDEOSIZE_QCIF;
+               }
+               else if (width <= 320 && height <= 240) {
+                       DBG("image type = VIDEOSIZE_QVGA\n");
+                       image_type = VIDEOSIZE_QVGA;
+               }
+               else {
+                       DBG("image type = VIDEOSIZE_CIF\n");
+                       image_type = VIDEOSIZE_CIF;
+               }
+       } else {
+               ERR("ConfigSensor410 failed\n");
+               return -EINVAL;
+       }
+
+       cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
+       cmd.direction = TRANSFER_WRITE;
+
+       /* VC Format */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT;
+       if (image_type == VIDEOSIZE_CIF) {
+               cmd.buffer.registers[i++].value =
+                   (u8) (CPIA2_VC_VC_FORMAT_UFIRST |
+                         CPIA2_VC_VC_FORMAT_SHORTLINE);
+       } else {
+               cmd.buffer.registers[i++].value =
+                   (u8) CPIA2_VC_VC_FORMAT_UFIRST;
+       }
+
+       /* VC Clocks */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS;
+       if (image_type == VIDEOSIZE_QCIF) {
+               if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
+                       cmd.buffer.registers[i++].value=
+                               (u8)(CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 |
+                                    CPIA2_VC_VC_672_CLOCKS_SCALING |
+                                    CPIA2_VC_VC_CLOCKS_LOGDIV2);
+                       DBG("VC_Clocks (0xc4) should be B\n");
+               }
+               else {
+                       cmd.buffer.registers[i++].value=
+                               (u8)(CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 |
+                                    CPIA2_VC_VC_CLOCKS_LOGDIV2);
+               }
+       } else {
+               if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
+                       cmd.buffer.registers[i++].value =
+                          (u8) (CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3 |
+                                CPIA2_VC_VC_CLOCKS_LOGDIV0);
+               }
+               else {
+                       cmd.buffer.registers[i++].value =
+                          (u8) (CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3 |
+                                CPIA2_VC_VC_676_CLOCKS_SCALING |
+                                CPIA2_VC_VC_CLOCKS_LOGDIV0);
+               }
+       }
+       DBG("VC_Clocks (0xc4) = 0x%0X\n", cmd.buffer.registers[i-1].value);
+
+       /* Input reqWidth from VC */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO;
+       if (image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value =
+                   (u8) (STV_IMAGE_QCIF_COLS / 4);
+       else
+               cmd.buffer.registers[i++].value =
+                   (u8) (STV_IMAGE_CIF_COLS / 4);
+
+       /* Timings */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI;
+       if (image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = (u8) 0;
+       else
+               cmd.buffer.registers[i++].value = (u8) 1;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO;
+       if (image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = (u8) 208;
+       else
+               cmd.buffer.registers[i++].value = (u8) 160;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI;
+       if (image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = (u8) 0;
+       else
+               cmd.buffer.registers[i++].value = (u8) 1;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO;
+       if (image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = (u8) 160;
+       else
+               cmd.buffer.registers[i++].value = (u8) 64;
+
+       /* Output Image Size */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE;
+       cmd.buffer.registers[i++].value = cam->params.roi.width / 4;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE;
+       cmd.buffer.registers[i++].value = cam->params.roi.height / 4;
+
+       /* Cropping */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP;
+       if (image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value =
+                   (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2);
+       else
+               cmd.buffer.registers[i++].value =
+                   (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2);
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP;
+       if (image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value =
+                   (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2);
+       else
+               cmd.buffer.registers[i++].value =
+                   (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2);
+
+       /* Scaling registers (defaults) */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE;
+       cmd.buffer.registers[i++].value = (u8) 0;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE;
+       cmd.buffer.registers[i++].value = (u8) 0;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN;
+       cmd.buffer.registers[i++].value = (u8) 31;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN;
+       cmd.buffer.registers[i++].value = (u8) 31;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP;
+       cmd.buffer.registers[i++].value = (u8) 0;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP;
+       cmd.buffer.registers[i++].value = (u8) 0;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT;
+       cmd.buffer.registers[i++].value = (u8) 0x81;    /* = 8/1 = 8 (HIBYTE/LOBYTE) */
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT;
+       cmd.buffer.registers[i++].value = (u8) 0x81;    /* = 8/1 = 8 (HIBYTE/LOBYTE) */
+
+       cmd.reg_count = i;
+
+       cpia2_send_command(cam, &cmd);
+
+       return i;
+}
+
+
+/******************************************************************************
+ *
+ *  config_sensor_500(cam)
+ *
+ *****************************************************************************/
+static int config_sensor_500(struct camera_data *cam,
+                            int req_width, int req_height)
+{
+       struct cpia2_command cmd;
+       int i = 0;
+       int image_size = VIDEOSIZE_CIF;
+       int image_type = VIDEOSIZE_VGA;
+       int width = req_width;
+       int height = req_height;
+       unsigned int device = cam->params.pnp_id.device_type;
+
+       image_size = cpia2_match_video_size(width, height);
+
+       if (width > STV_IMAGE_CIF_COLS || height > STV_IMAGE_CIF_ROWS)
+               image_type = VIDEOSIZE_VGA;
+       else if (width > STV_IMAGE_QVGA_COLS || height > STV_IMAGE_QVGA_ROWS)
+               image_type = VIDEOSIZE_CIF;
+       else if (width > STV_IMAGE_QCIF_COLS || height > STV_IMAGE_QCIF_ROWS)
+               image_type = VIDEOSIZE_QVGA;
+       else
+               image_type = VIDEOSIZE_QCIF;
+
+       if (image_size >= 0) {
+               set_vw_size(cam, image_size);
+               width = cam->params.roi.width;
+               height = cam->params.roi.height;
+       } else {
+               ERR("ConfigSensor500 failed\n");
+               return -EINVAL;
+       }
+
+       DBG("image_size = %d, width = %d, height = %d, type = %d\n",
+           image_size, width, height, image_type);
+
+       cmd.req_mode = CAMERAACCESS_TYPE_RANDOM | CAMERAACCESS_VC;
+       cmd.direction = TRANSFER_WRITE;
+       i = 0;
+
+       /* VC Format */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_FORMAT;
+       cmd.buffer.registers[i].value = (u8) CPIA2_VC_VC_FORMAT_UFIRST;
+       if (image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i].value |= (u8) CPIA2_VC_VC_FORMAT_DECIMATING;
+       i++;
+
+       /* VC Clocks */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_CLOCKS;
+       if (device == DEVICE_STV_672) {
+               if (image_type == VIDEOSIZE_VGA)
+                       cmd.buffer.registers[i].value =
+                               (u8)CPIA2_VC_VC_CLOCKS_LOGDIV1;
+               else
+                       cmd.buffer.registers[i].value =
+                               (u8)(CPIA2_VC_VC_672_CLOCKS_SCALING |
+                                    CPIA2_VC_VC_CLOCKS_LOGDIV3);
+       } else {
+               if (image_type == VIDEOSIZE_VGA)
+                       cmd.buffer.registers[i].value =
+                               (u8)CPIA2_VC_VC_CLOCKS_LOGDIV0;
+               else
+                       cmd.buffer.registers[i].value =
+                               (u8)(CPIA2_VC_VC_676_CLOCKS_SCALING |
+                                    CPIA2_VC_VC_CLOCKS_LOGDIV2);
+       }
+       i++;
+
+       DBG("VC_CLOCKS = 0x%X\n", cmd.buffer.registers[i-1].value);
+
+       /* Input width from VP */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_IHSIZE_LO;
+       if (image_type == VIDEOSIZE_VGA)
+               cmd.buffer.registers[i].value =
+                   (u8) (STV_IMAGE_VGA_COLS / 4);
+       else
+               cmd.buffer.registers[i].value =
+                   (u8) (STV_IMAGE_QVGA_COLS / 4);
+       i++;
+       DBG("Input width = %d\n", cmd.buffer.registers[i-1].value);
+
+       /* Timings */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_HI;
+       if (image_type == VIDEOSIZE_VGA)
+               cmd.buffer.registers[i++].value = (u8) 2;
+       else
+               cmd.buffer.registers[i++].value = (u8) 1;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_XLIM_LO;
+       if (image_type == VIDEOSIZE_VGA)
+               cmd.buffer.registers[i++].value = (u8) 250;
+       else if (image_type == VIDEOSIZE_QVGA)
+               cmd.buffer.registers[i++].value = (u8) 125;
+       else
+               cmd.buffer.registers[i++].value = (u8) 160;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_HI;
+       if (image_type == VIDEOSIZE_VGA)
+               cmd.buffer.registers[i++].value = (u8) 2;
+       else
+               cmd.buffer.registers[i++].value = (u8) 1;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_YLIM_LO;
+       if (image_type == VIDEOSIZE_VGA)
+               cmd.buffer.registers[i++].value = (u8) 12;
+       else if (image_type == VIDEOSIZE_QVGA)
+               cmd.buffer.registers[i++].value = (u8) 64;
+       else
+               cmd.buffer.registers[i++].value = (u8) 6;
+
+       /* Output Image Size */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_OHSIZE;
+       if (image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = STV_IMAGE_CIF_COLS  / 4;
+       else
+               cmd.buffer.registers[i++].value = width / 4;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_OVSIZE;
+       if (image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = STV_IMAGE_CIF_ROWS  / 4;
+       else
+               cmd.buffer.registers[i++].value = height / 4;
+
+       /* Cropping */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_HCROP;
+       if (image_type == VIDEOSIZE_VGA)
+               cmd.buffer.registers[i++].value =
+                   (u8) (((STV_IMAGE_VGA_COLS / 4) - (width / 4)) / 2);
+       else if (image_type == VIDEOSIZE_QVGA)
+               cmd.buffer.registers[i++].value =
+                   (u8) (((STV_IMAGE_QVGA_COLS / 4) - (width / 4)) / 2);
+       else if (image_type == VIDEOSIZE_CIF)
+               cmd.buffer.registers[i++].value =
+                   (u8) (((STV_IMAGE_CIF_COLS / 4) - (width / 4)) / 2);
+       else /*if (image_type == VIDEOSIZE_QCIF)*/
+               cmd.buffer.registers[i++].value =
+                       (u8) (((STV_IMAGE_QCIF_COLS / 4) - (width / 4)) / 2);
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_VCROP;
+       if (image_type == VIDEOSIZE_VGA)
+               cmd.buffer.registers[i++].value =
+                   (u8) (((STV_IMAGE_VGA_ROWS / 4) - (height / 4)) / 2);
+       else if (image_type == VIDEOSIZE_QVGA)
+               cmd.buffer.registers[i++].value =
+                   (u8) (((STV_IMAGE_QVGA_ROWS / 4) - (height / 4)) / 2);
+       else if (image_type == VIDEOSIZE_CIF)
+               cmd.buffer.registers[i++].value =
+                   (u8) (((STV_IMAGE_CIF_ROWS / 4) - (height / 4)) / 2);
+       else /*if (image_type == VIDEOSIZE_QCIF)*/
+               cmd.buffer.registers[i++].value =
+                   (u8) (((STV_IMAGE_QCIF_ROWS / 4) - (height / 4)) / 2);
+
+       /* Scaling registers (defaults) */
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_HPHASE;
+       if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = (u8) 36;
+       else
+               cmd.buffer.registers[i++].value = (u8) 0;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_VPHASE;
+       if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = (u8) 32;
+       else
+               cmd.buffer.registers[i++].value = (u8) 0;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_HISPAN;
+       if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = (u8) 26;
+       else
+               cmd.buffer.registers[i++].value = (u8) 31;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_VISPAN;
+       if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = (u8) 21;
+       else
+               cmd.buffer.registers[i++].value = (u8) 31;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_HICROP;
+       cmd.buffer.registers[i++].value = (u8) 0;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_VICROP;
+       cmd.buffer.registers[i++].value = (u8) 0;
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_HFRACT;
+       if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = (u8) 0x2B;    /* 2/11 */
+       else
+               cmd.buffer.registers[i++].value = (u8) 0x81;    /* 8/1 */
+
+       cmd.buffer.registers[i].index = CPIA2_VC_VC_VFRACT;
+       if (image_type == VIDEOSIZE_CIF || image_type == VIDEOSIZE_QCIF)
+               cmd.buffer.registers[i++].value = (u8) 0x13;    /* 1/3 */
+       else
+               cmd.buffer.registers[i++].value = (u8) 0x81;    /* 8/1 */
+
+       cmd.reg_count = i;
+
+       cpia2_send_command(cam, &cmd);
+
+       return i;
+}
+
+
+/******************************************************************************
+ *
+ *  setallproperties
+ *
+ *  This sets all user changeable properties to the values in cam->params.
+ *****************************************************************************/
+int set_all_properties(struct camera_data *cam)
+{
+       /**
+        * Don't set target_kb here, it will be set later.
+        * framerate and user_mode were already set (set_default_user_mode).
+        **/
+
+       cpia2_set_color_params(cam);
+
+       cpia2_usb_change_streaming_alternate(cam,
+                                         cam->params.camera_state.stream_mode);
+
+       cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
+                        cam->params.vp_params.user_effects);
+
+       cpia2_set_flicker_mode(cam,
+                              cam->params.flicker_control.flicker_mode_req);
+
+       cpia2_do_command(cam,
+                        CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
+                        TRANSFER_WRITE, cam->params.vp_params.gpio_direction);
+       cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, TRANSFER_WRITE,
+                        cam->params.vp_params.gpio_data);
+
+       wake_system(cam);
+
+       set_lowlight_boost(cam);
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_save_camera_state
+ *
+ *****************************************************************************/
+void cpia2_save_camera_state(struct camera_data *cam)
+{
+       get_color_params(cam);
+       cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
+       cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, TRANSFER_READ,
+                        0);
+       cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DATA, TRANSFER_READ, 0);
+       /* Don't get framerate or target_kb. Trust the values we already have */
+}
+
+/******************************************************************************
+ *
+ *  get_color_params
+ *
+ *****************************************************************************/
+void get_color_params(struct camera_data *cam)
+{
+       cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, TRANSFER_READ, 0);
+       cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, TRANSFER_READ, 0);
+       cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST, TRANSFER_READ, 0);
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_color_params
+ *
+ *****************************************************************************/
+void cpia2_set_color_params(struct camera_data *cam)
+{
+       DBG("Setting color params\n");
+       cpia2_set_brightness(cam, cam->params.color_params.brightness);
+       cpia2_set_contrast(cam, cam->params.color_params.contrast);
+       cpia2_set_saturation(cam, cam->params.color_params.saturation);
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_flicker_mode
+ *
+ *****************************************************************************/
+int cpia2_set_flicker_mode(struct camera_data *cam, int mode)
+{
+       unsigned char cam_reg;
+       int err = 0;
+
+       if(cam->params.pnp_id.device_type != DEVICE_STV_672)
+               return -EINVAL;
+
+       /* Set the appropriate bits in FLICKER_MODES, preserving the rest */
+       if((err = cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES,
+                                  TRANSFER_READ, 0)))
+               return err;
+       cam_reg = cam->params.flicker_control.cam_register;
+
+       switch(mode) {
+       case NEVER_FLICKER:
+               cam_reg |= CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
+               cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ;
+               break;
+       case FLICKER_60:
+               cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
+               cam_reg &= ~CPIA2_VP_FLICKER_MODES_50HZ;
+               break;
+       case FLICKER_50:
+               cam_reg &= ~CPIA2_VP_FLICKER_MODES_NEVER_FLICKER;
+               cam_reg |= CPIA2_VP_FLICKER_MODES_50HZ;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if((err = cpia2_do_command(cam, CPIA2_CMD_SET_FLICKER_MODES,
+                                  TRANSFER_WRITE, cam_reg)))
+               return err;
+
+       /* Set the appropriate bits in EXP_MODES, preserving the rest */
+       if((err = cpia2_do_command(cam, CPIA2_CMD_GET_VP_EXP_MODES,
+                                  TRANSFER_READ, 0)))
+               return err;
+       cam_reg = cam->params.vp_params.exposure_modes;
+
+       if (mode == NEVER_FLICKER) {
+               cam_reg |= CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER;
+       } else {
+               cam_reg &= ~CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER;
+       }
+
+       if((err = cpia2_do_command(cam, CPIA2_CMD_SET_VP_EXP_MODES,
+                                  TRANSFER_WRITE, cam_reg)))
+               return err;
+
+       if((err = cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4,
+                                  TRANSFER_WRITE, 1)))
+               return err;
+
+       switch(mode) {
+       case NEVER_FLICKER:
+               cam->params.flicker_control.flicker_mode_req = mode;
+               break;
+       case FLICKER_60:
+               cam->params.flicker_control.flicker_mode_req = mode;
+               cam->params.flicker_control.mains_frequency = 60;
+               break;
+       case FLICKER_50:
+               cam->params.flicker_control.flicker_mode_req = mode;
+               cam->params.flicker_control.mains_frequency = 50;
+               break;
+       default:
+               err = -EINVAL;
+       }
+
+       return err;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_property_flip
+ *
+ *****************************************************************************/
+void cpia2_set_property_flip(struct camera_data *cam, int prop_val)
+{
+       unsigned char cam_reg;
+
+       cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
+       cam_reg = cam->params.vp_params.user_effects;
+
+       if (prop_val)
+       {
+               cam_reg |= CPIA2_VP_USER_EFFECTS_FLIP;
+       }
+       else
+       {
+               cam_reg &= ~CPIA2_VP_USER_EFFECTS_FLIP;
+       }
+       cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
+                        cam_reg);
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_property_mirror
+ *
+ *****************************************************************************/
+void cpia2_set_property_mirror(struct camera_data *cam, int prop_val)
+{
+       unsigned char cam_reg;
+
+       cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
+       cam_reg = cam->params.vp_params.user_effects;
+
+       if (prop_val)
+       {
+               cam_reg |= CPIA2_VP_USER_EFFECTS_MIRROR;
+       }
+       else
+       {
+               cam_reg &= ~CPIA2_VP_USER_EFFECTS_MIRROR;
+       }
+       cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
+                        cam_reg);
+}
+
+/******************************************************************************
+ *
+ *  set_target_kb
+ *
+ *  The new Target KB is set in cam->params.vc_params.target_kb and
+ *  activates on reset.
+ *****************************************************************************/
+
+int cpia2_set_target_kb(struct camera_data *cam, unsigned char value)
+{
+       DBG("Requested target_kb = %d\n", value);
+       if (value != cam->params.vc_params.target_kb) {
+
+               cpia2_usb_stream_pause(cam);
+
+               /* reset camera for new target_kb */
+               cam->params.vc_params.target_kb = value;
+               cpia2_reset_camera(cam);
+
+               cpia2_usb_stream_resume(cam);
+       }
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_gpio
+ *
+ *****************************************************************************/
+int cpia2_set_gpio(struct camera_data *cam, unsigned char setting)
+{
+       int ret;
+
+       /* Set the microport direction (register 0x90, should be defined
+        * already) to 1 (user output), and set the microport data (0x91) to
+        * the value in the ioctl argument.
+        */
+
+       ret = cpia2_do_command(cam,
+                              CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
+                              CPIA2_VC_MP_DIR_OUTPUT,
+                              255);
+       if (ret < 0)
+               return ret;
+       cam->params.vp_params.gpio_direction = 255;
+
+       ret = cpia2_do_command(cam,
+                              CPIA2_CMD_SET_VC_MP_GPIO_DATA,
+                              CPIA2_VC_MP_DIR_OUTPUT,
+                              setting);
+       if (ret < 0)
+               return ret;
+       cam->params.vp_params.gpio_data = setting;
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_fps
+ *
+ *****************************************************************************/
+int cpia2_set_fps(struct camera_data *cam, int framerate)
+{
+       int retval;
+
+       switch(framerate) {
+               case CPIA2_VP_FRAMERATE_30:
+               case CPIA2_VP_FRAMERATE_25:
+                       if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
+                          cam->params.version.sensor_flags ==
+                                                   CPIA2_VP_SENSOR_FLAGS_500) {
+                               return -EINVAL;
+                       }
+                       /* Fall through */
+               case CPIA2_VP_FRAMERATE_15:
+               case CPIA2_VP_FRAMERATE_12_5:
+               case CPIA2_VP_FRAMERATE_7_5:
+               case CPIA2_VP_FRAMERATE_6_25:
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       if (cam->params.pnp_id.device_type == DEVICE_STV_672 &&
+           framerate == CPIA2_VP_FRAMERATE_15)
+               framerate = 0; /* Work around bug in VP4 */
+
+       retval = cpia2_do_command(cam,
+                                CPIA2_CMD_FRAMERATE_REQ,
+                                TRANSFER_WRITE,
+                                framerate);
+
+       if(retval == 0)
+               cam->params.vp_params.frame_rate = framerate;
+
+       return retval;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_brightness
+ *
+ *****************************************************************************/
+void cpia2_set_brightness(struct camera_data *cam, unsigned char value)
+{
+       /***
+        * Don't let the register be set to zero - bug in VP4 - flash of full
+        * brightness
+        ***/
+       if (cam->params.pnp_id.device_type == DEVICE_STV_672 && value == 0)
+               value++;
+       DBG("Setting brightness to %d (0x%0x)\n", value, value);
+       cpia2_do_command(cam,CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE,value);
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_contrast
+ *
+ *****************************************************************************/
+void cpia2_set_contrast(struct camera_data *cam, unsigned char value)
+{
+       DBG("Setting contrast to %d (0x%0x)\n", value, value);
+       cam->params.color_params.contrast = value;
+       cpia2_do_command(cam, CPIA2_CMD_SET_CONTRAST, TRANSFER_WRITE, value);
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_saturation
+ *
+ *****************************************************************************/
+void cpia2_set_saturation(struct camera_data *cam, unsigned char value)
+{
+       DBG("Setting saturation to %d (0x%0x)\n", value, value);
+       cam->params.color_params.saturation = value;
+       cpia2_do_command(cam,CPIA2_CMD_SET_VP_SATURATION, TRANSFER_WRITE,value);
+}
+
+/******************************************************************************
+ *
+ *  wake_system
+ *
+ *****************************************************************************/
+void wake_system(struct camera_data *cam)
+{
+       cpia2_do_command(cam, CPIA2_CMD_SET_WAKEUP, TRANSFER_WRITE, 0);
+}
+
+/******************************************************************************
+ *
+ *  set_lowlight_boost
+ *
+ *  Valid for STV500 sensor only
+ *****************************************************************************/
+void set_lowlight_boost(struct camera_data *cam)
+{
+       struct cpia2_command cmd;
+
+       if (cam->params.pnp_id.device_type != DEVICE_STV_672 ||
+           cam->params.version.sensor_flags != CPIA2_VP_SENSOR_FLAGS_500)
+               return;
+
+       cmd.direction = TRANSFER_WRITE;
+       cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+       cmd.reg_count = 3;
+       cmd.start = CPIA2_VP_RAM_ADDR_H;
+
+       cmd.buffer.block_data[0] = 0;   /* High byte of address to write to */
+       cmd.buffer.block_data[1] = 0x59;        /* Low byte of address to write to */
+       cmd.buffer.block_data[2] = 0;   /* High byte of data to write */
+
+       cpia2_send_command(cam, &cmd);
+
+       if (cam->params.vp_params.lowlight_boost) {
+               cmd.buffer.block_data[0] = 0x02;        /* Low byte data to write */
+       } else {
+               cmd.buffer.block_data[0] = 0x06;
+       }
+       cmd.start = CPIA2_VP_RAM_DATA;
+       cmd.reg_count = 1;
+       cpia2_send_command(cam, &cmd);
+
+       /* Rehash the VP4 values */
+       cpia2_do_command(cam, CPIA2_CMD_REHASH_VP4, TRANSFER_WRITE, 1);
+}
+
+/******************************************************************************
+ *
+ *  cpia2_set_format
+ *
+ *  Assumes that new size is already set in param struct.
+ *****************************************************************************/
+void cpia2_set_format(struct camera_data *cam)
+{
+       cam->flush = true;
+
+       cpia2_usb_stream_pause(cam);
+
+       /* reset camera to new size */
+       cpia2_set_low_power(cam);
+       cpia2_reset_camera(cam);
+       cam->flush = false;
+
+       cpia2_dbg_dump_registers(cam);
+
+       cpia2_usb_stream_resume(cam);
+}
+
+/******************************************************************************
+ *
+ * cpia2_dbg_dump_registers
+ *
+ *****************************************************************************/
+void cpia2_dbg_dump_registers(struct camera_data *cam)
+{
+#ifdef _CPIA2_DEBUG_
+       struct cpia2_command cmd;
+
+       if (!(debugs_on & DEBUG_DUMP_REGS))
+               return;
+
+       cmd.direction = TRANSFER_READ;
+
+       /* Start with bank 0 (SYSTEM) */
+       cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_SYSTEM;
+       cmd.reg_count = 3;
+       cmd.start = 0;
+       cpia2_send_command(cam, &cmd);
+       printk(KERN_DEBUG "System Device Hi      = 0x%X\n",
+              cmd.buffer.block_data[0]);
+       printk(KERN_DEBUG "System Device Lo      = 0x%X\n",
+              cmd.buffer.block_data[1]);
+       printk(KERN_DEBUG "System_system control = 0x%X\n",
+              cmd.buffer.block_data[2]);
+
+       /* Bank 1 (VC) */
+       cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
+       cmd.reg_count = 4;
+       cmd.start = 0x80;
+       cpia2_send_command(cam, &cmd);
+       printk(KERN_DEBUG "ASIC_ID       = 0x%X\n",
+              cmd.buffer.block_data[0]);
+       printk(KERN_DEBUG "ASIC_REV      = 0x%X\n",
+              cmd.buffer.block_data[1]);
+       printk(KERN_DEBUG "PW_CONTRL     = 0x%X\n",
+              cmd.buffer.block_data[2]);
+       printk(KERN_DEBUG "WAKEUP        = 0x%X\n",
+              cmd.buffer.block_data[3]);
+
+       cmd.start = 0xA0;       /* ST_CTRL */
+       cmd.reg_count = 1;
+       cpia2_send_command(cam, &cmd);
+       printk(KERN_DEBUG "Stream ctrl   = 0x%X\n",
+              cmd.buffer.block_data[0]);
+
+       cmd.start = 0xA4;       /* Stream status */
+       cpia2_send_command(cam, &cmd);
+       printk(KERN_DEBUG "Stream status = 0x%X\n",
+              cmd.buffer.block_data[0]);
+
+       cmd.start = 0xA8;       /* USB status */
+       cmd.reg_count = 3;
+       cpia2_send_command(cam, &cmd);
+       printk(KERN_DEBUG "USB_CTRL      = 0x%X\n",
+              cmd.buffer.block_data[0]);
+       printk(KERN_DEBUG "USB_STRM      = 0x%X\n",
+              cmd.buffer.block_data[1]);
+       printk(KERN_DEBUG "USB_STATUS    = 0x%X\n",
+              cmd.buffer.block_data[2]);
+
+       cmd.start = 0xAF;       /* USB settings */
+       cmd.reg_count = 1;
+       cpia2_send_command(cam, &cmd);
+       printk(KERN_DEBUG "USB settings  = 0x%X\n",
+              cmd.buffer.block_data[0]);
+
+       cmd.start = 0xC0;       /* VC stuff */
+       cmd.reg_count = 26;
+       cpia2_send_command(cam, &cmd);
+       printk(KERN_DEBUG "VC Control    = 0x%0X\n",
+              cmd.buffer.block_data[0]);
+       printk(KERN_DEBUG "VC Format     = 0x%0X\n",
+              cmd.buffer.block_data[3]);
+       printk(KERN_DEBUG "VC Clocks     = 0x%0X\n",
+              cmd.buffer.block_data[4]);
+       printk(KERN_DEBUG "VC IHSize     = 0x%0X\n",
+              cmd.buffer.block_data[5]);
+       printk(KERN_DEBUG "VC Xlim Hi    = 0x%0X\n",
+              cmd.buffer.block_data[6]);
+       printk(KERN_DEBUG "VC XLim Lo    = 0x%0X\n",
+              cmd.buffer.block_data[7]);
+       printk(KERN_DEBUG "VC YLim Hi    = 0x%0X\n",
+              cmd.buffer.block_data[8]);
+       printk(KERN_DEBUG "VC YLim Lo    = 0x%0X\n",
+              cmd.buffer.block_data[9]);
+       printk(KERN_DEBUG "VC OHSize     = 0x%0X\n",
+              cmd.buffer.block_data[10]);
+       printk(KERN_DEBUG "VC OVSize     = 0x%0X\n",
+              cmd.buffer.block_data[11]);
+       printk(KERN_DEBUG "VC HCrop      = 0x%0X\n",
+              cmd.buffer.block_data[12]);
+       printk(KERN_DEBUG "VC VCrop      = 0x%0X\n",
+              cmd.buffer.block_data[13]);
+       printk(KERN_DEBUG "VC HPhase     = 0x%0X\n",
+              cmd.buffer.block_data[14]);
+       printk(KERN_DEBUG "VC VPhase     = 0x%0X\n",
+              cmd.buffer.block_data[15]);
+       printk(KERN_DEBUG "VC HIspan     = 0x%0X\n",
+              cmd.buffer.block_data[16]);
+       printk(KERN_DEBUG "VC VIspan     = 0x%0X\n",
+              cmd.buffer.block_data[17]);
+       printk(KERN_DEBUG "VC HiCrop     = 0x%0X\n",
+              cmd.buffer.block_data[18]);
+       printk(KERN_DEBUG "VC ViCrop     = 0x%0X\n",
+              cmd.buffer.block_data[19]);
+       printk(KERN_DEBUG "VC HiFract    = 0x%0X\n",
+              cmd.buffer.block_data[20]);
+       printk(KERN_DEBUG "VC ViFract    = 0x%0X\n",
+              cmd.buffer.block_data[21]);
+       printk(KERN_DEBUG "VC JPeg Opt   = 0x%0X\n",
+              cmd.buffer.block_data[22]);
+       printk(KERN_DEBUG "VC Creep Per  = 0x%0X\n",
+              cmd.buffer.block_data[23]);
+       printk(KERN_DEBUG "VC User Sq.   = 0x%0X\n",
+              cmd.buffer.block_data[24]);
+       printk(KERN_DEBUG "VC Target KB  = 0x%0X\n",
+              cmd.buffer.block_data[25]);
+
+       /*** VP ***/
+       cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VP;
+       cmd.reg_count = 14;
+       cmd.start = 0;
+       cpia2_send_command(cam, &cmd);
+
+       printk(KERN_DEBUG "VP Dev Hi     = 0x%0X\n",
+              cmd.buffer.block_data[0]);
+       printk(KERN_DEBUG "VP Dev Lo     = 0x%0X\n",
+              cmd.buffer.block_data[1]);
+       printk(KERN_DEBUG "VP Sys State  = 0x%0X\n",
+              cmd.buffer.block_data[2]);
+       printk(KERN_DEBUG "VP Sys Ctrl   = 0x%0X\n",
+              cmd.buffer.block_data[3]);
+       printk(KERN_DEBUG "VP Sensor flg = 0x%0X\n",
+              cmd.buffer.block_data[5]);
+       printk(KERN_DEBUG "VP Sensor Rev = 0x%0X\n",
+              cmd.buffer.block_data[6]);
+       printk(KERN_DEBUG "VP Dev Config = 0x%0X\n",
+              cmd.buffer.block_data[7]);
+       printk(KERN_DEBUG "VP GPIO_DIR   = 0x%0X\n",
+              cmd.buffer.block_data[8]);
+       printk(KERN_DEBUG "VP GPIO_DATA  = 0x%0X\n",
+              cmd.buffer.block_data[9]);
+       printk(KERN_DEBUG "VP Ram ADDR H = 0x%0X\n",
+              cmd.buffer.block_data[10]);
+       printk(KERN_DEBUG "VP Ram ADDR L = 0x%0X\n",
+              cmd.buffer.block_data[11]);
+       printk(KERN_DEBUG "VP RAM Data   = 0x%0X\n",
+              cmd.buffer.block_data[12]);
+       printk(KERN_DEBUG "Do Call       = 0x%0X\n",
+              cmd.buffer.block_data[13]);
+
+       if (cam->params.pnp_id.device_type == DEVICE_STV_672) {
+               cmd.reg_count = 9;
+               cmd.start = 0x0E;
+               cpia2_send_command(cam, &cmd);
+               printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n",
+                      cmd.buffer.block_data[0]);
+               printk(KERN_DEBUG "VP Patch Rev  = 0x%0X\n",
+                      cmd.buffer.block_data[1]);
+               printk(KERN_DEBUG "VP Vid Mode   = 0x%0X\n",
+                      cmd.buffer.block_data[2]);
+               printk(KERN_DEBUG "VP Framerate  = 0x%0X\n",
+                      cmd.buffer.block_data[3]);
+               printk(KERN_DEBUG "VP UserEffect = 0x%0X\n",
+                      cmd.buffer.block_data[4]);
+               printk(KERN_DEBUG "VP White Bal  = 0x%0X\n",
+                      cmd.buffer.block_data[5]);
+               printk(KERN_DEBUG "VP WB thresh  = 0x%0X\n",
+                      cmd.buffer.block_data[6]);
+               printk(KERN_DEBUG "VP Exp Modes  = 0x%0X\n",
+                      cmd.buffer.block_data[7]);
+               printk(KERN_DEBUG "VP Exp Target = 0x%0X\n",
+                      cmd.buffer.block_data[8]);
+
+               cmd.reg_count = 1;
+               cmd.start = 0x1B;
+               cpia2_send_command(cam, &cmd);
+               printk(KERN_DEBUG "VP FlickerMds = 0x%0X\n",
+                      cmd.buffer.block_data[0]);
+       } else {
+               cmd.reg_count = 8 ;
+               cmd.start = 0x0E;
+               cpia2_send_command(cam, &cmd);
+               printk(KERN_DEBUG "VP Clock Ctrl = 0x%0X\n",
+                      cmd.buffer.block_data[0]);
+               printk(KERN_DEBUG "VP Patch Rev  = 0x%0X\n",
+                      cmd.buffer.block_data[1]);
+               printk(KERN_DEBUG "VP Vid Mode   = 0x%0X\n",
+                      cmd.buffer.block_data[5]);
+               printk(KERN_DEBUG "VP Framerate  = 0x%0X\n",
+                      cmd.buffer.block_data[6]);
+               printk(KERN_DEBUG "VP UserEffect = 0x%0X\n",
+                      cmd.buffer.block_data[7]);
+
+               cmd.reg_count = 1;
+               cmd.start = CPIA2_VP5_EXPOSURE_TARGET;
+               cpia2_send_command(cam, &cmd);
+               printk(KERN_DEBUG "VP5 Exp Target= 0x%0X\n",
+                      cmd.buffer.block_data[0]);
+
+               cmd.reg_count = 4;
+               cmd.start = 0x3A;
+               cpia2_send_command(cam, &cmd);
+               printk(KERN_DEBUG "VP5 MY Black  = 0x%0X\n",
+                      cmd.buffer.block_data[0]);
+               printk(KERN_DEBUG "VP5 MCY Range = 0x%0X\n",
+                      cmd.buffer.block_data[1]);
+               printk(KERN_DEBUG "VP5 MYCEILING = 0x%0X\n",
+                      cmd.buffer.block_data[2]);
+               printk(KERN_DEBUG "VP5 MCUV Sat  = 0x%0X\n",
+                      cmd.buffer.block_data[3]);
+       }
+#endif
+}
+
+/******************************************************************************
+ *
+ *  reset_camera_struct
+ *
+ *  Sets all values to the defaults
+ *****************************************************************************/
+void reset_camera_struct(struct camera_data *cam)
+{
+       /***
+        * The following parameter values are the defaults from the register map.
+        ***/
+       cam->params.color_params.brightness = DEFAULT_BRIGHTNESS;
+       cam->params.color_params.contrast = DEFAULT_CONTRAST;
+       cam->params.color_params.saturation = DEFAULT_SATURATION;
+       cam->params.vp_params.lowlight_boost = 0;
+
+       /* FlickerModes */
+       cam->params.flicker_control.flicker_mode_req = NEVER_FLICKER;
+       cam->params.flicker_control.mains_frequency = 60;
+
+       /* jpeg params */
+       cam->params.compression.jpeg_options = CPIA2_VC_VC_JPEG_OPT_DEFAULT;
+       cam->params.compression.creep_period = 2;
+       cam->params.compression.user_squeeze = 20;
+       cam->params.compression.inhibit_htables = false;
+
+       /* gpio params */
+       cam->params.vp_params.gpio_direction = 0;       /* write, the default safe mode */
+       cam->params.vp_params.gpio_data = 0;
+
+       /* Target kb params */
+       cam->params.vc_params.target_kb = DEFAULT_TARGET_KB;
+
+       /***
+        * Set Sensor FPS as fast as possible.
+        ***/
+       if(cam->params.pnp_id.device_type == DEVICE_STV_672) {
+               if(cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500)
+                       cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_15;
+               else
+                       cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30;
+       } else {
+               cam->params.vp_params.frame_rate = CPIA2_VP_FRAMERATE_30;
+       }
+
+       /***
+        * Set default video mode as large as possible :
+        * for vga sensor set to vga, for cif sensor set to CIF.
+        ***/
+       if (cam->params.version.sensor_flags == CPIA2_VP_SENSOR_FLAGS_500) {
+               cam->sensor_type = CPIA2_SENSOR_500;
+               cam->video_size = VIDEOSIZE_VGA;
+               cam->params.roi.width = STV_IMAGE_VGA_COLS;
+               cam->params.roi.height = STV_IMAGE_VGA_ROWS;
+       } else {
+               cam->sensor_type = CPIA2_SENSOR_410;
+               cam->video_size = VIDEOSIZE_CIF;
+               cam->params.roi.width = STV_IMAGE_CIF_COLS;
+               cam->params.roi.height = STV_IMAGE_CIF_ROWS;
+       }
+
+       /***
+        * Fill in the v4l structures.  video_cap is filled in inside the VIDIOCCAP
+        * Ioctl.  Here, just do the window and picture stucts.
+        ***/
+       cam->vp.palette = (u16) VIDEO_PALETTE_RGB24;    /* Is this right? */
+       cam->vp.brightness = (u16) cam->params.color_params.brightness * 256;
+       cam->vp.colour = (u16) cam->params.color_params.saturation * 256;
+       cam->vp.contrast = (u16) cam->params.color_params.contrast * 256;
+
+       cam->vw.x = 0;
+       cam->vw.y = 0;
+       cam->vw.width = cam->params.roi.width;
+       cam->vw.height = cam->params.roi.height;
+       cam->vw.flags = 0;
+       cam->vw.clipcount = 0;
+
+       return;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_init_camera_struct
+ *
+ *  Initializes camera struct, does not call reset to fill in defaults.
+ *****************************************************************************/
+struct camera_data *cpia2_init_camera_struct(void)
+{
+       struct camera_data *cam;
+
+       cam = kmalloc(sizeof(*cam), GFP_KERNEL);
+
+       if (!cam) {
+               ERR("couldn't kmalloc cpia2 struct\n");
+               return NULL;
+       }
+
+       /* Default everything to 0 */
+       memset(cam, 0, sizeof(struct camera_data));
+
+       cam->present = 1;
+       init_MUTEX(&cam->busy_lock);
+       init_waitqueue_head(&cam->wq_stream);
+
+       return cam;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_init_camera
+ *
+ *  Initializes camera.
+ *****************************************************************************/
+int cpia2_init_camera(struct camera_data *cam)
+{
+       DBG("Start\n");
+
+       cam->mmapped = false;
+
+       /* Get sensor and asic types before reset. */
+       cpia2_set_high_power(cam);
+       cpia2_get_version_info(cam);
+       if (cam->params.version.asic_id != CPIA2_ASIC_672) {
+               ERR("Device IO error (asicID has incorrect value of 0x%X\n",
+                   cam->params.version.asic_id);
+               return -ENODEV;
+       }
+
+       /* Set GPIO direction and data to a safe state. */
+       cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
+                        TRANSFER_WRITE, 0);
+       cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA,
+                        TRANSFER_WRITE, 0);
+
+       /* resetting struct requires version info for sensor and asic types */
+       reset_camera_struct(cam);
+
+       cpia2_set_low_power(cam);
+
+       DBG("End\n");
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_allocate_buffers
+ *
+ *****************************************************************************/
+int cpia2_allocate_buffers(struct camera_data *cam)
+{
+       int i;
+
+       if(!cam->buffers) {
+               u32 size = cam->num_frames*sizeof(struct framebuf);
+               cam->buffers = kmalloc(size, GFP_KERNEL);
+               if(!cam->buffers) {
+                       ERR("couldn't kmalloc frame buffer structures\n");
+                       return -ENOMEM;
+               }
+       }
+
+       if(!cam->frame_buffer) {
+               cam->frame_buffer = rvmalloc(cam->frame_size*cam->num_frames);
+               if (!cam->frame_buffer) {
+                       ERR("couldn't vmalloc frame buffer data area\n");
+                       kfree(cam->buffers);
+                       cam->buffers = NULL;
+                       return -ENOMEM;
+               }
+       }
+
+       for(i=0; i<cam->num_frames-1; ++i) {
+               cam->buffers[i].next = &cam->buffers[i+1];
+               cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size;
+               cam->buffers[i].status = FRAME_EMPTY;
+               cam->buffers[i].length = 0;
+               cam->buffers[i].max_length = 0;
+               cam->buffers[i].num = i;
+       }
+       cam->buffers[i].next = cam->buffers;
+       cam->buffers[i].data = cam->frame_buffer +i*cam->frame_size;
+       cam->buffers[i].status = FRAME_EMPTY;
+       cam->buffers[i].length = 0;
+       cam->buffers[i].max_length = 0;
+       cam->buffers[i].num = i;
+       cam->curbuff = cam->buffers;
+       cam->workbuff = cam->curbuff->next;
+       DBG("buffers=%p, curbuff=%p, workbuff=%p\n", cam->buffers, cam->curbuff,
+           cam->workbuff);
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_free_buffers
+ *
+ *****************************************************************************/
+void cpia2_free_buffers(struct camera_data *cam)
+{
+       if(cam->buffers) {
+               kfree(cam->buffers);
+               cam->buffers = NULL;
+       }
+       if(cam->frame_buffer) {
+               rvfree(cam->frame_buffer, cam->frame_size*cam->num_frames);
+               cam->frame_buffer = NULL;
+       }
+}
+
+/******************************************************************************
+ *
+ *  cpia2_read
+ *
+ *****************************************************************************/
+long cpia2_read(struct camera_data *cam,
+               char __user *buf, unsigned long count, int noblock)
+{
+       struct framebuf *frame;
+       if (!count) {
+               return 0;
+       }
+
+       if (!buf) {
+               ERR("%s: buffer NULL\n",__FUNCTION__);
+               return -EINVAL;
+       }
+
+       if (!cam) {
+               ERR("%s: Internal error, camera_data NULL!\n",__FUNCTION__);
+               return -EINVAL;
+       }
+
+       /* make this _really_ smp and multithread-safe */
+       if (down_interruptible(&cam->busy_lock))
+               return -ERESTARTSYS;
+
+       if (!cam->present) {
+               LOG("%s: camera removed\n",__FUNCTION__);
+               up(&cam->busy_lock);
+               return 0;       /* EOF */
+       }
+
+       if(!cam->streaming) {
+               /* Start streaming */
+               cpia2_usb_stream_start(cam,
+                                      cam->params.camera_state.stream_mode);
+       }
+
+       /* Copy cam->curbuff in case it changes while we're processing */
+       frame = cam->curbuff;
+       if (noblock && frame->status != FRAME_READY) {
+               up(&cam->busy_lock);
+               return -EAGAIN;
+       }
+
+       if(frame->status != FRAME_READY) {
+               up(&cam->busy_lock);
+               wait_event_interruptible(cam->wq_stream,
+                              !cam->present ||
+                              (frame = cam->curbuff)->status == FRAME_READY);
+               if (signal_pending(current))
+                       return -ERESTARTSYS;
+               /* make this _really_ smp and multithread-safe */
+               if (down_interruptible(&cam->busy_lock)) {
+                       return -ERESTARTSYS;
+               }
+               if(!cam->present) {
+                       up(&cam->busy_lock);
+                       return 0;
+               }
+       }
+
+       /* copy data to user space */
+       if (frame->length > count) {
+               up(&cam->busy_lock);
+               return -EFAULT;
+       }
+       if (copy_to_user(buf, frame->data, frame->length)) {
+               up(&cam->busy_lock);
+               return -EFAULT;
+       }
+
+       count = frame->length;
+
+       frame->status = FRAME_EMPTY;
+
+       up(&cam->busy_lock);
+       return count;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_poll
+ *
+ *****************************************************************************/
+unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
+                       poll_table *wait)
+{
+       unsigned int status=0;
+
+       if(!cam) {
+               ERR("%s: Internal error, camera_data not found!\n",__FUNCTION__);
+               return POLLERR;
+       }
+
+       down(&cam->busy_lock);
+
+       if(!cam->present) {
+               up(&cam->busy_lock);
+               return POLLHUP;
+       }
+
+       if(!cam->streaming) {
+               /* Start streaming */
+               cpia2_usb_stream_start(cam,
+                                      cam->params.camera_state.stream_mode);
+       }
+
+       up(&cam->busy_lock);
+       poll_wait(filp, &cam->wq_stream, wait);
+       down(&cam->busy_lock);
+
+       if(!cam->present)
+               status = POLLHUP;
+       else if(cam->curbuff->status == FRAME_READY)
+               status = POLLIN | POLLRDNORM;
+
+       up(&cam->busy_lock);
+       return status;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_remap_buffer
+ *
+ *****************************************************************************/
+int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
+{
+       const char *adr = (const char *)vma->vm_start;
+       unsigned long size = vma->vm_end-vma->vm_start;
+       unsigned long start_offset = vma->vm_pgoff << PAGE_SHIFT;
+       unsigned long start = (unsigned long) adr;
+       unsigned long page, pos;
+
+       if (!cam)
+               return -ENODEV;
+
+       DBG("mmap offset:%ld size:%ld\n", start_offset, size);
+
+       /* make this _really_ smp-safe */
+       if (down_interruptible(&cam->busy_lock))
+               return -ERESTARTSYS;
+
+       if (!cam->present) {
+               up(&cam->busy_lock);
+               return -ENODEV;
+       }
+
+       if (size > cam->frame_size*cam->num_frames  ||
+           (start_offset % cam->frame_size) != 0 ||
+           (start_offset+size > cam->frame_size*cam->num_frames)) {
+               up(&cam->busy_lock);
+               return -EINVAL;
+       }
+
+       pos = ((unsigned long) (cam->frame_buffer)) + start_offset;
+       while (size > 0) {
+               page = kvirt_to_pa(pos);
+               if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) {
+                       up(&cam->busy_lock);
+                       return -EAGAIN;
+               }
+               start += PAGE_SIZE;
+               pos += PAGE_SIZE;
+               if (size > PAGE_SIZE)
+                       size -= PAGE_SIZE;
+               else
+                       size = 0;
+       }
+
+       cam->mmapped = true;
+       up(&cam->busy_lock);
+       return 0;
+}
+
diff --git a/drivers/media/video/cpia2/cpia2_registers.h b/drivers/media/video/cpia2/cpia2_registers.h
new file mode 100644 (file)
index 0000000..3bbec51
--- /dev/null
@@ -0,0 +1,476 @@
+/****************************************************************************
+ *
+ *  Filename: cpia2registers.h
+ *
+ *  Copyright 2001, STMicrolectronics, Inc.
+ *
+ *  Description:
+ *     Definitions for the CPia2 register set
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ****************************************************************************/
+
+#ifndef CPIA2_REGISTER_HEADER
+#define CPIA2_REGISTER_HEADER
+
+/***
+ * System register set (Bank 0)
+ ***/
+#define CPIA2_SYSTEM_DEVICE_HI                     0x00
+#define CPIA2_SYSTEM_DEVICE_LO                     0x01
+
+#define CPIA2_SYSTEM_SYSTEM_CONTROL                0x02
+#define CPIA2_SYSTEM_CONTROL_LOW_POWER       0x00
+#define CPIA2_SYSTEM_CONTROL_HIGH_POWER      0x01
+#define CPIA2_SYSTEM_CONTROL_SUSPEND         0x02
+#define CPIA2_SYSTEM_CONTROL_V2W_ERR         0x10
+#define CPIA2_SYSTEM_CONTROL_RB_ERR          0x10
+#define CPIA2_SYSTEM_CONTROL_CLEAR_ERR       0x80
+
+#define CPIA2_SYSTEM_INT_PACKET_CTRL                0x04
+#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_SW_XX 0x01
+#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_EOF   0x02
+#define CPIA2_SYSTEM_INT_PACKET_CTRL_ENABLE_INT1  0x04
+
+#define CPIA2_SYSTEM_CACHE_CTRL                     0x05
+#define CPIA2_SYSTEM_CACHE_CTRL_CACHE_RESET      0x01
+#define CPIA2_SYSTEM_CACHE_CTRL_CACHE_FLUSH      0x02
+
+#define CPIA2_SYSTEM_SERIAL_CTRL                    0x06
+#define CPIA2_SYSTEM_SERIAL_CTRL_NULL_CMD        0x00
+#define CPIA2_SYSTEM_SERIAL_CTRL_START_CMD       0x01
+#define CPIA2_SYSTEM_SERIAL_CTRL_STOP_CMD        0x02
+#define CPIA2_SYSTEM_SERIAL_CTRL_WRITE_CMD       0x03
+#define CPIA2_SYSTEM_SERIAL_CTRL_READ_ACK_CMD    0x04
+#define CPIA2_SYSTEM_SERIAL_CTRL_READ_NACK_CMD   0x05
+
+#define CPIA2_SYSTEM_SERIAL_DATA                     0x07
+
+#define CPIA2_SYSTEM_VP_SERIAL_ADDR                  0x08
+
+/***
+ * I2C addresses for various devices in CPiA2
+ ***/
+#define CPIA2_SYSTEM_VP_SERIAL_ADDR_SENSOR           0x20
+#define CPIA2_SYSTEM_VP_SERIAL_ADDR_VP               0x88
+#define CPIA2_SYSTEM_VP_SERIAL_ADDR_676_VP           0x8A
+
+#define CPIA2_SYSTEM_SPARE_REG1                      0x09
+#define CPIA2_SYSTEM_SPARE_REG2                      0x0A
+#define CPIA2_SYSTEM_SPARE_REG3                      0x0B
+
+#define CPIA2_SYSTEM_MC_PORT_0                       0x0C
+#define CPIA2_SYSTEM_MC_PORT_1                       0x0D
+#define CPIA2_SYSTEM_MC_PORT_2                       0x0E
+#define CPIA2_SYSTEM_MC_PORT_3                       0x0F
+
+#define CPIA2_SYSTEM_STATUS_PKT                      0x20
+#define CPIA2_SYSTEM_STATUS_PKT_END                  0x27
+
+#define CPIA2_SYSTEM_DESCRIP_VID_HI                  0x30
+#define CPIA2_SYSTEM_DESCRIP_VID_LO                  0x31
+#define CPIA2_SYSTEM_DESCRIP_PID_HI                  0x32
+#define CPIA2_SYSTEM_DESCRIP_PID_LO                  0x33
+
+#define CPIA2_SYSTEM_FW_VERSION_HI                   0x34
+#define CPIA2_SYSTEM_FW_VERSION_LO                   0x35
+
+#define CPIA2_SYSTEM_CACHE_START_INDEX               0x80
+#define CPIA2_SYSTEM_CACHE_MAX_WRITES                0x10
+
+/***
+ * VC register set (Bank 1)
+ ***/
+#define CPIA2_VC_ASIC_ID                 0x80
+
+#define CPIA2_VC_ASIC_REV                0x81
+
+#define CPIA2_VC_PW_CTRL                 0x82
+#define CPIA2_VC_PW_CTRL_COLDSTART      0x01
+#define CPIA2_VC_PW_CTRL_CP_CLK_EN      0x02
+#define CPIA2_VC_PW_CTRL_VP_RESET_N     0x04
+#define CPIA2_VC_PW_CTRL_VC_CLK_EN      0x08
+#define CPIA2_VC_PW_CTRL_VC_RESET_N     0x10
+#define CPIA2_VC_PW_CTRL_GOTO_SUSPEND   0x20
+#define CPIA2_VC_PW_CTRL_UDC_SUSPEND    0x40
+#define CPIA2_VC_PW_CTRL_PWR_DOWN       0x80
+
+#define CPIA2_VC_WAKEUP                   0x83
+#define CPIA2_VC_WAKEUP_SW_ENABLE       0x01
+#define CPIA2_VC_WAKEUP_XX_ENABLE       0x02
+#define CPIA2_VC_WAKEUP_SW_ATWAKEUP     0x04
+#define CPIA2_VC_WAKEUP_XX_ATWAKEUP     0x08
+
+#define CPIA2_VC_CLOCK_CTRL               0x84
+#define CPIA2_VC_CLOCK_CTRL_TESTUP72    0x01
+
+#define CPIA2_VC_INT_ENABLE                0x88
+#define CPIA2_VC_INT_ENABLE_XX_IE       0x01
+#define CPIA2_VC_INT_ENABLE_SW_IE       0x02
+#define CPIA2_VC_INT_ENABLE_VC_IE       0x04
+#define CPIA2_VC_INT_ENABLE_USBDATA_IE  0x08
+#define CPIA2_VC_INT_ENABLE_USBSETUP_IE 0x10
+#define CPIA2_VC_INT_ENABLE_USBCFG_IE   0x20
+
+#define CPIA2_VC_INT_FLAG                  0x89
+#define CPIA2_VC_INT_ENABLE_XX_FLAG       0x01
+#define CPIA2_VC_INT_ENABLE_SW_FLAG       0x02
+#define CPIA2_VC_INT_ENABLE_VC_FLAG       0x04
+#define CPIA2_VC_INT_ENABLE_USBDATA_FLAG  0x08
+#define CPIA2_VC_INT_ENABLE_USBSETUP_FLAG 0x10
+#define CPIA2_VC_INT_ENABLE_USBCFG_FLAG   0x20
+#define CPIA2_VC_INT_ENABLE_SET_RESET_BIT 0x80
+
+#define CPIA2_VC_INT_STATE                 0x8A
+#define CPIA2_VC_INT_STATE_XX_STATE     0x01
+#define CPIA2_VC_INT_STATE_SW_STATE     0x02
+
+#define CPIA2_VC_MP_DIR                    0x90
+#define CPIA2_VC_MP_DIR_INPUT           0x00
+#define CPIA2_VC_MP_DIR_OUTPUT          0x01
+
+#define CPIA2_VC_MP_DATA                   0x91
+
+#define CPIA2_VC_DP_CTRL                   0x98
+#define CPIA2_VC_DP_CTRL_MODE_0         0x00
+#define CPIA2_VC_DP_CTRL_MODE_A         0x01
+#define CPIA2_VC_DP_CTRL_MODE_B         0x02
+#define CPIA2_VC_DP_CTRL_MODE_C         0x03
+#define CPIA2_VC_DP_CTRL_FAKE_FST       0x04
+
+#define CPIA2_VC_AD_CTRL                   0x99
+#define CPIA2_VC_AD_CTRL_SRC_0          0x00
+#define CPIA2_VC_AD_CTRL_SRC_DIGI_A     0x01
+#define CPIA2_VC_AD_CTRL_SRC_REG        0x02
+#define CPIA2_VC_AD_CTRL_DST_USB        0x00
+#define CPIA2_VC_AD_CTRL_DST_REG        0x04
+
+#define CPIA2_VC_AD_TEST_IN                0x9B
+
+#define CPIA2_VC_AD_TEST_OUT               0x9C
+
+#define CPIA2_VC_AD_STATUS                 0x9D
+#define CPIA2_VC_AD_STATUS_EMPTY        0x01
+#define CPIA2_VC_AD_STATUS_FULL         0x02
+
+#define CPIA2_VC_DP_DATA                   0x9E
+
+#define CPIA2_VC_ST_CTRL                   0xA0
+#define CPIA2_VC_ST_CTRL_SRC_VC         0x00
+#define CPIA2_VC_ST_CTRL_SRC_DP         0x01
+#define CPIA2_VC_ST_CTRL_SRC_REG        0x02
+
+#define CPIA2_VC_ST_CTRL_RAW_SELECT     0x04
+
+#define CPIA2_VC_ST_CTRL_DST_USB        0x00
+#define CPIA2_VC_ST_CTRL_DST_DP         0x08
+#define CPIA2_VC_ST_CTRL_DST_REG        0x10
+
+#define CPIA2_VC_ST_CTRL_FIFO_ENABLE    0x20
+#define CPIA2_VC_ST_CTRL_EOF_DETECT     0x40
+
+#define CPIA2_VC_ST_TEST                   0xA1
+#define CPIA2_VC_ST_TEST_MODE_MANUAL    0x00
+#define CPIA2_VC_ST_TEST_MODE_INCREMENT 0x02
+
+#define CPIA2_VC_ST_TEST_AUTO_FILL      0x08
+
+#define CPIA2_VC_ST_TEST_REPEAT_FIFO    0x10
+
+#define CPIA2_VC_ST_TEST_IN                0xA2
+
+#define CPIA2_VC_ST_TEST_OUT               0xA3
+
+#define CPIA2_VC_ST_STATUS                 0xA4
+#define CPIA2_VC_ST_STATUS_EMPTY        0x01
+#define CPIA2_VC_ST_STATUS_FULL         0x02
+
+#define CPIA2_VC_ST_FRAME_DETECT_1         0xA5
+
+#define CPIA2_VC_ST_FRAME_DETECT_2         0xA6
+
+#define CPIA2_VC_USB_CTRL                    0xA8
+#define CPIA2_VC_USB_CTRL_CMD_STALLED      0x01
+#define CPIA2_VC_USB_CTRL_CMD_READY        0x02
+#define CPIA2_VC_USB_CTRL_CMD_STATUS       0x04
+#define CPIA2_VC_USB_CTRL_CMD_STATUS_DIR   0x08
+#define CPIA2_VC_USB_CTRL_CMD_NO_CLASH     0x10
+#define CPIA2_VC_USB_CTRL_CMD_MICRO_ACCESS 0x80
+
+#define CPIA2_VC_USB_STRM                  0xA9
+#define CPIA2_VC_USB_STRM_ISO_ENABLE    0x01
+#define CPIA2_VC_USB_STRM_BLK_ENABLE    0x02
+#define CPIA2_VC_USB_STRM_INT_ENABLE    0x04
+#define CPIA2_VC_USB_STRM_AUD_ENABLE    0x08
+
+#define CPIA2_VC_USB_STATUS                   0xAA
+#define CPIA2_VC_USB_STATUS_CMD_IN_PROGRESS  0x01
+#define CPIA2_VC_USB_STATUS_CMD_STATUS_STALL 0x02
+#define CPIA2_VC_USB_STATUS_CMD_HANDSHAKE    0x04
+#define CPIA2_VC_USB_STATUS_CMD_OVERRIDE     0x08
+#define CPIA2_VC_USB_STATUS_CMD_FIFO_BUSY    0x10
+#define CPIA2_VC_USB_STATUS_BULK_REPEAT_TXN  0x20
+#define CPIA2_VC_USB_STATUS_CONFIG_DONE      0x40
+#define CPIA2_VC_USB_STATUS_USB_SUSPEND      0x80
+
+#define CPIA2_VC_USB_CMDW                   0xAB
+
+#define CPIA2_VC_USB_DATARW                 0xAC
+
+#define CPIA2_VC_USB_INFO                   0xAD
+
+#define CPIA2_VC_USB_CONFIG                 0xAE
+
+#define CPIA2_VC_USB_SETTINGS                  0xAF
+#define CPIA2_VC_USB_SETTINGS_CONFIG_MASK    0x03
+#define CPIA2_VC_USB_SETTINGS_INTERFACE_MASK 0x0C
+#define CPIA2_VC_USB_SETTINGS_ALTERNATE_MASK 0x70
+
+#define CPIA2_VC_USB_ISOLIM                  0xB0
+
+#define CPIA2_VC_USB_ISOFAILS                0xB1
+
+#define CPIA2_VC_USB_ISOMAXPKTHI             0xB2
+
+#define CPIA2_VC_USB_ISOMAXPKTLO             0xB3
+
+#define CPIA2_VC_V2W_CTRL                    0xB8
+#define CPIA2_VC_V2W_SELECT               0x01
+
+#define CPIA2_VC_V2W_SCL                     0xB9
+
+#define CPIA2_VC_V2W_SDA                     0xBA
+
+#define CPIA2_VC_VC_CTRL                     0xC0
+#define CPIA2_VC_VC_CTRL_RUN              0x01
+#define CPIA2_VC_VC_CTRL_SINGLESHOT       0x02
+#define CPIA2_VC_VC_CTRL_IDLING           0x04
+#define CPIA2_VC_VC_CTRL_INHIBIT_H_TABLES 0x10
+#define CPIA2_VC_VC_CTRL_INHIBIT_Q_TABLES 0x20
+#define CPIA2_VC_VC_CTRL_INHIBIT_PRIVATE  0x40
+
+#define CPIA2_VC_VC_RESTART_IVAL_HI          0xC1
+
+#define CPIA2_VC_VC_RESTART_IVAL_LO          0xC2
+
+#define CPIA2_VC_VC_FORMAT                   0xC3
+#define CPIA2_VC_VC_FORMAT_UFIRST         0x01
+#define CPIA2_VC_VC_FORMAT_MONO           0x02
+#define CPIA2_VC_VC_FORMAT_DECIMATING     0x04
+#define CPIA2_VC_VC_FORMAT_SHORTLINE      0x08
+#define CPIA2_VC_VC_FORMAT_SELFTEST       0x10
+
+#define CPIA2_VC_VC_CLOCKS                         0xC4
+#define CPIA2_VC_VC_CLOCKS_CLKDIV_MASK        0x03
+#define CPIA2_VC_VC_672_CLOCKS_CIF_DIV_BY_3   0x04
+#define CPIA2_VC_VC_672_CLOCKS_SCALING        0x08
+#define CPIA2_VC_VC_CLOCKS_LOGDIV0        0x00
+#define CPIA2_VC_VC_CLOCKS_LOGDIV1        0x01
+#define CPIA2_VC_VC_CLOCKS_LOGDIV2        0x02
+#define CPIA2_VC_VC_CLOCKS_LOGDIV3        0x03
+#define CPIA2_VC_VC_676_CLOCKS_CIF_DIV_BY_3   0x08
+#define CPIA2_VC_VC_676_CLOCKS_SCALING       0x10
+
+#define CPIA2_VC_VC_IHSIZE_LO                0xC5
+
+#define CPIA2_VC_VC_XLIM_HI                  0xC6
+
+#define CPIA2_VC_VC_XLIM_LO                  0xC7
+
+#define CPIA2_VC_VC_YLIM_HI                  0xC8
+
+#define CPIA2_VC_VC_YLIM_LO                  0xC9
+
+#define CPIA2_VC_VC_OHSIZE                   0xCA
+
+#define CPIA2_VC_VC_OVSIZE                   0xCB
+
+#define CPIA2_VC_VC_HCROP                    0xCC
+
+#define CPIA2_VC_VC_VCROP                    0xCD
+
+#define CPIA2_VC_VC_HPHASE                   0xCE
+
+#define CPIA2_VC_VC_VPHASE                   0xCF
+
+#define CPIA2_VC_VC_HISPAN                   0xD0
+
+#define CPIA2_VC_VC_VISPAN                   0xD1
+
+#define CPIA2_VC_VC_HICROP                   0xD2
+
+#define CPIA2_VC_VC_VICROP                   0xD3
+
+#define CPIA2_VC_VC_HFRACT                   0xD4
+#define CPIA2_VC_VC_HFRACT_DEN_MASK       0x0F
+#define CPIA2_VC_VC_HFRACT_NUM_MASK       0xF0
+
+#define CPIA2_VC_VC_VFRACT                   0xD5
+#define CPIA2_VC_VC_VFRACT_DEN_MASK       0x0F
+#define CPIA2_VC_VC_VFRACT_NUM_MASK       0xF0
+
+#define CPIA2_VC_VC_JPEG_OPT                      0xD6
+#define CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE     0x01
+#define CPIA2_VC_VC_JPEG_OPT_NO_DC_AUTO_SQUEEZE 0x02
+#define CPIA2_VC_VC_JPEG_OPT_AUTO_SQUEEZE       0x04
+#define CPIA2_VC_VC_JPEG_OPT_DEFAULT      (CPIA2_VC_VC_JPEG_OPT_DOUBLE_SQUEEZE|\
+                                          CPIA2_VC_VC_JPEG_OPT_AUTO_SQUEEZE)
+
+
+#define CPIA2_VC_VC_CREEP_PERIOD             0xD7
+#define CPIA2_VC_VC_USER_SQUEEZE             0xD8
+#define CPIA2_VC_VC_TARGET_KB                0xD9
+
+#define CPIA2_VC_VC_AUTO_SQUEEZE             0xE6
+
+
+/***
+ * VP register set (Bank 2)
+ ***/
+#define CPIA2_VP_DEVICEH                             0
+#define CPIA2_VP_DEVICEL                             1
+
+#define CPIA2_VP_SYSTEMSTATE                         0x02
+#define CPIA2_VP_SYSTEMSTATE_HK_ALIVE             0x01
+
+#define CPIA2_VP_SYSTEMCTRL                          0x03
+#define CPIA2_VP_SYSTEMCTRL_REQ_CLEAR_ERROR       0x80
+#define CPIA2_VP_SYSTEMCTRL_POWER_DOWN_PLL        0x20
+#define CPIA2_VP_SYSTEMCTRL_REQ_SUSPEND_STATE     0x10
+#define CPIA2_VP_SYSTEMCTRL_REQ_SERIAL_WAKEUP     0x08
+#define CPIA2_VP_SYSTEMCTRL_REQ_AUTOLOAD          0x04
+#define CPIA2_VP_SYSTEMCTRL_HK_CONTROL            0x02
+#define CPIA2_VP_SYSTEMCTRL_POWER_CONTROL         0x01
+
+#define CPIA2_VP_SENSOR_FLAGS                        0x05
+#define CPIA2_VP_SENSOR_FLAGS_404                 0x01
+#define CPIA2_VP_SENSOR_FLAGS_407                 0x02
+#define CPIA2_VP_SENSOR_FLAGS_409                 0x04
+#define CPIA2_VP_SENSOR_FLAGS_410                 0x08
+#define CPIA2_VP_SENSOR_FLAGS_500                 0x10
+
+#define CPIA2_VP_SENSOR_REV                          0x06
+
+#define CPIA2_VP_DEVICE_CONFIG                       0x07
+#define CPIA2_VP_DEVICE_CONFIG_SERIAL_BRIDGE      0x01
+
+#define CPIA2_VP_GPIO_DIRECTION                      0x08
+#define CPIA2_VP_GPIO_READ                        0xFF
+#define CPIA2_VP_GPIO_WRITE                       0x00
+
+#define CPIA2_VP_GPIO_DATA                           0x09
+
+#define CPIA2_VP_RAM_ADDR_H                          0x0A
+#define CPIA2_VP_RAM_ADDR_L                          0x0B
+#define CPIA2_VP_RAM_DATA                            0x0C
+
+#define CPIA2_VP_PATCH_REV                           0x0F
+
+#define CPIA2_VP4_USER_MODE                           0x10
+#define CPIA2_VP5_USER_MODE                           0x13
+#define CPIA2_VP_USER_MODE_CIF                    0x01
+#define CPIA2_VP_USER_MODE_QCIFDS                 0x02
+#define CPIA2_VP_USER_MODE_QCIFPTC                0x04
+#define CPIA2_VP_USER_MODE_QVGADS                 0x08
+#define CPIA2_VP_USER_MODE_QVGAPTC                0x10
+#define CPIA2_VP_USER_MODE_VGA                    0x20
+
+#define CPIA2_VP4_FRAMERATE_REQUEST                    0x11
+#define CPIA2_VP5_FRAMERATE_REQUEST                    0x14
+#define CPIA2_VP_FRAMERATE_60                     0x80
+#define CPIA2_VP_FRAMERATE_50                     0x40
+#define CPIA2_VP_FRAMERATE_30                     0x20
+#define CPIA2_VP_FRAMERATE_25                     0x10
+#define CPIA2_VP_FRAMERATE_15                     0x08
+#define CPIA2_VP_FRAMERATE_12_5                   0x04
+#define CPIA2_VP_FRAMERATE_7_5                    0x02
+#define CPIA2_VP_FRAMERATE_6_25                   0x01
+
+#define CPIA2_VP4_USER_EFFECTS                         0x12
+#define CPIA2_VP5_USER_EFFECTS                         0x15
+#define CPIA2_VP_USER_EFFECTS_COLBARS             0x01
+#define CPIA2_VP_USER_EFFECTS_COLBARS_GRAD        0x02
+#define CPIA2_VP_USER_EFFECTS_MIRROR              0x04
+#define CPIA2_VP_USER_EFFECTS_FLIP                0x40  // VP5 only
+
+/* NOTE: CPIA2_VP_EXPOSURE_MODES shares the same register as VP5 User
+ * Effects */
+#define CPIA2_VP_EXPOSURE_MODES                       0x15
+#define CPIA2_VP_EXPOSURE_MODES_INHIBIT_FLICKER   0x20
+#define CPIA2_VP_EXPOSURE_MODES_COMPILE_EXP       0x10
+
+#define CPIA2_VP4_EXPOSURE_TARGET                     0x16    // VP4
+#define CPIA2_VP5_EXPOSURE_TARGET                    0x20    // VP5
+
+#define CPIA2_VP_FLICKER_MODES                        0x1B
+#define CPIA2_VP_FLICKER_MODES_50HZ               0x80
+#define CPIA2_VP_FLICKER_MODES_CUSTOM_FLT_FFREQ   0x40
+#define CPIA2_VP_FLICKER_MODES_NEVER_FLICKER      0x20
+#define CPIA2_VP_FLICKER_MODES_INHIBIT_RUB        0x10
+#define CPIA2_VP_FLICKER_MODES_ADJUST_LINE_FREQ   0x08
+#define CPIA2_VP_FLICKER_MODES_CUSTOM_INT_FFREQ   0x04
+
+#define CPIA2_VP_UMISC                                0x1D
+#define CPIA2_VP_UMISC_FORCE_MONO                 0x80
+#define CPIA2_VP_UMISC_FORCE_ID_MASK              0x40
+#define CPIA2_VP_UMISC_INHIBIT_AUTO_FGS           0x20
+#define CPIA2_VP_UMISC_INHIBIT_AUTO_DIMS          0x08
+#define CPIA2_VP_UMISC_OPT_FOR_SENSOR_DS          0x04
+#define CPIA2_VP_UMISC_INHIBIT_AUTO_MODE_INT      0x02
+
+#define CPIA2_VP5_ANTIFLKRSETUP                       0x22  //34
+
+#define CPIA2_VP_INTERPOLATION                        0x24
+#define CPIA2_VP_INTERPOLATION_EVEN_FIRST         0x40
+#define CPIA2_VP_INTERPOLATION_HJOG               0x20
+#define CPIA2_VP_INTERPOLATION_VJOG               0x10
+
+#define CPIA2_VP_GAMMA                                0x25
+#define CPIA2_VP_DEFAULT_GAMMA                    0x10
+
+#define CPIA2_VP_YRANGE                               0x26
+
+#define CPIA2_VP_SATURATION                           0x27
+
+#define CPIA2_VP5_MYBLACK_LEVEL                       0x3A   //58
+#define CPIA2_VP5_MCYRANGE                            0x3B   //59
+#define CPIA2_VP5_MYCEILING                           0x3C   //60
+#define CPIA2_VP5_MCUVSATURATION                      0x3D   //61
+
+
+#define CPIA2_VP_REHASH_VALUES                        0x60
+
+
+/***
+ * Common sensor registers
+ ***/
+#define CPIA2_SENSOR_DEVICE_H                         0x00
+#define CPIA2_SENSOR_DEVICE_L                         0x01
+
+#define CPIA2_SENSOR_DATA_FORMAT                      0x16
+#define CPIA2_SENSOR_DATA_FORMAT_HMIRROR      0x08
+#define CPIA2_SENSOR_DATA_FORMAT_VMIRROR      0x10
+
+#define CPIA2_SENSOR_CR1                              0x76
+#define CPIA2_SENSOR_CR1_STAND_BY             0x01
+#define CPIA2_SENSOR_CR1_DOWN_RAMP_GEN        0x02
+#define CPIA2_SENSOR_CR1_DOWN_COLUMN_ADC      0x04
+#define CPIA2_SENSOR_CR1_DOWN_CAB_REGULATOR   0x08
+#define CPIA2_SENSOR_CR1_DOWN_AUDIO_REGULATOR 0x10
+#define CPIA2_SENSOR_CR1_DOWN_VRT_AMP         0x20
+#define CPIA2_SENSOR_CR1_DOWN_BAND_GAP        0x40
+
+#endif
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c
new file mode 100644 (file)
index 0000000..f4da029
--- /dev/null
@@ -0,0 +1,907 @@
+/****************************************************************************
+ *
+ *  Filename: cpia2_usb.c
+ *
+ *  Copyright 2001, STMicrolectronics, Inc.
+ *      Contact:  steve.miller@st.com
+ *
+ *  Description:
+ *     This is a USB driver for CPia2 based video cameras.
+ *     The infrastructure of this driver is based on the cpia usb driver by
+ *     Jochen Scharrlach and Johannes Erdfeldt.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Stripped of 2.4 stuff ready for main kernel submit by
+ *             Alan Cox <alan@redhat.com>
+ ****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+
+#include "cpia2.h"
+
+static int frame_sizes[] = {
+       0,      // USBIF_CMDONLY
+       0,      // USBIF_BULK
+       128,    // USBIF_ISO_1
+       384,    // USBIF_ISO_2
+       640,    // USBIF_ISO_3
+       768,    // USBIF_ISO_4
+       896,    // USBIF_ISO_5
+       1023,   // USBIF_ISO_6
+};
+
+#define FRAMES_PER_DESC    10
+#define FRAME_SIZE_PER_DESC   frame_sizes[cam->cur_alt]
+
+static void process_frame(struct camera_data *cam);
+static void cpia2_usb_complete(struct urb *urb, struct pt_regs *);
+static int cpia2_usb_probe(struct usb_interface *intf,
+                          const struct usb_device_id *id);
+static void cpia2_usb_disconnect(struct usb_interface *intf);
+
+static void free_sbufs(struct camera_data *cam);
+static void add_APPn(struct camera_data *cam);
+static void add_COM(struct camera_data *cam);
+static int submit_urbs(struct camera_data *cam);
+static int set_alternate(struct camera_data *cam, unsigned int alt);
+static int configure_transfer_mode(struct camera_data *cam, unsigned int alt);
+
+static struct usb_device_id cpia2_id_table[] = {
+       {USB_DEVICE(0x0553, 0x0100)},
+       {USB_DEVICE(0x0553, 0x0140)},
+       {USB_DEVICE(0x0553, 0x0151)},  /* STV0676 */
+       {}                      /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, cpia2_id_table);
+
+static struct usb_driver cpia2_driver = {
+       .name           = "cpia2",
+       .probe          = cpia2_usb_probe,
+       .disconnect     = cpia2_usb_disconnect,
+       .id_table       = cpia2_id_table
+};
+
+
+/******************************************************************************
+ *
+ *  process_frame
+ *
+ *****************************************************************************/
+static void process_frame(struct camera_data *cam)
+{
+       static int frame_count = 0;
+
+       unsigned char *inbuff = cam->workbuff->data;
+
+       DBG("Processing frame #%d, current:%d\n",
+           cam->workbuff->num, cam->curbuff->num);
+
+       if(cam->workbuff->length > cam->workbuff->max_length)
+               cam->workbuff->max_length = cam->workbuff->length;
+
+       if ((inbuff[0] == 0xFF) && (inbuff[1] == 0xD8)) {
+               frame_count++;
+       } else {
+               cam->workbuff->status = FRAME_ERROR;
+               DBG("Start of frame not found\n");
+               return;
+       }
+
+       /***
+        * Now the output buffer should have a JPEG image in it.
+        ***/
+       if(!cam->first_image_seen) {
+               /* Always skip the first image after streaming
+                * starts. It is almost certainly corrupt. */
+               cam->first_image_seen = 1;
+               cam->workbuff->status = FRAME_EMPTY;
+               return;
+       }
+       if (cam->workbuff->length > 3) {
+               if(cam->mmapped &&
+                  cam->workbuff->length < cam->workbuff->max_length) {
+                       /* No junk in the buffers */
+                       memset(cam->workbuff->data+cam->workbuff->length,
+                              0, cam->workbuff->max_length-
+                                 cam->workbuff->length);
+               }
+               cam->workbuff->max_length = cam->workbuff->length;
+               cam->workbuff->status = FRAME_READY;
+
+               if(!cam->mmapped && cam->num_frames > 2) {
+                       /* During normal reading, the most recent
+                        * frame will be read.  If the current frame
+                        * hasn't started reading yet, it will never
+                        * be read, so mark it empty.  If the buffer is
+                        * mmapped, or we have few buffers, we need to
+                        * wait for the user to free the buffer.
+                        *
+                        * NOTE: This is not entirely foolproof with 3
+                        * buffers, but it would take an EXTREMELY
+                        * overloaded system to cause problems (possible
+                        * image data corruption).  Basically, it would
+                        * need to take more time to execute cpia2_read
+                        * than it would for the camera to send
+                        * cam->num_frames-2 frames before problems
+                        * could occur.
+                        */
+                       cam->curbuff->status = FRAME_EMPTY;
+               }
+               cam->curbuff = cam->workbuff;
+               cam->workbuff = cam->workbuff->next;
+               DBG("Changed buffers, work:%d, current:%d\n",
+                   cam->workbuff->num, cam->curbuff->num);
+               return;
+       } else {
+               DBG("Not enough data for an image.\n");
+       }
+
+       cam->workbuff->status = FRAME_ERROR;
+       return;
+}
+
+/******************************************************************************
+ *
+ *  add_APPn
+ *
+ *  Adds a user specified APPn record
+ *****************************************************************************/
+static void add_APPn(struct camera_data *cam)
+{
+       if(cam->APP_len > 0) {
+               cam->workbuff->data[cam->workbuff->length++] = 0xFF;
+               cam->workbuff->data[cam->workbuff->length++] = 0xE0+cam->APPn;
+               cam->workbuff->data[cam->workbuff->length++] = 0;
+               cam->workbuff->data[cam->workbuff->length++] = cam->APP_len+2;
+               memcpy(cam->workbuff->data+cam->workbuff->length,
+                      cam->APP_data, cam->APP_len);
+               cam->workbuff->length += cam->APP_len;
+       }
+}
+
+/******************************************************************************
+ *
+ *  add_COM
+ *
+ *  Adds a user specified COM record
+ *****************************************************************************/
+static void add_COM(struct camera_data *cam)
+{
+       if(cam->COM_len > 0) {
+               cam->workbuff->data[cam->workbuff->length++] = 0xFF;
+               cam->workbuff->data[cam->workbuff->length++] = 0xFE;
+               cam->workbuff->data[cam->workbuff->length++] = 0;
+               cam->workbuff->data[cam->workbuff->length++] = cam->COM_len+2;
+               memcpy(cam->workbuff->data+cam->workbuff->length,
+                      cam->COM_data, cam->COM_len);
+               cam->workbuff->length += cam->COM_len;
+       }
+}
+
+/******************************************************************************
+ *
+ *  cpia2_usb_complete
+ *
+ *  callback when incoming packet is received
+ *****************************************************************************/
+static void cpia2_usb_complete(struct urb *urb, struct pt_regs *regs)
+{
+       int i;
+       unsigned char *cdata;
+       static int frame_ready = false;
+       struct camera_data *cam = (struct camera_data *) urb->context;
+
+       if (urb->status!=0) {
+               if (!(urb->status == -ENOENT ||
+                     urb->status == -ECONNRESET ||
+                     urb->status == -ESHUTDOWN))
+               {
+                       DBG("urb->status = %d!\n", urb->status);
+               }
+               DBG("Stopping streaming\n");
+               return;
+       }
+
+       if (!cam->streaming || !cam->present || cam->open_count == 0) {
+               LOG("Will now stop the streaming: streaming = %d, "
+                   "present=%d, open_count=%d\n",
+                   cam->streaming, cam->present, cam->open_count);
+               return;
+       }
+
+       /***
+        * Packet collater
+        ***/
+       //DBG("Collating %d packets\n", urb->number_of_packets);
+       for (i = 0; i < urb->number_of_packets; i++) {
+               u16 checksum, iso_checksum;
+               int j;
+               int n = urb->iso_frame_desc[i].actual_length;
+               int st = urb->iso_frame_desc[i].status;
+
+               if(cam->workbuff->status == FRAME_READY) {
+                       struct framebuf *ptr;
+                       /* Try to find an available buffer */
+                       DBG("workbuff full, searching\n");
+                       for (ptr = cam->workbuff->next;
+                            ptr != cam->workbuff;
+                            ptr = ptr->next)
+                       {
+                               if (ptr->status == FRAME_EMPTY) {
+                                       ptr->status = FRAME_READING;
+                                       ptr->length = 0;
+                                       break;
+                               }
+                       }
+                       if (ptr == cam->workbuff)
+                               break; /* No READING or EMPTY buffers left */
+
+                       cam->workbuff = ptr;
+               }
+
+               if (cam->workbuff->status == FRAME_EMPTY ||
+                   cam->workbuff->status == FRAME_ERROR) {
+                       cam->workbuff->status = FRAME_READING;
+                       cam->workbuff->length = 0;
+               }
+
+               //DBG("   Packet %d length = %d, status = %d\n", i, n, st);
+               cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+
+               if (st) {
+                       LOG("cpia2 data error: [%d] len=%d, status = %d\n",
+                           i, n, st);
+                       if(!ALLOW_CORRUPT)
+                               cam->workbuff->status = FRAME_ERROR;
+                       continue;
+               }
+
+               if(n<=2)
+                       continue;
+
+               checksum = 0;
+               for(j=0; j<n-2; ++j)
+                       checksum += cdata[j];
+               iso_checksum = cdata[j] + cdata[j+1]*256;
+               if(checksum != iso_checksum) {
+                       LOG("checksum mismatch: [%d] len=%d, calculated = %x, checksum = %x\n",
+                           i, n, (int)checksum, (int)iso_checksum);
+                       if(!ALLOW_CORRUPT) {
+                               cam->workbuff->status = FRAME_ERROR;
+                               continue;
+                       }
+               }
+               n -= 2;
+
+               if(cam->workbuff->status != FRAME_READING) {
+                       if((0xFF == cdata[0] && 0xD8 == cdata[1]) ||
+                          (0xD8 == cdata[0] && 0xFF == cdata[1] &&
+                           0 != cdata[2])) {
+                               /* frame is skipped, but increment total
+                                * frame count anyway */
+                               cam->frame_count++;
+                       }
+                       DBG("workbuff not reading, status=%d\n",
+                           cam->workbuff->status);
+                       continue;
+               }
+
+               if (cam->frame_size < cam->workbuff->length + n) {
+                       ERR("buffer overflow! length: %d, n: %d\n",
+                           cam->workbuff->length, n);
+                       cam->workbuff->status = FRAME_ERROR;
+                       if(cam->workbuff->length > cam->workbuff->max_length)
+                               cam->workbuff->max_length =
+                                       cam->workbuff->length;
+                       continue;
+               }
+
+               if (cam->workbuff->length == 0) {
+                       int data_offset;
+                       if ((0xD8 == cdata[0]) && (0xFF == cdata[1])) {
+                               data_offset = 1;
+                       } else if((0xFF == cdata[0]) && (0xD8 == cdata[1])
+                                 && (0xFF == cdata[2])) {
+                               data_offset = 2;
+                       } else {
+                               DBG("Ignoring packet, not beginning!\n");
+                               continue;
+                       }
+                       DBG("Start of frame pattern found\n");
+                       do_gettimeofday(&cam->workbuff->timestamp);
+                       cam->workbuff->seq = cam->frame_count++;
+                       cam->workbuff->data[0] = 0xFF;
+                       cam->workbuff->data[1] = 0xD8;
+                       cam->workbuff->length = 2;
+                       add_APPn(cam);
+                       add_COM(cam);
+                       memcpy(cam->workbuff->data+cam->workbuff->length,
+                              cdata+data_offset, n-data_offset);
+                       cam->workbuff->length += n-data_offset;
+               } else if (cam->workbuff->length > 0) {
+                       memcpy(cam->workbuff->data + cam->workbuff->length,
+                              cdata, n);
+                       cam->workbuff->length += n;
+               }
+
+               if ((cam->workbuff->length >= 3) &&
+                   (cam->workbuff->data[cam->workbuff->length - 3] == 0xFF) &&
+                   (cam->workbuff->data[cam->workbuff->length - 2] == 0xD9) &&
+                   (cam->workbuff->data[cam->workbuff->length - 1] == 0xFF)) {
+                       frame_ready = true;
+                       cam->workbuff->data[cam->workbuff->length - 1] = 0;
+                       cam->workbuff->length -= 1;
+               } else if ((cam->workbuff->length >= 2) &&
+                  (cam->workbuff->data[cam->workbuff->length - 2] == 0xFF) &&
+                  (cam->workbuff->data[cam->workbuff->length - 1] == 0xD9)) {
+                       frame_ready = true;
+               }
+
+               if (frame_ready) {
+                       DBG("Workbuff image size = %d\n",cam->workbuff->length);
+                       process_frame(cam);
+
+                       frame_ready = false;
+
+                       if (waitqueue_active(&cam->wq_stream))
+                               wake_up_interruptible(&cam->wq_stream);
+               }
+       }
+
+       if(cam->streaming) {
+               /* resubmit */
+               urb->dev = cam->dev;
+               if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0)
+                       ERR("%s: usb_submit_urb ret %d!\n", __func__, i);
+       }
+}
+
+/******************************************************************************
+ *
+ * configure_transfer_mode
+ *
+ *****************************************************************************/
+static int configure_transfer_mode(struct camera_data *cam, unsigned int alt)
+{
+       static unsigned char iso_regs[8][4] = {
+               {0x00, 0x00, 0x00, 0x00},
+               {0x00, 0x00, 0x00, 0x00},
+               {0xB9, 0x00, 0x00, 0x7E},
+               {0xB9, 0x00, 0x01, 0x7E},
+               {0xB9, 0x00, 0x02, 0x7E},
+               {0xB9, 0x00, 0x02, 0xFE},
+               {0xB9, 0x00, 0x03, 0x7E},
+               {0xB9, 0x00, 0x03, 0xFD}
+       };
+       struct cpia2_command cmd;
+       unsigned char reg;
+
+       if(!cam->present)
+               return -ENODEV;
+
+       /***
+        * Write the isoc registers according to the alternate selected
+        ***/
+       cmd.direction = TRANSFER_WRITE;
+       cmd.buffer.block_data[0] = iso_regs[alt][0];
+       cmd.buffer.block_data[1] = iso_regs[alt][1];
+       cmd.buffer.block_data[2] = iso_regs[alt][2];
+       cmd.buffer.block_data[3] = iso_regs[alt][3];
+       cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
+       cmd.start = CPIA2_VC_USB_ISOLIM;
+       cmd.reg_count = 4;
+       cpia2_send_command(cam, &cmd);
+
+       /***
+        * Enable relevant streams before starting polling.
+        * First read USB Stream Config Register.
+        ***/
+       cmd.direction = TRANSFER_READ;
+       cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
+       cmd.start = CPIA2_VC_USB_STRM;
+       cmd.reg_count = 1;
+       cpia2_send_command(cam, &cmd);
+       reg = cmd.buffer.block_data[0];
+
+       /* Clear iso, bulk, and int */
+       reg &= ~(CPIA2_VC_USB_STRM_BLK_ENABLE |
+                CPIA2_VC_USB_STRM_ISO_ENABLE |
+                CPIA2_VC_USB_STRM_INT_ENABLE);
+
+       if (alt == USBIF_BULK) {
+               DBG("Enabling bulk xfer\n");
+               reg |= CPIA2_VC_USB_STRM_BLK_ENABLE;    /* Enable Bulk */
+               cam->xfer_mode = XFER_BULK;
+       } else if (alt >= USBIF_ISO_1) {
+               DBG("Enabling ISOC xfer\n");
+               reg |= CPIA2_VC_USB_STRM_ISO_ENABLE;
+               cam->xfer_mode = XFER_ISOC;
+       }
+
+       cmd.buffer.block_data[0] = reg;
+       cmd.direction = TRANSFER_WRITE;
+       cmd.start = CPIA2_VC_USB_STRM;
+       cmd.reg_count = 1;
+       cmd.req_mode = CAMERAACCESS_TYPE_BLOCK | CAMERAACCESS_VC;
+       cpia2_send_command(cam, &cmd);
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ * cpia2_usb_change_streaming_alternate
+ *
+ *****************************************************************************/
+int cpia2_usb_change_streaming_alternate(struct camera_data *cam,
+                                        unsigned int alt)
+{
+       int ret = 0;
+
+       if(alt < USBIF_ISO_1 || alt > USBIF_ISO_6)
+               return -EINVAL;
+
+       if(alt == cam->params.camera_state.stream_mode)
+               return 0;
+
+       cpia2_usb_stream_pause(cam);
+
+       configure_transfer_mode(cam, alt);
+
+       cam->params.camera_state.stream_mode = alt;
+
+       /* Reset the camera to prevent image quality degradation */
+       cpia2_reset_camera(cam);
+
+       cpia2_usb_stream_resume(cam);
+
+       return ret;
+}
+
+/******************************************************************************
+ *
+ * set_alternate
+ *
+ *****************************************************************************/
+int set_alternate(struct camera_data *cam, unsigned int alt)
+{
+       int ret = 0;
+
+       if(alt == cam->cur_alt)
+               return 0;
+
+       if (cam->cur_alt != USBIF_CMDONLY) {
+               DBG("Changing from alt %d to %d\n", cam->cur_alt, USBIF_CMDONLY);
+               ret = usb_set_interface(cam->dev, cam->iface, USBIF_CMDONLY);
+               if (ret != 0)
+                       return ret;
+       }
+       if (alt != USBIF_CMDONLY) {
+               DBG("Changing from alt %d to %d\n", USBIF_CMDONLY, alt);
+               ret = usb_set_interface(cam->dev, cam->iface, alt);
+               if (ret != 0)
+                       return ret;
+       }
+
+       cam->old_alt = cam->cur_alt;
+       cam->cur_alt = alt;
+
+       return ret;
+}
+
+/******************************************************************************
+ *
+ * free_sbufs
+ *
+ * Free all cam->sbuf[]. All non-NULL .data and .urb members that are non-NULL
+ * are assumed to be allocated. Non-NULL .urb members are also assumed to be
+ * submitted (and must therefore be killed before they are freed).
+ *****************************************************************************/
+static void free_sbufs(struct camera_data *cam)
+{
+       int i;
+
+       for (i = 0; i < NUM_SBUF; i++) {
+               if(cam->sbuf[i].urb) {
+                       usb_kill_urb(cam->sbuf[i].urb);
+                       usb_free_urb(cam->sbuf[i].urb);
+                       cam->sbuf[i].urb = NULL;
+               }
+               if(cam->sbuf[i].data) {
+                       kfree(cam->sbuf[i].data);
+                       cam->sbuf[i].data = NULL;
+               }
+       }
+}
+
+/*******
+* Convenience functions
+*******/
+/****************************************************************************
+ *
+ *  write_packet
+ *
+ ***************************************************************************/
+static int write_packet(struct usb_device *udev,
+                       u8 request, u8 * registers, u16 start, size_t size)
+{
+       if (!registers || size <= 0)
+               return -EINVAL;
+
+       return usb_control_msg(udev,
+                              usb_sndctrlpipe(udev, 0),
+                              request,
+                              USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                              start,   /* value */
+                              0,       /* index */
+                              registers,       /* buffer */
+                              size,
+                              HZ);
+}
+
+/****************************************************************************
+ *
+ *  read_packet
+ *
+ ***************************************************************************/
+static int read_packet(struct usb_device *udev,
+                      u8 request, u8 * registers, u16 start, size_t size)
+{
+       if (!registers || size <= 0)
+               return -EINVAL;
+
+       return usb_control_msg(udev,
+                              usb_rcvctrlpipe(udev, 0),
+                              request,
+                              USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
+                              start,   /* value */
+                              0,       /* index */
+                              registers,       /* buffer */
+                              size,
+                              HZ);
+}
+
+/******************************************************************************
+ *
+ *  cpia2_usb_transfer_cmd
+ *
+ *****************************************************************************/
+int cpia2_usb_transfer_cmd(struct camera_data *cam,
+                          void *registers,
+                          u8 request, u8 start, u8 count, u8 direction)
+{
+       int err = 0;
+       struct usb_device *udev = cam->dev;
+
+       if (!udev) {
+               ERR("%s: Internal driver error: udev is NULL\n", __func__);
+               return -EINVAL;
+       }
+
+       if (!registers) {
+               ERR("%s: Internal driver error: register array is NULL\n", __func__);
+               return -EINVAL;
+       }
+
+       if (direction == TRANSFER_READ) {
+               err = read_packet(udev, request, (u8 *)registers, start, count);
+               if (err > 0)
+                       err = 0;
+       } else if (direction == TRANSFER_WRITE) {
+               err =write_packet(udev, request, (u8 *)registers, start, count);
+               if (err < 0) {
+                       LOG("Control message failed, err val = %d\n", err);
+                       LOG("Message: request = 0x%0X, start = 0x%0X\n",
+                           request, start);
+                       LOG("Message: count = %d, register[0] = 0x%0X\n",
+                           count, ((unsigned char *) registers)[0]);
+               } else
+                       err=0;
+       } else {
+               LOG("Unexpected first byte of direction: %d\n",
+                      direction);
+               return -EINVAL;
+       }
+
+       if(err != 0)
+               LOG("Unexpected error: %d\n", err);
+       return err;
+}
+
+
+/******************************************************************************
+ *
+ *  submit_urbs
+ *
+ *****************************************************************************/
+static int submit_urbs(struct camera_data *cam)
+{
+       struct urb *urb;
+       int fx, err, i;
+
+       for(i=0; i<NUM_SBUF; ++i) {
+               if (cam->sbuf[i].data)
+                       continue;
+               cam->sbuf[i].data =
+                   kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
+               if (!cam->sbuf[i].data) {
+                       return -ENOMEM;
+               }
+       }
+
+       /* We double buffer the Isoc lists, and also know the polling
+        * interval is every frame (1 == (1 << (bInterval -1))).
+        */
+       for(i=0; i<NUM_SBUF; ++i) {
+               if(cam->sbuf[i].urb) {
+                       continue;
+               }
+               urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
+               if (!urb) {
+                       return -ENOMEM;
+               }
+
+               cam->sbuf[i].urb = urb;
+               urb->dev = cam->dev;
+               urb->context = cam;
+               urb->pipe = usb_rcvisocpipe(cam->dev, 1 /*ISOC endpoint*/);
+               urb->transfer_flags = URB_ISO_ASAP;
+               urb->transfer_buffer = cam->sbuf[i].data;
+               urb->complete = cpia2_usb_complete;
+               urb->number_of_packets = FRAMES_PER_DESC;
+               urb->interval = 1;
+               urb->transfer_buffer_length =
+                       FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
+
+               for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
+                       urb->iso_frame_desc[fx].offset =
+                               FRAME_SIZE_PER_DESC * fx;
+                       urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
+               }
+       }
+
+
+       /* Queue the ISO urbs, and resubmit in the completion handler */
+       for(i=0; i<NUM_SBUF; ++i) {
+               err = usb_submit_urb(cam->sbuf[i].urb, GFP_KERNEL);
+               if (err) {
+                       ERR("usb_submit_urb[%d]() = %d\n", i, err);
+                       return err;
+               }
+       }
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_usb_stream_start
+ *
+ *****************************************************************************/
+int cpia2_usb_stream_start(struct camera_data *cam, unsigned int alternate)
+{
+       int ret;
+       int old_alt;
+
+       if(cam->streaming)
+               return 0;
+
+       if (cam->flush) {
+               int i;
+               DBG("Flushing buffers\n");
+               for(i=0; i<cam->num_frames; ++i) {
+                       cam->buffers[i].status = FRAME_EMPTY;
+                       cam->buffers[i].length = 0;
+               }
+               cam->curbuff = &cam->buffers[0];
+               cam->workbuff = cam->curbuff->next;
+               cam->flush = false;
+       }
+
+       old_alt = cam->params.camera_state.stream_mode;
+       cam->params.camera_state.stream_mode = 0;
+       ret = cpia2_usb_change_streaming_alternate(cam, alternate);
+       if (ret < 0) {
+               int ret2;
+               ERR("cpia2_usb_change_streaming_alternate() = %d!\n", ret);
+               cam->params.camera_state.stream_mode = old_alt;
+               ret2 = set_alternate(cam, USBIF_CMDONLY);
+               if (ret2 < 0) {
+                       ERR("cpia2_usb_change_streaming_alternate(%d) =%d has already "
+                           "failed. Then tried to call "
+                           "set_alternate(USBIF_CMDONLY) = %d.\n",
+                           alternate, ret, ret2);
+               }
+       } else {
+               cam->frame_count = 0;
+               cam->streaming = 1;
+               ret = cpia2_usb_stream_resume(cam);
+       }
+       return ret;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_usb_stream_pause
+ *
+ *****************************************************************************/
+int cpia2_usb_stream_pause(struct camera_data *cam)
+{
+       int ret = 0;
+       if(cam->streaming) {
+               ret = set_alternate(cam, USBIF_CMDONLY);
+               free_sbufs(cam);
+       }
+       return ret;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_usb_stream_resume
+ *
+ *****************************************************************************/
+int cpia2_usb_stream_resume(struct camera_data *cam)
+{
+       int ret = 0;
+       if(cam->streaming) {
+               cam->first_image_seen = 0;
+               ret = set_alternate(cam, cam->params.camera_state.stream_mode);
+               if(ret == 0) {
+                       ret = submit_urbs(cam);
+               }
+       }
+       return ret;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_usb_stream_stop
+ *
+ *****************************************************************************/
+int cpia2_usb_stream_stop(struct camera_data *cam)
+{
+       int ret;
+       ret = cpia2_usb_stream_pause(cam);
+       cam->streaming = 0;
+       configure_transfer_mode(cam, 0);
+       return ret;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_usb_probe
+ *
+ *  Probe and initialize.
+ *****************************************************************************/
+static int cpia2_usb_probe(struct usb_interface *intf,
+                          const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct usb_interface_descriptor *interface;
+       struct camera_data *cam;
+       int ret;
+
+       /* A multi-config CPiA2 camera? */
+       if (udev->descriptor.bNumConfigurations != 1)
+               return -ENODEV;
+       interface = &intf->cur_altsetting->desc;
+
+       /* If we get to this point, we found a CPiA2 camera */
+       LOG("CPiA2 USB camera found\n");
+
+       if((cam = cpia2_init_camera_struct()) == NULL)
+               return -ENOMEM;
+
+       cam->dev = udev;
+       cam->iface = interface->bInterfaceNumber;
+
+       ret = set_alternate(cam, USBIF_CMDONLY);
+       if (ret < 0) {
+               ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret);
+               kfree(cam);
+               return ret;
+       }
+
+       if ((ret = cpia2_register_camera(cam)) < 0) {
+               ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret);
+               kfree(cam);
+               return ret;
+       }
+
+
+       if((ret = cpia2_init_camera(cam)) < 0) {
+               ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret);
+               cpia2_unregister_camera(cam);
+               kfree(cam);
+               return ret;
+       }
+       LOG("  CPiA Version: %d.%02d (%d.%d)\n",
+              cam->params.version.firmware_revision_hi,
+              cam->params.version.firmware_revision_lo,
+              cam->params.version.asic_id,
+              cam->params.version.asic_rev);
+       LOG("  CPiA PnP-ID: %04x:%04x:%04x\n",
+              cam->params.pnp_id.vendor,
+              cam->params.pnp_id.product,
+              cam->params.pnp_id.device_revision);
+       LOG("  SensorID: %d.(version %d)\n",
+              cam->params.version.sensor_flags,
+              cam->params.version.sensor_rev);
+
+       usb_set_intfdata(intf, cam);
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_disconnect
+ *
+ *****************************************************************************/
+static void cpia2_usb_disconnect(struct usb_interface *intf)
+{
+       struct camera_data *cam = usb_get_intfdata(intf);
+       usb_set_intfdata(intf, NULL);
+       cam->present = 0;
+
+       DBG("Stopping stream\n");
+       cpia2_usb_stream_stop(cam);
+
+       DBG("Unregistering camera\n");
+       cpia2_unregister_camera(cam);
+
+       if(cam->buffers) {
+               DBG("Wakeup waiting processes\n");
+               cam->curbuff->status = FRAME_READY;
+               cam->curbuff->length = 0;
+               if (waitqueue_active(&cam->wq_stream))
+                       wake_up_interruptible(&cam->wq_stream);
+       }
+
+       DBG("Releasing interface\n");
+       usb_driver_release_interface(&cpia2_driver, intf);
+
+       if (cam->open_count == 0) {
+               DBG("Freeing camera structure\n");
+               kfree(cam);
+       }
+
+       LOG("CPiA2 camera disconnected.\n");
+}
+
+
+/******************************************************************************
+ *
+ *  usb_cpia2_init
+ *
+ *****************************************************************************/
+int cpia2_usb_init(void)
+{
+       return usb_register(&cpia2_driver);
+}
+
+/******************************************************************************
+ *
+ *  usb_cpia_cleanup
+ *
+ *****************************************************************************/
+void cpia2_usb_cleanup(void)
+{
+       schedule_timeout(2 * HZ);
+       usb_deregister(&cpia2_driver);
+}
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
new file mode 100644 (file)
index 0000000..08f8be3
--- /dev/null
@@ -0,0 +1,2079 @@
+/****************************************************************************
+ *
+ *  Filename: cpia2_v4l.c
+ *
+ *  Copyright 2001, STMicrolectronics, Inc.
+ *      Contact:  steve.miller@st.com
+ *  Copyright 2001,2005, Scott J. Bertin <scottbertin@yahoo.com>
+ *
+ *  Description:
+ *     This is a USB driver for CPia2 based video cameras.
+ *     The infrastructure of this driver is based on the cpia usb driver by
+ *     Jochen Scharrlach and Johannes Erdfeldt.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Stripped of 2.4 stuff ready for main kernel submit by
+ *             Alan Cox <alan@redhat.com>
+ ****************************************************************************/
+
+#include <linux/version.h>
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+
+#include "cpia2.h"
+#include "cpia2dev.h"
+
+
+//#define _CPIA2_DEBUG_
+
+#define MAKE_STRING_1(x)       #x
+#define MAKE_STRING(x) MAKE_STRING_1(x)
+
+static int video_nr = -1;
+module_param(video_nr, int, 0);
+MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)");
+
+static int buffer_size = 68*1024;
+module_param(buffer_size, int, 0);
+MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)");
+
+static int num_buffers = 3;
+module_param(num_buffers, int, 0);
+MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-"
+                MAKE_STRING(VIDEO_MAX_FRAME) ", default 3)");
+
+static int alternate = DEFAULT_ALT;
+module_param(alternate, int, 0);
+MODULE_PARM_DESC(alternate, "USB Alternate (" MAKE_STRING(USBIF_ISO_1) "-"
+                MAKE_STRING(USBIF_ISO_6) ", default "
+                MAKE_STRING(DEFAULT_ALT) ")");
+
+static int flicker_freq = 60;
+module_param(flicker_freq, int, 0);
+MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" MAKE_STRING(50) "or"
+                MAKE_STRING(60) ", default "
+                MAKE_STRING(60) ")");
+
+static int flicker_mode = NEVER_FLICKER;
+module_param(flicker_mode, int, 0);
+MODULE_PARM_DESC(flicker_mode,
+                "Flicker supression (" MAKE_STRING(NEVER_FLICKER) "or"
+                MAKE_STRING(ANTI_FLICKER_ON) ", default "
+                MAKE_STRING(NEVER_FLICKER) ")");
+
+MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>");
+MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras");
+MODULE_SUPPORTED_DEVICE("video");
+MODULE_LICENSE("GPL");
+
+#define ABOUT "V4L-Driver for Vision CPiA2 based cameras"
+
+#ifndef VID_HARDWARE_CPIA2
+#error "VID_HARDWARE_CPIA2 should have been defined in linux/videodev.h"
+#endif
+
+struct control_menu_info {
+       int value;
+       char name[32];
+};
+
+static struct control_menu_info framerate_controls[] =
+{
+       { CPIA2_VP_FRAMERATE_6_25, "6.25 fps" },
+       { CPIA2_VP_FRAMERATE_7_5,  "7.5 fps"  },
+       { CPIA2_VP_FRAMERATE_12_5, "12.5 fps" },
+       { CPIA2_VP_FRAMERATE_15,   "15 fps"   },
+       { CPIA2_VP_FRAMERATE_25,   "25 fps"   },
+       { CPIA2_VP_FRAMERATE_30,   "30 fps"   },
+};
+#define NUM_FRAMERATE_CONTROLS (sizeof(framerate_controls)/sizeof(framerate_controls[0]))
+
+static struct control_menu_info flicker_controls[] =
+{
+       { NEVER_FLICKER, "Off" },
+       { FLICKER_50,    "50 Hz" },
+       { FLICKER_60,    "60 Hz"  },
+};
+#define NUM_FLICKER_CONTROLS (sizeof(flicker_controls)/sizeof(flicker_controls[0]))
+
+static struct control_menu_info lights_controls[] =
+{
+       { 0,   "Off" },
+       { 64,  "Top" },
+       { 128, "Bottom"  },
+       { 192, "Both"  },
+};
+#define NUM_LIGHTS_CONTROLS (sizeof(lights_controls)/sizeof(lights_controls[0]))
+#define GPIO_LIGHTS_MASK 192
+
+static struct v4l2_queryctrl controls[] = {
+       {
+               .id            = V4L2_CID_BRIGHTNESS,
+               .type          = V4L2_CTRL_TYPE_INTEGER,
+               .name          = "Brightness",
+               .minimum       = 0,
+               .maximum       = 255,
+               .step          = 1,
+               .default_value = DEFAULT_BRIGHTNESS,
+       },
+       {
+               .id            = V4L2_CID_CONTRAST,
+               .type          = V4L2_CTRL_TYPE_INTEGER,
+               .name          = "Contrast",
+               .minimum       = 0,
+               .maximum       = 255,
+               .step          = 1,
+               .default_value = DEFAULT_CONTRAST,
+       },
+       {
+               .id            = V4L2_CID_SATURATION,
+               .type          = V4L2_CTRL_TYPE_INTEGER,
+               .name          = "Saturation",
+               .minimum       = 0,
+               .maximum       = 255,
+               .step          = 1,
+               .default_value = DEFAULT_SATURATION,
+       },
+       {
+               .id            = V4L2_CID_HFLIP,
+               .type          = V4L2_CTRL_TYPE_BOOLEAN,
+               .name          = "Mirror Horizontally",
+               .minimum       = 0,
+               .maximum       = 1,
+               .step          = 1,
+               .default_value = 0,
+       },
+       {
+               .id            = V4L2_CID_VFLIP,
+               .type          = V4L2_CTRL_TYPE_BOOLEAN,
+               .name          = "Flip Vertically",
+               .minimum       = 0,
+               .maximum       = 1,
+               .step          = 1,
+               .default_value = 0,
+       },
+       {
+               .id            = CPIA2_CID_TARGET_KB,
+               .type          = V4L2_CTRL_TYPE_INTEGER,
+               .name          = "Target KB",
+               .minimum       = 0,
+               .maximum       = 255,
+               .step          = 1,
+               .default_value = DEFAULT_TARGET_KB,
+       },
+       {
+               .id            = CPIA2_CID_GPIO,
+               .type          = V4L2_CTRL_TYPE_INTEGER,
+               .name          = "GPIO",
+               .minimum       = 0,
+               .maximum       = 255,
+               .step          = 1,
+               .default_value = 0,
+       },
+       {
+               .id            = CPIA2_CID_FLICKER_MODE,
+               .type          = V4L2_CTRL_TYPE_MENU,
+               .name          = "Flicker Reduction",
+               .minimum       = 0,
+               .maximum       = NUM_FLICKER_CONTROLS-1,
+               .step          = 1,
+               .default_value = 0,
+       },
+       {
+               .id            = CPIA2_CID_FRAMERATE,
+               .type          = V4L2_CTRL_TYPE_MENU,
+               .name          = "Framerate",
+               .minimum       = 0,
+               .maximum       = NUM_FRAMERATE_CONTROLS-1,
+               .step          = 1,
+               .default_value = NUM_FRAMERATE_CONTROLS-1,
+       },
+       {
+               .id            = CPIA2_CID_USB_ALT,
+               .type          = V4L2_CTRL_TYPE_INTEGER,
+               .name          = "USB Alternate",
+               .minimum       = USBIF_ISO_1,
+               .maximum       = USBIF_ISO_6,
+               .step          = 1,
+               .default_value = DEFAULT_ALT,
+       },
+       {
+               .id            = CPIA2_CID_LIGHTS,
+               .type          = V4L2_CTRL_TYPE_MENU,
+               .name          = "Lights",
+               .minimum       = 0,
+               .maximum       = NUM_LIGHTS_CONTROLS-1,
+               .step          = 1,
+               .default_value = 0,
+       },
+       {
+               .id            = CPIA2_CID_RESET_CAMERA,
+               .type          = V4L2_CTRL_TYPE_BUTTON,
+               .name          = "Reset Camera",
+               .minimum       = 0,
+               .maximum       = 0,
+               .step          = 0,
+               .default_value = 0,
+       },
+};
+#define NUM_CONTROLS (sizeof(controls)/sizeof(controls[0]))
+
+
+/******************************************************************************
+ *
+ *  cpia2_open
+ *
+ *****************************************************************************/
+static int cpia2_open(struct inode *inode, struct file *file)
+{
+       struct video_device *dev = video_devdata(file);
+       struct camera_data *cam = video_get_drvdata(dev);
+       int retval = 0;
+
+       if (!cam) {
+               ERR("Internal error, camera_data not found!\n");
+               return -ENODEV;
+       }
+
+       if(down_interruptible(&cam->busy_lock))
+               return -ERESTARTSYS;
+
+       if(!cam->present) {
+               retval = -ENODEV;
+               goto err_return;
+       }
+
+       if (cam->open_count > 0) {
+               goto skip_init;
+       }
+
+       if (cpia2_allocate_buffers(cam)) {
+               retval = -ENOMEM;
+               goto err_return;
+       }
+
+       /* reset the camera */
+       if (cpia2_reset_camera(cam) < 0) {
+               retval = -EIO;
+               goto err_return;
+       }
+
+       cam->APP_len = 0;
+       cam->COM_len = 0;
+
+skip_init:
+       {
+               struct cpia2_fh *fh = kmalloc(sizeof(*fh),GFP_KERNEL);
+               if(!fh) {
+                       retval = -ENOMEM;
+                       goto err_return;
+               }
+               file->private_data = fh;
+               fh->prio = V4L2_PRIORITY_UNSET;
+               v4l2_prio_open(&cam->prio, &fh->prio);
+               fh->mmapped = 0;
+       }
+
+       ++cam->open_count;
+
+       cpia2_dbg_dump_registers(cam);
+
+err_return:
+       up(&cam->busy_lock);
+       return retval;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_close
+ *
+ *****************************************************************************/
+static int cpia2_close(struct inode *inode, struct file *file)
+{
+       struct video_device *dev = video_devdata(file);
+       struct camera_data *cam = video_get_drvdata(dev);
+       struct cpia2_fh *fh = file->private_data;
+
+       down(&cam->busy_lock);
+
+       if (cam->present &&
+           (cam->open_count == 1
+            || fh->prio == V4L2_PRIORITY_RECORD
+           )) {
+               cpia2_usb_stream_stop(cam);
+
+               if(cam->open_count == 1) {
+                       /* save camera state for later open */
+                       cpia2_save_camera_state(cam);
+
+                       cpia2_set_low_power(cam);
+                       cpia2_free_buffers(cam);
+               }
+       }
+
+       {
+               if(fh->mmapped)
+                       cam->mmapped = 0;
+               v4l2_prio_close(&cam->prio,&fh->prio);
+               file->private_data = NULL;
+               kfree(fh);
+       }
+
+       if (--cam->open_count == 0) {
+               cpia2_free_buffers(cam);
+               if (!cam->present) {
+                       video_unregister_device(dev);
+                       kfree(cam);
+               }
+       }
+
+       up(&cam->busy_lock);
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_v4l_read
+ *
+ *****************************************************************************/
+static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count,
+                             loff_t *off)
+{
+       struct video_device *dev = video_devdata(file);
+       struct camera_data *cam = video_get_drvdata(dev);
+       int noblock = file->f_flags&O_NONBLOCK;
+
+       struct cpia2_fh *fh = file->private_data;
+
+       if(!cam)
+               return -EINVAL;
+
+       /* Priority check */
+       if(fh->prio != V4L2_PRIORITY_RECORD) {
+               return -EBUSY;
+       }
+
+       return cpia2_read(cam, buf, count, noblock);
+}
+
+
+/******************************************************************************
+ *
+ *  cpia2_v4l_poll
+ *
+ *****************************************************************************/
+static unsigned int cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait)
+{
+       struct video_device *dev = video_devdata(filp);
+       struct camera_data *cam = video_get_drvdata(dev);
+
+       struct cpia2_fh *fh = filp->private_data;
+
+       if(!cam)
+               return POLLERR;
+
+       /* Priority check */
+       if(fh->prio != V4L2_PRIORITY_RECORD) {
+               return POLLERR;
+       }
+
+       return cpia2_poll(cam, filp, wait);
+}
+
+
+/******************************************************************************
+ *
+ *  ioctl_cap_query
+ *
+ *****************************************************************************/
+static int ioctl_cap_query(void *arg, struct camera_data *cam)
+{
+       struct video_capability *vc;
+       int retval = 0;
+       vc = arg;
+
+       if (cam->params.pnp_id.product == 0x151)
+               strcpy(vc->name, "QX5 Microscope");
+       else
+               strcpy(vc->name, "CPiA2 Camera");
+
+       vc->type = VID_TYPE_CAPTURE | VID_TYPE_MJPEG_ENCODER;
+       vc->channels = 1;
+       vc->audios = 0;
+       vc->minwidth = 176;     /* VIDEOSIZE_QCIF */
+       vc->minheight = 144;
+       switch (cam->params.version.sensor_flags) {
+       case CPIA2_VP_SENSOR_FLAGS_500:
+               vc->maxwidth = STV_IMAGE_VGA_COLS;
+               vc->maxheight = STV_IMAGE_VGA_ROWS;
+               break;
+       case CPIA2_VP_SENSOR_FLAGS_410:
+               vc->maxwidth = STV_IMAGE_CIF_COLS;
+               vc->maxheight = STV_IMAGE_CIF_ROWS;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return retval;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_get_channel
+ *
+ *****************************************************************************/
+static int ioctl_get_channel(void *arg)
+{
+       int retval = 0;
+       struct video_channel *v;
+       v = arg;
+
+       if (v->channel != 0)
+               return -EINVAL;
+
+       v->channel = 0;
+       strcpy(v->name, "Camera");
+       v->tuners = 0;
+       v->flags = 0;
+       v->type = VIDEO_TYPE_CAMERA;
+       v->norm = 0;
+
+       return retval;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_set_channel
+ *
+ *****************************************************************************/
+static int ioctl_set_channel(void *arg)
+{
+       struct video_channel *v;
+       int retval = 0;
+       v = arg;
+
+       if (retval == 0 && v->channel != 0)
+               retval = -EINVAL;
+
+       return retval;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_set_image_prop
+ *
+ *****************************************************************************/
+static int ioctl_set_image_prop(void *arg, struct camera_data *cam)
+{
+       struct video_picture *vp;
+       int retval = 0;
+       vp = arg;
+
+       /* brightness, color, contrast need no check 0-65535 */
+       memcpy(&cam->vp, vp, sizeof(*vp));
+
+       /* update cam->params.colorParams */
+       cam->params.color_params.brightness = vp->brightness / 256;
+       cam->params.color_params.saturation = vp->colour / 256;
+       cam->params.color_params.contrast = vp->contrast / 256;
+
+       DBG("Requested params: bright 0x%X, sat 0x%X, contrast 0x%X\n",
+           cam->params.color_params.brightness,
+           cam->params.color_params.saturation,
+           cam->params.color_params.contrast);
+
+       cpia2_set_color_params(cam);
+
+       return retval;
+}
+
+static int sync(struct camera_data *cam, int frame_nr)
+{
+       struct framebuf *frame = &cam->buffers[frame_nr];
+
+       while (1) {
+               if (frame->status == FRAME_READY)
+                       return 0;
+
+               if (!cam->streaming) {
+                       frame->status = FRAME_READY;
+                       frame->length = 0;
+                       return 0;
+               }
+
+               up(&cam->busy_lock);
+               wait_event_interruptible(cam->wq_stream,
+                                        !cam->streaming ||
+                                        frame->status == FRAME_READY);
+               down(&cam->busy_lock);
+               if (signal_pending(current))
+                       return -ERESTARTSYS;
+               if(!cam->present)
+                       return -ENOTTY;
+       }
+}
+
+/******************************************************************************
+ *
+ *  ioctl_set_window_size
+ *
+ *****************************************************************************/
+static int ioctl_set_window_size(void *arg, struct camera_data *cam,
+                                struct cpia2_fh *fh)
+{
+       /* copy_from_user, check validity, copy to internal structure */
+       struct video_window *vw;
+       int frame, err;
+       vw = arg;
+
+       if (vw->clipcount != 0) /* clipping not supported */
+               return -EINVAL;
+
+       if (vw->clips != NULL)  /* clipping not supported */
+               return -EINVAL;
+
+       /* Ensure that only this process can change the format. */
+       err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD);
+       if(err != 0)
+               return err;
+
+       cam->pixelformat = V4L2_PIX_FMT_JPEG;
+
+       /* Be sure to supply the Huffman tables, this isn't MJPEG */
+       cam->params.compression.inhibit_htables = 0;
+
+       /* we set the video window to something smaller or equal to what
+        * is requested by the user???
+        */
+       DBG("Requested width = %d, height = %d\n", vw->width, vw->height);
+       if (vw->width != cam->vw.width || vw->height != cam->vw.height) {
+               cam->vw.width = vw->width;
+               cam->vw.height = vw->height;
+               cam->params.roi.width = vw->width;
+               cam->params.roi.height = vw->height;
+               cpia2_set_format(cam);
+       }
+
+       for (frame = 0; frame < cam->num_frames; ++frame) {
+               if (cam->buffers[frame].status == FRAME_READING)
+                       if ((err = sync(cam, frame)) < 0)
+                               return err;
+
+               cam->buffers[frame].status = FRAME_EMPTY;
+       }
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_get_mbuf
+ *
+ *****************************************************************************/
+static int ioctl_get_mbuf(void *arg, struct camera_data *cam)
+{
+       struct video_mbuf *vm;
+       int i;
+       vm = arg;
+
+       memset(vm, 0, sizeof(*vm));
+       vm->size = cam->frame_size*cam->num_frames;
+       vm->frames = cam->num_frames;
+       for (i = 0; i < cam->num_frames; i++)
+               vm->offsets[i] = cam->frame_size * i;
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_mcapture
+ *
+ *****************************************************************************/
+static int ioctl_mcapture(void *arg, struct camera_data *cam,
+                         struct cpia2_fh *fh)
+{
+       struct video_mmap *vm;
+       int video_size, err;
+       vm = arg;
+
+       if (vm->frame < 0 || vm->frame >= cam->num_frames)
+               return -EINVAL;
+
+       /* set video size */
+       video_size = cpia2_match_video_size(vm->width, vm->height);
+       if (cam->video_size < 0) {
+               return -EINVAL;
+       }
+
+       /* Ensure that only this process can change the format. */
+       err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD);
+       if(err != 0)
+               return err;
+
+       if (video_size != cam->video_size) {
+               cam->video_size = video_size;
+               cam->params.roi.width = vm->width;
+               cam->params.roi.height = vm->height;
+               cpia2_set_format(cam);
+       }
+
+       if (cam->buffers[vm->frame].status == FRAME_READING)
+               if ((err=sync(cam, vm->frame)) < 0)
+                       return err;
+
+       cam->buffers[vm->frame].status = FRAME_EMPTY;
+
+       return cpia2_usb_stream_start(cam,cam->params.camera_state.stream_mode);
+}
+
+/******************************************************************************
+ *
+ *  ioctl_sync
+ *
+ *****************************************************************************/
+static int ioctl_sync(void *arg, struct camera_data *cam)
+{
+       int frame;
+
+       frame = *(int*)arg;
+
+       if (frame < 0 || frame >= cam->num_frames)
+               return -EINVAL;
+
+       return sync(cam, frame);
+}
+
+
+/******************************************************************************
+ *
+ *  ioctl_set_gpio
+ *
+ *****************************************************************************/
+
+static int ioctl_set_gpio(void *arg, struct camera_data *cam)
+{
+       __u32 gpio_val;
+
+       gpio_val = *(__u32*) arg;
+
+       if (gpio_val &~ 0xFFU)
+               return -EINVAL;
+
+       return cpia2_set_gpio(cam, (unsigned char)gpio_val);
+}
+
+/******************************************************************************
+ *
+ *  ioctl_querycap
+ *
+ *  V4L2 device capabilities
+ *
+ *****************************************************************************/
+
+static int ioctl_querycap(void *arg, struct camera_data *cam)
+{
+       struct v4l2_capability *vc = arg;
+
+       memset(vc, 0, sizeof(*vc));
+       strcpy(vc->driver, "cpia2");
+
+       if (cam->params.pnp_id.product == 0x151)
+               strcpy(vc->card, "QX5 Microscope");
+       else
+               strcpy(vc->card, "CPiA2 Camera");
+       switch (cam->params.pnp_id.device_type) {
+       case DEVICE_STV_672:
+               strcat(vc->card, " (672/");
+               break;
+       case DEVICE_STV_676:
+               strcat(vc->card, " (676/");
+               break;
+       default:
+               strcat(vc->card, " (???/");
+               break;
+       }
+       switch (cam->params.version.sensor_flags) {
+       case CPIA2_VP_SENSOR_FLAGS_404:
+               strcat(vc->card, "404)");
+               break;
+       case CPIA2_VP_SENSOR_FLAGS_407:
+               strcat(vc->card, "407)");
+               break;
+       case CPIA2_VP_SENSOR_FLAGS_409:
+               strcat(vc->card, "409)");
+               break;
+       case CPIA2_VP_SENSOR_FLAGS_410:
+               strcat(vc->card, "410)");
+               break;
+       case CPIA2_VP_SENSOR_FLAGS_500:
+               strcat(vc->card, "500)");
+               break;
+       default:
+               strcat(vc->card, "???)");
+               break;
+       }
+
+       if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0)
+               memset(vc->bus_info,0, sizeof(vc->bus_info));
+
+       vc->version = KERNEL_VERSION(CPIA2_MAJ_VER, CPIA2_MIN_VER,
+                                    CPIA2_PATCH_VER);
+
+       vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
+                          V4L2_CAP_READWRITE |
+                          V4L2_CAP_STREAMING;
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_input
+ *
+ *  V4L2 input get/set/enumerate
+ *
+ *****************************************************************************/
+
+static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam)
+{
+       struct v4l2_input *i = arg;
+
+       if(ioclt_nr  != VIDIOC_G_INPUT) {
+               if (i->index != 0)
+                      return -EINVAL;
+       }
+
+       memset(i, 0, sizeof(*i));
+       strcpy(i->name, "Camera");
+       i->type = V4L2_INPUT_TYPE_CAMERA;
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_enum_fmt
+ *
+ *  V4L2 format enumerate
+ *
+ *****************************************************************************/
+
+static int ioctl_enum_fmt(void *arg,struct camera_data *cam)
+{
+       struct v4l2_fmtdesc *f = arg;
+       int index = f->index;
+
+       if (index < 0 || index > 1)
+              return -EINVAL;
+
+       memset(f, 0, sizeof(*f));
+       f->index = index;
+       f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       f->flags = V4L2_FMT_FLAG_COMPRESSED;
+       switch(index) {
+       case 0:
+               strcpy(f->description, "MJPEG");
+               f->pixelformat = V4L2_PIX_FMT_MJPEG;
+               break;
+       case 1:
+               strcpy(f->description, "JPEG");
+               f->pixelformat = V4L2_PIX_FMT_JPEG;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_try_fmt
+ *
+ *  V4L2 format try
+ *
+ *****************************************************************************/
+
+static int ioctl_try_fmt(void *arg,struct camera_data *cam)
+{
+       struct v4l2_format *f = arg;
+
+       if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+              return -EINVAL;
+
+       if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
+           f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
+              return -EINVAL;
+
+       f->fmt.pix.field = V4L2_FIELD_NONE;
+       f->fmt.pix.bytesperline = 0;
+       f->fmt.pix.sizeimage = cam->frame_size;
+       f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
+       f->fmt.pix.priv = 0;
+
+       switch (cpia2_match_video_size(f->fmt.pix.width, f->fmt.pix.height)) {
+       case VIDEOSIZE_VGA:
+               f->fmt.pix.width = 640;
+               f->fmt.pix.height = 480;
+               break;
+       case VIDEOSIZE_CIF:
+               f->fmt.pix.width = 352;
+               f->fmt.pix.height = 288;
+               break;
+       case VIDEOSIZE_QVGA:
+               f->fmt.pix.width = 320;
+               f->fmt.pix.height = 240;
+               break;
+       case VIDEOSIZE_288_216:
+               f->fmt.pix.width = 288;
+               f->fmt.pix.height = 216;
+               break;
+       case VIDEOSIZE_256_192:
+               f->fmt.pix.width = 256;
+               f->fmt.pix.height = 192;
+               break;
+       case VIDEOSIZE_224_168:
+               f->fmt.pix.width = 224;
+               f->fmt.pix.height = 168;
+               break;
+       case VIDEOSIZE_192_144:
+               f->fmt.pix.width = 192;
+               f->fmt.pix.height = 144;
+               break;
+       case VIDEOSIZE_QCIF:
+       default:
+               f->fmt.pix.width = 176;
+               f->fmt.pix.height = 144;
+               break;
+       }
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_set_fmt
+ *
+ *  V4L2 format set
+ *
+ *****************************************************************************/
+
+static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh)
+{
+       struct v4l2_format *f = arg;
+       int err, frame;
+
+       err = ioctl_try_fmt(arg, cam);
+       if(err != 0)
+               return err;
+
+       /* Ensure that only this process can change the format. */
+       err = v4l2_prio_change(&cam->prio, &fh->prio, V4L2_PRIORITY_RECORD);
+       if(err != 0) {
+               return err;
+       }
+
+       cam->pixelformat = f->fmt.pix.pixelformat;
+
+       /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle
+        * the missing Huffman table properly. */
+       cam->params.compression.inhibit_htables = 0;
+               /*f->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG;*/
+
+       /* we set the video window to something smaller or equal to what
+        * is requested by the user???
+        */
+       DBG("Requested width = %d, height = %d\n",
+           f->fmt.pix.width, f->fmt.pix.height);
+       if (f->fmt.pix.width != cam->vw.width ||
+           f->fmt.pix.height != cam->vw.height) {
+               cam->vw.width = f->fmt.pix.width;
+               cam->vw.height = f->fmt.pix.height;
+               cam->params.roi.width = f->fmt.pix.width;
+               cam->params.roi.height = f->fmt.pix.height;
+               cpia2_set_format(cam);
+       }
+
+       for (frame = 0; frame < cam->num_frames; ++frame) {
+               if (cam->buffers[frame].status == FRAME_READING)
+                       if ((err = sync(cam, frame)) < 0)
+                               return err;
+
+               cam->buffers[frame].status = FRAME_EMPTY;
+       }
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_get_fmt
+ *
+ *  V4L2 format get
+ *
+ *****************************************************************************/
+
+static int ioctl_get_fmt(void *arg,struct camera_data *cam)
+{
+       struct v4l2_format *f = arg;
+
+       if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+              return -EINVAL;
+
+       f->fmt.pix.width = cam->vw.width;
+       f->fmt.pix.height = cam->vw.height;
+       f->fmt.pix.pixelformat = cam->pixelformat;
+       f->fmt.pix.field = V4L2_FIELD_NONE;
+       f->fmt.pix.bytesperline = 0;
+       f->fmt.pix.sizeimage = cam->frame_size;
+       f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
+       f->fmt.pix.priv = 0;
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_cropcap
+ *
+ *  V4L2 query cropping capabilities
+ *  NOTE: cropping is currently disabled
+ *
+ *****************************************************************************/
+
+static int ioctl_cropcap(void *arg,struct camera_data *cam)
+{
+       struct v4l2_cropcap *c = arg;
+
+       if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+              return -EINVAL;
+
+       c->bounds.left = 0;
+       c->bounds.top = 0;
+       c->bounds.width = cam->vw.width;
+       c->bounds.height = cam->vw.height;
+       c->defrect.left = 0;
+       c->defrect.top = 0;
+       c->defrect.width = cam->vw.width;
+       c->defrect.height = cam->vw.height;
+       c->pixelaspect.numerator = 1;
+       c->pixelaspect.denominator = 1;
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_queryctrl
+ *
+ *  V4L2 query possible control variables
+ *
+ *****************************************************************************/
+
+static int ioctl_queryctrl(void *arg,struct camera_data *cam)
+{
+       struct v4l2_queryctrl *c = arg;
+       int i;
+
+       for(i=0; i<NUM_CONTROLS; ++i) {
+               if(c->id == controls[i].id) {
+                       memcpy(c, controls+i, sizeof(*c));
+                       break;
+               }
+       }
+
+       if(i == NUM_CONTROLS)
+               return -EINVAL;
+
+       /* Some devices have additional limitations */
+       switch(c->id) {
+       case V4L2_CID_BRIGHTNESS:
+               /***
+                * Don't let the register be set to zero - bug in VP4
+                * flash of full brightness
+                ***/
+               if (cam->params.pnp_id.device_type == DEVICE_STV_672)
+                       c->minimum = 1;
+               break;
+       case V4L2_CID_VFLIP:
+               // VP5 Only
+               if(cam->params.pnp_id.device_type == DEVICE_STV_672)
+                       c->flags |= V4L2_CTRL_FLAG_DISABLED;
+               break;
+       case CPIA2_CID_FRAMERATE:
+               if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
+                  cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
+                       // Maximum 15fps
+                       int i;
+                       for(i=0; i<c->maximum; ++i) {
+                               if(framerate_controls[i].value ==
+                                  CPIA2_VP_FRAMERATE_15) {
+                                       c->maximum = i;
+                                       c->default_value = i;
+                               }
+                       }
+               }
+               break;
+       case CPIA2_CID_FLICKER_MODE:
+               // Flicker control only valid for 672.
+               if(cam->params.pnp_id.device_type != DEVICE_STV_672)
+                       c->flags |= V4L2_CTRL_FLAG_DISABLED;
+               break;
+       case CPIA2_CID_LIGHTS:
+               // Light control only valid for the QX5 Microscope.
+               if(cam->params.pnp_id.product != 0x151)
+                       c->flags |= V4L2_CTRL_FLAG_DISABLED;
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_querymenu
+ *
+ *  V4L2 query possible control variables
+ *
+ *****************************************************************************/
+
+static int ioctl_querymenu(void *arg,struct camera_data *cam)
+{
+       struct v4l2_querymenu *m = arg;
+
+       memset(m->name, 0, sizeof(m->name));
+       m->reserved = 0;
+
+       switch(m->id) {
+       case CPIA2_CID_FLICKER_MODE:
+               if(m->index < 0 || m->index >= NUM_FLICKER_CONTROLS)
+                       return -EINVAL;
+
+               strcpy(m->name, flicker_controls[m->index].name);
+               break;
+       case CPIA2_CID_FRAMERATE:
+           {
+               int maximum = NUM_FRAMERATE_CONTROLS - 1;
+               if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
+                  cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
+                       // Maximum 15fps
+                       int i;
+                       for(i=0; i<maximum; ++i) {
+                               if(framerate_controls[i].value ==
+                                  CPIA2_VP_FRAMERATE_15)
+                                       maximum = i;
+                       }
+               }
+               if(m->index < 0 || m->index > maximum)
+                       return -EINVAL;
+
+               strcpy(m->name, framerate_controls[m->index].name);
+               break;
+           }
+       case CPIA2_CID_LIGHTS:
+               if(m->index < 0 || m->index >= NUM_LIGHTS_CONTROLS)
+                       return -EINVAL;
+
+               strcpy(m->name, lights_controls[m->index].name);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_g_ctrl
+ *
+ *  V4L2 get the value of a control variable
+ *
+ *****************************************************************************/
+
+static int ioctl_g_ctrl(void *arg,struct camera_data *cam)
+{
+       struct v4l2_control *c = arg;
+
+       switch(c->id) {
+       case V4L2_CID_BRIGHTNESS:
+               cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS,
+                                TRANSFER_READ, 0);
+               c->value = cam->params.color_params.brightness;
+               break;
+       case V4L2_CID_CONTRAST:
+               cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST,
+                                TRANSFER_READ, 0);
+               c->value = cam->params.color_params.contrast;
+               break;
+       case V4L2_CID_SATURATION:
+               cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION,
+                                TRANSFER_READ, 0);
+               c->value = cam->params.color_params.saturation;
+               break;
+       case V4L2_CID_HFLIP:
+               cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS,
+                                TRANSFER_READ, 0);
+               c->value = (cam->params.vp_params.user_effects &
+                           CPIA2_VP_USER_EFFECTS_MIRROR) != 0;
+               break;
+       case V4L2_CID_VFLIP:
+               cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS,
+                                TRANSFER_READ, 0);
+               c->value = (cam->params.vp_params.user_effects &
+                           CPIA2_VP_USER_EFFECTS_FLIP) != 0;
+               break;
+       case CPIA2_CID_TARGET_KB:
+               c->value = cam->params.vc_params.target_kb;
+               break;
+       case CPIA2_CID_GPIO:
+               cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA,
+                                TRANSFER_READ, 0);
+               c->value = cam->params.vp_params.gpio_data;
+               break;
+       case CPIA2_CID_FLICKER_MODE:
+       {
+               int i, mode;
+               cpia2_do_command(cam, CPIA2_CMD_GET_FLICKER_MODES,
+                                TRANSFER_READ, 0);
+               if(cam->params.flicker_control.cam_register &
+                  CPIA2_VP_FLICKER_MODES_NEVER_FLICKER) {
+                       mode = NEVER_FLICKER;
+               } else {
+                   if(cam->params.flicker_control.cam_register &
+                      CPIA2_VP_FLICKER_MODES_50HZ) {
+                       mode = FLICKER_50;
+                   } else {
+                       mode = FLICKER_60;
+                   }
+               }
+               for(i=0; i<NUM_FLICKER_CONTROLS; i++) {
+                       if(flicker_controls[i].value == mode) {
+                               c->value = i;
+                               break;
+                       }
+               }
+               if(i == NUM_FLICKER_CONTROLS)
+                       return -EINVAL;
+               break;
+       }
+       case CPIA2_CID_FRAMERATE:
+       {
+               int maximum = NUM_FRAMERATE_CONTROLS - 1;
+               int i;
+               for(i=0; i<= maximum; i++) {
+                       if(cam->params.vp_params.frame_rate ==
+                          framerate_controls[i].value)
+                               break;
+               }
+               if(i > maximum)
+                       return -EINVAL;
+               c->value = i;
+               break;
+       }
+       case CPIA2_CID_USB_ALT:
+               c->value = cam->params.camera_state.stream_mode;
+               break;
+       case CPIA2_CID_LIGHTS:
+       {
+               int i;
+               cpia2_do_command(cam, CPIA2_CMD_GET_VP_GPIO_DATA,
+                                TRANSFER_READ, 0);
+               for(i=0; i<NUM_LIGHTS_CONTROLS; i++) {
+                       if((cam->params.vp_params.gpio_data&GPIO_LIGHTS_MASK) ==
+                          lights_controls[i].value) {
+                               break;
+                       }
+               }
+               if(i == NUM_LIGHTS_CONTROLS)
+                       return -EINVAL;
+               c->value = i;
+               break;
+       }
+       case CPIA2_CID_RESET_CAMERA:
+               return -EINVAL;
+       default:
+               return -EINVAL;
+       }
+
+       DBG("Get control id:%d, value:%d\n", c->id, c->value);
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_s_ctrl
+ *
+ *  V4L2 set the value of a control variable
+ *
+ *****************************************************************************/
+
+static int ioctl_s_ctrl(void *arg,struct camera_data *cam)
+{
+       struct v4l2_control *c = arg;
+       int i;
+       int retval = 0;
+
+       DBG("Set control id:%d, value:%d\n", c->id, c->value);
+
+       /* Check that the value is in range */
+       for(i=0; i<NUM_CONTROLS; i++) {
+               if(c->id == controls[i].id) {
+                       if(c->value < controls[i].minimum ||
+                          c->value > controls[i].maximum) {
+                               return -EINVAL;
+                       }
+                       break;
+               }
+       }
+       if(i == NUM_CONTROLS)
+               return -EINVAL;
+
+       switch(c->id) {
+       case V4L2_CID_BRIGHTNESS:
+               cpia2_set_brightness(cam, c->value);
+               break;
+       case V4L2_CID_CONTRAST:
+               cpia2_set_contrast(cam, c->value);
+               break;
+       case V4L2_CID_SATURATION:
+               cpia2_set_saturation(cam, c->value);
+               break;
+       case V4L2_CID_HFLIP:
+               cpia2_set_property_mirror(cam, c->value);
+               break;
+       case V4L2_CID_VFLIP:
+               cpia2_set_property_flip(cam, c->value);
+               break;
+       case CPIA2_CID_TARGET_KB:
+               retval = cpia2_set_target_kb(cam, c->value);
+               break;
+       case CPIA2_CID_GPIO:
+               retval = cpia2_set_gpio(cam, c->value);
+               break;
+       case CPIA2_CID_FLICKER_MODE:
+               retval = cpia2_set_flicker_mode(cam,
+                                             flicker_controls[c->value].value);
+               break;
+       case CPIA2_CID_FRAMERATE:
+               retval = cpia2_set_fps(cam, framerate_controls[c->value].value);
+               break;
+       case CPIA2_CID_USB_ALT:
+               retval = cpia2_usb_change_streaming_alternate(cam, c->value);
+               break;
+       case CPIA2_CID_LIGHTS:
+               retval = cpia2_set_gpio(cam, lights_controls[c->value].value);
+               break;
+       case CPIA2_CID_RESET_CAMERA:
+               cpia2_usb_stream_pause(cam);
+               cpia2_reset_camera(cam);
+               cpia2_usb_stream_resume(cam);
+               break;
+       default:
+               retval = -EINVAL;
+       }
+
+       return retval;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_g_jpegcomp
+ *
+ *  V4L2 get the JPEG compression parameters
+ *
+ *****************************************************************************/
+
+static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam)
+{
+       struct v4l2_jpegcompression *parms = arg;
+
+       memset(parms, 0, sizeof(*parms));
+
+       parms->quality = 80; // TODO: Can this be made meaningful?
+
+       parms->jpeg_markers = V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI;
+       if(!cam->params.compression.inhibit_htables) {
+               parms->jpeg_markers |= V4L2_JPEG_MARKER_DHT;
+       }
+
+       parms->APPn = cam->APPn;
+       parms->APP_len = cam->APP_len;
+       if(cam->APP_len > 0) {
+               memcpy(parms->APP_data, cam->APP_data, cam->APP_len);
+               parms->jpeg_markers |= V4L2_JPEG_MARKER_APP;
+       }
+
+       parms->COM_len = cam->COM_len;
+       if(cam->COM_len > 0) {
+               memcpy(parms->COM_data, cam->COM_data, cam->COM_len);
+               parms->jpeg_markers |= JPEG_MARKER_COM;
+       }
+
+       DBG("G_JPEGCOMP APP_len:%d COM_len:%d\n",
+           parms->APP_len, parms->COM_len);
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_s_jpegcomp
+ *
+ *  V4L2 set the JPEG compression parameters
+ *  NOTE: quality and some jpeg_markers are ignored.
+ *
+ *****************************************************************************/
+
+static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam)
+{
+       struct v4l2_jpegcompression *parms = arg;
+
+       DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n",
+           parms->APP_len, parms->COM_len);
+
+       cam->params.compression.inhibit_htables =
+               !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT);
+
+       if(parms->APP_len != 0) {
+               if(parms->APP_len > 0 &&
+                  parms->APP_len <= sizeof(cam->APP_data) &&
+                  parms->APPn >= 0 && parms->APPn <= 15) {
+                       cam->APPn = parms->APPn;
+                       cam->APP_len = parms->APP_len;
+                       memcpy(cam->APP_data, parms->APP_data, parms->APP_len);
+               } else {
+                       LOG("Bad APPn Params n=%d len=%d\n",
+                           parms->APPn, parms->APP_len);
+                       return -EINVAL;
+               }
+       } else {
+               cam->APP_len = 0;
+       }
+
+       if(parms->COM_len != 0) {
+               if(parms->COM_len > 0 &&
+                  parms->COM_len <= sizeof(cam->COM_data)) {
+                       cam->COM_len = parms->COM_len;
+                       memcpy(cam->COM_data, parms->COM_data, parms->COM_len);
+               } else {
+                       LOG("Bad COM_len=%d\n", parms->COM_len);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_reqbufs
+ *
+ *  V4L2 Initiate memory mapping.
+ *  NOTE: The user's request is ignored. For now the buffers are fixed.
+ *
+ *****************************************************************************/
+
+static int ioctl_reqbufs(void *arg,struct camera_data *cam)
+{
+       struct v4l2_requestbuffers *req = arg;
+
+       if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+          req->memory != V4L2_MEMORY_MMAP)
+               return -EINVAL;
+
+       DBG("REQBUFS requested:%d returning:%d\n", req->count, cam->num_frames);
+       req->count = cam->num_frames;
+       memset(&req->reserved, 0, sizeof(req->reserved));
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_querybuf
+ *
+ *  V4L2 Query memory buffer status.
+ *
+ *****************************************************************************/
+
+static int ioctl_querybuf(void *arg,struct camera_data *cam)
+{
+       struct v4l2_buffer *buf = arg;
+
+       if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+          buf->index > cam->num_frames)
+               return -EINVAL;
+
+       buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
+       buf->length = cam->frame_size;
+
+       buf->memory = V4L2_MEMORY_MMAP;
+
+       if(cam->mmapped)
+               buf->flags = V4L2_BUF_FLAG_MAPPED;
+       else
+               buf->flags = 0;
+
+       switch (cam->buffers[buf->index].status) {
+       case FRAME_EMPTY:
+       case FRAME_ERROR:
+       case FRAME_READING:
+               buf->bytesused = 0;
+               buf->flags = V4L2_BUF_FLAG_QUEUED;
+               break;
+       case FRAME_READY:
+               buf->bytesused = cam->buffers[buf->index].length;
+               buf->timestamp = cam->buffers[buf->index].timestamp;
+               buf->sequence = cam->buffers[buf->index].seq;
+               buf->flags = V4L2_BUF_FLAG_DONE;
+               break;
+       }
+
+       DBG("QUERYBUF index:%d offset:%d flags:%d seq:%d bytesused:%d\n",
+            buf->index, buf->m.offset, buf->flags, buf->sequence,
+            buf->bytesused);
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_qbuf
+ *
+ *  V4L2 User is freeing buffer
+ *
+ *****************************************************************************/
+
+static int ioctl_qbuf(void *arg,struct camera_data *cam)
+{
+       struct v4l2_buffer *buf = arg;
+
+       if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+          buf->memory != V4L2_MEMORY_MMAP ||
+          buf->index > cam->num_frames)
+               return -EINVAL;
+
+       DBG("QBUF #%d\n", buf->index);
+
+       if(cam->buffers[buf->index].status == FRAME_READY)
+               cam->buffers[buf->index].status = FRAME_EMPTY;
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  find_earliest_filled_buffer
+ *
+ *  Helper for ioctl_dqbuf. Find the next ready buffer.
+ *
+ *****************************************************************************/
+
+static int find_earliest_filled_buffer(struct camera_data *cam)
+{
+       int i;
+       int found = -1;
+       for (i=0; i<cam->num_frames; i++) {
+               if(cam->buffers[i].status == FRAME_READY) {
+                       if(found < 0) {
+                               found = i;
+                       } else {
+                               /* find which buffer is earlier */
+                               struct timeval *tv1, *tv2;
+                               tv1 = &cam->buffers[i].timestamp;
+                               tv2 = &cam->buffers[found].timestamp;
+                               if(tv1->tv_sec < tv2->tv_sec ||
+                                  (tv1->tv_sec == tv2->tv_sec &&
+                                   tv1->tv_usec < tv2->tv_usec))
+                                       found = i;
+                       }
+               }
+       }
+       return found;
+}
+
+/******************************************************************************
+ *
+ *  ioctl_dqbuf
+ *
+ *  V4L2 User is asking for a filled buffer.
+ *
+ *****************************************************************************/
+
+static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
+{
+       struct v4l2_buffer *buf = arg;
+       int frame;
+
+       if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+          buf->memory != V4L2_MEMORY_MMAP)
+               return -EINVAL;
+
+       frame = find_earliest_filled_buffer(cam);
+
+       if(frame < 0 && file->f_flags&O_NONBLOCK)
+               return -EAGAIN;
+
+       if(frame < 0) {
+               /* Wait for a frame to become available */
+               struct framebuf *cb=cam->curbuff;
+               up(&cam->busy_lock);
+               wait_event_interruptible(cam->wq_stream,
+                                        !cam->present ||
+                                        (cb=cam->curbuff)->status == FRAME_READY);
+               down(&cam->busy_lock);
+               if (signal_pending(current))
+                       return -ERESTARTSYS;
+               if(!cam->present)
+                       return -ENOTTY;
+               frame = cb->num;
+       }
+
+
+       buf->index = frame;
+       buf->bytesused = cam->buffers[buf->index].length;
+       buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
+       buf->field = V4L2_FIELD_NONE;
+       buf->timestamp = cam->buffers[buf->index].timestamp;
+       buf->sequence = cam->buffers[buf->index].seq;
+       buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
+       buf->length = cam->frame_size;
+       buf->input = 0;
+       buf->reserved = 0;
+       memset(&buf->timecode, 0, sizeof(buf->timecode));
+
+       DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index,
+           cam->buffers[buf->index].status, buf->sequence, buf->bytesused);
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_ioctl
+ *
+ *****************************************************************************/
+static int cpia2_do_ioctl(struct inode *inode, struct file *file,
+                         unsigned int ioctl_nr, void *arg)
+{
+       struct video_device *dev = video_devdata(file);
+       struct camera_data *cam = video_get_drvdata(dev);
+       int retval = 0;
+
+       if (!cam)
+               return -ENOTTY;
+
+       /* make this _really_ smp-safe */
+       if (down_interruptible(&cam->busy_lock))
+               return -ERESTARTSYS;
+
+       if (!cam->present) {
+               up(&cam->busy_lock);
+               return -ENODEV;
+       }
+
+       /* Priority check */
+       switch (ioctl_nr) {
+       case VIDIOCSWIN:
+       case VIDIOCMCAPTURE:
+       case VIDIOC_S_FMT:
+       {
+               struct cpia2_fh *fh = file->private_data;
+               retval = v4l2_prio_check(&cam->prio, &fh->prio);
+               if(retval) {
+                       up(&cam->busy_lock);
+                       return retval;
+               }
+               break;
+       }
+       case VIDIOCGMBUF:
+       case VIDIOCSYNC:
+       {
+               struct cpia2_fh *fh = file->private_data;
+               if(fh->prio != V4L2_PRIORITY_RECORD) {
+                       up(&cam->busy_lock);
+                       return -EBUSY;
+               }
+               break;
+       }
+       default:
+               break;
+       }
+
+       switch (ioctl_nr) {
+       case VIDIOCGCAP:        /* query capabilities */
+               retval = ioctl_cap_query(arg, cam);
+               break;
+
+       case VIDIOCGCHAN:       /* get video source - we are a camera, nothing else */
+               retval = ioctl_get_channel(arg);
+               break;
+       case VIDIOCSCHAN:       /* set video source - we are a camera, nothing else */
+               retval = ioctl_set_channel(arg);
+               break;
+       case VIDIOCGPICT:       /* image properties */
+               memcpy(arg, &cam->vp, sizeof(struct video_picture));
+               break;
+       case VIDIOCSPICT:
+               retval = ioctl_set_image_prop(arg, cam);
+               break;
+       case VIDIOCGWIN:        /* get/set capture window */
+               memcpy(arg, &cam->vw, sizeof(struct video_window));
+               break;
+       case VIDIOCSWIN:
+               retval = ioctl_set_window_size(arg, cam, file->private_data);
+               break;
+       case VIDIOCGMBUF:       /* mmap interface */
+               retval = ioctl_get_mbuf(arg, cam);
+               break;
+       case VIDIOCMCAPTURE:
+               retval = ioctl_mcapture(arg, cam, file->private_data);
+               break;
+       case VIDIOCSYNC:
+               retval = ioctl_sync(arg, cam);
+               break;
+               /* pointless to implement overlay with this camera */
+       case VIDIOCCAPTURE:
+       case VIDIOCGFBUF:
+       case VIDIOCSFBUF:
+       case VIDIOCKEY:
+               retval = -EINVAL;
+               break;
+
+               /* tuner interface - we have none */
+       case VIDIOCGTUNER:
+       case VIDIOCSTUNER:
+       case VIDIOCGFREQ:
+       case VIDIOCSFREQ:
+               retval = -EINVAL;
+               break;
+
+               /* audio interface - we have none */
+       case VIDIOCGAUDIO:
+       case VIDIOCSAUDIO:
+               retval = -EINVAL;
+               break;
+
+       /* CPIA2 extension to Video4Linux API */
+       case CPIA2_IOC_SET_GPIO:
+               retval = ioctl_set_gpio(arg, cam);
+               break;
+       case VIDIOC_QUERYCAP:
+               retval = ioctl_querycap(arg,cam);
+               break;
+
+       case VIDIOC_ENUMINPUT:
+       case VIDIOC_G_INPUT:
+       case VIDIOC_S_INPUT:
+               retval = ioctl_input(ioctl_nr, arg,cam);
+               break;
+
+       case VIDIOC_ENUM_FMT:
+               retval = ioctl_enum_fmt(arg,cam);
+               break;
+       case VIDIOC_TRY_FMT:
+               retval = ioctl_try_fmt(arg,cam);
+               break;
+       case VIDIOC_G_FMT:
+               retval = ioctl_get_fmt(arg,cam);
+               break;
+       case VIDIOC_S_FMT:
+               retval = ioctl_set_fmt(arg,cam,file->private_data);
+               break;
+
+       case VIDIOC_CROPCAP:
+               retval = ioctl_cropcap(arg,cam);
+               break;
+       case VIDIOC_G_CROP:
+       case VIDIOC_S_CROP:
+               // TODO: I think cropping can be implemented - SJB
+               retval = -EINVAL;
+               break;
+
+       case VIDIOC_QUERYCTRL:
+               retval = ioctl_queryctrl(arg,cam);
+               break;
+       case VIDIOC_QUERYMENU:
+               retval = ioctl_querymenu(arg,cam);
+               break;
+       case VIDIOC_G_CTRL:
+               retval = ioctl_g_ctrl(arg,cam);
+               break;
+       case VIDIOC_S_CTRL:
+               retval = ioctl_s_ctrl(arg,cam);
+               break;
+
+       case VIDIOC_G_JPEGCOMP:
+               retval = ioctl_g_jpegcomp(arg,cam);
+               break;
+       case VIDIOC_S_JPEGCOMP:
+               retval = ioctl_s_jpegcomp(arg,cam);
+               break;
+
+       case VIDIOC_G_PRIORITY:
+       {
+               struct cpia2_fh *fh = file->private_data;
+               *(enum v4l2_priority*)arg = fh->prio;
+               break;
+       }
+       case VIDIOC_S_PRIORITY:
+       {
+               struct cpia2_fh *fh = file->private_data;
+               enum v4l2_priority prio;
+               prio = *(enum v4l2_priority*)arg;
+               if(cam->streaming &&
+                  prio != fh->prio &&
+                  fh->prio == V4L2_PRIORITY_RECORD) {
+                       /* Can't drop record priority while streaming */
+                       retval = -EBUSY;
+               } else if(prio == V4L2_PRIORITY_RECORD &&
+                  prio != fh->prio &&
+                  v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) {
+                       /* Only one program can record at a time */
+                       retval = -EBUSY;
+               } else {
+                       retval = v4l2_prio_change(&cam->prio, &fh->prio, prio);
+               }
+               break;
+       }
+
+       case VIDIOC_REQBUFS:
+               retval = ioctl_reqbufs(arg,cam);
+               break;
+       case VIDIOC_QUERYBUF:
+               retval = ioctl_querybuf(arg,cam);
+               break;
+       case VIDIOC_QBUF:
+               retval = ioctl_qbuf(arg,cam);
+               break;
+       case VIDIOC_DQBUF:
+               retval = ioctl_dqbuf(arg,cam,file);
+               break;
+       case VIDIOC_STREAMON:
+       {
+               int type;
+               DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming);
+               type = *(int*)arg;
+               if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+                       retval = -EINVAL;
+
+               if(!cam->streaming) {
+                       retval = cpia2_usb_stream_start(cam,
+                                         cam->params.camera_state.stream_mode);
+               } else {
+                       retval = -EINVAL;
+               }
+
+               break;
+       }
+       case VIDIOC_STREAMOFF:
+       {
+               int type;
+               DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming);
+               type = *(int*)arg;
+               if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+                       retval = -EINVAL;
+
+               if(cam->streaming) {
+                       retval = cpia2_usb_stream_stop(cam);
+               } else {
+                       retval = -EINVAL;
+               }
+
+               break;
+       }
+
+       case VIDIOC_ENUMOUTPUT:
+       case VIDIOC_G_OUTPUT:
+       case VIDIOC_S_OUTPUT:
+       case VIDIOC_G_MODULATOR:
+       case VIDIOC_S_MODULATOR:
+
+       case VIDIOC_ENUMAUDIO:
+       case VIDIOC_G_AUDIO:
+       case VIDIOC_S_AUDIO:
+
+       case VIDIOC_ENUMAUDOUT:
+       case VIDIOC_G_AUDOUT:
+       case VIDIOC_S_AUDOUT:
+
+       case VIDIOC_ENUMSTD:
+       case VIDIOC_QUERYSTD:
+       case VIDIOC_G_STD:
+       case VIDIOC_S_STD:
+
+       case VIDIOC_G_TUNER:
+       case VIDIOC_S_TUNER:
+       case VIDIOC_G_FREQUENCY:
+       case VIDIOC_S_FREQUENCY:
+
+       case VIDIOC_OVERLAY:
+       case VIDIOC_G_FBUF:
+       case VIDIOC_S_FBUF:
+
+       case VIDIOC_G_PARM:
+       case VIDIOC_S_PARM:
+               retval = -EINVAL;
+               break;
+       default:
+               retval = -ENOIOCTLCMD;
+               break;
+       }
+
+       up(&cam->busy_lock);
+       return retval;
+}
+
+static int cpia2_ioctl(struct inode *inode, struct file *file,
+                      unsigned int ioctl_nr, unsigned long iarg)
+{
+       return video_usercopy(inode, file, ioctl_nr, iarg, cpia2_do_ioctl);
+}
+
+/******************************************************************************
+ *
+ *  cpia2_mmap
+ *
+ *****************************************************************************/
+static int cpia2_mmap(struct file *file, struct vm_area_struct *area)
+{
+       int retval;
+       struct video_device *dev = video_devdata(file);
+       struct camera_data *cam = video_get_drvdata(dev);
+
+       /* Priority check */
+       struct cpia2_fh *fh = file->private_data;
+       if(fh->prio != V4L2_PRIORITY_RECORD) {
+               return -EBUSY;
+       }
+
+       retval = cpia2_remap_buffer(cam, area);
+
+       if(!retval)
+               fh->mmapped = 1;
+       return retval;
+}
+
+/******************************************************************************
+ *
+ *  reset_camera_struct_v4l
+ *
+ *  Sets all values to the defaults
+ *****************************************************************************/
+static void reset_camera_struct_v4l(struct camera_data *cam)
+{
+       /***
+        * Fill in the v4l structures.  video_cap is filled in inside the VIDIOCCAP
+        * Ioctl.  Here, just do the window and picture stucts.
+        ***/
+       cam->vp.palette = (u16) VIDEO_PALETTE_RGB24;    /* Is this right? */
+       cam->vp.brightness = (u16) cam->params.color_params.brightness * 256;
+       cam->vp.colour = (u16) cam->params.color_params.saturation * 256;
+       cam->vp.contrast = (u16) cam->params.color_params.contrast * 256;
+
+       cam->vw.x = 0;
+       cam->vw.y = 0;
+       cam->vw.width = cam->params.roi.width;
+       cam->vw.height = cam->params.roi.height;
+       cam->vw.flags = 0;
+       cam->vw.clipcount = 0;
+
+       cam->frame_size = buffer_size;
+       cam->num_frames = num_buffers;
+
+       /* FlickerModes */
+       cam->params.flicker_control.flicker_mode_req = flicker_mode;
+       cam->params.flicker_control.mains_frequency = flicker_freq;
+
+       /* streamMode */
+       cam->params.camera_state.stream_mode = alternate;
+
+       cam->pixelformat = V4L2_PIX_FMT_JPEG;
+       v4l2_prio_init(&cam->prio);
+       return;
+}
+
+/***
+ * The v4l video device structure initialized for this device
+ ***/
+static struct file_operations fops_template = {
+       .owner=      THIS_MODULE,
+       .open=       cpia2_open,
+       .release=    cpia2_close,
+       .read=       cpia2_v4l_read,
+       .poll=       cpia2_v4l_poll,
+       .ioctl=      cpia2_ioctl,
+       .llseek=     no_llseek,
+       .mmap=       cpia2_mmap,
+};
+
+static struct video_device cpia2_template = {
+       /* I could not find any place for the old .initialize initializer?? */
+       .owner=         THIS_MODULE,
+       .name=          "CPiA2 Camera",
+       .type=          VID_TYPE_CAPTURE,
+       .type2 =        V4L2_CAP_VIDEO_CAPTURE |
+                       V4L2_CAP_STREAMING,
+       .hardware=      VID_HARDWARE_CPIA2,
+       .minor=         -1,
+       .fops=          &fops_template,
+       .release=       video_device_release,
+};
+
+/******************************************************************************
+ *
+ *  cpia2_register_camera
+ *
+ *****************************************************************************/
+int cpia2_register_camera(struct camera_data *cam)
+{
+       cam->vdev = video_device_alloc();
+       if(!cam->vdev)
+               return -ENOMEM;
+
+       memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template));
+       video_set_drvdata(cam->vdev, cam);
+
+       reset_camera_struct_v4l(cam);
+
+       /* register v4l device */
+       if (video_register_device
+           (cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
+               ERR("video_register_device failed\n");
+               video_device_release(cam->vdev);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+/******************************************************************************
+ *
+ *  cpia2_unregister_camera
+ *
+ *****************************************************************************/
+void cpia2_unregister_camera(struct camera_data *cam)
+{
+       if (!cam->open_count) {
+               video_unregister_device(cam->vdev);
+       } else {
+               LOG("/dev/video%d removed while open, "
+                   "deferring video_unregister_device\n",
+                   cam->vdev->minor);
+       }
+}
+
+/******************************************************************************
+ *
+ *  check_parameters
+ *
+ *  Make sure that all user-supplied parameters are sensible
+ *****************************************************************************/
+static void __init check_parameters(void)
+{
+       if(buffer_size < PAGE_SIZE) {
+               buffer_size = PAGE_SIZE;
+               LOG("buffer_size too small, setting to %d\n", buffer_size);
+       } else if(buffer_size > 1024*1024) {
+               /* arbitrary upper limiit */
+               buffer_size = 1024*1024;
+               LOG("buffer_size ridiculously large, setting to %d\n",
+                   buffer_size);
+       } else {
+               buffer_size += PAGE_SIZE-1;
+               buffer_size &= ~(PAGE_SIZE-1);
+       }
+
+       if(num_buffers < 1) {
+               num_buffers = 1;
+               LOG("num_buffers too small, setting to %d\n", num_buffers);
+       } else if(num_buffers > VIDEO_MAX_FRAME) {
+               num_buffers = VIDEO_MAX_FRAME;
+               LOG("num_buffers too large, setting to %d\n", num_buffers);
+       }
+
+       if(alternate < USBIF_ISO_1 || alternate > USBIF_ISO_6) {
+               alternate = DEFAULT_ALT;
+               LOG("alternate specified is invalid, using %d\n", alternate);
+       }
+
+       if (flicker_mode != NEVER_FLICKER && flicker_mode != ANTI_FLICKER_ON) {
+               flicker_mode = NEVER_FLICKER;
+               LOG("Flicker mode specified is invalid, using %d\n",
+                   flicker_mode);
+       }
+
+       if (flicker_freq != FLICKER_50 && flicker_freq != FLICKER_60) {
+               flicker_freq = FLICKER_60;
+               LOG("Flicker mode specified is invalid, using %d\n",
+                   flicker_freq);
+       }
+
+       if(video_nr < -1 || video_nr > 64) {
+               video_nr = -1;
+               LOG("invalid video_nr specified, must be -1 to 64\n");
+       }
+
+       DBG("Using %d buffers, each %d bytes, alternate=%d\n",
+           num_buffers, buffer_size, alternate);
+}
+
+/************   Module Stuff ***************/
+
+
+/******************************************************************************
+ *
+ * cpia2_init/module_init
+ *
+ *****************************************************************************/
+static int __init cpia2_init(void)
+{
+       LOG("%s v%d.%d.%d\n",
+           ABOUT, CPIA2_MAJ_VER, CPIA2_MIN_VER, CPIA2_PATCH_VER);
+       check_parameters();
+       cpia2_usb_init();
+       return 0;
+}
+
+
+/******************************************************************************
+ *
+ * cpia2_exit/module_exit
+ *
+ *****************************************************************************/
+static void __exit cpia2_exit(void)
+{
+       cpia2_usb_cleanup();
+       schedule_timeout(2 * HZ);
+}
+
+module_init(cpia2_init);
+module_exit(cpia2_exit);
+
diff --git a/drivers/media/video/cpia2/cpia2dev.h b/drivers/media/video/cpia2/cpia2dev.h
new file mode 100644 (file)
index 0000000..d58097c
--- /dev/null
@@ -0,0 +1,50 @@
+/****************************************************************************
+ *
+ *  Filename: cpia2dev.h
+ *
+ *  Copyright 2001, STMicrolectronics, Inc.
+ *
+ *  Contact:  steve.miller@st.com
+ *
+ *  Description:
+ *     This file provides definitions for applications wanting to use the
+ *     cpia2 driver beyond the generic v4l capabilities.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ****************************************************************************/
+
+#ifndef CPIA2_DEV_HEADER
+#define CPIA2_DEV_HEADER
+
+#include <linux/videodev.h>
+
+/***
+ * The following defines are ioctl numbers based on video4linux private ioctls,
+ * which can range from 192 (BASE_VIDIOCPRIVATE) to 255. All of these take int
+ * args
+ */
+#define CPIA2_IOC_SET_GPIO         _IOW('v', BASE_VIDIOCPRIVATE + 17, __u32)
+
+/* V4L2 driver specific controls */
+#define CPIA2_CID_TARGET_KB     (V4L2_CID_PRIVATE_BASE+0)
+#define CPIA2_CID_GPIO          (V4L2_CID_PRIVATE_BASE+1)
+#define CPIA2_CID_FLICKER_MODE  (V4L2_CID_PRIVATE_BASE+2)
+#define CPIA2_CID_FRAMERATE     (V4L2_CID_PRIVATE_BASE+3)
+#define CPIA2_CID_USB_ALT       (V4L2_CID_PRIVATE_BASE+4)
+#define CPIA2_CID_LIGHTS        (V4L2_CID_PRIVATE_BASE+5)
+#define CPIA2_CID_RESET_CAMERA  (V4L2_CID_PRIVATE_BASE+6)
+
+#endif
diff --git a/drivers/media/video/cpia2/cpia2patch.h b/drivers/media/video/cpia2/cpia2patch.h
new file mode 100644 (file)
index 0000000..7f085fb
--- /dev/null
@@ -0,0 +1,233 @@
+/****************************************************************************
+ *
+ *  Filename: cpia2patch.h
+ *
+ *  Copyright 2001, STMicrolectronics, Inc.
+ *
+ *  Contact:  steve.miller@st.com
+ *
+ *  Description:
+ *     This file contains patch data for the CPiA2 (stv0672) VP4.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ****************************************************************************/
+
+#ifndef CPIA2_PATCH_HEADER
+#define CPIA2_PATCH_HEADER
+
+typedef struct {
+       unsigned char reg;
+       unsigned char count;
+       const unsigned char *data;
+} cpia2_patch;
+
+static const unsigned char start_address_hi[1] = {
+       0x01
+};
+
+static const unsigned char start_address_lo[1] = {
+       0xBC
+};
+
+static const unsigned char patch_block0[64] = {
+       0xE3, 0x02, 0xE3, 0x03, 0xE3, 0x04, 0xE3, 0x05,
+       0xE3, 0x06, 0xE3, 0x07, 0x93, 0x44, 0x56, 0xD4,
+       0x93, 0x4E, 0x56, 0x51, 0x93, 0x4E, 0x51, 0xD6,
+       0x93, 0x4E, 0x4F, 0x54, 0x93, 0x4E, 0x92, 0x4F,
+       0x92, 0xA4, 0x93, 0x05, 0x92, 0xF4, 0x93, 0x1B,
+       0x92, 0x92, 0x91, 0xE6, 0x92, 0x36, 0x92, 0x74,
+       0x92, 0x4A, 0x92, 0x8C, 0x92, 0x8E, 0xC8, 0xD0,
+       0x0B, 0x42, 0x02, 0xA0, 0xCA, 0x92, 0x09, 0x02
+};
+
+static const unsigned char patch_block1[64] = {
+       0xC9, 0x10, 0x0A, 0x0A, 0x0A, 0x81, 0xE3, 0xB8,
+       0xE3, 0xB0, 0xE3, 0xA8, 0xE3, 0xA0, 0xE3, 0x98,
+       0xE3, 0x90, 0xE1, 0x00, 0xCF, 0xD7, 0x0A, 0x12,
+       0xCC, 0x95, 0x08, 0xB2, 0x0A, 0x18, 0xE1, 0x00,
+       0x01, 0xEE, 0x0C, 0x08, 0x4A, 0x12, 0xC8, 0x18,
+       0xF0, 0x9A, 0xC0, 0x22, 0xF3, 0x1C, 0x4A, 0x13,
+       0xF3, 0x14, 0xC8, 0xA0, 0xF2, 0x14, 0xF2, 0x1C,
+       0xEB, 0x13, 0xD3, 0xA2, 0x63, 0x16, 0x48, 0x9E
+};
+
+static const unsigned char patch_block2[64] = {
+       0xF0, 0x18, 0xA4, 0x03, 0xF3, 0x93, 0xC0, 0x58,
+       0xF7, 0x13, 0x51, 0x9C, 0xE9, 0x20, 0xCF, 0xEF,
+       0x63, 0xF9, 0x92, 0x2E, 0xD3, 0x5F, 0x63, 0xFA,
+       0x92, 0x2E, 0xD3, 0x67, 0x63, 0xFB, 0x92, 0x2E,
+       0xD3, 0x6F, 0xE9, 0x1A, 0x63, 0x16, 0x48, 0xA7,
+       0xF0, 0x20, 0xA4, 0x06, 0xF3, 0x94, 0xC0, 0x27,
+       0xF7, 0x14, 0xF5, 0x13, 0x51, 0x9D, 0xF6, 0x13,
+       0x63, 0x18, 0xC4, 0x20, 0xCB, 0xEF, 0x63, 0xFC
+};
+
+static const unsigned char patch_block3[64] = {
+       0x92, 0x2E, 0xD3, 0x77, 0x63, 0xFD, 0x92, 0x2E,
+       0xD3, 0x7F, 0x63, 0xFE, 0x92, 0x2E, 0xD3, 0x87,
+       0x63, 0xFF, 0x92, 0x2E, 0xD3, 0x8F, 0x64, 0x38,
+       0x92, 0x2E, 0xD3, 0x97, 0x64, 0x39, 0x92, 0x2E,
+       0xD3, 0x9F, 0xE1, 0x00, 0xF5, 0x3A, 0xF4, 0x3B,
+       0xF7, 0xBF, 0xF2, 0xBC, 0xF2, 0x3D, 0xE1, 0x00,
+       0x80, 0x87, 0x90, 0x80, 0x51, 0xD5, 0x02, 0x22,
+       0x02, 0x32, 0x4B, 0xD3, 0xF7, 0x11, 0x0B, 0xDA
+};
+
+static const unsigned char patch_block4[64] = {
+       0xE1, 0x00, 0x0E, 0x02, 0x02, 0x40, 0x0D, 0xB5,
+       0xE3, 0x02, 0x48, 0x55, 0xE5, 0x12, 0xA4, 0x01,
+       0xE8, 0x1B, 0xE3, 0x90, 0xF0, 0x18, 0xA4, 0x01,
+       0xE8, 0xBF, 0x8D, 0xB8, 0x4B, 0xD1, 0x4B, 0xD8,
+       0x0B, 0xCB, 0x0B, 0xC2, 0xE1, 0x00, 0xE3, 0x02,
+       0xE3, 0x03, 0x52, 0xD3, 0x60, 0x59, 0xE6, 0x93,
+       0x0D, 0x22, 0x52, 0xD4, 0xE6, 0x93, 0x0D, 0x2A,
+       0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, 0x02, 0x5D
+};
+
+static const unsigned char patch_block5[64] = {
+       0x02, 0x63, 0xE3, 0x02, 0xC8, 0x12, 0x02, 0xCA,
+       0xC8, 0x52, 0x02, 0xC2, 0x82, 0x68, 0xE3, 0x02,
+       0xC8, 0x14, 0x02, 0xCA, 0xC8, 0x90, 0x02, 0xC2,
+       0x0A, 0xD0, 0xC9, 0x93, 0x0A, 0xDA, 0xCC, 0xD2,
+       0x0A, 0xE2, 0x63, 0x12, 0x02, 0xDA, 0x0A, 0x98,
+       0x0A, 0xA0, 0x0A, 0xA8, 0xE3, 0x90, 0xE1, 0x00,
+       0xE3, 0x02, 0x0A, 0xD0, 0xC9, 0x93, 0x0A, 0xDA,
+       0xCC, 0xD2, 0x0A, 0xE2, 0x63, 0x12, 0x02, 0xDA
+};
+
+static const unsigned char patch_block6[64] = {
+       0x0A, 0x98, 0x0A, 0xA0, 0x0A, 0xA8, 0x49, 0x91,
+       0xE5, 0x6A, 0xA4, 0x04, 0xC8, 0x12, 0x02, 0xCA,
+       0xC8, 0x52, 0x82, 0x89, 0xC8, 0x14, 0x02, 0xCA,
+       0xC8, 0x90, 0x02, 0xC2, 0xE3, 0x90, 0xE1, 0x00,
+       0x08, 0x60, 0xE1, 0x00, 0x48, 0x53, 0xE8, 0x97,
+       0x08, 0x5A, 0xE1, 0x00, 0xE3, 0x02, 0xE3, 0x03,
+       0x54, 0xD3, 0x60, 0x59, 0xE6, 0x93, 0x0D, 0x52,
+       0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00, 0x02, 0x9C
+};
+
+static const unsigned char patch_block7[64] = {
+       0xE3, 0x02, 0x55, 0x13, 0x93, 0x17, 0x55, 0x13,
+       0x93, 0x17, 0xE3, 0x90, 0xE1, 0x00, 0x75, 0x30,
+       0xE3, 0x02, 0xE3, 0x03, 0x55, 0x55, 0x60, 0x59,
+       0xE6, 0x93, 0x0D, 0xB2, 0xE3, 0x98, 0xE3, 0x90,
+       0xE1, 0x00, 0x02, 0xAE, 0xE7, 0x92, 0xE9, 0x18,
+       0xEA, 0x9A, 0xE8, 0x98, 0xE8, 0x10, 0xE8, 0x11,
+       0xE8, 0x51, 0xD2, 0xDA, 0xD2, 0xF3, 0xE8, 0x13,
+       0xD2, 0xFA, 0xE8, 0x50, 0xD2, 0xEA, 0xE8, 0xD0
+};
+
+static const unsigned char patch_block8[64] = {
+       0xE8, 0xD1, 0xD3, 0x0A, 0x03, 0x09, 0x48, 0x23,
+       0xE5, 0x2C, 0xA0, 0x03, 0x48, 0x24, 0xEA, 0x1C,
+       0x03, 0x08, 0xD2, 0xE3, 0xD3, 0x03, 0xD3, 0x13,
+       0xE1, 0x00, 0x02, 0xCB, 0x05, 0x93, 0x57, 0x93,
+       0xF0, 0x9A, 0xAC, 0x0B, 0xE3, 0x07, 0x92, 0xEA,
+       0xE2, 0x9F, 0xE5, 0x06, 0xE3, 0xB0, 0xA0, 0x02,
+       0xEB, 0x1E, 0x82, 0xD7, 0xEA, 0x1E, 0xE2, 0x3B,
+       0x85, 0x9B, 0xE9, 0x1E, 0xC8, 0x90, 0x85, 0x94
+};
+
+static const unsigned char patch_block9[64] = {
+       0x02, 0xDE, 0x05, 0x80, 0x57, 0x93, 0xF0, 0xBA,
+       0xAC, 0x06, 0x92, 0xEA, 0xE2, 0xBF, 0xE5, 0x06,
+       0xA0, 0x01, 0xEB, 0xBF, 0x85, 0x88, 0xE9, 0x3E,
+       0xC8, 0x90, 0x85, 0x81, 0xE9, 0x3E, 0xF0, 0xBA,
+       0xF3, 0x39, 0xF0, 0x3A, 0x60, 0x17, 0xF0, 0x3A,
+       0xC0, 0x90, 0xF0, 0xBA, 0xE1, 0x00, 0x00, 0x3F,
+       0xE3, 0x02, 0xE3, 0x03, 0x58, 0x10, 0x60, 0x59,
+       0xE6, 0x93, 0x0D, 0xA2, 0x58, 0x12, 0xE6, 0x93
+};
+
+static const unsigned char patch_block10[64] = {
+       0x0D, 0xAA, 0xE3, 0x98, 0xE3, 0x90, 0xE1, 0x00,
+       0x03, 0x01, 0xE1, 0x00, 0x03, 0x03, 0x9B, 0x7D,
+       0x8B, 0x8B, 0xE3, 0x02, 0xE3, 0x03, 0x58, 0x56,
+       0x60, 0x59, 0xE6, 0x93, 0x0D, 0xBA, 0xE3, 0x98,
+       0xE3, 0x90, 0xE1, 0x00, 0x03, 0x0F, 0x93, 0x11,
+       0xE1, 0x00, 0xE3, 0x02, 0x4A, 0x11, 0x0B, 0x42,
+       0x91, 0xAF, 0xE3, 0x90, 0xE1, 0x00, 0xF2, 0x91,
+       0xF0, 0x91, 0xA3, 0xFE, 0xE1, 0x00, 0x60, 0x92
+};
+
+static const unsigned char patch_block11[64] = {
+       0xC0, 0x5F, 0xF0, 0x13, 0xF0, 0x13, 0x59, 0x5B,
+       0xE2, 0x13, 0xF0, 0x11, 0x5A, 0x19, 0xE2, 0x13,
+       0xE1, 0x00, 0x00, 0x00, 0x03, 0x27, 0x68, 0x61,
+       0x76, 0x61, 0x6E, 0x61, 0x00, 0x06, 0x03, 0x2C,
+       0xE3, 0x02, 0xE3, 0x03, 0xE9, 0x38, 0x59, 0x15,
+       0x59, 0x5A, 0xF2, 0x9A, 0xBC, 0x0B, 0xA4, 0x0A,
+       0x59, 0x1E, 0xF3, 0x11, 0xF0, 0x1A, 0xE2, 0xBB,
+       0x59, 0x15, 0xF0, 0x11, 0x19, 0x2A, 0xE5, 0x02
+};
+
+static const unsigned char patch_block12[54] = {
+       0xA4, 0x01, 0xEB, 0xBF, 0xE3, 0x98, 0xE3, 0x90,
+       0xE1, 0x00, 0x03, 0x42, 0x19, 0x28, 0xE1, 0x00,
+       0xE9, 0x30, 0x60, 0x79, 0xE1, 0x00, 0xE3, 0x03,
+       0xE3, 0x07, 0x60, 0x79, 0x93, 0x4E, 0xE3, 0xB8,
+       0xE3, 0x98, 0xE1, 0x00, 0xE9, 0x1A, 0xF0, 0x1F,
+       0xE2, 0x33, 0xF0, 0x91, 0xE2, 0x92, 0xE0, 0x32,
+       0xF0, 0x31, 0xE1, 0x00, 0x00, 0x00
+};
+
+static const unsigned char do_call[1] = {
+       0x01
+};
+
+
+#define PATCH_DATA_SIZE 18
+
+static const cpia2_patch patch_data[PATCH_DATA_SIZE] = {
+       {0x0A, sizeof(start_address_hi), start_address_hi}
+       ,                       // 0
+       {0x0B, sizeof(start_address_lo), start_address_lo}
+       ,                       // 1
+       {0x0C, sizeof(patch_block0), patch_block0}
+       ,                       // 2
+       {0x0C, sizeof(patch_block1), patch_block1}
+       ,                       // 3
+       {0x0C, sizeof(patch_block2), patch_block2}
+       ,                       // 4
+       {0x0C, sizeof(patch_block3), patch_block3}
+       ,                       // 5
+       {0x0C, sizeof(patch_block4), patch_block4}
+       ,                       // 6
+       {0x0C, sizeof(patch_block5), patch_block5}
+       ,                       // 7
+       {0x0C, sizeof(patch_block6), patch_block6}
+       ,                       // 8
+       {0x0C, sizeof(patch_block7), patch_block7}
+       ,                       // 9
+       {0x0C, sizeof(patch_block8), patch_block8}
+       ,                       // 10
+       {0x0C, sizeof(patch_block9), patch_block9}
+       ,                       //11
+       {0x0C, sizeof(patch_block10), patch_block10}
+       ,                       // 12
+       {0x0C, sizeof(patch_block11), patch_block11}
+       ,                       // 13
+       {0x0C, sizeof(patch_block12), patch_block12}
+       ,                       // 14
+       {0x0A, sizeof(start_address_hi), start_address_hi}
+       ,                       // 15
+       {0x0B, sizeof(start_address_lo), start_address_lo}
+       ,                       // 16
+       {0x0D, sizeof(do_call), do_call}        //17
+};
+
+
+#endif
diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig
new file mode 100644 (file)
index 0000000..854264e
--- /dev/null
@@ -0,0 +1,9 @@
+config VIDEO_CX25840
+       tristate "Conexant CX2584x audio/video decoders"
+       depends on VIDEO_DEV && I2C && EXPERIMENTAL
+       select FW_LOADER
+       ---help---
+         Support for the Conexant CX2584x audio/video decoders.
+
+         To compile this driver as a module, choose M here: the
+         module will be called cx25840
index 543ebacdc9d71667e99f6e82c93a9a85eb32988f..32a896c23d1e418677158848fa1fe3e86769cb7b 100644 (file)
@@ -1,6 +1,6 @@
 cx25840-objs    := cx25840-core.o cx25840-audio.o cx25840-firmware.o \
                   cx25840-vbi.o
 
-obj-$(CONFIG_VIDEO_DECODER) += cx25840.o
+obj-$(CONFIG_VIDEO_CX25840) += cx25840.o
 
 EXTRA_CFLAGS += -I$(src)/..
index 5588b9a5c4304c795c5036acd232dca0747b7347..8a257978056ffcb520202c6abe4094c6f33d0357 100644 (file)
@@ -743,6 +743,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
 
                memset(input, 0, sizeof(*input));
                input->index = state->aud_input;
+               input->capability = V4L2_AUDCAP_STEREO;
                break;
        }
 
@@ -753,7 +754,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
        case VIDIOC_G_TUNER:
        {
                u8 mode = cx25840_read(client, 0x804);
-               u8 pref = cx25840_read(client, 0x809) & 0xf;
                u8 vpres = cx25840_read(client, 0x80a) & 0x10;
                int val = 0;
 
@@ -773,44 +773,49 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
                        val |= V4L2_TUNER_SUB_MONO;
 
                if (mode == 2 || mode == 4)
-                       val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+                       val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
 
                if (mode & 0x10)
                        val |= V4L2_TUNER_SUB_SAP;
 
                vt->rxsubchans = val;
-
-               switch (pref) {
-               case 0:
-                       vt->audmode = V4L2_TUNER_MODE_MONO;
-                       break;
-               case 1:
-               case 2:
-                       vt->audmode = V4L2_TUNER_MODE_LANG2;
-                       break;
-               case 4:
-               default:
-                       vt->audmode = V4L2_TUNER_MODE_STEREO;
-               }
+               vt->audmode = state->audmode;
                break;
        }
 
        case VIDIOC_S_TUNER:
+               if (state->radio)
+                       break;
+
                switch (vt->audmode) {
                case V4L2_TUNER_MODE_MONO:
-               case V4L2_TUNER_MODE_LANG1:
-                       /* Force PREF_MODE to MONO */
+                       /* mono      -> mono
+                          stereo    -> mono
+                          bilingual -> lang1 */
                        cx25840_and_or(client, 0x809, ~0xf, 0x00);
                        break;
-               case V4L2_TUNER_MODE_STEREO:
-                       /* Force PREF_MODE to STEREO */
+               case V4L2_TUNER_MODE_LANG1:
+                       /* mono      -> mono
+                          stereo    -> stereo
+                          bilingual -> lang1 */
                        cx25840_and_or(client, 0x809, ~0xf, 0x04);
                        break;
+               case V4L2_TUNER_MODE_STEREO:
+                       /* mono      -> mono
+                          stereo    -> stereo
+                          bilingual -> lang1/lang2 */
+                       cx25840_and_or(client, 0x809, ~0xf, 0x07);
+                       break;
                case V4L2_TUNER_MODE_LANG2:
-                       /* Force PREF_MODE to LANG2 */
+                       /* mono      -> mono
+                          stereo    ->stereo
+                          bilingual -> lang2 */
                        cx25840_and_or(client, 0x809, ~0xf, 0x01);
                        break;
+               default:
+                       return -EINVAL;
                }
+               state->audmode = vt->audmode;
                break;
 
        case VIDIOC_G_FMT:
@@ -891,6 +896,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
        state->aud_input = CX25840_AUDIO8;
        state->audclk_freq = 48000;
        state->pvr150_workaround = 0;
+       state->audmode = V4L2_TUNER_MODE_LANG1;
 
        cx25840_initialize(client, 1);
 
index 04d879da7d63f9e3ecc6094bec9d08662d184d43..e96fd1f1d6dc35f653181fe29e3241ddca23748f 100644 (file)
@@ -151,7 +151,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
        case VIDIOC_G_FMT:
        {
                static u16 lcr2vbi[] = {
-                       0, V4L2_SLICED_TELETEXT_B, 0,   /* 1 */
+                       0, V4L2_SLICED_TELETEXT_PAL_B, 0,       /* 1 */
                        0, V4L2_SLICED_WSS_625, 0,      /* 4 */
                        V4L2_SLICED_CAPTION_525,        /* 6 */
                        0, 0, V4L2_SLICED_VPS, 0, 0,    /* 9 */
@@ -231,7 +231,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
                for (i = 7; i <= 23; i++) {
                        for (x = 0; x <= 1; x++) {
                                switch (svbi->service_lines[1-x][i]) {
-                               case V4L2_SLICED_TELETEXT_B:
+                               case V4L2_SLICED_TELETEXT_PAL_B:
                                        lcr[i] |= 1 << (4 * x);
                                        break;
                                case V4L2_SLICED_WSS_625:
@@ -282,7 +282,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
 
                switch (id2) {
                case 1:
-                       id2 = V4L2_SLICED_TELETEXT_B;
+                       id2 = V4L2_SLICED_TELETEXT_PAL_B;
                        break;
                case 4:
                        id2 = V4L2_SLICED_WSS_625;
index fd22f30dcc1bf6ed1155b3f651bd0e2875f5b71d..dd70664d1dd9bd4f71d07180cd30b85a01b2fd14 100644 (file)
@@ -78,6 +78,7 @@ struct cx25840_state {
        enum cx25840_video_input vid_input;
        enum cx25840_audio_input aud_input;
        u32 audclk_freq;
+       int audmode;
 };
 
 /* ----------------------------------------------------------------------- */
index 87d79df053363a9c816e38125cac3f88dcf2426e..e140996e6ee4d43eecb7df09ded07cf680887d6d 100644 (file)
@@ -50,6 +50,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS
        depends on VIDEO_CX88_DVB
        select DVB_MT352
        select VIDEO_CX88_VP3054
+       select DVB_ZL10353
        select DVB_OR51132
        select DVB_CX22702
        select DVB_LGDT330X
@@ -81,6 +82,16 @@ config VIDEO_CX88_VP3054
          which also require support for the VP-3054
          Secondary I2C bus, such at DNTV Live! DVB-T Pro.
 
+config VIDEO_CX88_DVB_ZL10353
+       bool "Zarlink ZL10353 DVB-T Support"
+       default y
+       depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
+       select DVB_ZL10353
+       ---help---
+         This adds DVB-T support for cards based on the
+         Connexant 2388x chip and the ZL10353 demodulator,
+         successor to the Zarlink MT352.
+
 config VIDEO_CX88_DVB_OR51132
        bool "OR51132 ATSC Support"
        default y
index 2b902784facc0d6b1cd5bcb9b6b6420346d14911..6482b9aa6a1fa08b634a7f38e34a10f49b89d781 100644 (file)
@@ -17,6 +17,7 @@ extra-cflags-$(CONFIG_DVB_CX22702)   += -DHAVE_CX22702=1
 extra-cflags-$(CONFIG_DVB_OR51132)   += -DHAVE_OR51132=1
 extra-cflags-$(CONFIG_DVB_LGDT330X)  += -DHAVE_LGDT330X=1
 extra-cflags-$(CONFIG_DVB_MT352)     += -DHAVE_MT352=1
+extra-cflags-$(CONFIG_DVB_ZL10353)   += -DHAVE_ZL10353=1
 extra-cflags-$(CONFIG_DVB_NXT200X)   += -DHAVE_NXT200X=1
 extra-cflags-$(CONFIG_DVB_CX24123)   += -DHAVE_CX24123=1
 extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1
index 2acccd6d49bca63b3b9311ab8a6d014ded33d47c..bffef1decc8b2778b83c0237c1bb2ee3eda407c6 100644 (file)
@@ -672,6 +672,11 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
        chip = (snd_cx88_card_t *) card->private_data;
 
        core = cx88_core_get(pci);
+       if (NULL == core) {
+               err = -EINVAL;
+               kfree (chip);
+               return err;
+       }
 
        if (!pci_dma_supported(pci,0xffffffff)) {
                dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
@@ -688,11 +693,6 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
        spin_lock_init(&chip->reg_lock);
 
        cx88_reset(core);
-       if (NULL == core) {
-               err = -EINVAL;
-               kfree (chip);
-               return err;
-       }
        chip->core = core;
 
        /* get irq */
index 1bc999247fdcbd6d9fd3fe3642a4628cac07a522..c7042cf412318293c6f8f8b3e0064a53a9416839 100644 (file)
@@ -184,17 +184,18 @@ struct cx88_board cx88_boards[] = {
                .input          = {{
                        .type   = CX88_VMUX_TELEVISION,
                        .vmux   = 0,
-                       .gpio1  = 0x309f,
+                       .gpio1  = 0xe09f,
                },{
                        .type   = CX88_VMUX_COMPOSITE1,
                        .vmux   = 1,
-                       .gpio1  = 0x305f,
+                       .gpio1  = 0xe05f,
                },{
                        .type   = CX88_VMUX_SVIDEO,
                        .vmux   = 2,
-                       .gpio1  = 0x305f,
+                       .gpio1  = 0xe05f,
                }},
                .radio = {
+                       .gpio1  = 0xe0df,
                        .type   = CX88_RADIO,
                },
        },
@@ -322,19 +323,19 @@ struct cx88_board cx88_boards[] = {
                .input          = {{
                        .type   = CX88_VMUX_TELEVISION,
                        .vmux   = 0,
-                       .gpio0  = 0xff00,
+                       .gpio0  = 0xbff0,
                },{
                        .type   = CX88_VMUX_COMPOSITE1,
                        .vmux   = 1,
-                       .gpio0  = 0xff03,
+                       .gpio0  = 0xbff3,
                },{
                        .type   = CX88_VMUX_SVIDEO,
                        .vmux   = 2,
-                       .gpio0  = 0xff03,
+                       .gpio0  = 0xbff3,
                }},
                .radio = {
                        .type   = CX88_RADIO,
-                       .gpio0  = 0xff00,
+                       .gpio0  = 0xbff0,
                },
        },
        [CX88_BOARD_ASUS_PVR_416] = {
@@ -1048,6 +1049,50 @@ struct cx88_board cx88_boards[] = {
                }},
                .dvb            = 1,
        },
+       [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = {
+               /* FIXME: Standard video using the cx88 broadcast decoder is
+                * working, but blackbird isn't working yet, audio is only
+                * working correctly for television mode. S-Video and Composite
+                * are working for video-only, so I have them disabled for now.
+                */
+               .name           = "KWorld HardwareMpegTV XPert",
+               .tuner_type     = TUNER_PHILIPS_TDA8290,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .input          = {{
+                       .type   = CX88_VMUX_TELEVISION,
+                       .vmux   = 0,
+                       .gpio0  = 0x3de2,
+                       .gpio2  = 0x00ff,
+               }},
+               .radio = {
+                       .type   = CX88_RADIO,
+                       .gpio0  = 0x3de6,
+                       .gpio2  = 0x00ff,
+               },
+       },
+       [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID] = {
+               .name           = "DViCO FusionHDTV DVB-T Hybrid",
+               .tuner_type     = TUNER_THOMSON_FE6600,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .input          = {{
+                       .type   = CX88_VMUX_TELEVISION,
+                       .vmux   = 0,
+                       .gpio0  = 0x0000a75f,
+               },{
+                       .type   = CX88_VMUX_COMPOSITE1,
+                       .vmux   = 1,
+                       .gpio0  = 0x0000a75b,
+               },{
+                       .type   = CX88_VMUX_SVIDEO,
+                       .vmux   = 2,
+                       .gpio0  = 0x0000a75b,
+               }},
+               .dvb            = 1,
+       },
 
 };
 const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -1254,6 +1299,18 @@ struct cx88_subid cx88_subids[] = {
                .subdevice = 0xdb11,
                .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
                /* Re-branded DViCO: UltraView DVB-T Plus */
+       },{
+               .subvendor = 0x17de,
+               .subdevice = 0x0840,
+               .card      = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
+       },{
+               .subvendor = 0x18ac,
+               .subdevice = 0xdb40,
+               .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID,
+       },{
+               .subvendor = 0x18ac,
+               .subdevice = 0xdb44,
+               .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID,
        },
 };
 const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1372,6 +1429,40 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
        core->has_radio  = gdi_tuner[eeprom_data[0x0d]].fm;
 }
 
+/* ----------------------------------------------------------------------- */
+/* some DViCO specific stuff                                               */
+
+static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core)
+{
+       struct i2c_msg msg = { .addr = 0x45, .flags = 0 };
+       int i, err;
+       static u8 init_bufs[13][5] = {
+               { 0x10, 0x00, 0x20, 0x01, 0x03 },
+               { 0x10, 0x10, 0x01, 0x00, 0x21 },
+               { 0x10, 0x10, 0x10, 0x00, 0xCA },
+               { 0x10, 0x10, 0x12, 0x00, 0x08 },
+               { 0x10, 0x10, 0x13, 0x00, 0x0A },
+               { 0x10, 0x10, 0x16, 0x01, 0xC0 },
+               { 0x10, 0x10, 0x22, 0x01, 0x3D },
+               { 0x10, 0x10, 0x73, 0x01, 0x2E },
+               { 0x10, 0x10, 0x72, 0x00, 0xC5 },
+               { 0x10, 0x10, 0x71, 0x01, 0x97 },
+               { 0x10, 0x10, 0x70, 0x00, 0x0F },
+               { 0x10, 0x10, 0xB0, 0x00, 0x01 },
+               { 0x03, 0x0C },
+       };
+
+       for (i = 0; i < 13; i++) {
+               msg.buf = init_bufs[i];
+               msg.len = (i != 12 ? 5 : 2);
+               err = i2c_transfer(&core->i2c_adap, &msg, 1);
+               if (err != 1) {
+                       printk("dvico_fusionhdtv_hybrid_init buf %d failed (err = %d)!\n", i, err);
+                       return;
+               }
+       }
+}
+
 /* ----------------------------------------------------------------------- */
 
 void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
@@ -1438,11 +1529,15 @@ void cx88_card_setup(struct cx88_core *core)
        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
+       case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
                /* GPIO0:0 is hooked to mt352 reset pin */
                cx_set(MO_GP0_IO, 0x00000101);
                cx_clear(MO_GP0_IO, 0x00000001);
                msleep(1);
                cx_set(MO_GP0_IO, 0x00000101);
+               if (0 == core->i2c_rc &&
+                   core->board == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID)
+                       dvico_fusionhdtv_hybrid_init(core);
                break;
        case CX88_BOARD_KWORLD_DVB_T:
        case CX88_BOARD_DNTV_LIVE_DVB_T:
@@ -1460,7 +1555,7 @@ void cx88_card_setup(struct cx88_core *core)
                if (0 == core->i2c_rc) {
                        /* enable tuner */
                        int i;
-                       u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
+                       static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
                        core->i2c_client.addr = 0x0a;
 
                        for (i = 0; i < 5; i++)
index 3720f24a25cf751744c0b389c856f6c5857d884b..c2cdbafdb77b34ae3b06b723f5e963e61854f92b 100644 (file)
@@ -163,7 +163,7 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 
        /* save pointer to jmp instruction address */
        risc->jmp = rp;
-       BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
+       BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
        return 0;
 }
 
@@ -188,7 +188,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 
        /* save pointer to jmp instruction address */
        risc->jmp = rp;
-       BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
+       BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
        return 0;
 }
 
@@ -215,8 +215,7 @@ int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
 void
 cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf)
 {
-       if (in_interrupt())
-               BUG();
+       BUG_ON(in_interrupt());
        videobuf_waiton(&buf->vb,0,0);
        videobuf_dma_pci_unmap(pci, &buf->vb.dma);
        videobuf_dma_free(&buf->vb.dma);
@@ -1061,7 +1060,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
        core->pci_bus  = pci->bus->number;
        core->pci_slot = PCI_SLOT(pci->devfn);
        core->pci_irqmask = 0x00fc00;
-       init_MUTEX(&core->lock);
+       mutex_init(&core->lock);
 
        core->nr = cx88_devcount++;
        sprintf(core->name,"cx88[%d]",core->nr);
index e48aa3f6e50012a1c2e854a9d96943e11337038d..a9fc2695b157449c18670f0a37d4bca257098596 100644 (file)
@@ -40,6 +40,9 @@
 #  include "cx88-vp3054-i2c.h"
 # endif
 #endif
+#ifdef HAVE_ZL10353
+# include "zl10353.h"
+#endif
 #ifdef HAVE_CX22702
 # include "cx22702.h"
 #endif
@@ -111,6 +114,21 @@ static struct videobuf_queue_ops dvb_qops = {
 
 /* ------------------------------------------------------------------ */
 
+#if defined(HAVE_MT352) || defined(HAVE_ZL10353)
+static int zarlink_pll_set(struct dvb_frontend *fe,
+                             struct dvb_frontend_parameters *params,
+                             u8 *pllbuf)
+{
+       struct cx8802_dev *dev = fe->dvb->priv;
+
+       pllbuf[0] = dev->core->pll_addr << 1;
+       dvb_pll_configure(dev->core->pll_desc, pllbuf + 1,
+                         params->frequency,
+                         params->u.ofdm.bandwidth);
+       return 0;
+}
+#endif
+
 #ifdef HAVE_MT352
 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
 {
@@ -176,35 +194,22 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
        return 0;
 }
 
-static int mt352_pll_set(struct dvb_frontend* fe,
-                        struct dvb_frontend_parameters* params,
-                        u8* pllbuf)
-{
-       struct cx8802_dev *dev= fe->dvb->priv;
-
-       pllbuf[0] = dev->core->pll_addr << 1;
-       dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
-                         params->frequency,
-                         params->u.ofdm.bandwidth);
-       return 0;
-}
-
 static struct mt352_config dvico_fusionhdtv = {
        .demod_address = 0x0F,
        .demod_init    = dvico_fusionhdtv_demod_init,
-       .pll_set       = mt352_pll_set,
+       .pll_set       = zarlink_pll_set,
 };
 
 static struct mt352_config dntv_live_dvbt_config = {
        .demod_address = 0x0f,
        .demod_init    = dntv_live_dvbt_demod_init,
-       .pll_set       = mt352_pll_set,
+       .pll_set       = zarlink_pll_set,
 };
 
 static struct mt352_config dvico_fusionhdtv_dual = {
        .demod_address = 0x0F,
        .demod_init    = dvico_dual_demod_init,
-       .pll_set       = mt352_pll_set,
+       .pll_set       = zarlink_pll_set,
 };
 
 #ifdef HAVE_VP3054_I2C
@@ -294,6 +299,46 @@ static struct mt352_config dntv_live_dvbt_pro_config = {
 #endif
 #endif
 
+#ifdef HAVE_ZL10353
+static int dvico_hybrid_tune_pll(struct dvb_frontend *fe,
+                                struct dvb_frontend_parameters *params,
+                                u8 *pllbuf)
+{
+       struct cx8802_dev *dev= fe->dvb->priv;
+       struct i2c_msg msg =
+               { .addr = dev->core->pll_addr, .flags = 0,
+                 .buf = pllbuf + 1, .len = 4 };
+       int err;
+
+       pllbuf[0] = dev->core->pll_addr << 1;
+       dvb_pll_configure(dev->core->pll_desc, pllbuf + 1,
+                         params->frequency,
+                         params->u.ofdm.bandwidth);
+
+       if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
+               printk(KERN_WARNING "cx88-dvb: %s error "
+                          "(addr %02x <- %02x, err = %i)\n",
+                          __FUNCTION__, pllbuf[0], pllbuf[1], err);
+               if (err < 0)
+                       return err;
+               else
+                       return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static struct zl10353_config dvico_fusionhdtv_hybrid = {
+       .demod_address = 0x0F,
+       .pll_set       = dvico_hybrid_tune_pll,
+};
+
+static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
+       .demod_address = 0x0F,
+       .pll_set       = zarlink_pll_set,
+};
+#endif
+
 #ifdef HAVE_CX22702
 static struct cx22702_config connexant_refboard_config = {
        .demod_address = 0x43,
@@ -500,16 +545,27 @@ static int dvb_register(struct cx8802_dev *dev)
                                                   &dev->core->i2c_adap);
                break;
 #endif
+#if defined(HAVE_MT352) || defined(HAVE_ZL10353)
+       case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
+               dev->core->pll_addr = 0x60;
+               dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
 #ifdef HAVE_MT352
-       case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
-               dev->core->pll_addr = 0x61;
-               dev->core->pll_desc = &dvb_pll_lg_z201;
                dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
                                                 &dev->core->i2c_adap);
+               if (dev->dvb.frontend != NULL)
+                       break;
+#endif
+#ifdef HAVE_ZL10353
+               /* ZL10353 replaces MT352 on later cards */
+               dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_plus_v1_1,
+                                                  &dev->core->i2c_adap);
+#endif
                break;
-       case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
-               dev->core->pll_addr = 0x60;
-               dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
+#endif /* HAVE_MT352 || HAVE_ZL10353 */
+#ifdef HAVE_MT352
+       case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
+               dev->core->pll_addr = 0x61;
+               dev->core->pll_desc = &dvb_pll_lg_z201;
                dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
                                                 &dev->core->i2c_adap);
                break;
@@ -540,6 +596,14 @@ static int dvb_register(struct cx8802_dev *dev)
                                                 &dev->core->i2c_adap);
                break;
 #endif
+#ifdef HAVE_ZL10353
+       case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
+               dev->core->pll_addr = 0x61;
+               dev->core->pll_desc = &dvb_pll_thomson_fe6600;
+               dev->dvb.frontend = zl10353_attach(&dvico_fusionhdtv_hybrid,
+                                                  &dev->core->i2c_adap);
+               break;
+#endif
 #ifdef HAVE_OR51132
        case CX88_BOARD_PCHDTV_HD3000:
                dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
index 165d948624a3f53f9321f2f22b9a73038a118fc8..78a63b7dd380a33e806ef0f2c9d000eb523b6314 100644 (file)
 
 /* ---------------------------------------------------------------------- */
 
-/* DigitalNow DNTV Live DVB-T Remote */
-static IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = {
-       [0x00] = KEY_ESC,               /* 'go up a level?' */
-       /* Keys 0 to 9 */
-       [0x0a] = KEY_KP0,
-       [0x01] = KEY_KP1,
-       [0x02] = KEY_KP2,
-       [0x03] = KEY_KP3,
-       [0x04] = KEY_KP4,
-       [0x05] = KEY_KP5,
-       [0x06] = KEY_KP6,
-       [0x07] = KEY_KP7,
-       [0x08] = KEY_KP8,
-       [0x09] = KEY_KP9,
-
-       [0x0b] = KEY_TUNER,             /* tv/fm */
-       [0x0c] = KEY_SEARCH,            /* scan */
-       [0x0d] = KEY_STOP,
-       [0x0e] = KEY_PAUSE,
-       [0x0f] = KEY_LIST,              /* source */
-
-       [0x10] = KEY_MUTE,
-       [0x11] = KEY_REWIND,            /* backward << */
-       [0x12] = KEY_POWER,
-       [0x13] = KEY_S,                 /* snap */
-       [0x14] = KEY_AUDIO,             /* stereo */
-       [0x15] = KEY_CLEAR,             /* reset */
-       [0x16] = KEY_PLAY,
-       [0x17] = KEY_ENTER,
-       [0x18] = KEY_ZOOM,              /* full screen */
-       [0x19] = KEY_FASTFORWARD,       /* forward >> */
-       [0x1a] = KEY_CHANNELUP,
-       [0x1b] = KEY_VOLUMEUP,
-       [0x1c] = KEY_INFO,              /* preview */
-       [0x1d] = KEY_RECORD,            /* record */
-       [0x1e] = KEY_CHANNELDOWN,
-       [0x1f] = KEY_VOLUMEDOWN,
-};
-
-/* ---------------------------------------------------------------------- */
-
-/* IO-DATA BCTV7E Remote */
-static IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = {
-       [0x40] = KEY_TV,
-       [0x20] = KEY_RADIO,             /* FM */
-       [0x60] = KEY_EPG,
-       [0x00] = KEY_POWER,
-
-       /* Keys 0 to 9 */
-       [0x44] = KEY_KP0,               /* 10 */
-       [0x50] = KEY_KP1,
-       [0x30] = KEY_KP2,
-       [0x70] = KEY_KP3,
-       [0x48] = KEY_KP4,
-       [0x28] = KEY_KP5,
-       [0x68] = KEY_KP6,
-       [0x58] = KEY_KP7,
-       [0x38] = KEY_KP8,
-       [0x78] = KEY_KP9,
-
-       [0x10] = KEY_L,                 /* Live */
-       [0x08] = KEY_T,                 /* Time Shift */
-
-       [0x18] = KEY_PLAYPAUSE,         /* Play */
-
-       [0x24] = KEY_ENTER,             /* 11 */
-       [0x64] = KEY_ESC,               /* 12 */
-       [0x04] = KEY_M,                 /* Multi */
-
-       [0x54] = KEY_VIDEO,
-       [0x34] = KEY_CHANNELUP,
-       [0x74] = KEY_VOLUMEUP,
-       [0x14] = KEY_MUTE,
-
-       [0x4c] = KEY_S,                 /* SVIDEO */
-       [0x2c] = KEY_CHANNELDOWN,
-       [0x6c] = KEY_VOLUMEDOWN,
-       [0x0c] = KEY_ZOOM,
-
-       [0x5c] = KEY_PAUSE,
-       [0x3c] = KEY_C,                 /* || (red) */
-       [0x7c] = KEY_RECORD,            /* recording */
-       [0x1c] = KEY_STOP,
-
-       [0x41] = KEY_REWIND,            /* backward << */
-       [0x21] = KEY_PLAY,
-       [0x61] = KEY_FASTFORWARD,       /* forward >> */
-       [0x01] = KEY_NEXT,              /* skip >| */
-};
-
-/* ---------------------------------------------------------------------- */
-
-/* ADS Tech Instant TV DVB-T PCI Remote */
-static IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = {
-       /* Keys 0 to 9 */
-       [0x4d] = KEY_0,
-       [0x57] = KEY_1,
-       [0x4f] = KEY_2,
-       [0x53] = KEY_3,
-       [0x56] = KEY_4,
-       [0x4e] = KEY_5,
-       [0x5e] = KEY_6,
-       [0x54] = KEY_7,
-       [0x4c] = KEY_8,
-       [0x5c] = KEY_9,
-
-       [0x5b] = KEY_POWER,
-       [0x5f] = KEY_MUTE,
-       [0x55] = KEY_GOTO,
-       [0x5d] = KEY_SEARCH,
-       [0x17] = KEY_EPG,               /* Guide */
-       [0x1f] = KEY_MENU,
-       [0x0f] = KEY_UP,
-       [0x46] = KEY_DOWN,
-       [0x16] = KEY_LEFT,
-       [0x1e] = KEY_RIGHT,
-       [0x0e] = KEY_SELECT,            /* Enter */
-       [0x5a] = KEY_INFO,
-       [0x52] = KEY_EXIT,
-       [0x59] = KEY_PREVIOUS,
-       [0x51] = KEY_NEXT,
-       [0x58] = KEY_REWIND,
-       [0x50] = KEY_FORWARD,
-       [0x44] = KEY_PLAYPAUSE,
-       [0x07] = KEY_STOP,
-       [0x1b] = KEY_RECORD,
-       [0x13] = KEY_TUNER,             /* Live */
-       [0x0a] = KEY_A,
-       [0x12] = KEY_B,
-       [0x03] = KEY_PROG1,             /* 1 */
-       [0x01] = KEY_PROG2,             /* 2 */
-       [0x00] = KEY_PROG3,             /* 3 */
-       [0x06] = KEY_DVD,
-       [0x48] = KEY_AUX,               /* Photo */
-       [0x40] = KEY_VIDEO,
-       [0x19] = KEY_AUDIO,             /* Music */
-       [0x0b] = KEY_CHANNELUP,
-       [0x08] = KEY_CHANNELDOWN,
-       [0x15] = KEY_VOLUMEUP,
-       [0x1c] = KEY_VOLUMEDOWN,
-};
-
-/* ---------------------------------------------------------------------- */
-
-/* MSI TV@nywhere remote */
-static IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
-       /* Keys 0 to 9 */
-       [0x00] = KEY_0,
-       [0x01] = KEY_1,
-       [0x02] = KEY_2,
-       [0x03] = KEY_3,
-       [0x04] = KEY_4,
-       [0x05] = KEY_5,
-       [0x06] = KEY_6,
-       [0x07] = KEY_7,
-       [0x08] = KEY_8,
-       [0x09] = KEY_9,
-
-       [0x0c] = KEY_MUTE,
-       [0x0f] = KEY_SCREEN,            /* Full Screen */
-       [0x10] = KEY_F,                 /* Funtion */
-       [0x11] = KEY_T,                 /* Time shift */
-       [0x12] = KEY_POWER,
-       [0x13] = KEY_MEDIA,             /* MTS */
-       [0x14] = KEY_SLOW,
-       [0x16] = KEY_REWIND,            /* backward << */
-       [0x17] = KEY_ENTER,             /* Return */
-       [0x18] = KEY_FASTFORWARD,       /* forward >> */
-       [0x1a] = KEY_CHANNELUP,
-       [0x1b] = KEY_VOLUMEUP,
-       [0x1e] = KEY_CHANNELDOWN,
-       [0x1f] = KEY_VOLUMEDOWN,
-};
-
-/* ---------------------------------------------------------------------- */
-
-/* Cinergy 1400 DVB-T */
-static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
-       [0x01] = KEY_POWER,
-       [0x02] = KEY_1,
-       [0x03] = KEY_2,
-       [0x04] = KEY_3,
-       [0x05] = KEY_4,
-       [0x06] = KEY_5,
-       [0x07] = KEY_6,
-       [0x08] = KEY_7,
-       [0x09] = KEY_8,
-       [0x0a] = KEY_9,
-       [0x0c] = KEY_0,
-
-       [0x0b] = KEY_VIDEO,
-       [0x0d] = KEY_REFRESH,
-       [0x0e] = KEY_SELECT,
-       [0x0f] = KEY_EPG,
-       [0x10] = KEY_UP,
-       [0x11] = KEY_LEFT,
-       [0x12] = KEY_OK,
-       [0x13] = KEY_RIGHT,
-       [0x14] = KEY_DOWN,
-       [0x15] = KEY_TEXT,
-       [0x16] = KEY_INFO,
-
-       [0x17] = KEY_RED,
-       [0x18] = KEY_GREEN,
-       [0x19] = KEY_YELLOW,
-       [0x1a] = KEY_BLUE,
-
-       [0x1b] = KEY_CHANNELUP,
-       [0x1c] = KEY_VOLUMEUP,
-       [0x1d] = KEY_MUTE,
-       [0x1e] = KEY_VOLUMEDOWN,
-       [0x1f] = KEY_CHANNELDOWN,
-
-       [0x40] = KEY_PAUSE,
-       [0x4c] = KEY_PLAY,
-       [0x58] = KEY_RECORD,
-       [0x54] = KEY_PREVIOUS,
-       [0x48] = KEY_STOP,
-       [0x5c] = KEY_NEXT,
-};
-
-/* ---------------------------------------------------------------------- */
-
-/* AVERTV STUDIO 303 Remote */
-static IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = {
-       [ 0x2a ] = KEY_KP1,
-       [ 0x32 ] = KEY_KP2,
-       [ 0x3a ] = KEY_KP3,
-       [ 0x4a ] = KEY_KP4,
-       [ 0x52 ] = KEY_KP5,
-       [ 0x5a ] = KEY_KP6,
-       [ 0x6a ] = KEY_KP7,
-       [ 0x72 ] = KEY_KP8,
-       [ 0x7a ] = KEY_KP9,
-       [ 0x0e ] = KEY_KP0,
-
-       [ 0x02 ] = KEY_POWER,
-       [ 0x22 ] = KEY_VIDEO,
-       [ 0x42 ] = KEY_AUDIO,
-       [ 0x62 ] = KEY_ZOOM,
-       [ 0x0a ] = KEY_TV,
-       [ 0x12 ] = KEY_CD,
-       [ 0x1a ] = KEY_TEXT,
-
-       [ 0x16 ] = KEY_SUBTITLE,
-       [ 0x1e ] = KEY_REWIND,
-       [ 0x06 ] = KEY_PRINT,
-
-       [ 0x2e ] = KEY_SEARCH,
-       [ 0x36 ] = KEY_SLEEP,
-       [ 0x3e ] = KEY_SHUFFLE,
-       [ 0x26 ] = KEY_MUTE,
-
-       [ 0x4e ] = KEY_RECORD,
-       [ 0x56 ] = KEY_PAUSE,
-       [ 0x5e ] = KEY_STOP,
-       [ 0x46 ] = KEY_PLAY,
-
-       [ 0x6e ] = KEY_RED,
-       [ 0x0b ] = KEY_GREEN,
-       [ 0x66 ] = KEY_YELLOW,
-       [ 0x03 ] = KEY_BLUE,
-
-       [ 0x76 ] = KEY_LEFT,
-       [ 0x7e ] = KEY_RIGHT,
-       [ 0x13 ] = KEY_DOWN,
-       [ 0x1b ] = KEY_UP,
-};
-
-/* ---------------------------------------------------------------------- */
-
-/* DigitalNow DNTV Live! DVB-T Pro Remote */
-static IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = {
-       [ 0x16 ] = KEY_POWER,
-       [ 0x5b ] = KEY_HOME,
-
-       [ 0x55 ] = KEY_TV,              /* live tv */
-       [ 0x58 ] = KEY_TUNER,           /* digital Radio */
-       [ 0x5a ] = KEY_RADIO,           /* FM radio */
-       [ 0x59 ] = KEY_DVD,             /* dvd menu */
-       [ 0x03 ] = KEY_1,
-       [ 0x01 ] = KEY_2,
-       [ 0x06 ] = KEY_3,
-       [ 0x09 ] = KEY_4,
-       [ 0x1d ] = KEY_5,
-       [ 0x1f ] = KEY_6,
-       [ 0x0d ] = KEY_7,
-       [ 0x19 ] = KEY_8,
-       [ 0x1b ] = KEY_9,
-       [ 0x0c ] = KEY_CANCEL,
-       [ 0x15 ] = KEY_0,
-       [ 0x4a ] = KEY_CLEAR,
-       [ 0x13 ] = KEY_BACK,
-       [ 0x00 ] = KEY_TAB,
-       [ 0x4b ] = KEY_UP,
-       [ 0x4e ] = KEY_LEFT,
-       [ 0x4f ] = KEY_OK,
-       [ 0x52 ] = KEY_RIGHT,
-       [ 0x51 ] = KEY_DOWN,
-       [ 0x1e ] = KEY_VOLUMEUP,
-       [ 0x0a ] = KEY_VOLUMEDOWN,
-       [ 0x02 ] = KEY_CHANNELDOWN,
-       [ 0x05 ] = KEY_CHANNELUP,
-       [ 0x11 ] = KEY_RECORD,
-       [ 0x14 ] = KEY_PLAY,
-       [ 0x4c ] = KEY_PAUSE,
-       [ 0x1a ] = KEY_STOP,
-       [ 0x40 ] = KEY_REWIND,
-       [ 0x12 ] = KEY_FASTFORWARD,
-       [ 0x41 ] = KEY_PREVIOUSSONG,    /* replay |< */
-       [ 0x42 ] = KEY_NEXTSONG,        /* skip >| */
-       [ 0x54 ] = KEY_CAMERA,          /* capture */
-       [ 0x50 ] = KEY_LANGUAGE,        /* sap */
-       [ 0x47 ] = KEY_TV2,             /* pip */
-       [ 0x4d ] = KEY_SCREEN,
-       [ 0x43 ] = KEY_SUBTITLE,
-       [ 0x10 ] = KEY_MUTE,
-       [ 0x49 ] = KEY_AUDIO,           /* l/r */
-       [ 0x07 ] = KEY_SLEEP,
-       [ 0x08 ] = KEY_VIDEO,           /* a/v */
-       [ 0x0e ] = KEY_PREVIOUS,        /* recall */
-       [ 0x45 ] = KEY_ZOOM,            /* zoom + */
-       [ 0x46 ] = KEY_ANGLE,           /* zoom - */
-       [ 0x56 ] = KEY_RED,
-       [ 0x57 ] = KEY_GREEN,
-       [ 0x5c ] = KEY_YELLOW,
-       [ 0x5d ] = KEY_BLUE,
-};
-
-/* ---------------------------------------------------------------------- */
-
 struct cx88_IR {
        struct cx88_core *core;
        struct input_dev *input;
@@ -517,6 +186,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
                ir->mask_keydown = 0x02;
                ir->polling = 5; /* ms */
                break;
+       case CX88_BOARD_PROLINK_PLAYTVPVR:
        case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
                ir_codes = ir_codes_pixelview;
                ir->gpio_addr = MO_GP1_IO;
@@ -524,6 +194,13 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
                ir->mask_keyup = 0x80;
                ir->polling = 1; /* ms */
                break;
+       case CX88_BOARD_KWORLD_LTV883:
+               ir_codes = ir_codes_pixelview;
+               ir->gpio_addr = MO_GP1_IO;
+               ir->mask_keycode = 0x1f;
+               ir->mask_keyup = 0x60;
+               ir->polling = 1; /* ms */
+               break;
        case CX88_BOARD_ADSTECH_DVB_T_PCI:
                ir_codes = ir_codes_adstech_dvb_t_pci;
                ir->gpio_addr = MO_GP1_IO;
index 073494ceab0fbe17d59357d4eed19c9742cada9a..6c97aa740d27f776f381aa7e2b5b2864325c8160 100644 (file)
@@ -227,7 +227,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
                        .minimum       = 0x00,
                        .maximum       = 0xff,
                        .step          = 1,
-                       .default_value = 0,
+                       .default_value = 0x7f,
                        .type          = V4L2_CTRL_TYPE_INTEGER,
                },
                .off                   = 128,
@@ -255,7 +255,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
                        .minimum       = 0,
                        .maximum       = 0xff,
                        .step          = 1,
-                       .default_value = 0,
+                       .default_value = 0x7f,
                        .type          = V4L2_CTRL_TYPE_INTEGER,
                },
                .off                   = 128,
@@ -300,7 +300,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
                        .minimum       = 0,
                        .maximum       = 0x3f,
                        .step          = 1,
-                       .default_value = 0x1f,
+                       .default_value = 0x3f,
                        .type          = V4L2_CTRL_TYPE_INTEGER,
                },
                .reg                   = AUD_VOL_CTL,
@@ -336,17 +336,17 @@ static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bi
                return 1;
 
        /* is it free? */
-       down(&core->lock);
+       mutex_lock(&core->lock);
        if (dev->resources & bit) {
                /* no, someone else uses it */
-               up(&core->lock);
+               mutex_unlock(&core->lock);
                return 0;
        }
        /* it's free, grab it */
        fh->resources  |= bit;
        dev->resources |= bit;
        dprintk(1,"res: get %d\n",bit);
-       up(&core->lock);
+       mutex_unlock(&core->lock);
        return 1;
 }
 
@@ -366,14 +366,13 @@ static
 void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits)
 {
        struct cx88_core *core = dev->core;
-       if ((fh->resources & bits) != bits)
-               BUG();
+       BUG_ON((fh->resources & bits) != bits);
 
-       down(&core->lock);
+       mutex_lock(&core->lock);
        fh->resources  &= ~bits;
        dev->resources &= ~bits;
        dprintk(1,"res: put %d\n",bits);
-       up(&core->lock);
+       mutex_unlock(&core->lock);
 }
 
 /* ------------------------------------------------------------------ */
@@ -909,7 +908,8 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl)
        value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg);
        switch (ctl->id) {
        case V4L2_CID_AUDIO_BALANCE:
-               ctl->value = (value & 0x40) ? (value & 0x3f) : (0x40 - (value & 0x3f));
+               ctl->value = ((value & 0x7f) < 0x40) ? ((value & 0x7f) + 0x40)
+                                       : (0x7f - (value & 0x7f));
                break;
        case V4L2_CID_AUDIO_VOLUME:
                ctl->value = 0x3f - (value & 0x3f);
@@ -918,9 +918,9 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl)
                ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift;
                break;
        }
-       printk("get_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
-                                       ctl->id, c->reg, ctl->value,
-                                       c->mask, c->sreg ? " [shadowed]" : "");
+       dprintk(1,"get_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
+                               ctl->id, c->v.name, ctl->value, c->reg,
+                               value,c->mask, c->sreg ? " [shadowed]" : "");
        return 0;
 }
 
@@ -946,7 +946,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
        mask=c->mask;
        switch (ctl->id) {
        case V4L2_CID_AUDIO_BALANCE:
-               value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value;
+               value = (ctl->value < 0x40) ? (0x7f - ctl->value) : (ctl->value - 0x40);
                break;
        case V4L2_CID_AUDIO_VOLUME:
                value = 0x3f - (ctl->value & 0x3f);
@@ -969,9 +969,9 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
                value = ((ctl->value - c->off) << c->shift) & c->mask;
                break;
        }
-       printk("set_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
-                                       ctl->id, c->reg, value,
-                                       mask, c->sreg ? " [shadowed]" : "");
+       dprintk(1,"set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
+                               ctl->id, c->v.name, ctl->value, c->reg, value,
+                               mask, c->sreg ? " [shadowed]" : "");
        if (c->sreg) {
                cx_sandor(c->sreg, c->reg, mask, value);
        } else {
@@ -987,8 +987,7 @@ static void init_controls(struct cx88_core *core)
 
        for (i = 0; i < CX8800_CTLS; i++) {
                ctrl.id=cx8800_ctls[i].v.id;
-               ctrl.value=cx8800_ctls[i].v.default_value
-                               +cx8800_ctls[i].off;
+               ctrl.value=cx8800_ctls[i].v.default_value;
                set_control(core, &ctrl);
        }
 }
@@ -1252,7 +1251,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
 {
        int err;
 
-       dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
+       dprintk(2, "CORE IOCTL: 0x%x\n", cmd );
        if (video_debug > 1)
                v4l_print_ioctl(core->name,cmd);
 
@@ -1291,9 +1290,9 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
                if (i == ARRAY_SIZE(tvnorms))
                        return -EINVAL;
 
-               down(&core->lock);
+               mutex_lock(&core->lock);
                cx88_set_tvnorm(core,&tvnorms[i]);
-               up(&core->lock);
+               mutex_unlock(&core->lock);
                return 0;
        }
 
@@ -1343,10 +1342,10 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
 
                if (*i >= 4)
                        return -EINVAL;
-               down(&core->lock);
+               mutex_lock(&core->lock);
                cx88_newstation(core);
                video_mux(core,*i);
-               up(&core->lock);
+               mutex_unlock(&core->lock);
                return 0;
        }
 
@@ -1438,7 +1437,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
                        return -EINVAL;
                if (1 == radio && f->type != V4L2_TUNER_RADIO)
                        return -EINVAL;
-               down(&core->lock);
+               mutex_lock(&core->lock);
                core->freq = f->frequency;
                cx88_newstation(core);
                cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
@@ -1447,7 +1446,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
                msleep (10);
                cx88_set_tvaudio(core);
 
-               up(&core->lock);
+               mutex_unlock(&core->lock);
                return 0;
        }
 
@@ -1921,11 +1920,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
        pci_set_drvdata(pci_dev,dev);
 
        /* initial device configuration */
-       down(&core->lock);
+       mutex_lock(&core->lock);
        cx88_set_tvnorm(core,tvnorms);
        init_controls(core);
        video_mux(core,0);
-       up(&core->lock);
+       mutex_unlock(&core->lock);
 
        /* start tvaudio thread */
        if (core->tuner_type != TUNER_ABSENT)
index e9fd55b57fa61d3b691ee757f8f9388fcd1c1bd3..cfa8668784b42f7aa754105adee998e4b68b47a5 100644 (file)
@@ -35,6 +35,7 @@
 #include "cx88-reg.h"
 
 #include <linux/version.h>
+#include <linux/mutex.h>
 #define CX88_VERSION_CODE KERNEL_VERSION(0,0,5)
 
 #ifndef TRUE
@@ -62,7 +63,7 @@
 /* need "shadow" registers for some write-only ones ... */
 #define SHADOW_AUD_VOL_CTL           1
 #define SHADOW_AUD_BAL_CTL           2
-#define SHADOW_MAX                   2
+#define SHADOW_MAX                   3
 
 /* FM Radio deemphasis type */
 enum cx88_deemph_type {
@@ -187,6 +188,8 @@ extern struct sram_channel cx88_sram_channels[];
 #define CX88_BOARD_DNTV_LIVE_DVB_T_PRO     42
 #define CX88_BOARD_KWORLD_DVB_T_CX22702    43
 #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44
+#define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45
+#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID 46
 
 enum cx88_itype {
        CX88_VMUX_COMPOSITE1 = 1,
@@ -308,8 +311,7 @@ struct cx88_core {
        /* IR remote control state */
        struct cx88_IR             *ir;
 
-       struct semaphore           lock;
-
+       struct mutex               lock;
        /* various v4l controls */
        u32                        freq;
 
index 2831bdd120573b911a5e719670db3be550bbb205..0fcc935828f8e8a23e4f90523e3a54abfc3727a9 100644 (file)
@@ -1,6 +1,6 @@
 /*
     dpc7146.c - v4l2 driver for the dpc7146 demonstration board
-    
+
     Copyright (C) 2000-2003 Michael Hunold <michael@mihu.de>
 
     This program is free software; you can redistribute it and/or modify
@@ -52,7 +52,7 @@
 #define SAA711X_DECODED_BYTES_OF_TS_2   0x1C
 #define SAA711X_STATUS_BYTE             0x1F
 
-#define DPC_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0) 
+#define DPC_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0)
 
 static int debug = 0;
 module_param(debug, int, 0);
@@ -81,16 +81,16 @@ struct dpc
        struct video_device     *video_dev;
        struct video_device     *vbi_dev;
 
-       struct i2c_adapter      i2c_adapter;    
+       struct i2c_adapter      i2c_adapter;
        struct i2c_client       *saa7111a;
-       
+
        int cur_input;  /* current input */
 };
 
 /* fixme: add vbi stuff here */
 static int dpc_probe(struct saa7146_dev* dev)
 {
-       struct dpc* dpc = NULL; 
+       struct dpc* dpc = NULL;
        struct i2c_client *client;
        struct list_head *item;
 
@@ -118,20 +118,20 @@ static int dpc_probe(struct saa7146_dev* dev)
        /* loop through all i2c-devices on the bus and look who is there */
        list_for_each(item,&dpc->i2c_adapter.clients) {
                client = list_entry(item, struct i2c_client, list);
-               if( I2C_SAA7111A == client->addr ) 
+               if( I2C_SAA7111A == client->addr )
                        dpc->saa7111a = client;
        }
 
        /* check if all devices are present */
        if( 0 == dpc->saa7111a ) {
-               DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n"));    
+               DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n"));
                i2c_del_adapter(&dpc->i2c_adapter);
                kfree(dpc);
                return -ENODEV;
        }
-       
-       /* all devices are present, probe was successful */     
-       DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n"));  
+
+       /* all devices are present, probe was successful */
+       DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n"));
 
        /* we store the pointer in our private data field */
        dev->ext_priv = dpc;
@@ -182,7 +182,7 @@ static struct saa7146_ext_vv vv_data;
 static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
 {
        struct dpc* dpc = (struct dpc*)dev->ext_priv;
-       
+
        DEB_D(("dpc_v4l2.o: dpc_attach called.\n"));
 
        /* checking for i2c-devices can be omitted here, because we
@@ -193,7 +193,7 @@ static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data
                ERR(("cannot register capture v4l2 device. skipping.\n"));
                return -1;
        }
-       
+
        /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
        if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) {
                if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) {
@@ -205,18 +205,18 @@ static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data
 
        printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num);
        dpc_num++;
-       
+
        /* the rest */
        dpc->cur_input = 0;
        dpc_init_done(dev);
-       
+
        return 0;
 }
 
 static int dpc_detach(struct saa7146_dev* dev)
 {
        struct dpc* dpc = (struct dpc*)dev->ext_priv;
-       
+
        DEB_EE(("dev:%p\n",dev));
 
        i2c_release_client(dpc->saa7111a);
@@ -238,25 +238,25 @@ static int dpc_detach(struct saa7146_dev* dev)
 int dpc_vbi_bypass(struct saa7146_dev* dev)
 {
        struct dpc* dpc = (struct dpc*)dev->ext_priv;
-       
+
        int i = 1;
 
        /* switch bypass in saa7111a */
        if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) {
                printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n");
                return -1;
-       }                       
+       }
 
        return 0;
 }
 #endif
 
-static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
+static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
 {
        struct saa7146_dev *dev = fh->dev;
        struct dpc* dpc = (struct dpc*)dev->ext_priv;
 /*
-       struct saa7146_vv *vv = dev->vv_data; 
+       struct saa7146_vv *vv = dev->vv_data;
 */
        switch(cmd)
        {
@@ -264,11 +264,11 @@ static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
        {
                struct v4l2_input *i = arg;
                DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
-               
+
                if( i->index < 0 || i->index >= DPC_INPUTS) {
                        return -EINVAL;
                }
-               
+
                memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input));
 
                DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index));
@@ -289,13 +289,13 @@ static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                if (input < 0 || input >= DPC_INPUTS) {
                        return -EINVAL;
                }
-       
+
                dpc->cur_input = input;
 
                /* fixme: switch input here, switch audio, too! */
 //             saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
                printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n");
-               
+
                return 0;
        }
        default:
@@ -334,8 +334,8 @@ static struct saa7146_standard standard[] = {
 static struct saa7146_extension extension;
 
 static struct saa7146_pci_extension_data dpc = {
-        .ext_priv = "Multimedia eXtension Board",
-        .ext = &extension,
+       .ext_priv = "Multimedia eXtension Board",
+       .ext = &extension,
 };
 
 static struct pci_device_id pci_tbl[] = {
@@ -357,7 +357,7 @@ static struct saa7146_ext_vv vv_data = {
        .capabilities   = V4L2_CAP_VBI_CAPTURE,
        .stds           = &standard[0],
        .num_stds       = sizeof(standard)/sizeof(struct saa7146_standard),
-       .std_callback   = &std_callback, 
+       .std_callback   = &std_callback,
        .ioctls         = &ioctls[0],
        .ioctl          = dpc_ioctl,
 };
@@ -365,7 +365,7 @@ static struct saa7146_ext_vv vv_data = {
 static struct saa7146_extension extension = {
        .name           = "dpc7146 demonstration board",
        .flags          = SAA7146_USE_I2C_IRQ,
-       
+
        .pci_tbl        = &pci_tbl[0],
        .module         = THIS_MODULE,
 
@@ -375,7 +375,7 @@ static struct saa7146_extension extension = {
 
        .irq_mask       = 0,
        .irq_func       = NULL,
-};     
+};
 
 static int __init dpc_init_module(void)
 {
@@ -383,7 +383,7 @@ static int __init dpc_init_module(void)
                DEB_S(("failed to register extension.\n"));
                return -ENODEV;
        }
-       
+
        return 0;
 }
 
index 885fd01700864f47e40d60fc1c1e757724fd365d..5a793ae7cc23d40c8bab720f45d57478e0a15f07 100644 (file)
@@ -5,6 +5,7 @@ config VIDEO_EM28XX
        select VIDEO_TUNER
        select VIDEO_TVEEPROM
        select VIDEO_IR
+       select VIDEO_SAA711X
        ---help---
          This is a video4linux driver for Empia 28xx based TV cards.
 
index 58f7b4194a0d51a6359475923c93c84e6583dad5..4e22fc4889e14d3117f8aa2daf00cddf84309e23 100644 (file)
@@ -72,6 +72,24 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = 1,
                }},
        },
+       [EM2820_BOARD_KWORLD_PVRTV2800RF] = {
+               .name         = "Kworld PVR TV 2800 RF",
+               .is_em2800    = 0,
+               .vchannels    = 2,
+               .norm         = VIDEO_MODE_PAL,
+               .tda9887_conf = TDA9887_PRESENT,
+               .has_tuner    = 1,
+               .decoder      = EM28XX_SAA7113,
+               .input           = {{
+                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .vmux     = 0,
+                       .amux     = 1,
+               },{
+                       .type     = EM28XX_VMUX_SVIDEO,
+                       .vmux     = 9,
+                       .amux     = 1,
+               }},
+       },
        [EM2820_BOARD_TERRATEC_CINERGY_250] = {
                .name         = "Terratec Cinergy 250 USB",
                .vchannels    = 3,
@@ -83,7 +101,7 @@ struct em28xx_board em28xx_boards[] = {
                .input          = {{
                        .type     = EM28XX_VMUX_TELEVISION,
                        .vmux     = 2,
-                       .amux     = 0,
+                       .amux     = 1,
                },{
                        .type     = EM28XX_VMUX_COMPOSITE1,
                        .vmux     = 0,
@@ -257,27 +275,51 @@ struct usb_device_id em28xx_id_table [] = {
        { },
 };
 
+void em28xx_pre_card_setup(struct em28xx *dev)
+{
+       /* request some modules */
+       switch(dev->model){
+               case EM2880_BOARD_TERRATEC_PRODIGY_XS:
+               case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
+               case EM2880_BOARD_TERRATEC_HYBRID_XS:
+                       {
+                               em28xx_write_regs_req(dev, 0x00, 0x08, "\x7d", 1); // reset through GPIO?
+                               break;
+                       }
+       }
+}
+
 void em28xx_card_setup(struct em28xx *dev)
 {
        /* request some modules */
-       if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) {
-               struct tveeprom tv;
+       switch(dev->model){
+               case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
+                       {
+                               struct tveeprom tv;
 #ifdef CONFIG_MODULES
-               request_module("tveeprom");
-               request_module("ir-kbd-i2c");
-               request_module("msp3400");
+                               request_module("tveeprom");
+                               request_module("ir-kbd-i2c");
+                               request_module("msp3400");
 #endif
-               /* Call first TVeeprom */
+                               /* Call first TVeeprom */
+
+                               dev->i2c_client.addr = 0xa0 >> 1;
+                               tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
 
-               dev->i2c_client.addr = 0xa0 >> 1;
-               tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
+                               dev->tuner_type= tv.tuner_type;
+                               if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
+                                       dev->i2s_speed=2048000;
+                                       dev->has_msp34xx=1;
+                               } else
+                                       dev->has_msp34xx=0;
+                               break;
+                       }
+               case EM2820_BOARD_KWORLD_PVRTV2800RF:
+                       {
+                               em28xx_write_regs_req(dev,0x00,0x08, "\xf9", 1); // GPIO enables sound on KWORLD PVR TV 2800RF
+                               break;
+                       }
 
-               dev->tuner_type= tv.tuner_type;
-               if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
-                       dev->i2s_speed=2048000;
-                       dev->has_msp34xx=1;
-               } else
-                       dev->has_msp34xx=0;
        }
 }
 
index 6ca8631bc36dc98cf97c65c68bb5f20a1acb3334..5b6cece37aee9bebcd629f9b76474fd8190d7b96 100644 (file)
@@ -420,7 +420,6 @@ static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client)
                tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
                tun_setup.type = dev->tuner_type;
                tun_setup.addr = dev->tuner_addr;
-
                em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
        }
 
index 30dfa5370c733322cdda605bc98842887bb27030..31e89e4f18be5764200c57a76730e3bda95f93d5 100644 (file)
@@ -43,91 +43,6 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
 #define dprintk(fmt, arg...)   if (ir_debug) \
        printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
 
-/* ---------------------------------------------------------------------- */
-
-static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = {
-       [ 0x01 ] = KEY_CHANNEL,
-       [ 0x02 ] = KEY_SELECT,
-       [ 0x03 ] = KEY_MUTE,
-       [ 0x04 ] = KEY_POWER,
-       [ 0x05 ] = KEY_KP1,
-       [ 0x06 ] = KEY_KP2,
-       [ 0x07 ] = KEY_KP3,
-       [ 0x08 ] = KEY_CHANNELUP,
-       [ 0x09 ] = KEY_KP4,
-       [ 0x0a ] = KEY_KP5,
-       [ 0x0b ] = KEY_KP6,
-       [ 0x0c ] = KEY_CHANNELDOWN,
-       [ 0x0d ] = KEY_KP7,
-       [ 0x0e ] = KEY_KP8,
-       [ 0x0f ] = KEY_KP9,
-       [ 0x10 ] = KEY_VOLUMEUP,
-       [ 0x11 ] = KEY_KP0,
-       [ 0x12 ] = KEY_MENU,
-       [ 0x13 ] = KEY_PRINT,
-       [ 0x14 ] = KEY_VOLUMEDOWN,
-       [ 0x16 ] = KEY_PAUSE,
-       [ 0x18 ] = KEY_RECORD,
-       [ 0x19 ] = KEY_REWIND,
-       [ 0x1a ] = KEY_PLAY,
-       [ 0x1b ] = KEY_FORWARD,
-       [ 0x1c ] = KEY_BACKSPACE,
-       [ 0x1e ] = KEY_STOP,
-       [ 0x40 ] = KEY_ZOOM,
-};
-
-static IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = {
-       [ 0x3a ] = KEY_KP0,
-       [ 0x31 ] = KEY_KP1,
-       [ 0x32 ] = KEY_KP2,
-       [ 0x33 ] = KEY_KP3,
-       [ 0x34 ] = KEY_KP4,
-       [ 0x35 ] = KEY_KP5,
-       [ 0x36 ] = KEY_KP6,
-       [ 0x37 ] = KEY_KP7,
-       [ 0x38 ] = KEY_KP8,
-       [ 0x39 ] = KEY_KP9,
-
-       [ 0x2f ] = KEY_POWER,
-
-       [ 0x2e ] = KEY_P,
-       [ 0x1f ] = KEY_L,
-       [ 0x2b ] = KEY_I,
-
-       [ 0x2d ] = KEY_ZOOM,
-       [ 0x1e ] = KEY_ZOOM,
-       [ 0x1b ] = KEY_VOLUMEUP,
-       [ 0x0f ] = KEY_VOLUMEDOWN,
-       [ 0x17 ] = KEY_CHANNELUP,
-       [ 0x1c ] = KEY_CHANNELDOWN,
-       [ 0x25 ] = KEY_INFO,
-
-       [ 0x3c ] = KEY_MUTE,
-
-       [ 0x3d ] = KEY_LEFT,
-       [ 0x3b ] = KEY_RIGHT,
-
-       [ 0x3f ] = KEY_UP,
-       [ 0x3e ] = KEY_DOWN,
-       [ 0x1a ] = KEY_PAUSE,
-
-       [ 0x1d ] = KEY_MENU,
-       [ 0x19 ] = KEY_PLAY,
-       [ 0x16 ] = KEY_REWIND,
-       [ 0x13 ] = KEY_FORWARD,
-       [ 0x15 ] = KEY_PAUSE,
-       [ 0x0e ] = KEY_REWIND,
-       [ 0x0d ] = KEY_PLAY,
-       [ 0x0b ] = KEY_STOP,
-       [ 0x07 ] = KEY_FORWARD,
-       [ 0x27 ] = KEY_RECORD,
-       [ 0x26 ] = KEY_TUNER,
-       [ 0x29 ] = KEY_TEXT,
-       [ 0x2a ] = KEY_MEDIA,
-       [ 0x18 ] = KEY_EPG,
-       [ 0x27 ] = KEY_RECORD,
-};
-
 /* ----------------------------------------------------------------------- */
 
 static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
index 5b267808a9d4a3d169e7847601bc3d5b9425e65a..780342f7b23965b6891e181fd531d06d33154613 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/bitmap.h>
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <linux/version.h>
@@ -59,8 +60,14 @@ MODULE_LICENSE("GPL");
 static LIST_HEAD(em28xx_devlist);
 
 static unsigned int card[]     = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
+static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
+static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
 module_param_array(card,  int, NULL, 0444);
+module_param_array(video_nr, int, NULL, 0444);
+module_param_array(vbi_nr, int, NULL, 0444);
 MODULE_PARM_DESC(card,"card type");
+MODULE_PARM_DESC(video_nr,"video device numbers");
+MODULE_PARM_DESC(vbi_nr,"vbi device numbers");
 
 static int tuner = -1;
 module_param(tuner, int, 0444);
@@ -70,6 +77,9 @@ static unsigned int video_debug = 0;
 module_param(video_debug,int,0644);
 MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
 
+/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
+static unsigned long em28xx_devused;
+
 /* supported tv norms */
 static struct em28xx_tvnorm tvnorms[] = {
        {
@@ -91,23 +101,6 @@ static struct em28xx_tvnorm tvnorms[] = {
        }
 };
 
-static const unsigned char saa7114_i2c_init[] = {
-       0x00,0x00,0x01,0x08,0x02,0xc4,0x03,0x30,0x04,0x90,0x05,0x90,0x06,0xeb,0x07,0xe0,
-       0x08,0x88,0x09,0x40,0x0a,0x80,0x0b,0x44,0x0c,0x40,0x0d,0x00,0x0e,0x81,0x0f,0x2a,
-       0x10,0x06,0x11,0x00,0x12,0xc8,0x13,0x80,0x14,0x00,0x15,0x11,0x16,0x01,0x17,0x42,
-       0x18,0x40,0x19,0x80,0x40,0x00,0x41,0xff,0x42,0xff,0x43,0xff,0x44,0xff,0x45,0xff,
-       0x46,0xff,0x47,0xff,0x48,0xff,0x49,0xff,0x4a,0xff,0x4b,0xff,0x4c,0xff,0x4d,0xff,
-       0x4e,0xff,0x4f,0xff,0x50,0xff,0x51,0xff,0x52,0xff,0x53,0xff,0x54,0x5f,0x55,0xff,
-       0x56,0xff,0x57,0xff,0x58,0x00,0x59,0x47,0x5a,0x03,0x5b,0x03,0x5d,0x3e,0x5e,0x00,
-       0x80,0x1c,0x83,0x01,0x84,0xa5,0x85,0x10,0x86,0x45,0x87,0x41,0x88,0xf0,0x88,0x00,
-       0x88,0xf0,0x90,0x00,0x91,0x08,0x92,0x00,0x93,0x80,0x94,0x08,0x95,0x00,0x96,0xc0,
-       0x97,0x02,0x98,0x13,0x99,0x00,0x9a,0x38,0x9b,0x01,0x9c,0x80,0x9d,0x02,0x9e,0x06,
-       0x9f,0x01,0xa0,0x01,0xa1,0x00,0xa2,0x00,0xa4,0x80,0xa5,0x36,0xa6,0x36,0xa8,0x67,
-       0xa9,0x04,0xaa,0x00,0xac,0x33,0xad,0x02,0xae,0x00,0xb0,0xcd,0xb1,0x04,0xb2,0xcd,
-       0xb3,0x04,0xb4,0x01,0xb8,0x00,0xb9,0x00,0xba,0x00,0xbb,0x00,0xbc,0x00,0xbd,0x00,
-       0xbe,0x00,0xbf,0x00
-};
-
 #define TVNORMS ARRAY_SIZE(tvnorms)
 
 /* supported controls */
@@ -134,65 +127,6 @@ static struct v4l2_queryctrl em28xx_qctrl[] = {
        }
 };
 
-/* FIXME: These are specific to saa711x - should be moved to its code */
-static struct v4l2_queryctrl saa711x_qctrl[] = {
-       {
-               .id = V4L2_CID_BRIGHTNESS,
-               .type = V4L2_CTRL_TYPE_INTEGER,
-               .name = "Brightness",
-               .minimum = -128,
-               .maximum = 127,
-               .step = 1,
-               .default_value = 0,
-               .flags = 0,
-       },{
-               .id = V4L2_CID_CONTRAST,
-               .type = V4L2_CTRL_TYPE_INTEGER,
-               .name = "Contrast",
-               .minimum = 0x0,
-               .maximum = 0x1f,
-               .step = 0x1,
-               .default_value = 0x10,
-               .flags = 0,
-       },{
-               .id = V4L2_CID_SATURATION,
-               .type = V4L2_CTRL_TYPE_INTEGER,
-               .name = "Saturation",
-               .minimum = 0x0,
-               .maximum = 0x1f,
-               .step = 0x1,
-               .default_value = 0x10,
-               .flags = 0,
-       },{
-               .id = V4L2_CID_RED_BALANCE,
-               .type = V4L2_CTRL_TYPE_INTEGER,
-               .name = "Red chroma balance",
-               .minimum = -128,
-               .maximum = 127,
-               .step = 1,
-               .default_value = 0,
-               .flags = 0,
-       },{
-               .id = V4L2_CID_BLUE_BALANCE,
-               .type = V4L2_CTRL_TYPE_INTEGER,
-               .name = "Blue chroma balance",
-               .minimum = -128,
-               .maximum = 127,
-               .step = 1,
-               .default_value = 0,
-               .flags = 0,
-       },{
-               .id = V4L2_CID_GAMMA,
-               .type = V4L2_CTRL_TYPE_INTEGER,
-               .name = "Gamma",
-               .minimum = 0x0,
-               .maximum = 0x3f,
-               .step = 0x1,
-               .default_value = 0x20,
-               .flags = 0,
-       }
-};
-
 static struct usb_driver em28xx_usb_driver;
 
 static DEFINE_MUTEX(em28xx_sysfs_lock);
@@ -211,6 +145,11 @@ static int em28xx_config(struct em28xx *dev)
        em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1);
 
        /* enable vbi capturing */
+
+/*     em28xx_write_regs_req(dev,0x00,0x0e,"\xC0",1); audio register */
+/*     em28xx_write_regs_req(dev,0x00,0x0f,"\x80",1); clk register */
+       em28xx_write_regs_req(dev,0x00,0x11,"\x51",1);
+
        em28xx_audio_usb_mute(dev, 1);
        dev->mute = 1;          /* maybe not the right place... */
        dev->volume = 0x1f;
@@ -230,22 +169,9 @@ static int em28xx_config(struct em28xx *dev)
 static void em28xx_config_i2c(struct em28xx *dev)
 {
        struct v4l2_frequency f;
-       struct video_decoder_init em28xx_vdi = {.data = NULL };
-
-
-       /* configure decoder */
-       if(dev->model == EM2820_BOARD_MSI_VOX_USB_2){
-               em28xx_vdi.data=saa7114_i2c_init;
-               em28xx_vdi.len=sizeof(saa7114_i2c_init);
-       }
-
-
-       em28xx_i2c_call_clients(dev, DECODER_INIT, &em28xx_vdi);
-       em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &dev->ctl_input);
-/*     em28xx_i2c_call_clients(dev,DECODER_SET_PICTURE, &dev->vpic); */
-/*     em28xx_i2c_call_clients(dev,DECODER_SET_NORM,&dev->tvnorm->id); */
-/*     em28xx_i2c_call_clients(dev,DECODER_ENABLE_OUTPUT,&output); */
-/*     em28xx_i2c_call_clients(dev,DECODER_DUMP, NULL); */
+       em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL);
+       em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &dev->ctl_input);
+       em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
 
        /* configure tuner */
        f.tuner = 0;
@@ -285,8 +211,7 @@ static void video_mux(struct em28xx *dev, int index)
        dev->ctl_input = index;
        dev->ctl_ainput = INPUT(index)->amux;
 
-       em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input);
-
+       em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &input);
 
        em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
 
@@ -298,11 +223,11 @@ static void video_mux(struct em28xx *dev, int index)
                em28xx_audio_source(dev, ainput);
        } else {
                switch (dev->ctl_ainput) {
-               case 0:
-                       ainput = EM28XX_AUDIO_SRC_TUNER;
-                       break;
-               default:
-                       ainput = EM28XX_AUDIO_SRC_LINE;
+                       case 0:
+                               ainput = EM28XX_AUDIO_SRC_TUNER;
+                               break;
+                       default:
+                               ainput = EM28XX_AUDIO_SRC_LINE;
                }
                em28xx_audio_source(dev, ainput);
        }
@@ -323,13 +248,20 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
                h = list_entry(list, struct em28xx, devlist);
                if (h->vdev->minor == minor) {
                        dev  = h;
+                       dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+               }
+               if (h->vbi_dev->minor == minor) {
+                       dev  = h;
+                       dev->type = V4L2_BUF_TYPE_VBI_CAPTURE;
                }
        }
+       if (NULL == dev)
+               return -ENODEV;
 
        filp->private_data=dev;
 
-
-       em28xx_videodbg("users=%d\n", dev->users);
+       em28xx_videodbg("open minor=%d type=%s users=%d\n",
+                               minor,v4l2_type_names[dev->type],dev->users);
 
        if (!down_read_trylock(&em28xx_disconnect))
                return -ERESTARTSYS;
@@ -340,40 +272,36 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
                return -EBUSY;
        }
 
-/*     if(dev->vbi_dev->minor == minor){
-               dev->type=V4L2_BUF_TYPE_VBI_CAPTURE;
-       }*/
-       if (dev->vdev->minor == minor) {
-               dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       }
-
-       init_MUTEX(&dev->fileop_lock);  /* to 1 == available */
+       mutex_init(&dev->fileop_lock);  /* to 1 == available */
        spin_lock_init(&dev->queue_lock);
        init_waitqueue_head(&dev->wait_frame);
        init_waitqueue_head(&dev->wait_stream);
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
 
-       em28xx_set_alternate(dev);
+       if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+               em28xx_set_alternate(dev);
 
-       dev->width = norm_maxw(dev);
-       dev->height = norm_maxh(dev);
-       dev->frame_size = dev->width * dev->height * 2;
-       dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
-       dev->bytesperline = dev->width * 2;
-       dev->hscale = 0;
-       dev->vscale = 0;
+               dev->width = norm_maxw(dev);
+               dev->height = norm_maxh(dev);
+               dev->frame_size = dev->width * dev->height * 2;
+               dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
+               dev->bytesperline = dev->width * 2;
+               dev->hscale = 0;
+               dev->vscale = 0;
 
-       em28xx_capture_start(dev, 1);
-       em28xx_resolution_set(dev);
+               em28xx_capture_start(dev, 1);
+               em28xx_resolution_set(dev);
 
-       /* device needs to be initialized before isoc transfer */
-       video_mux(dev, 0);
+               /* device needs to be initialized before isoc transfer */
+               video_mux(dev, 0);
 
-       /* start the transfer */
-       errCode = em28xx_init_isoc(dev);
-       if (errCode)
-               goto err;
+               /* start the transfer */
+               errCode = em28xx_init_isoc(dev);
+               if (errCode)
+                       goto err;
+
+       }
 
        dev->users++;
        filp->private_data = dev;
@@ -386,10 +314,8 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
 
        dev->state |= DEV_INITIALIZED;
 
-       video_mux(dev, 0);
-
-      err:
-       up(&dev->lock);
+err:
+       mutex_unlock(&dev->lock);
        up_read(&em28xx_disconnect);
        return errCode;
 }
@@ -403,14 +329,21 @@ static void em28xx_release_resources(struct em28xx *dev)
 {
        mutex_lock(&em28xx_sysfs_lock);
 
-       em28xx_info("V4L2 device /dev/video%d deregistered\n",
-                   dev->vdev->minor);
+       /*FIXME: I2C IR should be disconnected */
+
+       em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n",
+                               dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN,
+                               dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN);
        list_del(&dev->devlist);
        video_unregister_device(dev->vdev);
-/*     video_unregister_device(dev->vbi_dev); */
+       video_unregister_device(dev->vbi_dev);
        em28xx_i2c_unregister(dev);
        usb_put_dev(dev->udev);
        mutex_unlock(&em28xx_sysfs_lock);
+
+
+       /* Mark device as unused */
+       em28xx_devused&=~(1<<dev->devno);
 }
 
 /*
@@ -424,7 +357,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
 
        em28xx_videodbg("users=%d\n", dev->users);
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
 
        em28xx_uninit_isoc(dev);
 
@@ -433,7 +366,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
        /* the device is already disconnect, free the remaining resources */
        if (dev->state & DEV_DISCONNECTED) {
                em28xx_release_resources(dev);
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                kfree(dev);
                return 0;
        }
@@ -449,7 +382,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
 
        dev->users--;
        wake_up_interruptible_nr(&dev->open, 1);
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
        return 0;
 }
 
@@ -466,32 +399,54 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
        int ret = 0;
        struct em28xx *dev = filp->private_data;
 
-       if (down_interruptible(&dev->fileop_lock))
+       if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+               em28xx_videodbg("V4l2_Buf_type_videocapture is set\n");
+       }
+       if (dev->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+               em28xx_videodbg("V4L2_BUF_TYPE_VBI_CAPTURE is set\n");
+               em28xx_videodbg("not supported yet! ...\n");
+               if (copy_to_user(buf, "", 1)) {
+                       mutex_unlock(&dev->fileop_lock);
+                       return -EFAULT;
+               }
+               return (1);
+       }
+       if (dev->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
+               em28xx_videodbg("V4L2_BUF_TYPE_SLICED_VBI_CAPTURE is set\n");
+               em28xx_videodbg("not supported yet! ...\n");
+               if (copy_to_user(buf, "", 1)) {
+                       mutex_unlock(&dev->fileop_lock);
+                       return -EFAULT;
+               }
+               return (1);
+       }
+
+       if (mutex_lock_interruptible(&dev->fileop_lock))
                return -ERESTARTSYS;
 
        if (dev->state & DEV_DISCONNECTED) {
                em28xx_videodbg("device not present\n");
-               up(&dev->fileop_lock);
+               mutex_unlock(&dev->fileop_lock);
                return -ENODEV;
        }
 
        if (dev->state & DEV_MISCONFIGURED) {
                em28xx_videodbg("device misconfigured; close and open it again\n");
-               up(&dev->fileop_lock);
+               mutex_unlock(&dev->fileop_lock);
                return -EIO;
        }
 
        if (dev->io == IO_MMAP) {
                em28xx_videodbg ("IO method is set to mmap; close and open"
                                " the device again to choose the read method\n");
-               up(&dev->fileop_lock);
+               mutex_unlock(&dev->fileop_lock);
                return -EINVAL;
        }
 
        if (dev->io == IO_NONE) {
                if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) {
                        em28xx_errdev("read failed, not enough memory\n");
-                       up(&dev->fileop_lock);
+                       mutex_unlock(&dev->fileop_lock);
                        return -ENOMEM;
                }
                dev->io = IO_READ;
@@ -500,13 +455,13 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
        }
 
        if (!count) {
-               up(&dev->fileop_lock);
+               mutex_unlock(&dev->fileop_lock);
                return 0;
        }
 
        if (list_empty(&dev->outqueue)) {
                if (filp->f_flags & O_NONBLOCK) {
-                       up(&dev->fileop_lock);
+                       mutex_unlock(&dev->fileop_lock);
                        return -EAGAIN;
                }
                ret = wait_event_interruptible
@@ -514,11 +469,11 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
                     (!list_empty(&dev->outqueue)) ||
                     (dev->state & DEV_DISCONNECTED));
                if (ret) {
-                       up(&dev->fileop_lock);
+                       mutex_unlock(&dev->fileop_lock);
                        return ret;
                }
                if (dev->state & DEV_DISCONNECTED) {
-                       up(&dev->fileop_lock);
+                       mutex_unlock(&dev->fileop_lock);
                        return -ENODEV;
                }
        }
@@ -537,12 +492,12 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
                count = f->buf.length;
 
        if (copy_to_user(buf, f->bufmem, count)) {
-               up(&dev->fileop_lock);
+               mutex_unlock(&dev->fileop_lock);
                return -EFAULT;
        }
        *f_pos += count;
 
-       up(&dev->fileop_lock);
+       mutex_unlock(&dev->fileop_lock);
 
        return count;
 }
@@ -556,7 +511,7 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
        unsigned int mask = 0;
        struct em28xx *dev = filp->private_data;
 
-       if (down_interruptible(&dev->fileop_lock))
+       if (mutex_lock_interruptible(&dev->fileop_lock))
                return POLLERR;
 
        if (dev->state & DEV_DISCONNECTED) {
@@ -582,13 +537,13 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
                        if (!list_empty(&dev->outqueue))
                                mask |= POLLIN | POLLRDNORM;
 
-                       up(&dev->fileop_lock);
+                       mutex_unlock(&dev->fileop_lock);
 
                        return mask;
                }
        }
 
-       up(&dev->fileop_lock);
+       mutex_unlock(&dev->fileop_lock);
        return POLLERR;
 }
 
@@ -628,25 +583,25 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
 
        struct em28xx *dev = filp->private_data;
 
-       if (down_interruptible(&dev->fileop_lock))
+       if (mutex_lock_interruptible(&dev->fileop_lock))
                return -ERESTARTSYS;
 
        if (dev->state & DEV_DISCONNECTED) {
                em28xx_videodbg("mmap: device not present\n");
-               up(&dev->fileop_lock);
+               mutex_unlock(&dev->fileop_lock);
                return -ENODEV;
        }
 
        if (dev->state & DEV_MISCONFIGURED) {
                em28xx_videodbg ("mmap: Device is misconfigured; close and "
                                                "open it again\n");
-               up(&dev->fileop_lock);
+               mutex_unlock(&dev->fileop_lock);
                return -EIO;
        }
 
        if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
            size != PAGE_ALIGN(dev->frame[0].buf.length)) {
-               up(&dev->fileop_lock);
+               mutex_unlock(&dev->fileop_lock);
                return -EINVAL;
        }
 
@@ -656,7 +611,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
        }
        if (i == dev->num_frames) {
                em28xx_videodbg("mmap: user supplied mapping address is out of range\n");
-               up(&dev->fileop_lock);
+               mutex_unlock(&dev->fileop_lock);
                return -EINVAL;
        }
 
@@ -668,7 +623,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
        while (size > 0) {      /* size is page-aligned */
                if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
                        em28xx_videodbg("mmap: vm_insert_page failed\n");
-                       up(&dev->fileop_lock);
+                       mutex_unlock(&dev->fileop_lock);
                        return -EAGAIN;
                }
                start += PAGE_SIZE;
@@ -680,7 +635,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
        vma->vm_private_data = &dev->frame[i];
 
        em28xx_vm_open(vma);
-       up(&dev->fileop_lock);
+       mutex_unlock(&dev->fileop_lock);
        return 0;
 }
 
@@ -702,43 +657,6 @@ static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
        }
 }
 
-/*FIXME: should be moved to saa711x */
-static int saa711x_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
-{
-       s32 tmp;
-       switch (ctrl->id) {
-       case V4L2_CID_BRIGHTNESS:
-               if ((tmp = em28xx_brightness_get(dev)) < 0)
-                       return -EIO;
-               ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
-               return 0;
-       case V4L2_CID_CONTRAST:
-               if ((ctrl->value = em28xx_contrast_get(dev)) < 0)
-                       return -EIO;
-               return 0;
-       case V4L2_CID_SATURATION:
-               if ((ctrl->value = em28xx_saturation_get(dev)) < 0)
-                       return -EIO;
-               return 0;
-       case V4L2_CID_RED_BALANCE:
-               if ((tmp = em28xx_v_balance_get(dev)) < 0)
-                       return -EIO;
-               ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
-               return 0;
-       case V4L2_CID_BLUE_BALANCE:
-               if ((tmp = em28xx_u_balance_get(dev)) < 0)
-                       return -EIO;
-               ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
-               return 0;
-       case V4L2_CID_GAMMA:
-               if ((ctrl->value = em28xx_gamma_get(dev)) < 0)
-                       return -EIO;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
 /*
  * em28xx_set_ctrl()
  * mute or set new saturation, brightness or contrast
@@ -761,27 +679,6 @@ static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
        }
 }
 
-/*FIXME: should be moved to saa711x */
-static int saa711x_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
-{
-       switch (ctrl->id) {
-       case V4L2_CID_BRIGHTNESS:
-               return em28xx_brightness_set(dev, ctrl->value);
-       case V4L2_CID_CONTRAST:
-               return em28xx_contrast_set(dev, ctrl->value);
-       case V4L2_CID_SATURATION:
-               return em28xx_saturation_set(dev, ctrl->value);
-       case V4L2_CID_RED_BALANCE:
-               return em28xx_v_balance_set(dev, ctrl->value);
-       case V4L2_CID_BLUE_BALANCE:
-               return em28xx_u_balance_set(dev, ctrl->value);
-       case V4L2_CID_GAMMA:
-               return em28xx_gamma_set(dev, ctrl->value);
-       default:
-               return -EINVAL;
-       }
-}
-
 /*
  * em28xx_stream_interrupt()
  * stops streaming
@@ -802,7 +699,8 @@ static int em28xx_stream_interrupt(struct em28xx *dev)
        else if (ret) {
                dev->state |= DEV_MISCONFIGURED;
                em28xx_videodbg("device is misconfigured; close and "
-                       "open /dev/video%d again\n", dev->vdev->minor);
+                       "open /dev/video%d again\n",
+                               dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN);
                return ret;
        }
 
@@ -853,6 +751,181 @@ static int em28xx_set_norm(struct em28xx *dev, int width, int height)
        return 0;
 }
 
+static int em28xx_get_fmt(struct em28xx *dev, struct v4l2_format *format)
+{
+       em28xx_videodbg("VIDIOC_G_FMT: type=%s\n",
+               (format->type ==V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
+               "V4L2_BUF_TYPE_VIDEO_CAPTURE" :
+               (format->type ==V4L2_BUF_TYPE_VBI_CAPTURE) ?
+               "V4L2_BUF_TYPE_VBI_CAPTURE" :
+               (format->type ==V4L2_CAP_SLICED_VBI_CAPTURE) ?
+               "V4L2_BUF_TYPE_SLICED_VBI_CAPTURE " :
+               "not supported");
+
+       switch (format->type) {
+       case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+       {
+               format->fmt.pix.width = dev->width;
+               format->fmt.pix.height = dev->height;
+               format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+               format->fmt.pix.bytesperline = dev->bytesperline;
+               format->fmt.pix.sizeimage = dev->frame_size;
+               format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+               format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;       /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
+
+               em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width,
+                       dev->height);
+               break;
+       }
+
+       case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+       {
+               format->fmt.sliced.service_set=0;
+
+               em28xx_i2c_call_clients(dev,VIDIOC_G_FMT,format);
+
+               if (format->fmt.sliced.service_set==0)
+                       return -EINVAL;
+
+               break;
+       }
+
+       default:
+               return -EINVAL;
+       }
+       return (0);
+}
+
+static int em28xx_set_fmt(struct em28xx *dev, unsigned int cmd, struct v4l2_format *format)
+{
+       u32 i;
+       int ret = 0;
+       int width = format->fmt.pix.width;
+       int height = format->fmt.pix.height;
+       unsigned int hscale, vscale;
+       unsigned int maxh, maxw;
+
+       maxw = norm_maxw(dev);
+       maxh = norm_maxh(dev);
+
+       em28xx_videodbg("%s: type=%s\n",
+                       cmd == VIDIOC_TRY_FMT ?
+                       "VIDIOC_TRY_FMT" : "VIDIOC_S_FMT",
+                       format->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ?
+                       "V4L2_BUF_TYPE_VIDEO_CAPTURE" :
+                       format->type == V4L2_BUF_TYPE_VBI_CAPTURE ?
+                       "V4L2_BUF_TYPE_VBI_CAPTURE " :
+                       "not supported");
+
+       if (format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
+               em28xx_i2c_call_clients(dev,VIDIOC_G_FMT,format);
+
+               if (format->fmt.sliced.service_set==0)
+                       return -EINVAL;
+
+               return 0;
+       }
+
+
+       if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       em28xx_videodbg("%s: requested %dx%d\n",
+               cmd == VIDIOC_TRY_FMT ?
+               "VIDIOC_TRY_FMT" : "VIDIOC_S_FMT",
+               format->fmt.pix.width, format->fmt.pix.height);
+
+       /* FIXME: Move some code away from here */
+       /* width must even because of the YUYV format */
+       /* height must be even because of interlacing */
+       height &= 0xfffe;
+       width &= 0xfffe;
+
+       if (height < 32)
+               height = 32;
+       if (height > maxh)
+               height = maxh;
+       if (width < 48)
+               width = 48;
+       if (width > maxw)
+               width = maxw;
+
+       if(dev->is_em2800){
+               /* the em2800 can only scale down to 50% */
+               if(height % (maxh / 2))
+                       height=maxh;
+               if(width % (maxw / 2))
+                       width=maxw;
+               /* according to empiatech support */
+               /* the MaxPacketSize is to small to support */
+               /* framesizes larger than 640x480 @ 30 fps */
+               /* or 640x576 @ 25 fps. As this would cut */
+               /* of a part of the image we prefer */
+               /* 360x576 or 360x480 for now */
+               if(width == maxw && height == maxh)
+                       width /= 2;
+       }
+
+       if ((hscale = (((unsigned long)maxw) << 12) / width - 4096L) >= 0x4000)
+               hscale = 0x3fff;
+
+       width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
+
+       if ((vscale = (((unsigned long)maxh) << 12) / height - 4096L) >= 0x4000)
+               vscale = 0x3fff;
+
+       height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
+
+       format->fmt.pix.width = width;
+       format->fmt.pix.height = height;
+       format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+       format->fmt.pix.bytesperline = width * 2;
+       format->fmt.pix.sizeimage = width * 2 * height;
+       format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+       format->fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+       em28xx_videodbg("%s: returned %dx%d (%d, %d)\n",
+               cmd == VIDIOC_TRY_FMT ?
+               "VIDIOC_TRY_FMT" :"VIDIOC_S_FMT",
+               format->fmt.pix.width, format->fmt.pix.height, hscale, vscale);
+
+       if (cmd == VIDIOC_TRY_FMT)
+               return 0;
+
+       for (i = 0; i < dev->num_frames; i++)
+               if (dev->frame[i].vma_use_count) {
+                       em28xx_videodbg("VIDIOC_S_FMT failed. "
+                               "Unmap the buffers first.\n");
+                       return -EINVAL;
+               }
+
+       /* stop io in case it is already in progress */
+       if (dev->stream == STREAM_ON) {
+               em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
+               if ((ret = em28xx_stream_interrupt(dev)))
+                       return ret;
+       }
+
+       em28xx_release_buffers(dev);
+       dev->io = IO_NONE;
+
+       /* set new image size */
+       dev->width = width;
+       dev->height = height;
+       dev->frame_size = dev->width * dev->height * 2;
+       dev->field_size = dev->frame_size >> 1;
+       dev->bytesperline = dev->width * 2;
+       dev->hscale = hscale;
+       dev->vscale = vscale;
+       em28xx_uninit_isoc(dev);
+       em28xx_set_alternate(dev);
+       em28xx_capture_start(dev, 1);
+       em28xx_resolution_set(dev);
+       em28xx_init_isoc(dev);
+
+       return 0;
+}
+
 /*
  * em28xx_v4l2_do_ioctl()
  * This function is _not_ called directly, but from
@@ -868,392 +941,325 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
        switch (cmd) {
                /* ---------- tv norms ---------- */
        case VIDIOC_ENUMSTD:
-               {
-                       struct v4l2_standard *e = arg;
-                       unsigned int i;
+       {
+               struct v4l2_standard *e = arg;
+               unsigned int i;
 
-                       i = e->index;
-                       if (i >= TVNORMS)
-                               return -EINVAL;
-                       ret = v4l2_video_std_construct(e, tvnorms[e->index].id,
-                                                      tvnorms[e->index].name);
-                       e->index = i;
-                       if (ret < 0)
-                               return ret;
-                       return 0;
-               }
+               i = e->index;
+               if (i >= TVNORMS)
+                       return -EINVAL;
+               ret = v4l2_video_std_construct(e, tvnorms[e->index].id,
+                                               tvnorms[e->index].name);
+               e->index = i;
+               if (ret < 0)
+                       return ret;
+               return 0;
+       }
        case VIDIOC_G_STD:
-               {
-                       v4l2_std_id *id = arg;
+       {
+               v4l2_std_id *id = arg;
 
-                       *id = dev->tvnorm->id;
-                       return 0;
-               }
+               *id = dev->tvnorm->id;
+               return 0;
+       }
        case VIDIOC_S_STD:
-               {
-                       v4l2_std_id *id = arg;
-                       unsigned int i;
+       {
+               v4l2_std_id *id = arg;
+               unsigned int i;
 
+               for (i = 0; i < TVNORMS; i++)
+                       if (*id == tvnorms[i].id)
+                               break;
+               if (i == TVNORMS)
                        for (i = 0; i < TVNORMS; i++)
-                               if (*id == tvnorms[i].id)
+                               if (*id & tvnorms[i].id)
                                        break;
-                       if (i == TVNORMS)
-                               for (i = 0; i < TVNORMS; i++)
-                                       if (*id & tvnorms[i].id)
-                                               break;
-                       if (i == TVNORMS)
-                               return -EINVAL;
-
-                       down(&dev->lock);
-                       dev->tvnorm = &tvnorms[i];
+               if (i == TVNORMS)
+                       return -EINVAL;
 
-                       em28xx_set_norm(dev, dev->width, dev->height);
+               mutex_lock(&dev->lock);
+               dev->tvnorm = &tvnorms[i];
 
-/*
-               dev->width=norm_maxw(dev);
-               dev->height=norm_maxh(dev);
-               dev->frame_size=dev->width*dev->height*2;
-               dev->field_size=dev->frame_size>>1;
-               dev->bytesperline=dev->width*2;
-               dev->hscale=0;
-               dev->vscale=0;
+               em28xx_set_norm(dev, dev->width, dev->height);
 
-               em28xx_resolution_set(dev);
-*/
-/*
-               em28xx_uninit_isoc(dev);
-               em28xx_set_alternate(dev);
-               em28xx_capture_start(dev, 1);
-               em28xx_resolution_set(dev);
-               em28xx_init_isoc(dev);
-*/
-                       em28xx_i2c_call_clients(dev, DECODER_SET_NORM,
-                                               &tvnorms[i].mode);
-                       em28xx_i2c_call_clients(dev, VIDIOC_S_STD,
-                                               &dev->tvnorm->id);
+               em28xx_i2c_call_clients(dev, VIDIOC_S_STD,
+                                       &dev->tvnorm->id);
 
-                       up(&dev->lock);
+               mutex_unlock(&dev->lock);
 
-                       return 0;
-               }
+               return 0;
+       }
 
-               /* ------ input switching ---------- */
+       /* ------ input switching ---------- */
        case VIDIOC_ENUMINPUT:
-               {
-                       struct v4l2_input *i = arg;
-                       unsigned int n;
-                       static const char *iname[] = {
-                               [EM28XX_VMUX_COMPOSITE1] = "Composite1",
-                               [EM28XX_VMUX_COMPOSITE2] = "Composite2",
-                               [EM28XX_VMUX_COMPOSITE3] = "Composite3",
-                               [EM28XX_VMUX_COMPOSITE4] = "Composite4",
-                               [EM28XX_VMUX_SVIDEO] = "S-Video",
-                               [EM28XX_VMUX_TELEVISION] = "Television",
-                               [EM28XX_VMUX_CABLE] = "Cable TV",
-                               [EM28XX_VMUX_DVB] = "DVB",
-                               [EM28XX_VMUX_DEBUG] = "for debug only",
-                       };
-
-                       n = i->index;
-                       if (n >= MAX_EM28XX_INPUT)
-                               return -EINVAL;
-                       if (0 == INPUT(n)->type)
-                               return -EINVAL;
-                       memset(i, 0, sizeof(*i));
-                       i->index = n;
-                       i->type = V4L2_INPUT_TYPE_CAMERA;
-                       strcpy(i->name, iname[INPUT(n)->type]);
-                       if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
-                           (EM28XX_VMUX_CABLE == INPUT(n)->type))
-                               i->type = V4L2_INPUT_TYPE_TUNER;
-                       for (n = 0; n < ARRAY_SIZE(tvnorms); n++)
-                               i->std |= tvnorms[n].id;
-                       return 0;
-               }
-
+       {
+               struct v4l2_input *i = arg;
+               unsigned int n;
+               static const char *iname[] = {
+                       [EM28XX_VMUX_COMPOSITE1] = "Composite1",
+                       [EM28XX_VMUX_COMPOSITE2] = "Composite2",
+                       [EM28XX_VMUX_COMPOSITE3] = "Composite3",
+                       [EM28XX_VMUX_COMPOSITE4] = "Composite4",
+                       [EM28XX_VMUX_SVIDEO] = "S-Video",
+                       [EM28XX_VMUX_TELEVISION] = "Television",
+                       [EM28XX_VMUX_CABLE] = "Cable TV",
+                       [EM28XX_VMUX_DVB] = "DVB",
+                       [EM28XX_VMUX_DEBUG] = "for debug only",
+               };
+
+               n = i->index;
+               if (n >= MAX_EM28XX_INPUT)
+                       return -EINVAL;
+               if (0 == INPUT(n)->type)
+                       return -EINVAL;
+               memset(i, 0, sizeof(*i));
+               i->index = n;
+               i->type = V4L2_INPUT_TYPE_CAMERA;
+               strcpy(i->name, iname[INPUT(n)->type]);
+               if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
+                       (EM28XX_VMUX_CABLE == INPUT(n)->type))
+                       i->type = V4L2_INPUT_TYPE_TUNER;
+               for (n = 0; n < ARRAY_SIZE(tvnorms); n++)
+                       i->std |= tvnorms[n].id;
+               return 0;
+       }
        case VIDIOC_G_INPUT:
-               {
-                       int *i = arg;
-                       *i = dev->ctl_input;
-
-                       return 0;
-               }
+       {
+               int *i = arg;
+               *i = dev->ctl_input;
 
+               return 0;
+       }
        case VIDIOC_S_INPUT:
-               {
-                       int *index = arg;
-
-                       if (*index >= MAX_EM28XX_INPUT)
-                               return -EINVAL;
-                       if (0 == INPUT(*index)->type)
-                               return -EINVAL;
+       {
+               int *index = arg;
 
-                       down(&dev->lock);
-                       video_mux(dev, *index);
-                       up(&dev->lock);
+               if (*index >= MAX_EM28XX_INPUT)
+                       return -EINVAL;
+               if (0 == INPUT(*index)->type)
+                       return -EINVAL;
 
-                       return 0;
-               }
+               mutex_lock(&dev->lock);
+               video_mux(dev, *index);
+               mutex_unlock(&dev->lock);
 
+               return 0;
+       }
        case VIDIOC_G_AUDIO:
-               {
-                       struct v4l2_audio *a = arg;
-                       unsigned int index = a->index;
+       {
+               struct v4l2_audio *a = arg;
+               unsigned int index = a->index;
 
-                       if (a->index > 1)
-                               return -EINVAL;
-                       memset(a, 0, sizeof(*a));
-                       index = dev->ctl_ainput;
+               if (a->index > 1)
+                       return -EINVAL;
+               memset(a, 0, sizeof(*a));
+               index = dev->ctl_ainput;
 
-                       if (index == 0) {
-                               strcpy(a->name, "Television");
-                       } else {
-                               strcpy(a->name, "Line In");
-                       }
-                       a->capability = V4L2_AUDCAP_STEREO;
-                       a->index = index;
-                       return 0;
+               if (index == 0) {
+                       strcpy(a->name, "Television");
+               } else {
+                       strcpy(a->name, "Line In");
                }
-
+               a->capability = V4L2_AUDCAP_STEREO;
+               a->index = index;
+               return 0;
+       }
        case VIDIOC_S_AUDIO:
-               {
-                       struct v4l2_audio *a = arg;
-                       if (a->index != dev->ctl_ainput)
-                               return -EINVAL;
+       {
+               struct v4l2_audio *a = arg;
 
-                       return 0;
-               }
+               if (a->index != dev->ctl_ainput)
+                       return -EINVAL;
 
-               /* --- controls ---------------------------------------------- */
+               return 0;
+       }
+
+       /* --- controls ---------------------------------------------- */
        case VIDIOC_QUERYCTRL:
-               {
-                       struct v4l2_queryctrl *qc = arg;
-                       int i, id=qc->id;
-
-                       memset(qc,0,sizeof(*qc));
-                       qc->id=id;
-
-                       if (!dev->has_msp34xx) {
-                               for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
-                                       if (qc->id && qc->id == em28xx_qctrl[i].id) {
-                                               memcpy(qc, &(em28xx_qctrl[i]),
-                                               sizeof(*qc));
-                                               return 0;
-                                       }
-                               }
-                       }
-                       if (dev->decoder == EM28XX_TVP5150) {
-                               em28xx_i2c_call_clients(dev,cmd,qc);
-                               if (qc->type)
-                                       return 0;
-                               else
-                                       return -EINVAL;
-                       }
-                       for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) {
-                               if (qc->id && qc->id == saa711x_qctrl[i].id) {
-                                       memcpy(qc, &(saa711x_qctrl[i]),
-                                              sizeof(*qc));
-                                       return 0;
-                               }
-                       }
+       {
+               struct v4l2_queryctrl *qc = arg;
+               int i, id=qc->id;
 
-                       return -EINVAL;
-               }
+               memset(qc,0,sizeof(*qc));
+               qc->id=id;
 
-       case VIDIOC_G_CTRL:
-               {
-                       struct v4l2_control *ctrl = arg;
-                       int retval=-EINVAL;
-
-                       if (!dev->has_msp34xx)
-                               retval=em28xx_get_ctrl(dev, ctrl);
-                       if (retval==-EINVAL) {
-                               if (dev->decoder == EM28XX_TVP5150) {
-                                       em28xx_i2c_call_clients(dev,cmd,arg);
+               if (!dev->has_msp34xx) {
+                       for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
+                               if (qc->id && qc->id == em28xx_qctrl[i].id) {
+                                       memcpy(qc, &(em28xx_qctrl[i]),
+                                       sizeof(*qc));
                                        return 0;
                                }
-
-                               return saa711x_get_ctrl(dev, ctrl);
-                       } else return retval;
+                       }
                }
+               em28xx_i2c_call_clients(dev,cmd,qc);
+               if (qc->type)
+                       return 0;
+               else
+                       return -EINVAL;
+       }
+       case VIDIOC_G_CTRL:
+       {
+               struct v4l2_control *ctrl = arg;
+               int retval=-EINVAL;
 
+               if (!dev->has_msp34xx)
+                       retval=em28xx_get_ctrl(dev, ctrl);
+               if (retval==-EINVAL) {
+                       em28xx_i2c_call_clients(dev,cmd,arg);
+                       return 0;
+               } else return retval;
+       }
        case VIDIOC_S_CTRL:
-               {
-                       struct v4l2_control *ctrl = arg;
-                       u8 i;
-
-                       if (!dev->has_msp34xx){
-                               for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
-                                       if (ctrl->id == em28xx_qctrl[i].id) {
-                                               if (ctrl->value <
-                                               em28xx_qctrl[i].minimum
-                                               || ctrl->value >
-                                               em28xx_qctrl[i].maximum)
-                                                       return -ERANGE;
-                                               return em28xx_set_ctrl(dev, ctrl);
-                                       }
-                               }
-                       }
-
-                       if (dev->decoder == EM28XX_TVP5150) {
-                               em28xx_i2c_call_clients(dev,cmd,arg);
-                               return 0;
-                       } else if (!dev->has_msp34xx) {
-                               for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
-                                       if (ctrl->id == em28xx_qctrl[i].id) {
-                                               if (ctrl->value <
-                                               em28xx_qctrl[i].minimum
-                                               || ctrl->value >
-                                               em28xx_qctrl[i].maximum)
-                                                       return -ERANGE;
-                                               return em28xx_set_ctrl(dev, ctrl);
-                                       }
-                               }
-                               for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) {
-                                       if (ctrl->id == saa711x_qctrl[i].id) {
-                                               if (ctrl->value <
-                                               saa711x_qctrl[i].minimum
-                                               || ctrl->value >
-                                               saa711x_qctrl[i].maximum)
-                                                       return -ERANGE;
-                                               return saa711x_set_ctrl(dev, ctrl);
-                                       }
+       {
+               struct v4l2_control *ctrl = arg;
+               u8 i;
+
+               if (!dev->has_msp34xx){
+                       for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
+                               if (ctrl->id == em28xx_qctrl[i].id) {
+                                       if (ctrl->value <
+                                       em28xx_qctrl[i].minimum
+                                       || ctrl->value >
+                                       em28xx_qctrl[i].maximum)
+                                               return -ERANGE;
+                                       return em28xx_set_ctrl(dev, ctrl);
                                }
                        }
-
-                       return -EINVAL;
                }
 
-               /* --- tuner ioctls ------------------------------------------ */
+               em28xx_i2c_call_clients(dev,cmd,arg);
+               return 0;
+       }
+       /* --- tuner ioctls ------------------------------------------ */
        case VIDIOC_G_TUNER:
-               {
-                       struct v4l2_tuner *t = arg;
-                       int status = 0;
+       {
+               struct v4l2_tuner *t = arg;
+               int status = 0;
 
-                       if (0 != t->index)
-                               return -EINVAL;
+               if (0 != t->index)
+                       return -EINVAL;
 
-                       memset(t, 0, sizeof(*t));
-                       strcpy(t->name, "Tuner");
-                       t->type = V4L2_TUNER_ANALOG_TV;
-                       t->capability = V4L2_TUNER_CAP_NORM;
-                       t->rangehigh = 0xffffffffUL;    /* FIXME: set correct range */
+               memset(t, 0, sizeof(*t));
+               strcpy(t->name, "Tuner");
+               t->type = V4L2_TUNER_ANALOG_TV;
+               t->capability = V4L2_TUNER_CAP_NORM;
+               t->rangehigh = 0xffffffffUL;    /* FIXME: set correct range */
 /*             t->signal = 0xffff;*/
 /*             em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/
-                       /* No way to get signal strength? */
-                       down(&dev->lock);
-                       em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
-                                               &status);
-                       up(&dev->lock);
-                       t->signal =
-                           (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
-
-                       em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal,
-                                t->afc);
-                       return 0;
-               }
+               /* No way to get signal strength? */
+               mutex_lock(&dev->lock);
+               em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
+                                       &status);
+               mutex_unlock(&dev->lock);
+               t->signal =
+                       (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
+
+               em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal,
+                               t->afc);
+               return 0;
+       }
        case VIDIOC_S_TUNER:
-               {
-                       struct v4l2_tuner *t = arg;
-                       int status = 0;
+       {
+               struct v4l2_tuner *t = arg;
+               int status = 0;
 
-                       if (0 != t->index)
-                               return -EINVAL;
-                       memset(t, 0, sizeof(*t));
-                       strcpy(t->name, "Tuner");
-                       t->type = V4L2_TUNER_ANALOG_TV;
-                       t->capability = V4L2_TUNER_CAP_NORM;
-                       t->rangehigh = 0xffffffffUL;    /* FIXME: set correct range */
+               if (0 != t->index)
+                       return -EINVAL;
+               memset(t, 0, sizeof(*t));
+               strcpy(t->name, "Tuner");
+               t->type = V4L2_TUNER_ANALOG_TV;
+               t->capability = V4L2_TUNER_CAP_NORM;
+               t->rangehigh = 0xffffffffUL;    /* FIXME: set correct range */
 /*             t->signal = 0xffff; */
-                       /* No way to get signal strength? */
-                       down(&dev->lock);
-                       em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
-                                               &status);
-                       up(&dev->lock);
-                       t->signal =
-                           (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
-
-                       em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n",
-                                t->signal, t->afc);
-                       return 0;
-               }
+               /* No way to get signal strength? */
+               mutex_lock(&dev->lock);
+               em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
+                                       &status);
+               mutex_unlock(&dev->lock);
+               t->signal =
+                       (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
+
+               em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n",
+                               t->signal, t->afc);
+               return 0;
+       }
        case VIDIOC_G_FREQUENCY:
-               {
-                       struct v4l2_frequency *f = arg;
+       {
+               struct v4l2_frequency *f = arg;
 
-                       memset(f, 0, sizeof(*f));
-                       f->type = V4L2_TUNER_ANALOG_TV;
-                       f->frequency = dev->ctl_freq;
+               memset(f, 0, sizeof(*f));
+               f->type = V4L2_TUNER_ANALOG_TV;
+               f->frequency = dev->ctl_freq;
 
-                       return 0;
-               }
+               return 0;
+       }
        case VIDIOC_S_FREQUENCY:
-               {
-                       struct v4l2_frequency *f = arg;
-
-                       if (0 != f->tuner)
-                               return -EINVAL;
+       {
+               struct v4l2_frequency *f = arg;
 
-                       if (V4L2_TUNER_ANALOG_TV != f->type)
-                               return -EINVAL;
+               if (0 != f->tuner)
+                       return -EINVAL;
 
-                       down(&dev->lock);
-                       dev->ctl_freq = f->frequency;
-                       em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
-                       up(&dev->lock);
-                       return 0;
-               }
+               if (V4L2_TUNER_ANALOG_TV != f->type)
+                       return -EINVAL;
 
+               mutex_lock(&dev->lock);
+               dev->ctl_freq = f->frequency;
+               em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
+               mutex_unlock(&dev->lock);
+               return 0;
+       }
        case VIDIOC_CROPCAP:
-               {
-                       struct v4l2_cropcap *cc = arg;
+       {
+               struct v4l2_cropcap *cc = arg;
 
-                       if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-                               return -EINVAL;
-                       cc->bounds.left = 0;
-                       cc->bounds.top = 0;
-                       cc->bounds.width = dev->width;
-                       cc->bounds.height = dev->height;
-                       cc->defrect = cc->bounds;
-                       cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */
-                       cc->pixelaspect.denominator = 59;
-                       return 0;
-               }
+               if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+                       return -EINVAL;
+               cc->bounds.left = 0;
+               cc->bounds.top = 0;
+               cc->bounds.width = dev->width;
+               cc->bounds.height = dev->height;
+               cc->defrect = cc->bounds;
+               cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */
+               cc->pixelaspect.denominator = 59;
+               return 0;
+       }
        case VIDIOC_STREAMON:
-               {
-                       int *type = arg;
+       {
+               int *type = arg;
 
-                       if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
-                           || dev->io != IO_MMAP)
-                               return -EINVAL;
+               if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
+                       || dev->io != IO_MMAP)
+                       return -EINVAL;
 
-                       if (list_empty(&dev->inqueue))
-                               return -EINVAL;
+               if (list_empty(&dev->inqueue))
+                       return -EINVAL;
 
-                       dev->stream = STREAM_ON;        /* FIXME: Start video capture here? */
+               dev->stream = STREAM_ON;        /* FIXME: Start video capture here? */
 
-                       em28xx_videodbg("VIDIOC_STREAMON: starting stream\n");
+               em28xx_videodbg("VIDIOC_STREAMON: starting stream\n");
 
-                       return 0;
-               }
+               return 0;
+       }
        case VIDIOC_STREAMOFF:
-               {
-                       int *type = arg;
-                       int ret;
-
-                       if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
-                           || dev->io != IO_MMAP)
-                               return -EINVAL;
+       {
+               int *type = arg;
+               int ret;
 
-                       if (dev->stream == STREAM_ON) {
-                               em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n");
-                               if ((ret = em28xx_stream_interrupt(dev)))
-                                       return ret;
-                       }
-                       em28xx_empty_framequeues(dev);
+               if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
+                       || dev->io != IO_MMAP)
+                       return -EINVAL;
 
-                       return 0;
+               if (dev->stream == STREAM_ON) {
+                       em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n");
+                       if ((ret = em28xx_stream_interrupt(dev)))
+                               return ret;
                }
+               em28xx_empty_framequeues(dev);
+
+               return 0;
+       }
        default:
                return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
                                                  driver_ioctl);
@@ -1283,327 +1289,170 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
                /* --- capabilities ------------------------------------------ */
        case VIDIOC_QUERYCAP:
                {
-                       struct v4l2_capability *cap = arg;
-
-                       memset(cap, 0, sizeof(*cap));
-                       strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
-                       strlcpy(cap->card, em28xx_boards[dev->model].name,
-                               sizeof(cap->card));
-                       strlcpy(cap->bus_info, dev->udev->dev.bus_id,
-                               sizeof(cap->bus_info));
-                       cap->version = EM28XX_VERSION_CODE;
-                       cap->capabilities =
-                           V4L2_CAP_VIDEO_CAPTURE |
-                           V4L2_CAP_AUDIO |
-                           V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
-                       if (dev->has_tuner)
-                               cap->capabilities |= V4L2_CAP_TUNER;
-                       return 0;
-               }
-
-               /* --- capture ioctls ---------------------------------------- */
+               struct v4l2_capability *cap = arg;
+
+               memset(cap, 0, sizeof(*cap));
+               strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
+               strlcpy(cap->card, em28xx_boards[dev->model].name,
+                       sizeof(cap->card));
+               strlcpy(cap->bus_info, dev->udev->dev.bus_id,
+                       sizeof(cap->bus_info));
+               cap->version = EM28XX_VERSION_CODE;
+               cap->capabilities =
+                               V4L2_CAP_SLICED_VBI_CAPTURE |
+                               V4L2_CAP_VIDEO_CAPTURE |
+                               V4L2_CAP_AUDIO |
+                               V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
+               if (dev->has_tuner)
+                       cap->capabilities |= V4L2_CAP_TUNER;
+               return 0;
+       }
+       /* --- capture ioctls ---------------------------------------- */
        case VIDIOC_ENUM_FMT:
-               {
-                       struct v4l2_fmtdesc *fmtd = arg;
-
-                       if (fmtd->index != 0)
-                               return -EINVAL;
-                       memset(fmtd, 0, sizeof(*fmtd));
-                       fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-                       strcpy(fmtd->description, "Packed YUY2");
-                       fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
-                       memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
-                       return 0;
-               }
+       {
+               struct v4l2_fmtdesc *fmtd = arg;
 
+               if (fmtd->index != 0)
+                       return -EINVAL;
+               memset(fmtd, 0, sizeof(*fmtd));
+               fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+               strcpy(fmtd->description, "Packed YUY2");
+               fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
+               memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
+               return 0;
+       }
        case VIDIOC_G_FMT:
-               {
-                       struct v4l2_format *format = arg;
-
-                       em28xx_videodbg("VIDIOC_G_FMT: type=%s\n",
-                                format->type ==
-                                V4L2_BUF_TYPE_VIDEO_CAPTURE ?
-                                "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
-                                V4L2_BUF_TYPE_VBI_CAPTURE ?
-                                "V4L2_BUF_TYPE_VBI_CAPTURE " :
-                                "not supported");
-
-                       if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-                               return -EINVAL;
-
-                       format->fmt.pix.width = dev->width;
-                       format->fmt.pix.height = dev->height;
-                       format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
-                       format->fmt.pix.bytesperline = dev->bytesperline;
-                       format->fmt.pix.sizeimage = dev->frame_size;
-                       format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-                       format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;       /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
-
-                       em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width,
-                                dev->height);
-                       return 0;
-               }
+               return em28xx_get_fmt(dev, (struct v4l2_format *) arg);
 
        case VIDIOC_TRY_FMT:
        case VIDIOC_S_FMT:
-               {
-                       struct v4l2_format *format = arg;
-                       u32 i;
-                       int ret = 0;
-                       int width = format->fmt.pix.width;
-                       int height = format->fmt.pix.height;
-                       unsigned int hscale, vscale;
-                       unsigned int maxh, maxw;
-
-                       maxw = norm_maxw(dev);
-                       maxh = norm_maxh(dev);
-
-/*             int both_fields; */
-
-                       em28xx_videodbg("%s: type=%s\n",
-                                cmd ==
-                                VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
-                                "VIDIOC_S_FMT",
-                                format->type ==
-                                V4L2_BUF_TYPE_VIDEO_CAPTURE ?
-                                "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
-                                V4L2_BUF_TYPE_VBI_CAPTURE ?
-                                "V4L2_BUF_TYPE_VBI_CAPTURE " :
-                                "not supported");
-
-                       if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-                               return -EINVAL;
-
-                       em28xx_videodbg("%s: requested %dx%d\n",
-                                cmd ==
-                                VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
-                                "VIDIOC_S_FMT", format->fmt.pix.width,
-                                format->fmt.pix.height);
-
-                       /* FIXME: Move some code away from here */
-                       /* width must even because of the YUYV format */
-                       /* height must be even because of interlacing */
-                       height &= 0xfffe;
-                       width &= 0xfffe;
-
-                       if (height < 32)
-                               height = 32;
-                       if (height > maxh)
-                               height = maxh;
-                       if (width < 48)
-                               width = 48;
-                       if (width > maxw)
-                               width = maxw;
-
-                       if(dev->is_em2800){
-                               /* the em2800 can only scale down to 50% */
-                               if(height % (maxh / 2))
-                                       height=maxh;
-                               if(width % (maxw / 2))
-                                       width=maxw;
-                               /* according to empiatech support */
-                               /* the MaxPacketSize is to small to support */
-                               /* framesizes larger than 640x480 @ 30 fps */
-                               /* or 640x576 @ 25 fps. As this would cut */
-                               /* of a part of the image we prefer */
-                               /* 360x576 or 360x480 for now */
-                               if(width == maxw && height == maxh)
-                                       width /= 2;
-                       }
-
-                       if ((hscale =
-                            (((unsigned long)maxw) << 12) / width - 4096L) >=
-                           0x4000)
-                               hscale = 0x3fff;
-                       width =
-                           (((unsigned long)maxw) << 12) / (hscale + 4096L);
-
-                       if ((vscale =
-                            (((unsigned long)maxh) << 12) / height - 4096L) >=
-                           0x4000)
-                               vscale = 0x3fff;
-                       height =
-                           (((unsigned long)maxh) << 12) / (vscale + 4096L);
-
-                       format->fmt.pix.width = width;
-                       format->fmt.pix.height = height;
-                       format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
-                       format->fmt.pix.bytesperline = width * 2;
-                       format->fmt.pix.sizeimage = width * 2 * height;
-                       format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-                       format->fmt.pix.field = V4L2_FIELD_INTERLACED;
-
-                       em28xx_videodbg("%s: returned %dx%d (%d, %d)\n",
-                                cmd ==
-                                VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
-                                "VIDIOC_S_FMT", format->fmt.pix.width,
-                                format->fmt.pix.height, hscale, vscale);
-
-                       if (cmd == VIDIOC_TRY_FMT)
-                               return 0;
-
-                       for (i = 0; i < dev->num_frames; i++)
-                               if (dev->frame[i].vma_use_count) {
-                                       em28xx_videodbg("VIDIOC_S_FMT failed. "
-                                               "Unmap the buffers first.\n");
-                                       return -EINVAL;
-                               }
+               return em28xx_set_fmt(dev, cmd, (struct v4l2_format *)arg);
 
-                       /* stop io in case it is already in progress */
-                       if (dev->stream == STREAM_ON) {
-                               em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
-                               if ((ret = em28xx_stream_interrupt(dev)))
-                                       return ret;
-                       }
+       case VIDIOC_REQBUFS:
+       {
+               struct v4l2_requestbuffers *rb = arg;
+               u32 i;
+               int ret;
 
-                       em28xx_release_buffers(dev);
-                       dev->io = IO_NONE;
-
-                       /* set new image size */
-                       dev->width = width;
-                       dev->height = height;
-                       dev->frame_size = dev->width * dev->height * 2;
-                       dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
-                       dev->bytesperline = dev->width * 2;
-                       dev->hscale = hscale;
-                       dev->vscale = vscale;
-/*                     dev->both_fileds = both_fileds; */
-                       em28xx_uninit_isoc(dev);
-                       em28xx_set_alternate(dev);
-                       em28xx_capture_start(dev, 1);
-                       em28xx_resolution_set(dev);
-                       em28xx_init_isoc(dev);
+               if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+                       rb->memory != V4L2_MEMORY_MMAP)
+                       return -EINVAL;
 
-                       return 0;
+               if (dev->io == IO_READ) {
+                       em28xx_videodbg ("method is set to read;"
+                               " close and open the device again to"
+                               " choose the mmap I/O method\n");
+                       return -EINVAL;
                }
 
-               /* --- streaming capture ------------------------------------- */
-       case VIDIOC_REQBUFS:
-               {
-                       struct v4l2_requestbuffers *rb = arg;
-                       u32 i;
-                       int ret;
-
-                       if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-                           rb->memory != V4L2_MEMORY_MMAP)
-                               return -EINVAL;
-
-                       if (dev->io == IO_READ) {
-                               em28xx_videodbg ("method is set to read;"
-                                       " close and open the device again to"
-                                       " choose the mmap I/O method\n");
+               for (i = 0; i < dev->num_frames; i++)
+                       if (dev->frame[i].vma_use_count) {
+                               em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n");
                                return -EINVAL;
                        }
 
-                       for (i = 0; i < dev->num_frames; i++)
-                               if (dev->frame[i].vma_use_count) {
-                                       em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n");
-                                       return -EINVAL;
-                               }
-
-                       if (dev->stream == STREAM_ON) {
-                               em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n");
-                               if ((ret = em28xx_stream_interrupt(dev)))
-                                       return ret;
-                       }
-
-                       em28xx_empty_framequeues(dev);
+               if (dev->stream == STREAM_ON) {
+                       em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n");
+                       if ((ret = em28xx_stream_interrupt(dev)))
+                               return ret;
+               }
 
-                       em28xx_release_buffers(dev);
-                       if (rb->count)
-                               rb->count =
-                                   em28xx_request_buffers(dev, rb->count);
+               em28xx_empty_framequeues(dev);
 
-                       dev->frame_current = NULL;
+               em28xx_release_buffers(dev);
+               if (rb->count)
+                       rb->count =
+                               em28xx_request_buffers(dev, rb->count);
 
-                       em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n",
-                                                    rb->count);
-                       dev->io = rb->count ? IO_MMAP : IO_NONE;
-                       return 0;
-               }
+               dev->frame_current = NULL;
 
+               em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n",
+                                               rb->count);
+               dev->io = rb->count ? IO_MMAP : IO_NONE;
+               return 0;
+       }
        case VIDIOC_QUERYBUF:
-               {
-                       struct v4l2_buffer *b = arg;
+       {
+               struct v4l2_buffer *b = arg;
 
-                       if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-                           b->index >= dev->num_frames || dev->io != IO_MMAP)
-                               return -EINVAL;
+               if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+                       b->index >= dev->num_frames || dev->io != IO_MMAP)
+                       return -EINVAL;
 
-                       memcpy(b, &dev->frame[b->index].buf, sizeof(*b));
+               memcpy(b, &dev->frame[b->index].buf, sizeof(*b));
 
-                       if (dev->frame[b->index].vma_use_count) {
-                               b->flags |= V4L2_BUF_FLAG_MAPPED;
-                       }
-                       if (dev->frame[b->index].state == F_DONE)
-                               b->flags |= V4L2_BUF_FLAG_DONE;
-                       else if (dev->frame[b->index].state != F_UNUSED)
-                               b->flags |= V4L2_BUF_FLAG_QUEUED;
-                       return 0;
+               if (dev->frame[b->index].vma_use_count) {
+                       b->flags |= V4L2_BUF_FLAG_MAPPED;
                }
+               if (dev->frame[b->index].state == F_DONE)
+                       b->flags |= V4L2_BUF_FLAG_DONE;
+               else if (dev->frame[b->index].state != F_UNUSED)
+                       b->flags |= V4L2_BUF_FLAG_QUEUED;
+               return 0;
+       }
        case VIDIOC_QBUF:
-               {
-                       struct v4l2_buffer *b = arg;
-                       unsigned long lock_flags;
+       {
+               struct v4l2_buffer *b = arg;
+               unsigned long lock_flags;
 
-                       if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-                           b->index >= dev->num_frames || dev->io != IO_MMAP) {
-                               return -EINVAL;
-                       }
+               if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+                       b->index >= dev->num_frames || dev->io != IO_MMAP) {
+                       return -EINVAL;
+               }
 
-                       if (dev->frame[b->index].state != F_UNUSED) {
-                               return -EAGAIN;
-                       }
-                       dev->frame[b->index].state = F_QUEUED;
+               if (dev->frame[b->index].state != F_UNUSED) {
+                       return -EAGAIN;
+               }
+               dev->frame[b->index].state = F_QUEUED;
 
-                       /* add frame to fifo */
-                       spin_lock_irqsave(&dev->queue_lock, lock_flags);
-                       list_add_tail(&dev->frame[b->index].frame,
-                                     &dev->inqueue);
-                       spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
+               /* add frame to fifo */
+               spin_lock_irqsave(&dev->queue_lock, lock_flags);
+               list_add_tail(&dev->frame[b->index].frame,
+                               &dev->inqueue);
+               spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
 
-                       return 0;
-               }
+               return 0;
+       }
        case VIDIOC_DQBUF:
-               {
-                       struct v4l2_buffer *b = arg;
-                       struct em28xx_frame_t *f;
-                       unsigned long lock_flags;
-                       int ret = 0;
+       {
+               struct v4l2_buffer *b = arg;
+               struct em28xx_frame_t *f;
+               unsigned long lock_flags;
+               int ret = 0;
 
-                       if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
-                           || dev->io != IO_MMAP)
-                               return -EINVAL;
+               if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
+                       || dev->io != IO_MMAP)
+                       return -EINVAL;
 
-                       if (list_empty(&dev->outqueue)) {
-                               if (dev->stream == STREAM_OFF)
-                                       return -EINVAL;
-                               if (filp->f_flags & O_NONBLOCK)
-                                       return -EAGAIN;
-                               ret = wait_event_interruptible
-                                   (dev->wait_frame,
-                                    (!list_empty(&dev->outqueue)) ||
-                                    (dev->state & DEV_DISCONNECTED));
-                               if (ret)
-                                       return ret;
-                               if (dev->state & DEV_DISCONNECTED)
-                                       return -ENODEV;
-                       }
+               if (list_empty(&dev->outqueue)) {
+                       if (dev->stream == STREAM_OFF)
+                               return -EINVAL;
+                       if (filp->f_flags & O_NONBLOCK)
+                               return -EAGAIN;
+                       ret = wait_event_interruptible
+                               (dev->wait_frame,
+                               (!list_empty(&dev->outqueue)) ||
+                               (dev->state & DEV_DISCONNECTED));
+                       if (ret)
+                               return ret;
+                       if (dev->state & DEV_DISCONNECTED)
+                               return -ENODEV;
+               }
 
-                       spin_lock_irqsave(&dev->queue_lock, lock_flags);
-                       f = list_entry(dev->outqueue.next,
-                                      struct em28xx_frame_t, frame);
-                       list_del(dev->outqueue.next);
-                       spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
+               spin_lock_irqsave(&dev->queue_lock, lock_flags);
+               f = list_entry(dev->outqueue.next,
+                               struct em28xx_frame_t, frame);
+               list_del(dev->outqueue.next);
+               spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
 
-                       f->state = F_UNUSED;
-                       memcpy(b, &f->buf, sizeof(*b));
+               f->state = F_UNUSED;
+               memcpy(b, &f->buf, sizeof(*b));
 
-                       if (f->vma_use_count)
-                               b->flags |= V4L2_BUF_FLAG_MAPPED;
+               if (f->vma_use_count)
+                       b->flags |= V4L2_BUF_FLAG_MAPPED;
 
-                       return 0;
-               }
+               return 0;
+       }
        default:
                return em28xx_do_ioctl(inode, filp, dev, cmd, arg,
                                       em28xx_video_do_ioctl);
@@ -1621,25 +1470,25 @@ static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp,
        int ret = 0;
        struct em28xx *dev = filp->private_data;
 
-       if (down_interruptible(&dev->fileop_lock))
+       if (mutex_lock_interruptible(&dev->fileop_lock))
                return -ERESTARTSYS;
 
        if (dev->state & DEV_DISCONNECTED) {
                em28xx_errdev("v4l2 ioctl: device not present\n");
-               up(&dev->fileop_lock);
+               mutex_unlock(&dev->fileop_lock);
                return -ENODEV;
        }
 
        if (dev->state & DEV_MISCONFIGURED) {
                em28xx_errdev
                    ("v4l2 ioctl: device is misconfigured; close and open it again\n");
-               up(&dev->fileop_lock);
+               mutex_unlock(&dev->fileop_lock);
                return -EIO;
        }
 
        ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl);
 
-       up(&dev->fileop_lock);
+       mutex_unlock(&dev->fileop_lock);
 
        return ret;
 }
@@ -1673,7 +1522,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
 
        dev->udev = udev;
        dev->model = model;
-       init_MUTEX(&dev->lock);
+       mutex_init(&dev->lock);
        init_waitqueue_head(&dev->open);
 
        dev->em28xx_write_regs = em28xx_write_regs;
@@ -1729,10 +1578,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        dev->vpic.depth = 16;
        dev->vpic.palette = VIDEO_PALETTE_YUV422;
 
+       em28xx_pre_card_setup(dev);
 #ifdef CONFIG_MODULES
        /* request some modules */
        if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114)
-               request_module("saa711x");
+               request_module("saa7115");
        if (dev->decoder == EM28XX_TVP5150)
                request_module("tvp5150");
        if (dev->has_tuner)
@@ -1744,10 +1594,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        if (errCode) {
                em28xx_errdev("error configuring device\n");
                kfree(dev);
+               em28xx_devused&=~(1<<dev->devno);
                return -ENOMEM;
        }
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        /* register i2c bus */
        em28xx_i2c_register(dev);
 
@@ -1757,7 +1608,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        /* configure the device */
        em28xx_config_i2c(dev);
 
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 
        errCode = em28xx_config(dev);
 
@@ -1770,9 +1621,30 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        if (NULL == dev->vdev) {
                em28xx_errdev("cannot allocate video_device.\n");
                kfree(dev);
+               em28xx_devused&=~(1<<dev->devno);
                return -ENOMEM;
        }
 
+       dev->vbi_dev = video_device_alloc();
+       if (NULL == dev->vbi_dev) {
+               em28xx_errdev("cannot allocate video_device.\n");
+               kfree(dev->vdev);
+               kfree(dev);
+               em28xx_devused&=~(1<<dev->devno);
+               return -ENOMEM;
+       }
+
+       /* Fills VBI device info */
+       dev->vbi_dev->type = VFL_TYPE_VBI;
+       dev->vbi_dev->hardware = 0;
+       dev->vbi_dev->fops = &em28xx_v4l_fops;
+       dev->vbi_dev->minor = -1;
+       dev->vbi_dev->dev = &dev->udev->dev;
+       dev->vbi_dev->release = video_device_release;
+       snprintf(dev->vbi_dev->name, sizeof(dev->vbi_dev->name), "%s#%d %s",
+                                                        "em28xx",dev->devno,"vbi");
+
+       /* Fills CAPTURE device info */
        dev->vdev->type = VID_TYPE_CAPTURE;
        if (dev->has_tuner)
                dev->vdev->type |= VID_TYPE_TUNER;
@@ -1781,21 +1653,39 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        dev->vdev->minor = -1;
        dev->vdev->dev = &dev->udev->dev;
        dev->vdev->release = video_device_release;
-       snprintf(dev->vdev->name, sizeof(dev->vdev->name), "%s",
-                "em28xx video");
+       snprintf(dev->vdev->name, sizeof(dev->vbi_dev->name), "%s#%d %s",
+                                                        "em28xx",dev->devno,"video");
+
        list_add_tail(&dev->devlist,&em28xx_devlist);
 
        /* register v4l2 device */
-       down(&dev->lock);
-       if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1))) {
+       mutex_lock(&dev->lock);
+       if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
+                                        video_nr[dev->devno]))) {
                em28xx_errdev("unable to register video device (error=%i).\n",
                              retval);
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                list_del(&dev->devlist);
                video_device_release(dev->vdev);
                kfree(dev);
+               em28xx_devused&=~(1<<dev->devno);
                return -ENODEV;
        }
+
+       if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
+                                       vbi_nr[dev->devno]) < 0) {
+               printk("unable to register vbi device\n");
+               mutex_unlock(&dev->lock);
+               list_del(&dev->devlist);
+               video_device_release(dev->vbi_dev);
+               video_device_release(dev->vdev);
+               kfree(dev);
+               em28xx_devused&=~(1<<dev->devno);
+               return -ENODEV;
+       } else {
+               printk("registered VBI\n");
+       }
+
        if (dev->has_msp34xx) {
                /* Send a reset to other chips via gpio */
                em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
@@ -1806,10 +1696,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        }
        video_mux(dev, 0);
 
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 
-       em28xx_info("V4L2 device registered as /dev/video%d\n",
-                   dev->vdev->minor);
+       em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
+                               dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN,
+                               dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN);
 
        return 0;
 }
@@ -1831,6 +1722,9 @@ static int em28xx_usb_probe(struct usb_interface *interface,
        udev = usb_get_dev(interface_to_usbdev(interface));
        ifnum = interface->altsetting[0].desc.bInterfaceNumber;
 
+       /* Check to see next free device and mark as used */
+       nr=find_first_zero_bit(&em28xx_devused,EM28XX_MAXBOARDS);
+       em28xx_devused|=1<<nr;
 
        /* Don't register audio interfaces */
        if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
@@ -1838,6 +1732,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
                                udev->descriptor.idVendor,udev->descriptor.idProduct,
                                ifnum,
                                interface->altsetting[0].desc.bInterfaceClass);
+
+               em28xx_devused&=~(1<<nr);
                return -ENODEV;
        }
 
@@ -1852,18 +1748,20 @@ static int em28xx_usb_probe(struct usb_interface *interface,
        if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
            USB_ENDPOINT_XFER_ISOC) {
                em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n");
+               em28xx_devused&=~(1<<nr);
                return -ENODEV;
        }
        if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
                em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n");
+               em28xx_devused&=~(1<<nr);
                return -ENODEV;
        }
 
        model=id->driver_info;
-       nr=interface->minor;
 
-       if (nr>EM28XX_MAXBOARDS) {
+       if (nr >= EM28XX_MAXBOARDS) {
                printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS);
+               em28xx_devused&=~(1<<nr);
                return -ENOMEM;
        }
 
@@ -1871,19 +1769,24 @@ static int em28xx_usb_probe(struct usb_interface *interface,
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (dev == NULL) {
                em28xx_err(DRIVER_NAME ": out of memory!\n");
+               em28xx_devused&=~(1<<nr);
                return -ENOMEM;
        }
 
+       snprintf(dev->name, 29, "em28xx #%d", nr);
+       dev->devno=nr;
+
        /* compute alternate max packet sizes */
        uif = udev->actconfig->interface[0];
 
        dev->num_alt=uif->num_altsetting;
-       printk(DRIVER_NAME ": Alternate settings: %i\n",dev->num_alt);
+       em28xx_info("Alternate settings: %i\n",dev->num_alt);
 //     dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)*
        dev->alt_max_pkt_size = kmalloc(32*
                                                dev->num_alt,GFP_KERNEL);
        if (dev->alt_max_pkt_size == NULL) {
-               em28xx_err(DRIVER_NAME ": out of memory!\n");
+               em28xx_errdev("out of memory!\n");
+               em28xx_devused&=~(1<<nr);
                return -ENOMEM;
        }
 
@@ -1892,27 +1795,26 @@ static int em28xx_usb_probe(struct usb_interface *interface,
                                                        wMaxPacketSize);
                dev->alt_max_pkt_size[i] =
                    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
-               printk(DRIVER_NAME ": Alternate setting %i, max size= %i\n",i,
+               em28xx_info("Alternate setting %i, max size= %i\n",i,
                                                        dev->alt_max_pkt_size[i]);
        }
 
-       snprintf(dev->name, 29, "em28xx #%d", nr);
-
        if ((card[nr]>=0)&&(card[nr]<em28xx_bcount))
                model=card[nr];
 
        if ((model==EM2800_BOARD_UNKNOWN)||(model==EM2820_BOARD_UNKNOWN)) {
-               printk( "%s: Your board has no eeprom inside it and thus can't\n"
+               em28xx_errdev( "Your board has no eeprom inside it and thus can't\n"
                        "%s: be autodetected.  Please pass card=<n> insmod option to\n"
                        "%s: workaround that.  Redirect complaints to the vendor of\n"
-                       "%s: the TV card.  Best regards,\n"
+                       "%s: the TV card. Generic type will be used."
+                       "%s: Best regards,\n"
                        "%s:         -- tux\n",
                        dev->name,dev->name,dev->name,dev->name,dev->name);
-               printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
+               em28xx_errdev("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
                        dev->name);
                for (i = 0; i < em28xx_bcount; i++) {
-                       printk("%s:    card=%d -> %s\n",
-                               dev->name, i, em28xx_boards[i].name);
+                       em28xx_errdev("    card=%d -> %s\n", i,
+                                                       em28xx_boards[i].name);
                }
        }
 
@@ -1938,15 +1840,12 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
        struct em28xx *dev = usb_get_intfdata(interface);
        usb_set_intfdata(interface, NULL);
 
-/*FIXME: IR should be disconnected */
-
        if (!dev)
                return;
 
-
        down_write(&em28xx_disconnect);
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
 
        em28xx_info("disconnecting %s\n", dev->vdev->name);
 
@@ -1955,7 +1854,9 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
        if (dev->users) {
                em28xx_warn
                    ("device /dev/video%d is open! Deregistration and memory "
-                    "deallocation are deferred on close.\n", dev->vdev->minor);
+                    "deallocation are deferred on close.\n",
+                               dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN);
+
                dev->state |= DEV_MISCONFIGURED;
                em28xx_uninit_isoc(dev);
                dev->state |= DEV_DISCONNECTED;
@@ -1966,7 +1867,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
                em28xx_release_resources(dev);
        }
 
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 
        if (!dev->users) {
                kfree(dev->alt_max_pkt_size);
index 33de9d846af5ed1cd1311784ad19daf928c00298..e1ddc2f27a2152df39dbe8f9af74749cb2bbdb31 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/videodev.h>
 #include <linux/i2c.h>
+#include <linux/mutex.h>
 #include <media/ir-kbd-i2c.h>
 
 /* Boards supported by driver */
 #define EM2800_BOARD_LEADTEK_WINFAST_USBII      7
 #define EM2800_BOARD_KWORLD_USB2800             8
 #define EM2820_BOARD_PINNACLE_DVC_90           9
+#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900   10
+#define EM2880_BOARD_TERRATEC_HYBRID_XS                11
+#define EM2820_BOARD_KWORLD_PVRTV2800RF                12
+#define EM2880_BOARD_TERRATEC_PRODIGY_XS       13
 
 #define UNSET -1
 
@@ -209,6 +214,7 @@ struct em28xx {
        /* generic device properties */
        char name[30];          /* name (including minor) of the device */
        int model;              /* index in the device_data struct */
+       int devno;              /* marks the number of this device */
        unsigned int is_em2800;
        int video_inputs;       /* number of video inputs */
        struct list_head        devlist;
@@ -256,7 +262,7 @@ struct em28xx {
        enum em28xx_stream_state stream;
        enum em28xx_io_method io;
        /* locks */
-       struct semaphore lock, fileop_lock;
+       struct mutex lock, fileop_lock;
        spinlock_t queue_lock;
        struct list_head inqueue, outqueue;
        wait_queue_head_t open, wait_frame, wait_stream;
@@ -326,6 +332,7 @@ int em28xx_set_alternate(struct em28xx *dev);
 
 /* Provided by em28xx-cards.c */
 extern int em2800_variant_detect(struct usb_device* udev,int model);
+extern void em28xx_pre_card_setup(struct em28xx *dev);
 extern void em28xx_card_setup(struct em28xx *dev);
 extern struct em28xx_board em28xx_boards[];
 extern struct usb_device_id em28xx_id_table[];
index e7bbeb11553d5d72ef17337d9dcac0a932c9f8bf..c7fed340565524d8ad13553e7fce99ed84c56c37 100644 (file)
@@ -1,9 +1,9 @@
 /*
     hexium_gemini.c - v4l2 driver for Hexium Gemini frame grabber cards
-               
+
     Visit http://www.mihu.de/linux/saa7146/ and follow the link
     to "hexium" for further details about this card.
-    
+
     Copyright (C) 2003 Michael Hunold <michael@mihu.de>
 
     This program is free software; you can redistribute it and/or modify
@@ -81,7 +81,7 @@ struct hexium
 
        struct video_device     *video_dev;
        struct i2c_adapter      i2c_adapter;
-               
+
        int             cur_input;      /* current input */
        v4l2_std_id     cur_std;        /* current standard */
        int             cur_bw;         /* current black/white status */
@@ -174,7 +174,7 @@ static struct saa7146_standard hexium_standards[] = {
                .h_offset       = 1,    .h_pixels       = 720,
                .v_max_out      = 576,  .h_max_out      = 768,
        }
-};             
+};
 
 /* bring hardware to a sane state. this has to be done, just in case someone
    wants to capture from this device before it has been properly initialized.
@@ -311,7 +311,7 @@ static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
        struct saa7146_dev *dev = fh->dev;
        struct hexium *hexium = (struct hexium *) dev->ext_priv;
 /*
-       struct saa7146_vv *vv = dev->vv_data; 
+       struct saa7146_vv *vv = dev->vv_data;
 */
        switch (cmd) {
        case VIDIOC_ENUMINPUT:
index aad4a18aafd662ff6de64d6ae1e5b328366b1540..137c4736da04085ccf8d3df188d905ea97ceda43 100644 (file)
@@ -3,7 +3,7 @@
 
     Visit http://www.mihu.de/linux/saa7146/ and follow the link
     to "hexium" for further details about this card.
-    
+
     Copyright (C) 2003 Michael Hunold <michael@mihu.de>
 
     This program is free software; you can redistribute it and/or modify
@@ -69,7 +69,7 @@ struct hexium
 {
        int type;
        struct video_device     *video_dev;
-       struct i2c_adapter      i2c_adapter;    
+       struct i2c_adapter      i2c_adapter;
 
        int cur_input;  /* current input */
 };
@@ -86,7 +86,7 @@ static u8 hexium_saa7110[53]={
 };
 
 static struct {
-       struct hexium_data data[8];     
+       struct hexium_data data[8];
 } hexium_input_select[] = {
 {
        { /* cvbs 1 */
@@ -153,7 +153,7 @@ static struct {
                { 0x30, 0x60 },
                { 0x31, 0xB5 }, // ??
                { 0x21, 0x03 },
-       } 
+       }
 }, {
        { /* y/c 1 */
                { 0x06, 0x80 },
@@ -187,7 +187,7 @@ static struct {
                { 0x31, 0x75 },
                { 0x21, 0x21 },
        }
-}      
+}
 };
 
 static struct saa7146_standard hexium_standards[] = {
@@ -207,7 +207,7 @@ static struct saa7146_standard hexium_standards[] = {
                .h_offset       = 1,    .h_pixels       = 720,
                .v_max_out      = 576,  .h_max_out      = 768,
        }
-};             
+};
 
 /* this is only called for old HV-PCI6/Orion cards
    without eeprom */
@@ -272,7 +272,7 @@ static int hexium_probe(struct saa7146_dev *dev)
                return 0;
        }
 
-       /* check if this is an old hexium Orion card by looking at 
+       /* check if this is an old hexium Orion card by looking at
           a saa7110 at address 0x4e */
        if (0 == (err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, &data))) {
                printk("hexium_orion: device is a Hexium HV-PCI6/Orion (old).\n");
@@ -314,7 +314,7 @@ static int hexium_set_input(struct hexium *hexium, int input)
 {
        union i2c_smbus_data data;
        int i = 0;
-       
+
        DEB_D((".\n"));
 
        for (i = 0; i < 8; i++) {
@@ -375,7 +375,7 @@ static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
        struct saa7146_dev *dev = fh->dev;
        struct hexium *hexium = (struct hexium *) dev->ext_priv;
 /*
-       struct saa7146_vv *vv = dev->vv_data; 
+       struct saa7146_vv *vv = dev->vv_data;
 */
        switch (cmd) {
        case VIDIOC_ENUMINPUT:
index 58b0e698282206e0e028423d202be8c24d5db35c..95bacf435414ead307c6230cd65479f42a9369dc 100644 (file)
 #include <media/ir-common.h>
 #include <media/ir-kbd-i2c.h>
 
-/* Mark Phalan <phalanm@o2.ie> */
-static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
-       [  0 ] = KEY_KP0,
-       [  1 ] = KEY_KP1,
-       [  2 ] = KEY_KP2,
-       [  3 ] = KEY_KP3,
-       [  4 ] = KEY_KP4,
-       [  5 ] = KEY_KP5,
-       [  6 ] = KEY_KP6,
-       [  7 ] = KEY_KP7,
-       [  8 ] = KEY_KP8,
-       [  9 ] = KEY_KP9,
-
-       [ 18 ] = KEY_POWER,
-       [ 16 ] = KEY_MUTE,
-       [ 31 ] = KEY_VOLUMEDOWN,
-       [ 27 ] = KEY_VOLUMEUP,
-       [ 26 ] = KEY_CHANNELUP,
-       [ 30 ] = KEY_CHANNELDOWN,
-       [ 14 ] = KEY_PAGEUP,
-       [ 29 ] = KEY_PAGEDOWN,
-       [ 19 ] = KEY_SOUND,
-
-       [ 24 ] = KEY_KPPLUSMINUS,       /* CH +/- */
-       [ 22 ] = KEY_SUBTITLE,          /* CC */
-       [ 13 ] = KEY_TEXT,              /* TTX */
-       [ 11 ] = KEY_TV,                /* AIR/CBL */
-       [ 17 ] = KEY_PC,                /* PC/TV */
-       [ 23 ] = KEY_OK,                /* CH RTN */
-       [ 25 ] = KEY_MODE,              /* FUNC */
-       [ 12 ] = KEY_SEARCH,            /* AUTOSCAN */
-
-       /* Not sure what to do with these ones! */
-       [ 15 ] = KEY_SELECT,            /* SOURCE */
-       [ 10 ] = KEY_KPPLUS,            /* +100 */
-       [ 20 ] = KEY_KPEQUAL,           /* SYNC */
-       [ 28 ] = KEY_MEDIA,             /* PC/TV */
-};
-
 /* ----------------------------------------------------------------------- */
 /* insmod parameters                                                       */
 
 static int debug;
 module_param(debug, int, 0644);    /* debug level (0,1,2) */
 
+static int hauppauge = 0;
+module_param(hauppauge, int, 0644);    /* Choose Hauppauge remote */
+MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)");
+
+
 #define DEVNAME "ir-kbd-i2c"
 #define dprintk(level, fmt, arg...)    if (debug >= level) \
        printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
@@ -336,7 +302,11 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
                name        = "Hauppauge";
                ir->get_key = get_key_haup;
                ir_type     = IR_TYPE_RC5;
-               ir_codes    = ir_codes_rc5_tv;
+               if (hauppauge == 1) {
+                       ir_codes    = ir_codes_hauppauge_new;
+               } else {
+                       ir_codes    = ir_codes_rc5_tv;
+               }
                break;
        case 0x30:
                name        = "KNC One";
index 2869464aee0d699677efccf99593dcdeb11526d3..850bee97090c91e169531c0d218d9933c4b9f1e1 100644 (file)
@@ -925,7 +925,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        return -EINVAL;
                if (p->palette != VIDEO_PALETTE_YUV422)
                        return -EINVAL;
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS,
                                      p->brightness >> 10);
                sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE,
@@ -935,7 +935,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST,
                                      p->contrast >> 10);
                meye.picture = *p;
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -946,21 +946,21 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                if (*i < 0 || *i >= gbuffers)
                        return -EINVAL;
 
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
 
                switch (meye.grab_buffer[*i].state) {
 
                case MEYE_BUF_UNUSED:
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -EINVAL;
                case MEYE_BUF_USING:
                        if (file->f_flags & O_NONBLOCK) {
-                               up(&meye.lock);
+                               mutex_unlock(&meye.lock);
                                return -EAGAIN;
                        }
                        if (wait_event_interruptible(meye.proc_list,
                                                     (meye.grab_buffer[*i].state != MEYE_BUF_USING))) {
-                               up(&meye.lock);
+                               mutex_unlock(&meye.lock);
                                return -EINTR;
                        }
                        /* fall through */
@@ -968,7 +968,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
                        kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int));
                }
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -987,7 +987,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED)
                        return -EBUSY;
 
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                if (vm->width == 640 && vm->height == 480) {
                        if (meye.params.subsample) {
                                meye.params.subsample = 0;
@@ -999,7 +999,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                                restart = 1;
                        }
                } else {
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -EINVAL;
                }
 
@@ -1007,7 +1007,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        mchip_continuous_start();
                meye.grab_buffer[vm->frame].state = MEYE_BUF_USING;
                kfifo_put(meye.grabq, (unsigned char *)&vm->frame, sizeof(int));
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -1039,7 +1039,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        return -EINVAL;
                if (jp->framerate > 31)
                        return -EINVAL;
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                if (meye.params.subsample != jp->subsample ||
                    meye.params.quality != jp->quality)
                        mchip_hic_stop();       /* need restart */
@@ -1050,7 +1050,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                                      meye.params.agc);
                sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE,
                                      meye.params.picture);
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -1068,12 +1068,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                }
                if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED)
                        return -EBUSY;
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
                        mchip_cont_compression_start();
                meye.grab_buffer[*nb].state = MEYE_BUF_USING;
                kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int));
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -1084,20 +1084,20 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                if (*i < 0 || *i >= gbuffers)
                        return -EINVAL;
 
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                switch (meye.grab_buffer[*i].state) {
 
                case MEYE_BUF_UNUSED:
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -EINVAL;
                case MEYE_BUF_USING:
                        if (file->f_flags & O_NONBLOCK) {
-                               up(&meye.lock);
+                               mutex_unlock(&meye.lock);
                                return -EAGAIN;
                        }
                        if (wait_event_interruptible(meye.proc_list,
                                                     (meye.grab_buffer[*i].state != MEYE_BUF_USING))) {
-                               up(&meye.lock);
+                               mutex_unlock(&meye.lock);
                                return -EINTR;
                        }
                        /* fall through */
@@ -1106,7 +1106,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int));
                }
                *i = meye.grab_buffer[*i].size;
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -1116,14 +1116,14 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        return -EINVAL;
                if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
                        return -EBUSY;
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                meye.grab_buffer[0].state = MEYE_BUF_USING;
                mchip_take_picture();
                mchip_get_picture(
                        meye.grab_fbuffer,
                        mchip_hsize() * mchip_vsize() * 2);
                meye.grab_buffer[0].state = MEYE_BUF_DONE;
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -1134,7 +1134,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        return -EINVAL;
                if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
                        return -EBUSY;
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                meye.grab_buffer[0].state = MEYE_BUF_USING;
                *len = -1;
                while (*len == -1) {
@@ -1142,7 +1142,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);
                }
                meye.grab_buffer[0].state = MEYE_BUF_DONE;
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -1285,7 +1285,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
        case VIDIOC_S_CTRL: {
                struct v4l2_control *c = arg;
 
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                switch (c->id) {
                case V4L2_CID_BRIGHTNESS:
                        sonypi_camera_command(
@@ -1329,17 +1329,17 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        meye.params.framerate = c->value;
                        break;
                default:
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -EINVAL;
                }
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
        case VIDIOC_G_CTRL: {
                struct v4l2_control *c = arg;
 
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                switch (c->id) {
                case V4L2_CID_BRIGHTNESS:
                        c->value = meye.picture.brightness >> 10;
@@ -1369,10 +1369,10 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        c->value = meye.params.framerate;
                        break;
                default:
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -EINVAL;
                }
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -1469,7 +1469,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                    f->fmt.pix.field != V4L2_FIELD_NONE)
                        return -EINVAL;
                f->fmt.pix.field = V4L2_FIELD_NONE;
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                if (f->fmt.pix.width <= 320) {
                        f->fmt.pix.width = 320;
                        f->fmt.pix.height = 240;
@@ -1487,7 +1487,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
                        break;
                }
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
                f->fmt.pix.sizeimage = f->fmt.pix.height *
                                       f->fmt.pix.bytesperline;
@@ -1509,11 +1509,11 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        /* already allocated, no modifications */
                        break;
                }
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                if (meye.grab_fbuffer) {
                        for (i = 0; i < gbuffers; i++)
                                if (meye.vma_use_count[i]) {
-                                       up(&meye.lock);
+                                       mutex_unlock(&meye.lock);
                                        return -EINVAL;
                                }
                        rvfree(meye.grab_fbuffer, gbuffers * gbufsize);
@@ -1525,12 +1525,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                if (!meye.grab_fbuffer) {
                        printk(KERN_ERR "meye: v4l framebuffer allocation"
                                        " failed\n");
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -ENOMEM;
                }
                for (i = 0; i < gbuffers; i++)
                        meye.vma_use_count[i] = 0;
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -1569,12 +1569,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        return -EINVAL;
                if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED)
                        return -EINVAL;
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                buf->flags |= V4L2_BUF_FLAG_QUEUED;
                buf->flags &= ~V4L2_BUF_FLAG_DONE;
                meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
                kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int));
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -1587,23 +1587,23 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                if (buf->memory != V4L2_MEMORY_MMAP)
                        return -EINVAL;
 
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -EAGAIN;
                }
                if (wait_event_interruptible(meye.proc_list,
                                             kfifo_len(meye.doneq) != 0) < 0) {
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -EINTR;
                }
                if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr,
                               sizeof(int))) {
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -EBUSY;
                }
                if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) {
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -EINVAL;
                }
                buf->index = reqnr;
@@ -1616,12 +1616,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                buf->m.offset = reqnr * gbufsize;
                buf->length = gbufsize;
                meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED;
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
        case VIDIOC_STREAMON: {
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                switch (meye.mchip_mode) {
                case MCHIP_HIC_MODE_CONT_OUT:
                        mchip_continuous_start();
@@ -1630,23 +1630,23 @@ static int meye_do_ioctl(struct inode *inode, struct file *file,
                        mchip_cont_compression_start();
                        break;
                default:
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -EINVAL;
                }
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
        case VIDIOC_STREAMOFF: {
                int i;
 
-               down(&meye.lock);
+               mutex_lock(&meye.lock);
                mchip_hic_stop();
                kfifo_reset(meye.grabq);
                kfifo_reset(meye.doneq);
                for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
                        meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                break;
        }
 
@@ -1672,11 +1672,11 @@ static unsigned int meye_poll(struct file *file, poll_table *wait)
 {
        unsigned int res = 0;
 
-       down(&meye.lock);
+       mutex_lock(&meye.lock);
        poll_wait(file, &meye.proc_list, wait);
        if (kfifo_len(meye.doneq))
                res = POLLIN | POLLRDNORM;
-       up(&meye.lock);
+       mutex_unlock(&meye.lock);
        return res;
 }
 
@@ -1704,9 +1704,9 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma)
        unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
        unsigned long page, pos;
 
-       down(&meye.lock);
+       mutex_lock(&meye.lock);
        if (size > gbuffers * gbufsize) {
-               up(&meye.lock);
+               mutex_unlock(&meye.lock);
                return -EINVAL;
        }
        if (!meye.grab_fbuffer) {
@@ -1716,7 +1716,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma)
                meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize);
                if (!meye.grab_fbuffer) {
                        printk(KERN_ERR "meye: v4l framebuffer allocation failed\n");
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -ENOMEM;
                }
                for (i = 0; i < gbuffers; i++)
@@ -1727,7 +1727,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma)
        while (size > 0) {
                page = vmalloc_to_pfn((void *)pos);
                if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
-                       up(&meye.lock);
+                       mutex_unlock(&meye.lock);
                        return -EAGAIN;
                }
                start += PAGE_SIZE;
@@ -1744,7 +1744,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma)
        vma->vm_private_data = (void *) (offset / gbufsize);
        meye_vm_open(vma);
 
-       up(&meye.lock);
+       mutex_unlock(&meye.lock);
        return 0;
 }
 
@@ -1913,7 +1913,7 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
                goto outvideoreg;
        }
 
-       init_MUTEX(&meye.lock);
+       mutex_init(&meye.lock);
        init_waitqueue_head(&meye.proc_list);
        meye.picture.depth = 16;
        meye.picture.palette = VIDEO_PALETTE_YUV422;
index e8cd897b0d20e9c6c7349fd67c7579caee4c0e6a..0d09a0e3803c5cdfd5c4e6f911573cdae41b29a1 100644 (file)
 
 /* private API definitions */
 #include <linux/meye.h>
+#include <linux/mutex.h>
+
 
 /* Enable jpg software correction */
 #define MEYE_JPEG_CORRECTION   1
@@ -301,7 +303,7 @@ struct meye {
                                        /* list of buffers */
        struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS];
        int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */
-       struct semaphore lock;          /* semaphore for open/mmap... */
+       struct mutex lock;              /* mutex for open/mmap... */
        struct kfifo *grabq;            /* queue for buffers to be grabbed */
        spinlock_t grabq_lock;          /* lock protecting the queue */
        struct kfifo *doneq;            /* queue for grabbed buffers */
index 69ed369c2f4801227f57c529123d5235bfd039ef..11ea9765769c7df12e8181040502d4339e295fc8 100644 (file)
@@ -411,9 +411,9 @@ static int msp_mode_v4l2_to_v4l1(int rxsubchans)
        if (rxsubchans & V4L2_TUNER_SUB_STEREO)
                mode |= VIDEO_SOUND_STEREO;
        if (rxsubchans & V4L2_TUNER_SUB_LANG2)
-               mode |= VIDEO_SOUND_LANG2;
+               mode |= VIDEO_SOUND_LANG2 | VIDEO_SOUND_STEREO;
        if (rxsubchans & V4L2_TUNER_SUB_LANG1)
-               mode |= VIDEO_SOUND_LANG1;
+               mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_STEREO;
        if (mode == 0)
                mode |= VIDEO_SOUND_MONO;
        return mode;
@@ -430,21 +430,6 @@ static int msp_mode_v4l1_to_v4l2(int mode)
        return V4L2_TUNER_MODE_MONO;
 }
 
-static void msp_any_detect_stereo(struct i2c_client *client)
-{
-       struct msp_state *state  = i2c_get_clientdata(client);
-
-       switch (state->opmode) {
-       case OPMODE_MANUAL:
-       case OPMODE_AUTODETECT:
-               autodetect_stereo(client);
-               break;
-       case OPMODE_AUTOSELECT:
-               msp34xxg_detect_stereo(client);
-               break;
-       }
-}
-
 static struct v4l2_queryctrl msp_qctrl_std[] = {
        {
                .id            = V4L2_CID_AUDIO_VOLUME,
@@ -506,22 +491,6 @@ static struct v4l2_queryctrl msp_qctrl_sound_processing[] = {
 };
 
 
-static void msp_any_set_audmode(struct i2c_client *client, int audmode)
-{
-       struct msp_state *state = i2c_get_clientdata(client);
-
-       switch (state->opmode) {
-       case OPMODE_MANUAL:
-       case OPMODE_AUTODETECT:
-               state->watch_stereo = 0;
-               msp3400c_setstereo(client, audmode);
-               break;
-       case OPMODE_AUTOSELECT:
-               msp34xxg_set_audmode(client, audmode);
-               break;
-       }
-}
-
 static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
 {
        struct msp_state *state = i2c_get_clientdata(client);
@@ -653,11 +622,10 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
                }
                if (scart) {
                        state->rxsubchans = V4L2_TUNER_SUB_STEREO;
-                       state->audmode = V4L2_TUNER_MODE_STEREO;
                        msp_set_scart(client, scart, 0);
                        msp_write_dsp(client, 0x000d, 0x1900);
                        if (state->opmode != OPMODE_AUTOSELECT)
-                               msp3400c_setstereo(client, state->audmode);
+                               msp_set_audmode(client);
                }
                msp_wake_thread(client);
                break;
@@ -671,8 +639,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
                switch (state->opmode) {
                case OPMODE_MANUAL:
                        /* set msp3400 to FM radio mode */
-                       msp3400c_setmode(client, MSP_MODE_FM_RADIO);
-                       msp3400c_setcarrier(client, MSP_CARRIER(10.7),
+                       msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
+                       msp3400c_set_carrier(client, MSP_CARRIER(10.7),
                                            MSP_CARRIER(10.7));
                        msp_set_audio(client);
                        break;
@@ -706,7 +674,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
                if (state->radio)
                        break;
                if (state->opmode == OPMODE_AUTOSELECT)
-                       msp_any_detect_stereo(client);
+                       msp_detect_stereo(client);
                va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans);
                break;
        }
@@ -722,8 +690,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
                state->treble = va->treble;
                msp_set_audio(client);
 
-               if (va->mode != 0 && state->radio == 0)
-                       msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode));
+               if (va->mode != 0 && state->radio == 0) {
+                       state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
+               }
                break;
        }
 
@@ -831,11 +800,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
                        return -EINVAL;
                }
 
-               msp_any_detect_stereo(client);
-               if (state->audmode == V4L2_TUNER_MODE_STEREO) {
-                       a->capability = V4L2_AUDCAP_STEREO;
-               }
-
+               a->capability = V4L2_AUDCAP_STEREO;
+               a->mode = 0;  /* TODO: add support for AVL */
                break;
        }
 
@@ -865,16 +831,10 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
                }
                if (scart) {
                        state->rxsubchans = V4L2_TUNER_SUB_STEREO;
-                       state->audmode = V4L2_TUNER_MODE_STEREO;
                        msp_set_scart(client, scart, 0);
                        msp_write_dsp(client, 0x000d, 0x1900);
                }
-               if (sarg->capability == V4L2_AUDCAP_STEREO) {
-                       state->audmode = V4L2_TUNER_MODE_STEREO;
-               } else {
-                       state->audmode &= ~V4L2_TUNER_MODE_STEREO;
-               }
-               msp_any_set_audmode(client, state->audmode);
+               msp_set_audmode(client);
                msp_wake_thread(client);
                break;
        }
@@ -886,7 +846,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
                if (state->radio)
                        break;
                if (state->opmode == OPMODE_AUTOSELECT)
-                       msp_any_detect_stereo(client);
+                       msp_detect_stereo(client);
                vt->audmode    = state->audmode;
                vt->rxsubchans = state->rxsubchans;
                vt->capability = V4L2_TUNER_CAP_STEREO |
@@ -898,11 +858,11 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
        {
                struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
 
-               if (state->radio)
+               if (state->radio)  /* TODO: add mono/stereo support for radio */
                        break;
+               state->audmode = vt->audmode;
                /* only set audmode */
-               if (vt->audmode != -1 && vt->audmode != 0)
-                       msp_any_set_audmode(client, vt->audmode);
+               msp_set_audmode(client);
                break;
        }
 
@@ -927,7 +887,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
                        return -EINVAL;
                }
                break;
-
        }
 
        case VIDIOC_S_AUDOUT:
@@ -993,7 +952,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
                const char *p;
 
                if (state->opmode == OPMODE_AUTOSELECT)
-                       msp_any_detect_stereo(client);
+                       msp_detect_stereo(client);
                v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n",
                                client->name, state->rev1, state->rev2);
                v4l_info(client, "Audio:    volume %d%s\n",
@@ -1094,6 +1053,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
 
        memset(state, 0, sizeof(*state));
        state->v4l2_std = V4L2_STD_NTSC;
+       state->audmode = V4L2_TUNER_MODE_LANG1;
        state->volume = 58880;  /* 0db gain */
        state->balance = 32768; /* 0db gain */
        state->bass = 32768;
index 2072c3efebb31fb364aa6e2e7625fbb6dd5eceb5..852ab6a115faf1eb365ec6297497194aee8e709a 100644 (file)
@@ -109,7 +109,7 @@ static struct msp3400c_init_data_dem {
                {-2, -8, -10, 10, 50, 86},
                {-4, -12, -9, 23, 79, 126},
                MSP_CARRIER(6.5), MSP_CARRIER(6.5),
-               0x00c6, 0x0140, 0x0120, 0x7c03
+               0x00c6, 0x0140, 0x0120, 0x7c00
        },
 };
 
@@ -154,54 +154,60 @@ const char *msp_standard_std_name(int std)
        return "unknown";
 }
 
-void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
+static void msp_set_source(struct i2c_client *client, u16 src)
+{
+       struct msp_state *state = i2c_get_clientdata(client);
+
+       if (msp_dolby) {
+               msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */
+               msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */
+       } else {
+               msp_write_dsp(client, 0x0008, src);
+               msp_write_dsp(client, 0x0009, src);
+       }
+       msp_write_dsp(client, 0x000a, src);
+       msp_write_dsp(client, 0x000b, src);
+       msp_write_dsp(client, 0x000c, src);
+       if (state->has_scart23_in_scart2_out)
+               msp_write_dsp(client, 0x0041, src);
+}
+
+void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2)
 {
        msp_write_dem(client, 0x0093, cdo1 & 0xfff);
        msp_write_dem(client, 0x009b, cdo1 >> 12);
        msp_write_dem(client, 0x00a3, cdo2 & 0xfff);
        msp_write_dem(client, 0x00ab, cdo2 >> 12);
-       msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
+       msp_write_dem(client, 0x0056, 0); /* LOAD_REG_1/2 */
 }
 
-void msp3400c_setmode(struct i2c_client *client, int type)
+void msp3400c_set_mode(struct i2c_client *client, int mode)
 {
        struct msp_state *state = i2c_get_clientdata(client);
+       struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
        int i;
 
-       v4l_dbg(1, msp_debug, client, "setmode: %d\n", type);
-       state->mode       = type;
-       state->audmode    = V4L2_TUNER_MODE_MONO;
+       v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
+       state->mode = mode;
        state->rxsubchans = V4L2_TUNER_SUB_MONO;
 
-       msp_write_dem(client, 0x00bb, msp3400c_init_data[type].ad_cv);
+       msp_write_dem(client, 0x00bb, data->ad_cv);
 
        for (i = 5; i >= 0; i--)               /* fir 1 */
-               msp_write_dem(client, 0x0001, msp3400c_init_data[type].fir1[i]);
+               msp_write_dem(client, 0x0001, data->fir1[i]);
 
        msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */
        msp_write_dem(client, 0x0005, 0x0040);
        msp_write_dem(client, 0x0005, 0x0000);
        for (i = 5; i >= 0; i--)
-               msp_write_dem(client, 0x0005, msp3400c_init_data[type].fir2[i]);
+               msp_write_dem(client, 0x0005, data->fir2[i]);
 
-       msp_write_dem(client, 0x0083, msp3400c_init_data[type].mode_reg);
+       msp_write_dem(client, 0x0083, data->mode_reg);
 
-       msp3400c_setcarrier(client, msp3400c_init_data[type].cdo1,
-                           msp3400c_init_data[type].cdo2);
+       msp3400c_set_carrier(client, data->cdo1, data->cdo2);
 
-       msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
-
-       if (msp_dolby) {
-               msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */
-               msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */
-               msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src);
-       } else {
-               msp_write_dsp(client, 0x0008, msp3400c_init_data[type].dsp_src);
-               msp_write_dsp(client, 0x0009, msp3400c_init_data[type].dsp_src);
-               msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src);
-       }
-       msp_write_dsp(client, 0x000a, msp3400c_init_data[type].dsp_src);
-       msp_write_dsp(client, 0x000e, msp3400c_init_data[type].dsp_matrix);
+       msp_set_source(client, data->dsp_src);
+       msp_write_dsp(client, 0x000e, data->dsp_matrix);
 
        if (state->has_nicam) {
                /* nicam prescale */
@@ -209,29 +215,31 @@ void msp3400c_setmode(struct i2c_client *client, int type)
        }
 }
 
-/* turn on/off nicam + stereo */
-void msp3400c_setstereo(struct i2c_client *client, int mode)
+/* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP,
+   nor do they support stereo BTSC. */
+static void msp3400c_set_audmode(struct i2c_client *client)
 {
        static char *strmode[] = { "mono", "stereo", "lang2", "lang1" };
        struct msp_state *state = i2c_get_clientdata(client);
-       int nicam = 0;          /* channel source: FM/AM or nicam */
-       int src = 0;
+       char *modestr = (state->audmode >= 0 && state->audmode < 4) ?
+               strmode[state->audmode] : "unknown";
+       int src = 0;    /* channel source: FM/AM, nicam or SCART */
 
        if (state->opmode == OPMODE_AUTOSELECT) {
                /* this method would break everything, let's make sure
                 * it's never called
                 */
-               v4l_dbg(1, msp_debug, client, "setstereo called with mode=%d instead of set_source (ignored)\n",
-                    mode);
+               v4l_dbg(1, msp_debug, client,
+                       "set_audmode called with mode=%d instead of set_source (ignored)\n",
+                       state->audmode);
                return;
        }
 
        /* switch demodulator */
        switch (state->mode) {
        case MSP_MODE_FM_TERRA:
-               v4l_dbg(1, msp_debug, client, "FM setstereo: %s\n", strmode[mode]);
-               msp3400c_setcarrier(client, state->second, state->main);
-               switch (mode) {
+               v4l_dbg(1, msp_debug, client, "FM set_audmode: %s\n", modestr);
+               switch (state->audmode) {
                case V4L2_TUNER_MODE_STEREO:
                        msp_write_dsp(client, 0x000e, 0x3001);
                        break;
@@ -243,50 +251,49 @@ void msp3400c_setstereo(struct i2c_client *client, int mode)
                }
                break;
        case MSP_MODE_FM_SAT:
-               v4l_dbg(1, msp_debug, client, "SAT setstereo: %s\n", strmode[mode]);
-               switch (mode) {
+               v4l_dbg(1, msp_debug, client, "SAT set_audmode: %s\n", modestr);
+               switch (state->audmode) {
                case V4L2_TUNER_MODE_MONO:
-                       msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
+                       msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
                        break;
                case V4L2_TUNER_MODE_STEREO:
-                       msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
+                       msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
                        break;
                case V4L2_TUNER_MODE_LANG1:
-                       msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
+                       msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
                        break;
                case V4L2_TUNER_MODE_LANG2:
-                       msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
+                       msp3400c_set_carrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
                        break;
                }
                break;
        case MSP_MODE_FM_NICAM1:
        case MSP_MODE_FM_NICAM2:
        case MSP_MODE_AM_NICAM:
-               v4l_dbg(1, msp_debug, client, "NICAM setstereo: %s\n",strmode[mode]);
-               msp3400c_setcarrier(client,state->second,state->main);
+               v4l_dbg(1, msp_debug, client, "NICAM set_audmode: %s\n",modestr);
+               msp3400c_set_carrier(client, state->second, state->main);
                if (state->nicam_on)
-                       nicam=0x0100;
+                       src = 0x0100;  /* NICAM */
                break;
        case MSP_MODE_BTSC:
-               v4l_dbg(1, msp_debug, client, "BTSC setstereo: %s\n",strmode[mode]);
-               nicam=0x0300;
+               v4l_dbg(1, msp_debug, client, "BTSC set_audmode: %s\n",modestr);
                break;
        case MSP_MODE_EXTERN:
-               v4l_dbg(1, msp_debug, client, "extern setstereo: %s\n",strmode[mode]);
-               nicam = 0x0200;
+               v4l_dbg(1, msp_debug, client, "extern set_audmode: %s\n",modestr);
+               src = 0x0200;  /* SCART */
                break;
        case MSP_MODE_FM_RADIO:
-               v4l_dbg(1, msp_debug, client, "FM-Radio setstereo: %s\n",strmode[mode]);
+               v4l_dbg(1, msp_debug, client, "FM-Radio set_audmode: %s\n",modestr);
                break;
        default:
-               v4l_dbg(1, msp_debug, client, "mono setstereo\n");
+               v4l_dbg(1, msp_debug, client, "mono set_audmode\n");
                return;
        }
 
        /* switch audio */
-       switch (mode) {
+       switch (state->audmode) {
        case V4L2_TUNER_MODE_STEREO:
-               src = 0x0020 | nicam;
+               src |= 0x0020;
                break;
        case V4L2_TUNER_MODE_MONO:
                if (state->mode == MSP_MODE_AM_NICAM) {
@@ -297,29 +304,22 @@ void msp3400c_setstereo(struct i2c_client *client, int mode)
                        src = 0x0200;
                        break;
                }
+               if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
+                       src = 0x0030;
+               break;
        case V4L2_TUNER_MODE_LANG1:
-               src = 0x0000 | nicam;
+               /* switch to stereo for stereo transmission, otherwise
+                  keep first language */
+               if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
+                       src |= 0x0020;
                break;
        case V4L2_TUNER_MODE_LANG2:
-               src = 0x0010 | nicam;
+               src |= 0x0010;
                break;
        }
-       v4l_dbg(1, msp_debug, client, "setstereo final source/matrix = 0x%x\n", src);
+       v4l_dbg(1, msp_debug, client, "set_audmode final source/matrix = 0x%x\n", src);
 
-       if (msp_dolby) {
-               msp_write_dsp(client, 0x0008, 0x0520);
-               msp_write_dsp(client, 0x0009, 0x0620);
-               msp_write_dsp(client, 0x000a, src);
-               msp_write_dsp(client, 0x000b, src);
-       } else {
-               msp_write_dsp(client, 0x0008, src);
-               msp_write_dsp(client, 0x0009, src);
-               msp_write_dsp(client, 0x000a, src);
-               msp_write_dsp(client, 0x000b, src);
-               msp_write_dsp(client, 0x000c, src);
-               if (state->has_scart23_in_scart2_out)
-                       msp_write_dsp(client, 0x0041, src);
-       }
+       msp_set_source(client, src);
 }
 
 static void msp3400c_print_mode(struct i2c_client *client)
@@ -347,12 +347,12 @@ static void msp3400c_print_mode(struct i2c_client *client)
 
 /* ----------------------------------------------------------------------- */
 
-int autodetect_stereo(struct i2c_client *client)
+static int msp3400c_detect_stereo(struct i2c_client *client)
 {
        struct msp_state *state = i2c_get_clientdata(client);
        int val;
        int rxsubchans = state->rxsubchans;
-       int newnicam   = state->nicam_on;
+       int newnicam = state->nicam_on;
        int update = 0;
 
        switch (state->mode) {
@@ -362,7 +362,7 @@ int autodetect_stereo(struct i2c_client *client)
                        val -= 65536;
                v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val);
                if (val > 4096) {
-                       rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
+                       rxsubchans = V4L2_TUNER_SUB_STEREO;
                } else if (val < -4096) {
                        rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
                } else {
@@ -386,14 +386,11 @@ int autodetect_stereo(struct i2c_client *client)
                                break;
                        case 1:
                        case 9:
-                               rxsubchans = V4L2_TUNER_SUB_MONO
-                                       | V4L2_TUNER_SUB_LANG1;
+                               rxsubchans = V4L2_TUNER_SUB_MONO;
                                break;
                        case 2:
                        case 10:
-                               rxsubchans = V4L2_TUNER_SUB_MONO
-                                       | V4L2_TUNER_SUB_LANG1
-                                       | V4L2_TUNER_SUB_LANG2;
+                               rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
                                break;
                        default:
                                rxsubchans = V4L2_TUNER_SUB_MONO;
@@ -405,30 +402,17 @@ int autodetect_stereo(struct i2c_client *client)
                        rxsubchans = V4L2_TUNER_SUB_MONO;
                }
                break;
-       case MSP_MODE_BTSC:
-               val = msp_read_dem(client, 0x200);
-               v4l_dbg(2, msp_debug, client, "status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
-                       val,
-                       (val & 0x0002) ? "no"     : "yes",
-                       (val & 0x0004) ? "no"     : "yes",
-                       (val & 0x0040) ? "stereo" : "mono",
-                       (val & 0x0080) ? ", nicam 2nd mono" : "",
-                       (val & 0x0100) ? ", bilingual/SAP"  : "");
-               rxsubchans = V4L2_TUNER_SUB_MONO;
-               if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO;
-               if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1;
-               break;
        }
        if (rxsubchans != state->rxsubchans) {
                update = 1;
-               v4l_dbg(1, msp_debug, client, "watch: rxsubchans %d => %d\n",
-                       state->rxsubchans,rxsubchans);
+               v4l_dbg(1, msp_debug, client, "watch: rxsubchans %02x => %02x\n",
+                       state->rxsubchans, rxsubchans);
                state->rxsubchans = rxsubchans;
        }
        if (newnicam != state->nicam_on) {
                update = 1;
                v4l_dbg(1, msp_debug, client, "watch: nicam %d => %d\n",
-                       state->nicam_on,newnicam);
+                       state->nicam_on, newnicam);
                state->nicam_on = newnicam;
        }
        return update;
@@ -443,13 +427,8 @@ static void watch_stereo(struct i2c_client *client)
 {
        struct msp_state *state = i2c_get_clientdata(client);
 
-       if (autodetect_stereo(client)) {
-               if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
-                       msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
-               else if (state->rxsubchans & V4L2_TUNER_SUB_LANG1)
-                       msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
-               else
-                       msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
+       if (msp3400c_detect_stereo(client)) {
+               msp3400c_set_audmode(client);
        }
 
        if (msp_once)
@@ -461,7 +440,7 @@ int msp3400c_thread(void *data)
        struct i2c_client *client = data;
        struct msp_state *state = i2c_get_clientdata(client);
        struct msp3400c_carrier_detect *cd;
-       int count, max1,max2,val1,val2, val,this;
+       int count, max1, max2, val1, val2, val, this;
 
 
        v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n");
@@ -471,7 +450,7 @@ int msp3400c_thread(void *data)
                v4l_dbg(2, msp_debug, client, "msp3400 thread: wakeup\n");
 
        restart:
-               v4l_dbg(1, msp_debug, client, "thread: restart scan\n");
+               v4l_dbg(2, msp_debug, client, "thread: restart scan\n");
                state->restart = 0;
                if (kthread_should_stop())
                        break;
@@ -485,13 +464,14 @@ int msp3400c_thread(void *data)
 
                /* mute */
                msp_set_mute(client);
-               msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
+               msp3400c_set_mode(client, MSP_MODE_AM_DETECT /* +1 */ );
                val1 = val2 = 0;
                max1 = max2 = -1;
                state->watch_stereo = 0;
+               state->nicam_on = 0;
 
                /* some time for the tuner to sync */
-               if (msp_sleep(state,200))
+               if (msp_sleep(state, 200))
                        goto restart;
 
                /* carrier detect pass #1 -- main carrier */
@@ -506,7 +486,7 @@ int msp3400c_thread(void *data)
                }
 
                for (this = 0; this < count; this++) {
-                       msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
+                       msp3400c_set_carrier(client, cd[this].cdo, cd[this].cdo);
                        if (msp_sleep(state,100))
                                goto restart;
                        val = msp_read_dsp(client, 0x1b);
@@ -542,7 +522,7 @@ int msp3400c_thread(void *data)
                        max2 = 0;
                }
                for (this = 0; this < count; this++) {
-                       msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
+                       msp3400c_set_carrier(client, cd[this].cdo, cd[this].cdo);
                        if (msp_sleep(state,100))
                                goto restart;
                        val = msp_read_dsp(client, 0x1b);
@@ -554,22 +534,20 @@ int msp3400c_thread(void *data)
                }
 
                /* program the msp3400 according to the results */
-               state->main   = msp3400c_carrier_detect_main[max1].cdo;
+               state->main = msp3400c_carrier_detect_main[max1].cdo;
                switch (max1) {
                case 1: /* 5.5 */
                        if (max2 == 0) {
                                /* B/G FM-stereo */
                                state->second = msp3400c_carrier_detect_55[max2].cdo;
-                               msp3400c_setmode(client, MSP_MODE_FM_TERRA);
-                               state->nicam_on = 0;
-                               msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
+                               msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
                                state->watch_stereo = 1;
                        } else if (max2 == 1 && state->has_nicam) {
                                /* B/G NICAM */
                                state->second = msp3400c_carrier_detect_55[max2].cdo;
-                               msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
+                               msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);
+                               msp3400c_set_carrier(client, state->second, state->main);
                                state->nicam_on = 1;
-                               msp3400c_setcarrier(client, state->second, state->main);
                                state->watch_stereo = 1;
                        } else {
                                goto no_second;
@@ -578,35 +556,31 @@ int msp3400c_thread(void *data)
                case 2: /* 6.0 */
                        /* PAL I NICAM */
                        state->second = MSP_CARRIER(6.552);
-                       msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
+                       msp3400c_set_mode(client, MSP_MODE_FM_NICAM2);
+                       msp3400c_set_carrier(client, state->second, state->main);
                        state->nicam_on = 1;
-                       msp3400c_setcarrier(client, state->second, state->main);
                        state->watch_stereo = 1;
                        break;
                case 3: /* 6.5 */
                        if (max2 == 1 || max2 == 2) {
                                /* D/K FM-stereo */
                                state->second = msp3400c_carrier_detect_65[max2].cdo;
-                               msp3400c_setmode(client, MSP_MODE_FM_TERRA);
-                               state->nicam_on = 0;
-                               msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
+                               msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
                                state->watch_stereo = 1;
                        } else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) {
                                /* L NICAM or AM-mono */
                                state->second = msp3400c_carrier_detect_65[max2].cdo;
-                               msp3400c_setmode(client, MSP_MODE_AM_NICAM);
-                               state->nicam_on = 0;
-                               msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
-                               msp3400c_setcarrier(client, state->second, state->main);
+                               msp3400c_set_mode(client, MSP_MODE_AM_NICAM);
+                               msp3400c_set_carrier(client, state->second, state->main);
                                /* volume prescale for SCART (AM mono input) */
                                msp_write_dsp(client, 0x000d, 0x1900);
                                state->watch_stereo = 1;
                        } else if (max2 == 0 && state->has_nicam) {
                                /* D/K NICAM */
                                state->second = msp3400c_carrier_detect_65[max2].cdo;
-                               msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
+                               msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);
+                               msp3400c_set_carrier(client, state->second, state->main);
                                state->nicam_on = 1;
-                               msp3400c_setcarrier(client, state->second, state->main);
                                state->watch_stereo = 1;
                        } else {
                                goto no_second;
@@ -616,23 +590,25 @@ int msp3400c_thread(void *data)
                default:
                no_second:
                        state->second = msp3400c_carrier_detect_main[max1].cdo;
-                       msp3400c_setmode(client, MSP_MODE_FM_TERRA);
-                       state->nicam_on = 0;
-                       msp3400c_setcarrier(client, state->second, state->main);
+                       msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
+                       msp3400c_set_carrier(client, state->second, state->main);
                        state->rxsubchans = V4L2_TUNER_SUB_MONO;
-                       msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
                        break;
                }
 
                /* unmute */
                msp_set_audio(client);
+               msp3400c_set_audmode(client);
 
                if (msp_debug)
                        msp3400c_print_mode(client);
 
-               /* monitor tv audio mode */
+               /* monitor tv audio mode, the first time don't wait
+                  so long to get a quick stereo/bilingual result */
+               if (msp_sleep(state, 1000))
+                       goto restart;
                while (state->watch_stereo) {
-                       if (msp_sleep(state,5000))
+                       if (msp_sleep(state, 5000))
                                goto restart;
                        watch_stereo(client);
                }
@@ -656,7 +632,7 @@ int msp3410d_thread(void *data)
                v4l_dbg(2, msp_debug, client, "msp3410 thread: wakeup\n");
 
        restart:
-               v4l_dbg(1, msp_debug, client, "thread: restart scan\n");
+               v4l_dbg(2, msp_debug, client, "thread: restart scan\n");
                state->restart = 0;
                if (kthread_should_stop())
                        break;
@@ -681,9 +657,10 @@ int msp3410d_thread(void *data)
                else
                        std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;
                state->watch_stereo = 0;
+               state->nicam_on = 0;
 
                if (msp_debug)
-                       v4l_dbg(1, msp_debug, client, "setting standard: %s (0x%04x)\n",
+                       v4l_dbg(2, msp_debug, client, "setting standard: %s (0x%04x)\n",
                               msp_standard_std_name(std), std);
 
                if (std != 1) {
@@ -700,7 +677,7 @@ int msp3410d_thread(void *data)
                                val = msp_read_dem(client, 0x7e);
                                if (val < 0x07ff)
                                        break;
-                               v4l_dbg(1, msp_debug, client, "detection still in progress\n");
+                               v4l_dbg(2, msp_debug, client, "detection still in progress\n");
                        }
                }
                for (i = 0; msp_stdlist[i].name != NULL; i++)
@@ -739,48 +716,34 @@ int msp3410d_thread(void *data)
                        state->rxsubchans = V4L2_TUNER_SUB_STEREO;
                        state->nicam_on = 1;
                        state->watch_stereo = 1;
-                       msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
                        break;
                case 0x0009:
                        state->mode = MSP_MODE_AM_NICAM;
                        state->rxsubchans = V4L2_TUNER_SUB_MONO;
                        state->nicam_on = 1;
-                       msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
                        state->watch_stereo = 1;
                        break;
                case 0x0020: /* BTSC */
-                       /* just turn on stereo */
+                       /* The pre-'G' models only have BTSC-mono */
                        state->mode = MSP_MODE_BTSC;
-                       state->rxsubchans = V4L2_TUNER_SUB_STEREO;
-                       state->nicam_on = 0;
-                       state->watch_stereo = 1;
-                       msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
+                       state->rxsubchans = V4L2_TUNER_SUB_MONO;
                        break;
                case 0x0040: /* FM radio */
                        state->mode = MSP_MODE_FM_RADIO;
                        state->rxsubchans = V4L2_TUNER_SUB_STEREO;
-                       state->audmode = V4L2_TUNER_MODE_STEREO;
-                       state->nicam_on = 0;
-                       state->watch_stereo = 0;
                        /* not needed in theory if we have radio, but
                           short programming enables carrier mute */
-                       msp3400c_setmode(client, MSP_MODE_FM_RADIO);
-                       msp3400c_setcarrier(client, MSP_CARRIER(10.7),
+                       msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
+                       msp3400c_set_carrier(client, MSP_CARRIER(10.7),
                                            MSP_CARRIER(10.7));
-                       /* scart routing */
+                       /* scart routing (this doesn't belong here I think) */
                        msp_set_scart(client,SCART_IN2,0);
-                       /* msp34xx does radio decoding */
-                       msp_write_dsp(client, 0x08, 0x0020);
-                       msp_write_dsp(client, 0x09, 0x0020);
-                       msp_write_dsp(client, 0x0b, 0x0020);
                        break;
                case 0x0003:
                case 0x0004:
                case 0x0005:
                        state->mode = MSP_MODE_FM_TERRA;
                        state->rxsubchans = V4L2_TUNER_SUB_MONO;
-                       state->audmode = V4L2_TUNER_MODE_MONO;
-                       state->nicam_on = 0;
                        state->watch_stereo = 1;
                        break;
                }
@@ -791,11 +754,16 @@ int msp3410d_thread(void *data)
                if (state->has_i2s_conf)
                        msp_write_dem(client, 0x40, state->i2s_mode);
 
-               /* monitor tv audio mode */
+               msp3400c_set_audmode(client);
+
+               /* monitor tv audio mode, the first time don't wait
+                  so long to get a quick stereo/bilingual result */
+               if (msp_sleep(state, 1000))
+                       goto restart;
                while (state->watch_stereo) {
-                       if (msp_sleep(state,5000))
-                               goto restart;
                        watch_stereo(client);
+                       if (msp_sleep(state, 5000))
+                               goto restart;
                }
        }
        v4l_dbg(1, msp_debug, client, "thread: exit\n");
@@ -813,7 +781,7 @@ int msp3410d_thread(void *data)
  * the value for source is the same as bit 15:8 of DSP registers 0x08,
  * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
  *
- * this function replaces msp3400c_setstereo
+ * this function replaces msp3400c_set_audmode
  */
 static void msp34xxg_set_source(struct i2c_client *client, int source)
 {
@@ -826,12 +794,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source)
        int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20);
 
        v4l_dbg(1, msp_debug, client, "set source to %d (0x%x)\n", source, value);
-       /* Loudspeaker Output */
-       msp_write_dsp(client, 0x08, value);
-       /* SCART1 DA Output */
-       msp_write_dsp(client, 0x0a, value);
-       /* Quasi-peak detector */
-       msp_write_dsp(client, 0x0c, value);
+       msp_set_source(client, value);
        /*
         * set identification threshold. Personally, I
         * I set it to a higher value that the default
@@ -948,13 +911,14 @@ int msp34xxg_thread(void *data)
                if (msp_write_dsp(client, 0x13, state->acb))
                        return -1;
 
-               msp_write_dem(client, 0x40, state->i2s_mode);
+               if (state->has_i2s_conf)
+                       msp_write_dem(client, 0x40, state->i2s_mode);
        }
        v4l_dbg(1, msp_debug, client, "thread: exit\n");
        return 0;
 }
 
-void msp34xxg_detect_stereo(struct i2c_client *client)
+static void msp34xxg_detect_stereo(struct i2c_client *client)
 {
        struct msp_state *state = i2c_get_clientdata(client);
 
@@ -964,11 +928,11 @@ void msp34xxg_detect_stereo(struct i2c_client *client)
 
        state->rxsubchans = 0;
        if (is_stereo)
-               state->rxsubchans |= V4L2_TUNER_SUB_STEREO;
+               state->rxsubchans = V4L2_TUNER_SUB_STEREO;
        else
-               state->rxsubchans |= V4L2_TUNER_SUB_MONO;
+               state->rxsubchans = V4L2_TUNER_SUB_MONO;
        if (is_bilingual) {
-               state->rxsubchans |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+               state->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
                /* I'm supposed to check whether it's SAP or not
                 * and set only LANG2/SAP in this case. Yet, the MSP
                 * does a lot of work to hide this and handle everything
@@ -980,12 +944,12 @@ void msp34xxg_detect_stereo(struct i2c_client *client)
                status, is_stereo, is_bilingual, state->rxsubchans);
 }
 
-void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
+static void msp34xxg_set_audmode(struct i2c_client *client)
 {
        struct msp_state *state = i2c_get_clientdata(client);
        int source;
 
-       switch (audmode) {
+       switch (state->audmode) {
        case V4L2_TUNER_MODE_MONO:
                source = 0; /* mono only */
                break;
@@ -1000,11 +964,40 @@ void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
                source = 4; /* stereo or B */
                break;
        default:
-               audmode = 0;
                source  = 1;
                break;
        }
-       state->audmode = audmode;
        msp34xxg_set_source(client, source);
 }
 
+void msp_set_audmode(struct i2c_client *client)
+{
+       struct msp_state *state = i2c_get_clientdata(client);
+
+       switch (state->opmode) {
+       case OPMODE_MANUAL:
+       case OPMODE_AUTODETECT:
+               state->watch_stereo = 0;
+               msp3400c_set_audmode(client);
+               break;
+       case OPMODE_AUTOSELECT:
+               msp34xxg_set_audmode(client);
+               break;
+       }
+}
+
+void msp_detect_stereo(struct i2c_client *client)
+{
+       struct msp_state *state  = i2c_get_clientdata(client);
+
+       switch (state->opmode) {
+       case OPMODE_MANUAL:
+       case OPMODE_AUTODETECT:
+               msp3400c_detect_stereo(client);
+               break;
+       case OPMODE_AUTOSELECT:
+               msp34xxg_detect_stereo(client);
+               break;
+       }
+}
+
index a9ac57d0700b7a6ddd02102fb19985b208e653a8..6fb5c8c994e7dbbca4d34f071f7b90ee43084fdc 100644 (file)
@@ -104,14 +104,12 @@ int msp_sleep(struct msp_state *state, int timeout);
 
 /* msp3400-kthreads.c */
 const char *msp_standard_std_name(int std);
-void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2);
-void msp3400c_setmode(struct i2c_client *client, int type);
-void msp3400c_setstereo(struct i2c_client *client, int mode);
-int autodetect_stereo(struct i2c_client *client);
+void msp_set_audmode(struct i2c_client *client);
+void msp_detect_stereo(struct i2c_client *client);
 int msp3400c_thread(void *data);
 int msp3410d_thread(void *data);
 int msp34xxg_thread(void *data);
-void msp34xxg_detect_stereo(struct i2c_client *client);
-void msp34xxg_set_audmode(struct i2c_client *client, int audmode);
+void msp3400c_set_mode(struct i2c_client *client, int mode);
+void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2);
 
 #endif /* MSP3400_H */
index 41715cacf92632e64448013981e292f7569809a9..eb3b31867494b0ac0bf97ae08f94c7c84d48ae20 100644 (file)
@@ -1,11 +1,11 @@
 /*
     mxb - v4l2 driver for the Multimedia eXtension Board
-    
+
     Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
 
     Visit http://www.mihu.de/linux/saa7146/mxb/
     for further details about this card.
-    
+
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
 
 #define I2C_SAA7111 0x24
 
-#define MXB_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0) 
+#define MXB_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0)
 
 /* global variable */
 static int mxb_num = 0;
 
-/* initial frequence the tuner will be tuned to. 
+/* initial frequence the tuner will be tuned to.
    in verden (lower saxony, germany) 4148 is a
    channel called "phoenix" */
 static int freq = 4148;
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
 enum { TUNER, AUX1, AUX3, AUX3_YC };
 
 static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
-       { TUNER,        "Tuner",                V4L2_INPUT_TYPE_TUNER,  1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, 
+       { TUNER,        "Tuner",                V4L2_INPUT_TYPE_TUNER,  1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
        { AUX1,         "AUX1",                 V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
        { AUX3,         "AUX3 Composite",       V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
        { AUX3_YC,      "AUX3 S-Video",         V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
@@ -66,7 +66,7 @@ static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
 static struct {
        int hps_source;
        int hps_sync;
-} input_port_selection[MXB_INPUTS] = {         
+} input_port_selection[MXB_INPUTS] = {
        { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
        { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
        { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
@@ -81,7 +81,7 @@ static int video_audio_connect[MXB_INPUTS] =
 /* these are the necessary input-output-pins for bringing one audio source
 (see above) to the CD-output */
 static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] =
-               { 
+               {
                {{1,1,0},{1,1,0}},      /* Tuner */
                {{5,1,0},{6,1,0}},      /* AUX 1 */
                {{4,1,0},{6,1,0}},      /* AUX 2 */
@@ -122,8 +122,8 @@ static struct saa7146_extension_ioctls ioctls[] = {
        { VIDIOC_S_FREQUENCY,   SAA7146_EXCLUSIVE },
        { VIDIOC_G_AUDIO,       SAA7146_EXCLUSIVE },
        { VIDIOC_S_AUDIO,       SAA7146_EXCLUSIVE },
-       { MXB_S_AUDIO_CD,       SAA7146_EXCLUSIVE },    /* custom control */    
-       { MXB_S_AUDIO_LINE,     SAA7146_EXCLUSIVE },    /* custom control */    
+       { MXB_S_AUDIO_CD,       SAA7146_EXCLUSIVE },    /* custom control */
+       { MXB_S_AUDIO_LINE,     SAA7146_EXCLUSIVE },    /* custom control */
        { 0,                    0 }
 };
 
@@ -132,7 +132,7 @@ struct mxb
        struct video_device     *video_dev;
        struct video_device     *vbi_dev;
 
-       struct i2c_adapter      i2c_adapter;    
+       struct i2c_adapter      i2c_adapter;
 
        struct i2c_client*      saa7111a;
        struct i2c_client*      tda9840;
@@ -200,15 +200,15 @@ static int mxb_probe(struct saa7146_dev* dev)
                client = list_entry(item, struct i2c_client, list);
                if( I2C_TEA6420_1 == client->addr )
                        mxb->tea6420_1 = client;
-               if( I2C_TEA6420_2 == client->addr ) 
+               if( I2C_TEA6420_2 == client->addr )
                        mxb->tea6420_2 = client;
-               if( I2C_TEA6415C_2 == client->addr ) 
+               if( I2C_TEA6415C_2 == client->addr )
                        mxb->tea6415c = client;
-               if( I2C_TDA9840 == client->addr ) 
+               if( I2C_TDA9840 == client->addr )
                        mxb->tda9840 = client;
                if( I2C_SAA7111 == client->addr )
                        mxb->saa7111a = client;
-               if( 0x60 == client->addr ) 
+               if( 0x60 == client->addr )
                        mxb->tuner = client;
        }
 
@@ -222,7 +222,7 @@ static int mxb_probe(struct saa7146_dev* dev)
                return -ENODEV;
        }
 
-       /* all devices are present, probe was successful */     
+       /* all devices are present, probe was successful */
 
        /* we store the pointer in our private data field */
        dev->ext_priv = mxb;
@@ -230,7 +230,7 @@ static int mxb_probe(struct saa7146_dev* dev)
        return 0;
 }
 
-/* some init data for the saa7740, the so-called 'sound arena module'. 
+/* some init data for the saa7740, the so-called 'sound arena module'.
    there are no specs available, so we simply use some init values */
 static struct {
        int     length;
@@ -330,7 +330,7 @@ static int mxb_init_done(struct saa7146_dev* dev)
        v4l2_std_id std = V4L2_STD_PAL_BG;
 
        int i = 0, err = 0;
-       struct  tea6415c_multiplex vm;  
+       struct  tea6415c_multiplex vm;
 
        /* select video mode in saa7111a */
        i = VIDEO_MODE_PAL;
@@ -380,16 +380,16 @@ static int mxb_init_done(struct saa7146_dev* dev)
        vm.in  = 3;
        vm.out = 13;
        mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
-                               
+
        /* the rest for mxb */
        mxb->cur_input = 0;
        mxb->cur_mute = 1;
 
        mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
        mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);
-                       
+
        /* check if the saa7740 (aka 'sound arena module') is present
-          on the mxb. if so, we must initialize it. due to lack of 
+          on the mxb. if so, we must initialize it. due to lack of
           informations about the saa7740, the values were reverse
           engineered. */
        msg.addr = 0x1b;
@@ -409,7 +409,7 @@ static int mxb_init_done(struct saa7146_dev* dev)
                                break;
                        }
 
-                       msg.len = mxb_saa7740_init[i].length;           
+                       msg.len = mxb_saa7740_init[i].length;
                        msg.buf = &mxb_saa7740_init[i].data[0];
                        if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
                                DEB_D(("failed to initialize 'sound arena module'.\n"));
@@ -418,12 +418,12 @@ static int mxb_init_done(struct saa7146_dev* dev)
                }
                INFO(("'sound arena module' detected.\n"));
        }
-err:   
+err:
        /* the rest for saa7146: you should definitely set some basic values
           for the input-port handling of the saa7146. */
 
        /* ext->saa has been filled by the core driver */
-          
+
        /* some stuff is done via variables */
        saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync);
 
@@ -431,7 +431,7 @@ err:
 
        /* this is ugly, but because of the fact that this is completely
           hardware dependend, it should be done directly... */
-       saa7146_write(dev, DD1_STREAM_B,        0x00000000);
+       saa7146_write(dev, DD1_STREAM_B,        0x00000000);
        saa7146_write(dev, DD1_INIT,            0x02000200);
        saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
 
@@ -453,7 +453,7 @@ static struct saa7146_ext_vv vv_data;
 static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
 {
        struct mxb* mxb = (struct mxb*)dev->ext_priv;
-       
+
        DEB_EE(("dev:%p\n",dev));
 
        /* checking for i2c-devices can be omitted here, because we
@@ -464,7 +464,7 @@ static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data
                ERR(("cannot register capture v4l2 device. skipping.\n"));
                return -1;
        }
-       
+
        /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
        if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
                if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
@@ -513,17 +513,17 @@ static int mxb_detach(struct saa7146_dev* dev)
        return 0;
 }
 
-static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
+static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
 {
        struct saa7146_dev *dev = fh->dev;
        struct mxb* mxb = (struct mxb*)dev->ext_priv;
-       struct saa7146_vv *vv = dev->vv_data; 
-       
+       struct saa7146_vv *vv = dev->vv_data;
+
        switch(cmd) {
        case VIDIOC_ENUMINPUT:
        {
                struct v4l2_input *i = arg;
-               
+
                DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
                if( i->index < 0 || i->index >= MXB_INPUTS) {
                        return -EINVAL;
@@ -559,11 +559,11 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                                break;
                        }
                }
-               
+
                if( i < 0 ) {
                        return -EAGAIN;
                }
-                       
+
                switch (vc->id ) {
                        case V4L2_CID_AUDIO_MUTE: {
                                vc->value = mxb->cur_mute;
@@ -571,7 +571,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                                return 0;
                        }
                }
-               
+
                DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
                return 0;
        }
@@ -580,17 +580,17 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
        {
                struct  v4l2_control    *vc = arg;
                int i = 0;
-               
+
                for (i = MAXCONTROLS - 1; i >= 0; i--) {
                        if (mxb_controls[i].id == vc->id) {
                                break;
                        }
                }
-               
+
                if( i < 0 ) {
                        return -EAGAIN;
                }
-               
+
                switch (vc->id ) {
                        case V4L2_CID_AUDIO_MUTE: {
                                mxb->cur_mute = vc->value;
@@ -614,12 +614,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                *input = mxb->cur_input;
 
                DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
-               return 0;               
-       }       
+               return 0;
+       }
        case VIDIOC_S_INPUT:
        {
                int input = *(int *)arg;
-               struct  tea6415c_multiplex vm;  
+               struct  tea6415c_multiplex vm;
                int i = 0;
 
                DEB_EE(("VIDIOC_S_INPUT %d.\n",input));
@@ -627,34 +627,34 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                if (input < 0 || input >= MXB_INPUTS) {
                        return -EINVAL;
                }
-               
+
                /* fixme: locke das setzen des inputs mit hilfe des mutexes
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                video_mux(dev,*i);
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                */
-                               
+
                /* fixme: check if streaming capture
                if ( 0 != dev->streaming ) {
                        DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
                        return -EPERM;
                }
                */
-               
+
                mxb->cur_input = input;
-       
+
                saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
-               
+
                /* prepare switching of tea6415c and saa7111a;
                   have a look at the 'background'-file for further informations  */
                switch( input ) {
-                       
+
                        case TUNER:
                        {
                                i = 0;
                                vm.in  = 3;
                                vm.out = 17;
-                                                               
+
                        if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
                                        printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");
                                        return -EFAULT;
@@ -662,7 +662,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                                /* connect tuner-output always to multicable */
                                vm.in  = 3;
                                vm.out = 13;
-                               break;                          
+                               break;
                        }
                        case AUX3_YC:
                        {
@@ -703,11 +703,11 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                                break;
                        }
                }
-                               
+
                /* switch video in saa7111a */
                if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {
                        printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
-               }                       
+               }
 
                /* switch the audio-source only if necessary */
                if( 0 == mxb->cur_mute ) {
@@ -738,11 +738,11 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                t->rangehigh = 13684;   /* 855.25 MHz / 62.5 kHz = 13684 */
                /* FIXME: add the real signal strength here */
                t->signal = 0xffff;
-               t->afc = 0;             
+               t->afc = 0;
 
                mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);
                t->audmode = mxb->cur_mode;
-               
+
                if( byte < 0 ) {
                        t->rxsubchans  = V4L2_TUNER_SUB_MONO;
                } else {
@@ -777,12 +777,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                struct v4l2_tuner *t = arg;
                int result = 0;
                int byte = 0;
-               
+
                if( 0 != t->index ) {
                        DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
                        return -EINVAL;
                }
-       
+
                switch(t->audmode) {
                        case V4L2_TUNER_MODE_STEREO: {
                                mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
@@ -813,7 +813,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {
                        printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);
                }
-                               
+
                return 0;
        }
        case VIDIOC_G_FREQUENCY:
@@ -839,7 +839,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
 
                if (V4L2_TUNER_ANALOG_TV != f->type)
                        return -EINVAL;
-               
+
                if(0 != mxb->cur_input) {
                        DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
                        return -EINVAL;
@@ -848,7 +848,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                mxb->cur_freq = *f;
                DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
 
-               /* tune in desired frequency */                 
+               /* tune in desired frequency */
                mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
 
                /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
@@ -861,12 +861,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
        case MXB_S_AUDIO_CD:
        {
                int i = *(int*)arg;
-                               
+
                if( i < 0 || i >= MXB_AUDIOS ) {
                        DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
                        return -EINVAL;
                }
-               
+
                DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
 
                mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
@@ -877,12 +877,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
        case MXB_S_AUDIO_LINE:
        {
                int i = *(int*)arg;
-                               
+
                if( i < 0 || i >= MXB_AUDIOS ) {
                        DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
                        return -EINVAL;
                }
-               
+
                DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
                mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
                mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
@@ -894,13 +894,13 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                struct v4l2_audio *a = arg;
 
                if( a->index < 0 || a->index > MXB_INPUTS ) {
-                       DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
+                       DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
                        return -EINVAL;
                }
-               
-               DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
+
+               DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
                memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
-               
+
                return 0;
        }
        case VIDIOC_S_AUDIO:
@@ -908,7 +908,7 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
                struct v4l2_audio *a = arg;
                DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
                return 0;
-       }       
+       }
        default:
 /*
                DEB2(printk("does not handle this ioctl.\n"));
@@ -928,7 +928,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
                v4l2_std_id std = V4L2_STD_PAL_I;
                DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
                /* set the 7146 gpio register -- I don't know what this does exactly */
-               saa7146_write(dev, GPIO_CTRL, 0x00404050);
+               saa7146_write(dev, GPIO_CTRL, 0x00404050);
                /* unset the 7111 gpio register -- I don't know what this does exactly */
                mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
                mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
@@ -936,7 +936,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
                v4l2_std_id std = V4L2_STD_PAL_BG;
                DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
                /* set the 7146 gpio register -- I don't know what this does exactly */
-               saa7146_write(dev, GPIO_CTRL, 0x00404050);
+               saa7146_write(dev, GPIO_CTRL, 0x00404050);
                /* set the 7111 gpio register -- I don't know what this does exactly */
                mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
                mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
@@ -969,8 +969,8 @@ static struct saa7146_standard standard[] = {
 };
 
 static struct saa7146_pci_extension_data mxb = {
-        .ext_priv = "Multimedia eXtension Board",
-        .ext = &extension,
+       .ext_priv = "Multimedia eXtension Board",
+       .ext = &extension,
 };
 
 static struct pci_device_id pci_tbl[] = {
@@ -992,7 +992,7 @@ static struct saa7146_ext_vv vv_data = {
        .capabilities   = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
        .stds           = &standard[0],
        .num_stds       = sizeof(standard)/sizeof(struct saa7146_standard),
-       .std_callback   = &std_callback, 
+       .std_callback   = &std_callback,
        .ioctls         = &ioctls[0],
        .ioctl          = mxb_ioctl,
 };
@@ -1000,7 +1000,7 @@ static struct saa7146_ext_vv vv_data = {
 static struct saa7146_extension extension = {
        .name           = MXB_IDENTIFIER,
        .flags          = SAA7146_USE_I2C_IRQ,
-       
+
        .pci_tbl        = &pci_tbl[0],
        .module         = THIS_MODULE,
 
@@ -1010,7 +1010,7 @@ static struct saa7146_extension extension = {
 
        .irq_mask       = 0,
        .irq_func       = NULL,
-};     
+};
 
 static int __init mxb_init_module(void)
 {
@@ -1018,7 +1018,7 @@ static int __init mxb_init_module(void)
                DEB_S(("failed to register extension.\n"));
                return -ENODEV;
        }
-       
+
        return 0;
 }
 
index 2332ed5f7c6b38a0e158dad63ff14c1cfffdfcfa..400a57ba62ecbc53a91f266646df43b45bbaade9 100644 (file)
@@ -38,5 +38,5 @@ static struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
                .name   = "CD-ROM (X10)",
                .capability = V4L2_AUDCAP_STEREO,
        }
-};     
+};
 #endif
index f3fc361bec97b405e1f147b46ac46a56bb149728..15fd85acabda445e3c2046ba56037e30baa0d182 100644 (file)
@@ -48,7 +48,7 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/irq.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #include "planb.h"
 #include "saa7196.h"
@@ -329,12 +329,12 @@ static volatile struct dbdma_cmd *cmd_geo_setup(
 
 static inline void planb_lock(struct planb *pb)
 {
-       down(&pb->lock);
+       mutex_lock(&pb->lock);
 }
 
 static inline void planb_unlock(struct planb *pb)
 {
-       up(&pb->lock);
+       mutex_unlock(&pb->lock);
 }
 
 /***************/
@@ -2067,7 +2067,7 @@ static int init_planb(struct planb *pb)
 #endif
        pb->tab_size = PLANB_MAXLINES + 40;
        pb->suspend = 0;
-       init_MUTEX(&pb->lock);
+       mutex_init(&pb->lock);
        pb->ch1_cmd = 0;
        pb->ch2_cmd = 0;
        pb->mask = 0;
index 8a0faad16118a9a5bc138de88ebd12cfe53b5e3c..79b6b561426eb68ba24dd5268e915e504c1c566d 100644 (file)
@@ -174,7 +174,7 @@ struct planb {
        int     user;
        unsigned int tab_size;
        int     maxlines;
-       struct semaphore lock;
+       struct mutex lock;
        unsigned int    irq;                    /* interrupt number */
        volatile unsigned int intr_mask;
 
index 9e6448639480c75f22553f4e4a9b924a7b194101..05ca55939e771a30f8c02320f23937c0449aaefa 100644 (file)
@@ -30,6 +30,8 @@
 #include <asm/io.h>
 #include <linux/sched.h>
 #include <linux/videodev.h>
+#include <linux/mutex.h>
+
 #include <asm/uaccess.h>
 
 
@@ -44,7 +46,7 @@ struct pms_device
        struct video_picture picture;
        int height;
        int width;
-       struct semaphore lock;
+       struct mutex lock;
 };
 
 struct i2c_info
@@ -724,10 +726,10 @@ static int pms_do_ioctl(struct inode *inode, struct file *file,
                        struct video_channel *v = arg;
                        if(v->channel<0 || v->channel>3)
                                return -EINVAL;
-                       down(&pd->lock);
+                       mutex_lock(&pd->lock);
                        pms_videosource(v->channel&1);
                        pms_vcrinput(v->channel>>1);
-                       up(&pd->lock);
+                       mutex_unlock(&pd->lock);
                        return 0;
                }
                case VIDIOCGTUNER:
@@ -761,7 +763,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file,
                        struct video_tuner *v = arg;
                        if(v->tuner)
                                return -EINVAL;
-                       down(&pd->lock);
+                       mutex_lock(&pd->lock);
                        switch(v->mode)
                        {
                                case VIDEO_MODE_AUTO:
@@ -785,10 +787,10 @@ static int pms_do_ioctl(struct inode *inode, struct file *file,
                                        pms_format(2);
                                        break;
                                default:
-                                       up(&pd->lock);
+                                       mutex_unlock(&pd->lock);
                                        return -EINVAL;
                        }
-                       up(&pd->lock);
+                       mutex_unlock(&pd->lock);
                        return 0;
                }
                case VIDIOCGPICT:
@@ -809,12 +811,12 @@ static int pms_do_ioctl(struct inode *inode, struct file *file,
                         *      Now load the card.
                         */
 
-                       down(&pd->lock);
+                       mutex_lock(&pd->lock);
                        pms_brightness(p->brightness>>8);
                        pms_hue(p->hue>>8);
                        pms_colour(p->colour>>8);
                        pms_contrast(p->contrast>>8);   
-                       up(&pd->lock);
+                       mutex_unlock(&pd->lock);
                        return 0;
                }
                case VIDIOCSWIN:
@@ -830,9 +832,9 @@ static int pms_do_ioctl(struct inode *inode, struct file *file,
                                return -EINVAL;
                        pd->width=vw->width;
                        pd->height=vw->height;
-                       down(&pd->lock);
+                       mutex_lock(&pd->lock);
                        pms_resolution(pd->width, pd->height);
-                       up(&pd->lock);                  /* Ok we figured out what to use from our wide choice */
+                       mutex_unlock(&pd->lock);                        /* Ok we figured out what to use from our wide choice */
                        return 0;
                }
                case VIDIOCGWIN:
@@ -872,9 +874,9 @@ static ssize_t pms_read(struct file *file, char __user *buf,
        struct pms_device *pd=(struct pms_device *)v;
        int len;
        
-       down(&pd->lock);
+       mutex_lock(&pd->lock);
        len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
-       up(&pd->lock);
+       mutex_unlock(&pd->lock);
        return len;
 }
 
@@ -1029,7 +1031,7 @@ static int __init init_pms_cards(void)
                return -ENODEV;
        }
        memcpy(&pms_device, &pms_template, sizeof(pms_template));
-       init_MUTEX(&pms_device.lock);
+       mutex_init(&pms_device.lock);
        pms_device.height=240;
        pms_device.width=320;
        pms_swsense(75);
index 2ce0102013083bdbd497addd96aa55cc3a28ab5b..dd830e0e5e96f112ff7b2181df9f771a5dfdf1b8 100644 (file)
@@ -46,6 +46,8 @@
 #include <linux/i2c.h>
 #include <linux/videotext.h>
 #include <linux/videodev.h>
+#include <linux/mutex.h>
+
 #include "saa5246a.h"
 
 MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
@@ -57,7 +59,7 @@ struct saa5246a_device
        u8     pgbuf[NUM_DAUS][VTX_VIRTUALSIZE];
        int    is_searching[NUM_DAUS];
        struct i2c_client *client;
-       struct semaphore lock;
+       struct mutex lock;
 };
 
 static struct video_device saa_template;       /* Declared near bottom */
@@ -90,7 +92,7 @@ static int saa5246a_attach(struct i2c_adapter *adap, int addr, int kind)
                return -ENOMEM;
        }
        strlcpy(client->name, IF_NAME, I2C_NAME_SIZE);
-       init_MUTEX(&t->lock);
+       mutex_init(&t->lock);
 
        /*
         *      Now create a video4linux device
@@ -719,9 +721,9 @@ static int saa5246a_ioctl(struct inode *inode, struct file *file,
        int err;
 
        cmd = vtx_fix_command(cmd);
-       down(&t->lock);
+       mutex_lock(&t->lock);
        err = video_usercopy(inode, file, cmd, arg, do_saa5246a_ioctl);
-       up(&t->lock);
+       mutex_unlock(&t->lock);
        return err;
 }
 
index 5694eb58c3a1fb5e236e585a0069ea65bb7a34ec..a9f3cf0b1e3c5b6044586e103627df0f0427d323 100644 (file)
@@ -56,6 +56,8 @@
 #include <linux/i2c.h>
 #include <linux/videotext.h>
 #include <linux/videodev.h>
+#include <linux/mutex.h>
+
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -105,7 +107,7 @@ struct saa5249_device
        int disp_mode;
        int virtual_mode;
        struct i2c_client *client;
-       struct semaphore lock;
+       struct mutex lock;
 };
 
 
@@ -158,7 +160,7 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind)
                return -ENOMEM;
        }
        strlcpy(client->name, IF_NAME, I2C_NAME_SIZE);
-       init_MUTEX(&t->lock);
+       mutex_init(&t->lock);
        
        /*
         *      Now create a video4linux device
@@ -619,9 +621,9 @@ static int saa5249_ioctl(struct inode *inode, struct file *file,
        int err;
        
        cmd = vtx_fix_command(cmd);
-       down(&t->lock);
+       mutex_lock(&t->lock);
        err = video_usercopy(inode,file,cmd,arg,do_saa5249_ioctl);
-       up(&t->lock);
+       mutex_unlock(&t->lock);
        return err;
 }
 
index ffd87ce55556acf7e786381f67da905d5891dea3..b184fd00b4e779270f41f0625fe331fa68b5466d 100644 (file)
@@ -1,4 +1,4 @@
-/* saa7115 - Philips SAA7114/SAA7115 video decoder driver
+/* saa7115 - Philips SAA7113/SAA7114/SAA7115 video decoder driver
  *
  * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
  * the saa7111 driver by Dave Perks.
@@ -16,6 +16,7 @@
  * (2/17/2003)
  *
  * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
+ * SAA7113 support by Mauro Carvalho Chehab <mchehab@infradead.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -42,8 +43,9 @@
 #include <media/audiochip.h>
 #include <asm/div64.h>
 
-MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver");
-MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil");
+MODULE_DESCRIPTION("Philips SAA7113/SAA7114/SAA7115 video decoder driver");
+MODULE_AUTHOR(  "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
+               "Hans Verkuil, Mauro Carvalho Chehab");
 MODULE_LICENSE("GPL");
 
 static int debug = 0;
@@ -51,7 +53,10 @@ module_param(debug, bool, 0644);
 
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = {
+               0x4a >>1, 0x48 >>1,     /* SAA7113 */
+               0x42 >> 1, 0x40 >> 1,   /* SAA7114 and SAA7115 */
+               I2C_CLIENT_END };
 
 
 I2C_CLIENT_INSMOD;
@@ -101,10 +106,12 @@ static inline int saa7115_read(struct i2c_client *client, u8 reg)
    Hauppauge driver sets. */
 
 static const unsigned char saa7115_init_auto_input[] = {
+               /* Front-End Part */
        0x01, 0x48,             /* white peak control disabled */
        0x03, 0x20,             /* was 0x30. 0x20: long vertical blanking */
        0x04, 0x90,             /* analog gain set to 0 */
        0x05, 0x90,             /* analog gain set to 0 */
+               /* Decoder Part */
        0x06, 0xeb,             /* horiz sync begin = -21 */
        0x07, 0xe0,             /* horiz sync stop = -17 */
        0x0a, 0x80,             /* was 0x88. decoder brightness, 0x80 is itu standard */
@@ -123,6 +130,8 @@ static const unsigned char saa7115_init_auto_input[] = {
        0x1b, 0x42,             /* misc chroma control 0x42 = recommended */
        0x1c, 0xa9,             /* combfilter control 0xA9 = recommended */
        0x1d, 0x01,             /* combfilter control 0x01 = recommended */
+
+               /* Power Device Control */
        0x88, 0xd0,             /* reset device */
        0x88, 0xf0,             /* set device programmed, all in operational mode */
        0x00, 0x00
@@ -338,6 +347,33 @@ static const unsigned char saa7115_cfg_vbi_off[] = {
        0x00, 0x00
 };
 
+static const unsigned char saa7113_init_auto_input[] = {
+       0x01, 0x08,     /* PH7113_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */
+       0x02, 0xc2,     /* PH7113_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */
+       0x03, 0x30,     /* PH7113_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */
+       0x04, 0x00,     /* PH7113_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */
+       0x05, 0x00,     /* PH7113_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */
+       0x06, 0x89,     /* PH7113_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */
+       0x07, 0x0d,     /* PH7113_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */
+       0x08, 0x88,     /* PH7113_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */
+       0x09, 0x01,     /* PH7113_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */
+       0x0a, 0x80,     /* PH7113_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */
+       0x0b, 0x47,     /* PH7113_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */
+       0x0c, 0x40,     /* PH7113_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */
+       0x0d, 0x00,     /* PH7113_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */
+       0x0e, 0x01,     /* PH7113_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */
+       0x0f, 0x2a,     /* PH7113_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */
+       0x10, 0x08,     /* PH7113_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */
+       0x11, 0x0c,     /* PH7113_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */
+       0x12, 0x07,     /* PH7113_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */
+       0x13, 0x00,     /* PH7113_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */
+       0x14, 0x00,     /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */
+       0x15, 0x00,     /* PH7113_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */
+       0x16, 0x00,     /* PH7113_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */
+       0x17, 0x00,     /* PH7113_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */
+       0x00, 0x00
+};
+
 static const unsigned char saa7115_init_misc[] = {
        0x38, 0x03,             /* audio stuff */
        0x39, 0x10,
@@ -677,10 +713,35 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
                saa7115_writeregs(client, saa7115_cfg_50hz_video);
        }
 
+       /* Register 0E - Bits D6-D4 on NO-AUTO mode
+               (SAA7113 doesn't have auto mode)
+           50 Hz / 625 lines           60 Hz / 525 lines
+       000 PAL BGDHI (4.43Mhz)         NTSC M (3.58MHz)
+       001 NTSC 4.43 (50 Hz)           PAL 4.43 (60 Hz)
+       010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz)
+       011 NTSC N (3.58MHz)            PAL M (3.58MHz)
+       100 reserved                    NTSC-Japan (3.58MHz)
+       */
+       if (state->ident == V4L2_IDENT_SAA7113) {
+               u8 reg =  saa7115_read(client, 0x0e) & 0x8f;
+
+               if (std == V4L2_STD_PAL_M) {
+                       reg|=0x30;
+               } else if (std == V4L2_STD_PAL_N) {
+                       reg|=0x20;
+               } else if (std == V4L2_STD_PAL_60) {
+                       reg|=0x10;
+               } else if (std == V4L2_STD_NTSC_M_JP) {
+                       reg|=0x40;
+               }
+               saa7115_write(client, 0x0e, reg);
+       }
+
+
        state->std = std;
 
        /* restart task B if needed */
-       if (taskb && state->ident == V4L2_IDENT_SAA7114) {
+       if (taskb && state->ident != V4L2_IDENT_SAA7115) {
                saa7115_writeregs(client, saa7115_cfg_vbi_on);
        }
 
@@ -703,7 +764,7 @@ static void saa7115_log_status(struct i2c_client *client)
        int vcr;
 
        v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
-       if (client->name[6] == '4') {
+       if (state->ident != V4L2_IDENT_SAA7115) {
                /* status for the saa7114 */
                reg1f = saa7115_read(client, 0x1f);
                signalOk = (reg1f & 0xc1) == 0x81;
@@ -751,8 +812,8 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
        u8 lcr[24];
        int i, x;
 
-       /* saa7114 doesn't yet support VBI */
-       if (state->ident == V4L2_IDENT_SAA7114)
+       /* saa7113/71144 doesn't yet support VBI */
+       if (state->ident != V4L2_IDENT_SAA7115)
                return;
 
        for (i = 0; i <= 23; i++)
@@ -791,7 +852,7 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
                                        case 0:
                                                lcr[i] |= 0xf << (4 * x);
                                                break;
-                                       case V4L2_SLICED_TELETEXT_B:
+                                       case V4L2_SLICED_TELETEXT_PAL_B:
                                                lcr[i] |= 1 << (4 * x);
                                                break;
                                        case V4L2_SLICED_CAPTION_525:
@@ -820,7 +881,7 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
 static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
 {
        static u16 lcr2vbi[] = {
-               0, V4L2_SLICED_TELETEXT_B, 0,   /* 1 */
+               0, V4L2_SLICED_TELETEXT_PAL_B, 0,       /* 1 */
                0, V4L2_SLICED_CAPTION_525,     /* 4 */
                V4L2_SLICED_WSS_625, 0,         /* 5 */
                V4L2_SLICED_VPS, 0, 0, 0, 0,    /* 7 */
@@ -985,7 +1046,7 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
        /* decode payloads */
        switch (id2) {
        case 1:
-               vbi->type = V4L2_SLICED_TELETEXT_B;
+               vbi->type = V4L2_SLICED_TELETEXT_PAL_B;
                break;
        case 4:
                if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1]))
@@ -1261,14 +1322,12 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
 
        saa7115_write(client, 0, 5);
        chip_id = saa7115_read(client, 0) & 0x0f;
-       if (chip_id != 4 && chip_id != 5) {
+       if (chip_id <3 && chip_id > 5) {
                v4l_dbg(1, debug, client, "saa7115 not found\n");
                kfree(client);
                return 0;
        }
-       if (chip_id == 4) {
-               snprintf(client->name, sizeof(client->name) - 1, "saa7114");
-       }
+       snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id);
        v4l_info(client, "saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name);
 
        state = kzalloc(sizeof(struct saa7115_state), GFP_KERNEL);
@@ -1285,13 +1344,27 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
        state->contrast = 64;
        state->hue = 0;
        state->sat = 64;
-       state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115;
+       switch (chip_id) {
+       case 3:
+               state->ident = V4L2_IDENT_SAA7113;
+               break;
+       case 4:
+               state->ident = V4L2_IDENT_SAA7114;
+               break;
+       default:
+               state->ident = V4L2_IDENT_SAA7115;
+               break;
+       }
+
        state->audclk_freq = 48000;
 
        v4l_dbg(1, debug, client, "writing init values\n");
 
        /* init to 60hz/48khz */
-       saa7115_writeregs(client, saa7115_init_auto_input);
+       if (state->ident==V4L2_IDENT_SAA7113)
+               saa7115_writeregs(client, saa7113_init_auto_input);
+       else
+               saa7115_writeregs(client, saa7115_init_auto_input);
        saa7115_writeregs(client, saa7115_init_misc);
        saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
        saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
index 7df5e0826e123fb2659995e5836c313a6aef432e..64e2c108df344122c6c266cb0038a4640d7d5eb8 100644 (file)
@@ -308,8 +308,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
 
 static int dsp_buffer_free(struct saa7134_dev *dev)
 {
-       if (!dev->dmasound.blksize)
-               BUG();
+       BUG_ON(!dev->dmasound.blksize);
 
        videobuf_dma_free(&dev->dmasound.dma);
 
@@ -611,12 +610,12 @@ static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
        struct saa7134_dev *dev = saa7134->dev;
        int err;
 
-       down(&dev->dmasound.lock);
+       mutex_lock(&dev->dmasound.lock);
 
        dev->dmasound.read_count  = 0;
        dev->dmasound.read_offset = 0;
 
-       up(&dev->dmasound.lock);
+       mutex_unlock(&dev->dmasound.lock);
 
        pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
        if (pcm == NULL)
@@ -934,7 +933,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
 
        chip->irq = dev->pci->irq;
 
-       init_MUTEX(&dev->dmasound.lock);
+       mutex_init(&dev->dmasound.lock);
 
        if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
                goto __nodev;
index 6bc63a4086c151970beb6ddc2d9cf5b4f431a67c..fdd7f48f3b76fe22f4a616c7b543dbb52122ac51 100644 (file)
@@ -536,7 +536,7 @@ struct saa7134_board saa7134_boards[] = {
                .radio = {
                        .name = name_radio,
                        .amux = LINE2,
-       },
+               },
        },
        [SAA7134_BOARD_MD7134] = {
                .name           = "Medion 7134",
@@ -640,6 +640,32 @@ struct saa7134_board saa7134_boards[] = {
                        .tv   = 1,
                }},
        },
+       [SAA7134_BOARD_ELSA_700TV] = {
+               .name           = "ELSA EX-VISION 700TV",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_HITACHI_NTSC,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .inputs         = {{
+                       .name = name_tv,
+                       .vmux = 4,
+                       .amux = LINE2,
+                       .tv   = 1,
+               },{
+                       .name = name_comp1,
+                       .vmux = 6,
+                       .amux = LINE1,
+               },{
+                       .name = name_svideo,
+                       .vmux = 7,
+                       .amux = LINE1,
+               }},
+               .mute           = {
+                       .name = name_mute,
+                       .amux = TV,
+               },
+       },
        [SAA7134_BOARD_ASUSTeK_TVFM7134] = {
                .name           = "ASUS TV-FM 7134",
                .audio_clock    = 0x00187de7,
@@ -2002,7 +2028,7 @@ struct saa7134_board saa7134_boards[] = {
        [SAA7134_BOARD_FLYTV_DIGIMATRIX] = {
                .name           = "FlyTV mini Asus Digimatrix",
                .audio_clock    = 0x00200000,
-               .tuner_type     = TUNER_LG_NTSC_TALN_MINI,
+               .tuner_type     = TUNER_LG_TALN,
                .radio_type     = UNSET,
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
@@ -2598,6 +2624,7 @@ struct saa7134_board saa7134_boards[] = {
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
                .gpiomask       = 0x00200000,
+               .mpeg           = SAA7134_MPEG_DVB,
                .inputs         = {{
                        .name = name_tv,        /* Analog broadcast/cable TV */
                        .vmux = 1,
@@ -2623,6 +2650,164 @@ struct saa7134_board saa7134_boards[] = {
                        .gpio = 0x000000,       /* GPIO21=Low for FM radio antenna */
                },
        },
+       [SAA7134_BOARD_AVERMEDIA_777] = {
+               .name           = "AverTV DVB-T 777",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_ABSENT,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .mpeg           = SAA7134_MPEG_DVB,
+               .inputs = {{
+                       .name   = name_comp1,
+                       .vmux   = 0,
+                       .amux   = LINE1,
+               },{
+                       .name   = name_svideo,
+                       .vmux   = 8,
+                       .amux   = LINE1,
+               }},
+       },
+       [SAA7134_BOARD_FLYDVBT_LR301] = {
+               /* LifeView FlyDVB-T */
+               /* Giampiero Giancipoli <gianci@libero.it> */
+               .name           = "LifeView FlyDVB-T",
+               .audio_clock    = 0x00200000,
+               .tuner_type     = TUNER_ABSENT,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .mpeg           = SAA7134_MPEG_DVB,
+               .inputs         = {{
+                       .name = name_comp1,     /* Composite input */
+                       .vmux = 3,
+                       .amux = LINE2,
+               },{
+                       .name = name_svideo,    /* S-Video signal on S-Video input */
+                       .vmux = 8,
+                       .amux = LINE2,
+               }},
+       },
+       [SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331] = {
+               .name           = "ADS Instant TV Duo Cardbus PTV331",
+               .audio_clock    = 0x00200000,
+               .tuner_type     = TUNER_PHILIPS_TDA8290,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .mpeg           = SAA7134_MPEG_DVB,
+               .gpiomask       = 0x00600000, /* Bit 21 0=Radio, Bit 22 0=TV */
+               .inputs = {{
+                       .name   = name_tv,
+                       .vmux   = 1,
+                       .amux   = TV,
+                       .tv     = 1,
+                       .gpio   = 0x00200000,
+               }},
+       },
+       [SAA7134_BOARD_TEVION_DVBT_220RF] = {
+               .name           = "Tevion/KWorld DVB-T 220RF",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_PHILIPS_TDA8290,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .mpeg           = SAA7134_MPEG_DVB,
+               .inputs = {{
+                       .name   = name_tv,
+                       .vmux   = 1,
+                       .amux   = TV,
+                       .tv     = 1,
+               },{
+                       .name   = name_comp1,
+                       .vmux   = 3,
+                       .amux   = LINE1,
+               },{
+                       .name   = name_svideo,
+                       .vmux   = 0,
+                       .amux   = LINE1,
+               }},
+               .radio = {
+                       .name   = name_radio,
+                       .amux   = LINE1,
+               },
+       },
+       [SAA7134_BOARD_KWORLD_ATSC110] = {
+               .name           = "Kworld ATSC110",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_PHILIPS_TUV1236D,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .tda9887_conf   = TDA9887_PRESENT,
+               .mpeg           = SAA7134_MPEG_DVB,
+               .inputs         = {{
+                       .name = name_tv,
+                       .vmux = 1,
+                       .amux = TV,
+                       .tv   = 1,
+               },{
+                       .name = name_comp1,
+                       .vmux = 3,
+                       .amux = LINE2,
+               },{
+                       .name = name_svideo,
+                       .vmux = 8,
+                       .amux = LINE2,
+               }},
+       },
+       [SAA7134_BOARD_AVERMEDIA_A169_B] = {
+               /* AVerMedia A169  */
+               /* Rickard Osser <ricky@osser.se>  */
+               /* This card has two saa7134 chips on it,
+                  but only one of them is currently working. */
+               .name           = "AVerMedia A169 B",
+               .audio_clock    = 0x02187de7,
+               .tuner_type     = TUNER_LG_TALN,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .tda9887_conf   = TDA9887_PRESENT,
+               .gpiomask       = 0x0a60000,
+       },
+       [SAA7134_BOARD_AVERMEDIA_A169_B1] = {
+               /* AVerMedia A169 */
+               /* Rickard Osser <ricky@osser.se> */
+               .name           = "AVerMedia A169 B1",
+               .audio_clock    = 0x02187de7,
+               .tuner_type     = TUNER_LG_TALN,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .tda9887_conf   = TDA9887_PRESENT,
+               .gpiomask       = 0xca60000,
+               .inputs         = {{
+                       .name = name_tv,
+                       .vmux = 4,
+                       .amux = TV,
+                       .tv   = 1,
+                       .gpio = 0x04a61000,
+               },{
+                       .name = name_comp2,  /*  Composite SVIDEO (B/W if signal is carried with SVIDEO) */
+                       .vmux = 1,
+                       .amux = LINE2,
+               },{
+                       .name = name_svideo,
+                       .vmux = 9,           /* 9 is correct as S-VIDEO1 according to a169.inf! */
+                       .amux = LINE1,
+               }},
+       },
+       [SAA7134_BOARD_MD7134_BRIDGE_2] = {
+               /* This card has two saa7134 chips on it,
+                  but only one of them is currently working.
+                  The programming for the primary decoder is
+                  in SAA7134_BOARD_MD7134 */
+               .name           = "Medion 7134 Bridge #2",
+               .audio_clock    = 0x00187de7,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+       },
 };
 
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -2751,6 +2936,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x1048,
                .subdevice    = 0x226a,
                .driver_data  = SAA7134_BOARD_ELSA_500TV,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+               .subvendor    = 0x1048,
+               .subdevice    = 0x226c,
+               .driver_data  = SAA7134_BOARD_ELSA_700TV,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -3093,6 +3284,54 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x5168,
                .subdevice    = 0x0319,
                .driver_data  = SAA7134_BOARD_FLYDVB_TRIO,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,  /* SAA 7131E */
+               .subvendor    = 0x1461,
+               .subdevice    = 0x2c05,
+               .driver_data  = SAA7134_BOARD_AVERMEDIA_777,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+               .subvendor    = 0x5168,
+               .subdevice    = 0x0301,
+               .driver_data  = SAA7134_BOARD_FLYDVBT_LR301,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+               .subvendor    = 0x0331,
+               .subdevice    = 0x1421,
+               .driver_data  = SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+               .subvendor    = 0x17de,
+               .subdevice    = 0x7201,
+               .driver_data  = SAA7134_BOARD_TEVION_DVBT_220RF,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
+               .subvendor    = 0x17de,
+               .subdevice    = 0x7350,
+               .driver_data  = SAA7134_BOARD_KWORLD_ATSC110,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+               .subvendor    = 0x1461,
+               .subdevice    = 0x7360,
+               .driver_data  = SAA7134_BOARD_AVERMEDIA_A169_B,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+               .subvendor    = 0x1461,
+               .subdevice    = 0x6360,
+               .driver_data  = SAA7134_BOARD_AVERMEDIA_A169_B1,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+               .subvendor    = 0x16be,
+               .subdevice    = 0x0005,
+               .driver_data  = SAA7134_BOARD_MD7134_BRIDGE_2,
        },{
                /* --- boards without eeprom + subsystem ID --- */
                .vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -3193,13 +3432,15 @@ int saa7134_board_init1(struct saa7134_dev *dev)
        case SAA7134_BOARD_GOTVIEW_7135:
        case SAA7134_BOARD_KWORLD_TERMINATOR:
        case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
+       case SAA7134_BOARD_FLYDVBT_LR301:
+       case SAA7134_BOARD_FLYDVBTDUO:
                dev->has_remote = SAA7134_REMOTE_GPIO;
                break;
        case SAA7134_BOARD_MD5044:
                printk("%s: seems there are two different versions of the MD5044\n"
-               "%s: (with the same ID) out there.  If sound doesn't work for\n"
-               "%s: you try the audio_clock_override=0x200000 insmod option.\n",
-               dev->name,dev->name,dev->name);
+                      "%s: (with the same ID) out there.  If sound doesn't work for\n"
+                      "%s: you try the audio_clock_override=0x200000 insmod option.\n",
+                      dev->name,dev->name,dev->name);
                break;
        case SAA7134_BOARD_CINERGY400_CARDBUS:
                /* power-up tuner chip */
@@ -3220,6 +3461,10 @@ int saa7134_board_init1(struct saa7134_dev *dev)
                saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
                saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
                break;
+       case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
+               saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
+               saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00);
+               break;
        case SAA7134_BOARD_AVERMEDIA_CARDBUS:
                /* power-up tuner chip */
                saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0xffffffff, 0xffffffff);
@@ -3242,6 +3487,13 @@ int saa7134_board_init1(struct saa7134_dev *dev)
        case SAA7134_BOARD_UPMOST_PURPLE_TV:
                dev->has_remote = SAA7134_REMOTE_I2C;
                break;
+       case SAA7134_BOARD_AVERMEDIA_A169_B:
+       case SAA7134_BOARD_MD7134_BRIDGE_2:
+               printk("%s: %s: dual saa713x broadcast decoders\n"
+                      "%s: Sorry, none of the inputs to this chip are supported yet.\n"
+                      "%s: Dual decoder functionality is disabled for now, use the other chip.\n",
+                      dev->name,card(dev).name,dev->name,dev->name);
+               break;
        }
        return 0;
 }
@@ -3362,14 +3614,44 @@ int saa7134_board_init2(struct saa7134_dev *dev)
                }
                break;
        case SAA7134_BOARD_PHILIPS_TIGER:
+       case SAA7134_BOARD_TEVION_DVBT_220RF:
        case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
-               /* this is a hybrid board, initialize to analog mode */
+               /* this is a hybrid board, initialize to analog mode
+                * and configure firmware eeprom address
+                */
                {
                u8 data[] = { 0x3c, 0x33, 0x68};
                struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
                i2c_transfer(&dev->i2c_adap, &msg, 1);
                }
                break;
+       case SAA7134_BOARD_FLYDVB_TRIO:
+               {
+               u8 data[] = { 0x3c, 0x33, 0x62};
+               struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)};
+               i2c_transfer(&dev->i2c_adap, &msg, 1);
+               }
+               break;
+       case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
+               /* make the tda10046 find its eeprom */
+               {
+               u8 data[] = { 0x3c, 0x33, 0x62};
+               struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
+               i2c_transfer(&dev->i2c_adap, &msg, 1);
+               }
+               break;
+       case SAA7134_BOARD_KWORLD_ATSC110:
+               {
+                       /* enable tuner */
+                       int i;
+                       static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
+                       dev->i2c_client.addr = 0x0a;
+                       for (i = 0; i < 5; i++)
+                               if (2 != i2c_master_send(&dev->i2c_client,&buffer[i*2],2))
+                                       printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n",
+                                              dev->name, i);
+               }
+               break;
        }
        return 0;
 }
index 028904bd94a23bb6a754f5162a660179c06820fd..58e568d7d2ee2b7545920dcb775f07a64c4de50f 100644 (file)
@@ -66,6 +66,11 @@ static unsigned int latency = UNSET;
 module_param(latency, int, 0444);
 MODULE_PARM_DESC(latency,"pci latency timer");
 
+int saa7134_no_overlay=-1;
+module_param_named(no_overlay, saa7134_no_overlay, int, 0444);
+MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
+               " [some VIA/SIS chipsets are known to have problem with overlay]");
+
 static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int vbi_nr[]   = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
@@ -251,8 +256,7 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
 
 void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf)
 {
-       if (in_interrupt())
-               BUG();
+       BUG_ON(in_interrupt());
 
        videobuf_waiton(&buf->vb,0,0);
        videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
@@ -613,7 +617,7 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
 
        saa_writel(SAA7134_IRQ1, 0);
        saa_writel(SAA7134_IRQ2, 0);
-       init_MUTEX(&dev->lock);
+       mutex_init(&dev->lock);
        spin_lock_init(&dev->slock);
 
        saa7134_track_gpio(dev,"pre-init");
@@ -835,6 +839,22 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
                        latency = 0x0A;
                }
 #endif
+               if (pci_pci_problems & PCIPCI_FAIL) {
+                       printk(KERN_INFO "%s: quirk: this driver and your "
+                                       "chipset may not work together"
+                                       " in overlay mode.\n",dev->name);
+                       if (!saa7134_no_overlay) {
+                               printk(KERN_INFO "%s: quirk: overlay "
+                                               "mode will be disabled.\n",
+                                               dev->name);
+                               saa7134_no_overlay = 1;
+                       } else {
+                               printk(KERN_INFO "%s: quirk: overlay "
+                                               "mode will be forced. Use this"
+                                               " option at your own risk.\n",
+                                               dev->name);
+                       }
+               }
        }
        if (UNSET != latency) {
                printk(KERN_INFO "%s: setting pci latency timer to %d\n",
@@ -937,6 +957,11 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
        v4l2_prio_init(&dev->prio);
 
        /* register v4l devices */
+       if (saa7134_no_overlay <= 0) {
+               saa7134_video_template.type |= VID_TYPE_OVERLAY;
+       } else {
+               printk("bttv: Overlay support disabled.\n");
+       }
        dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
        err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
                                    video_nr[dev->nr]);
index 9db8e13f21c32c59f0a2cb5417242f5fc7862e76..86cfdb8514cb58dc42c6cacfe2e42daf7de80264 100644 (file)
@@ -32,6 +32,7 @@
 #include "saa7134-reg.h"
 #include "saa7134.h"
 #include <media/v4l2-common.h>
+#include "dvb-pll.h"
 
 #ifdef HAVE_MT352
 # include "mt352.h"
@@ -42,7 +43,6 @@
 #endif
 #ifdef HAVE_NXT200X
 # include "nxt200x.h"
-# include "dvb-pll.h"
 #endif
 
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -114,6 +114,24 @@ static int mt352_pinnacle_init(struct dvb_frontend* fe)
        return 0;
 }
 
+static int mt352_aver777_init(struct dvb_frontend* fe)
+{
+       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x2d };
+       static u8 reset []         = { RESET,      0x80 };
+       static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
+       static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0xa0 };
+       static u8 capt_range_cfg[] = { CAPT_RANGE, 0x33 };
+
+       mt352_write(fe, clock_config,   sizeof(clock_config));
+       udelay(200);
+       mt352_write(fe, reset,          sizeof(reset));
+       mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
+       mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
+       mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
+
+       return 0;
+}
+
 static int mt352_pinnacle_pll_set(struct dvb_frontend* fe,
                                  struct dvb_frontend_parameters* params,
                                  u8* pllbuf)
@@ -146,6 +164,15 @@ static int mt352_pinnacle_pll_set(struct dvb_frontend* fe,
        return 0;
 }
 
+static int mt352_aver777_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8* pllbuf)
+{
+       pllbuf[0] = 0xc2;
+       dvb_pll_configure(&dvb_pll_philips_td1316, pllbuf+1,
+                         params->frequency,
+                         params->u.ofdm.bandwidth);
+       return 0;
+}
+
 static struct mt352_config pinnacle_300i = {
        .demod_address = 0x3c >> 1,
        .adc_clock     = 20333,
@@ -154,6 +181,12 @@ static struct mt352_config pinnacle_300i = {
        .demod_init    = mt352_pinnacle_init,
        .pll_set       = mt352_pinnacle_pll_set,
 };
+
+static struct mt352_config avermedia_777 = {
+       .demod_address = 0xf,
+       .demod_init    = mt352_aver777_init,
+       .pll_set       = mt352_aver777_pll_set,
+};
 #endif
 
 /* ------------------------------------------------------------------ */
@@ -781,7 +814,7 @@ static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_pa
        tda8290_msg.buf = tda8290_open;
        i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
        return ret;
-};
+}
 
 static int philips_tiger_dvb_mode(struct dvb_frontend *fe)
 {
@@ -817,6 +850,110 @@ static struct tda1004x_config philips_tiger_config = {
        .request_firmware = NULL,
 };
 
+/* ------------------------------------------------------------------ */
+
+static int lifeview_trio_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+       int ret;
+
+       ret = philips_tda827xa_pll_set(0x60, fe, params);
+       return ret;
+}
+
+static int lifeview_trio_dvb_mode(struct dvb_frontend *fe)
+{
+       return 0;
+}
+
+static void lifeview_trio_analog_mode(struct dvb_frontend *fe)
+{
+       philips_tda827xa_pll_sleep(0x60, fe);
+}
+
+static struct tda1004x_config lifeview_trio_config = {
+       .demod_address = 0x09,
+       .invert        = 1,
+       .invert_oclk   = 0,
+       .xtal_freq     = TDA10046_XTAL_16M,
+       .agc_config    = TDA10046_AGC_TDA827X_GPL,
+       .if_freq       = TDA10046_FREQ_045,
+       .pll_init      = lifeview_trio_dvb_mode,
+       .pll_set       = lifeview_trio_pll_set,
+       .pll_sleep     = lifeview_trio_analog_mode,
+       .request_firmware = NULL,
+};
+
+/* ------------------------------------------------------------------ */
+
+static int ads_duo_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+       int ret;
+
+       ret = philips_tda827xa_pll_set(0x61, fe, params);
+       return ret;
+}
+
+static int ads_duo_dvb_mode(struct dvb_frontend *fe)
+{
+       struct saa7134_dev *dev = fe->dvb->priv;
+       /* route TDA8275a AGC input to the channel decoder */
+       saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x60);
+       return 0;
+}
+
+static void ads_duo_analog_mode(struct dvb_frontend *fe)
+{
+       struct saa7134_dev *dev = fe->dvb->priv;
+       /* route TDA8275a AGC input to the analog IF chip*/
+       saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x20);
+       philips_tda827xa_pll_sleep( 0x61, fe);
+}
+
+static struct tda1004x_config ads_tech_duo_config = {
+       .demod_address = 0x08,
+       .invert        = 1,
+       .invert_oclk   = 0,
+       .xtal_freq     = TDA10046_XTAL_16M,
+       .agc_config    = TDA10046_AGC_TDA827X_GPL,
+       .if_freq       = TDA10046_FREQ_045,
+       .pll_init      = ads_duo_dvb_mode,
+       .pll_set       = ads_duo_pll_set,
+       .pll_sleep     = ads_duo_analog_mode,
+       .request_firmware = NULL,
+};
+
+/* ------------------------------------------------------------------ */
+
+static int tevion_dvb220rf_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+       int ret;
+       ret = philips_tda827xa_pll_set(0x60, fe, params);
+       return ret;
+}
+
+static int tevion_dvb220rf_pll_init(struct dvb_frontend *fe)
+{
+       return 0;
+}
+
+static void tevion_dvb220rf_pll_sleep(struct dvb_frontend *fe)
+{
+       philips_tda827xa_pll_sleep( 0x61, fe);
+}
+
+static struct tda1004x_config tevion_dvbt220rf_config = {
+       .demod_address = 0x08,
+       .invert        = 1,
+       .invert_oclk   = 0,
+       .xtal_freq     = TDA10046_XTAL_16M,
+       .agc_config    = TDA10046_AGC_TDA827X,
+       .if_freq       = TDA10046_FREQ_045,
+       .pll_init      = tevion_dvb220rf_pll_init,
+       .pll_set       = tevion_dvb220rf_pll_set,
+       .pll_sleep     = tevion_dvb220rf_pll_sleep,
+       .request_firmware = NULL,
+};
+
 #endif
 
 /* ------------------------------------------------------------------ */
@@ -827,6 +964,22 @@ static struct nxt200x_config avertvhda180 = {
        .pll_address      = 0x61,
        .pll_desc         = &dvb_pll_tdhu2,
 };
+
+static int nxt200x_set_pll_input(u8 *buf, int input)
+{
+       if (input)
+               buf[3] |= 0x08;
+       else
+               buf[3] &= ~0x08;
+       return 0;
+}
+
+static struct nxt200x_config kworldatsc110 = {
+       .demod_address    = 0x0a,
+       .pll_address      = 0x61,
+       .pll_desc         = &dvb_pll_tuv1236d,
+       .set_pll_input    = nxt200x_set_pll_input,
+};
 #endif
 
 /* ------------------------------------------------------------------ */
@@ -851,6 +1004,12 @@ static int dvb_init(struct saa7134_dev *dev)
                dev->dvb.frontend = mt352_attach(&pinnacle_300i,
                                                 &dev->i2c_adap);
                break;
+
+       case SAA7134_BOARD_AVERMEDIA_777:
+               printk("%s: avertv 777 dvb setup\n",dev->name);
+               dev->dvb.frontend = mt352_attach(&avermedia_777,
+                                                &dev->i2c_adap);
+               break;
 #endif
 #ifdef HAVE_TDA1004X
        case SAA7134_BOARD_MD7134:
@@ -889,11 +1048,30 @@ static int dvb_init(struct saa7134_dev *dev)
                dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
                                                    &dev->i2c_adap);
                break;
+       case SAA7134_BOARD_FLYDVBT_LR301:
+               dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
+                                                   &dev->i2c_adap);
+               break;
+       case SAA7134_BOARD_FLYDVB_TRIO:
+               dev->dvb.frontend = tda10046_attach(&lifeview_trio_config,
+                                                   &dev->i2c_adap);
+               break;
+       case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
+               dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config,
+                                                   &dev->i2c_adap);
+               break;
+       case SAA7134_BOARD_TEVION_DVBT_220RF:
+               dev->dvb.frontend = tda10046_attach(&tevion_dvbt220rf_config,
+                                                   &dev->i2c_adap);
+               break;
 #endif
 #ifdef HAVE_NXT200X
        case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
                dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap);
                break;
+       case SAA7134_BOARD_KWORLD_ATSC110:
+               dev->dvb.frontend = nxt200x_attach(&kworldatsc110, &dev->i2c_adap);
+               break;
 #endif
        default:
                printk("%s: Huh? unknown DVB card?\n",dev->name);
index bd4c389d4c37a6d190f61130ce8d686c630b8b73..1d972edb3be6b2cbb3e9c167e24754c5c27cf02f 100644 (file)
@@ -89,7 +89,7 @@ static int ts_open(struct inode *inode, struct file *file)
 
        dprintk("open minor=%d\n",minor);
        err = -EBUSY;
-       if (down_trylock(&dev->empress_tsq.lock))
+       if (!mutex_trylock(&dev->empress_tsq.lock))
                goto done;
        if (dev->empress_users)
                goto done_up;
@@ -99,7 +99,7 @@ static int ts_open(struct inode *inode, struct file *file)
        err = 0;
 
 done_up:
-       up(&dev->empress_tsq.lock);
+       mutex_unlock(&dev->empress_tsq.lock);
 done:
        return err;
 }
@@ -110,7 +110,7 @@ static int ts_release(struct inode *inode, struct file *file)
 
        if (dev->empress_tsq.streaming)
                videobuf_streamoff(&dev->empress_tsq);
-       down(&dev->empress_tsq.lock);
+       mutex_lock(&dev->empress_tsq.lock);
        if (dev->empress_tsq.reading)
                videobuf_read_stop(&dev->empress_tsq);
        videobuf_mmap_free(&dev->empress_tsq);
@@ -119,7 +119,7 @@ static int ts_release(struct inode *inode, struct file *file)
        /* stop the encoder */
        ts_reset_encoder(dev);
 
-       up(&dev->empress_tsq.lock);
+       mutex_unlock(&dev->empress_tsq.lock);
        return 0;
 }
 
index 82d28cbf289f1a1fe1bb5e22168ee32d8de2e001..1426e4c8602faa00a519e2e6a9a2c1e47d6860bf 100644 (file)
@@ -42,485 +42,6 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
 #define i2cdprintk(fmt, arg...)    if (ir_debug) \
        printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
 
-/* ---------------------------------------------------------------------- */
-
-static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
-       [   15 ] = KEY_KP0,
-       [    3 ] = KEY_KP1,
-       [    4 ] = KEY_KP2,
-       [    5 ] = KEY_KP3,
-       [    7 ] = KEY_KP4,
-       [    8 ] = KEY_KP5,
-       [    9 ] = KEY_KP6,
-       [   11 ] = KEY_KP7,
-       [   12 ] = KEY_KP8,
-       [   13 ] = KEY_KP9,
-
-       [   14 ] = KEY_MODE,         // Air/Cable
-       [   17 ] = KEY_VIDEO,        // Video
-       [   21 ] = KEY_AUDIO,        // Audio
-       [    0 ] = KEY_POWER,        // Power
-       [   24 ] = KEY_TUNER,        // AV Source
-       [    2 ] = KEY_ZOOM,         // Fullscreen
-       [   26 ] = KEY_LANGUAGE,     // Stereo
-       [   27 ] = KEY_MUTE,         // Mute
-       [   20 ] = KEY_VOLUMEUP,     // Volume +
-       [   23 ] = KEY_VOLUMEDOWN,   // Volume -
-       [   18 ] = KEY_CHANNELUP,    // Channel +
-       [   19 ] = KEY_CHANNELDOWN,  // Channel -
-       [    6 ] = KEY_AGAIN,        // Recall
-       [   16 ] = KEY_ENTER,      // Enter
-};
-
-
-static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
-       [    0 ] = KEY_KP0,
-       [    1 ] = KEY_KP1,
-       [    2 ] = KEY_KP2,
-       [    3 ] = KEY_KP3,
-       [    4 ] = KEY_KP4,
-       [    5 ] = KEY_KP5,
-       [    6 ] = KEY_KP6,
-       [    7 ] = KEY_KP7,
-       [    8 ] = KEY_KP8,
-       [    9 ] = KEY_KP9,
-
-       [ 0x0a ] = KEY_POWER,
-       [ 0x0b ] = KEY_PROG1,           // app
-       [ 0x0c ] = KEY_ZOOM,            // zoom/fullscreen
-       [ 0x0d ] = KEY_CHANNELUP,       // channel
-       [ 0x0e ] = KEY_CHANNELDOWN,     // channel-
-       [ 0x0f ] = KEY_VOLUMEUP,
-       [ 0x10 ] = KEY_VOLUMEDOWN,
-       [ 0x11 ] = KEY_TUNER,           // AV
-       [ 0x12 ] = KEY_NUMLOCK,         // -/--
-       [ 0x13 ] = KEY_AUDIO,           // audio
-       [ 0x14 ] = KEY_MUTE,
-       [ 0x15 ] = KEY_UP,
-       [ 0x16 ] = KEY_DOWN,
-       [ 0x17 ] = KEY_LEFT,
-       [ 0x18 ] = KEY_RIGHT,
-       [ 0x19 ] = BTN_LEFT,
-       [ 0x1a ] = BTN_RIGHT,
-       [ 0x1b ] = KEY_WWW,             // text
-       [ 0x1c ] = KEY_REWIND,
-       [ 0x1d ] = KEY_FORWARD,
-       [ 0x1e ] = KEY_RECORD,
-       [ 0x1f ] = KEY_PLAY,
-       [ 0x20 ] = KEY_PREVIOUSSONG,
-       [ 0x21 ] = KEY_NEXTSONG,
-       [ 0x22 ] = KEY_PAUSE,
-       [ 0x23 ] = KEY_STOP,
-};
-
-/* Alfons Geser <a.geser@cox.net>
- * updates from Job D. R. Borges <jobdrb@ig.com.br> */
-static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
-       [ 18 ] = KEY_POWER,
-       [  1 ] = KEY_TV,             // DVR
-       [ 21 ] = KEY_DVD,            // DVD
-       [ 23 ] = KEY_AUDIO,          // music
-                                    // DVR mode / DVD mode / music mode
-
-       [ 27 ] = KEY_MUTE,           // mute
-       [  2 ] = KEY_LANGUAGE,       // MTS/SAP / audio / autoseek
-       [ 30 ] = KEY_SUBTITLE,       // closed captioning / subtitle / seek
-       [ 22 ] = KEY_ZOOM,           // full screen
-       [ 28 ] = KEY_VIDEO,          // video source / eject / delall
-       [ 29 ] = KEY_RESTART,        // playback / angle / del
-       [ 47 ] = KEY_SEARCH,         // scan / menu / playlist
-       [ 48 ] = KEY_CHANNEL,        // CH surfing / bookmark / memo
-
-       [ 49 ] = KEY_HELP,           // help
-       [ 50 ] = KEY_MODE,           // num/memo
-       [ 51 ] = KEY_ESC,            // cancel
-
-       [ 12 ] = KEY_UP,             // up
-       [ 16 ] = KEY_DOWN,           // down
-       [  8 ] = KEY_LEFT,           // left
-       [  4 ] = KEY_RIGHT,          // right
-       [  3 ] = KEY_SELECT,         // select
-
-       [ 31 ] = KEY_REWIND,         // rewind
-       [ 32 ] = KEY_PLAYPAUSE,      // play/pause
-       [ 41 ] = KEY_FORWARD,        // forward
-       [ 20 ] = KEY_AGAIN,          // repeat
-       [ 43 ] = KEY_RECORD,         // recording
-       [ 44 ] = KEY_STOP,           // stop
-       [ 45 ] = KEY_PLAY,           // play
-       [ 46 ] = KEY_SHUFFLE,        // snapshot / shuffle
-
-       [  0 ] = KEY_KP0,
-       [  5 ] = KEY_KP1,
-       [  6 ] = KEY_KP2,
-       [  7 ] = KEY_KP3,
-       [  9 ] = KEY_KP4,
-       [ 10 ] = KEY_KP5,
-       [ 11 ] = KEY_KP6,
-       [ 13 ] = KEY_KP7,
-       [ 14 ] = KEY_KP8,
-       [ 15 ] = KEY_KP9,
-
-       [ 42 ] = KEY_VOLUMEUP,
-       [ 17 ] = KEY_VOLUMEDOWN,
-       [ 24 ] = KEY_CHANNELUP,      // CH.tracking up
-       [ 25 ] = KEY_CHANNELDOWN,    // CH.tracking down
-
-       [ 19 ] = KEY_KPENTER,        // enter
-       [ 33 ] = KEY_KPDOT,          // . (decimal dot)
-};
-
-static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
-       [ 30 ] = KEY_POWER,             // power
-       [ 28 ] = KEY_SEARCH,            // scan
-       [  7 ] = KEY_SELECT,            // source
-
-       [ 22 ] = KEY_VOLUMEUP,
-       [ 20 ] = KEY_VOLUMEDOWN,
-       [ 31 ] = KEY_CHANNELUP,
-       [ 23 ] = KEY_CHANNELDOWN,
-       [ 24 ] = KEY_MUTE,
-
-       [  2 ] = KEY_KP0,
-       [  1 ] = KEY_KP1,
-       [ 11 ] = KEY_KP2,
-       [ 27 ] = KEY_KP3,
-       [  5 ] = KEY_KP4,
-       [  9 ] = KEY_KP5,
-       [ 21 ] = KEY_KP6,
-       [  6 ] = KEY_KP7,
-       [ 10 ] = KEY_KP8,
-       [ 18 ] = KEY_KP9,
-       [ 16 ] = KEY_KPDOT,
-
-       [  3 ] = KEY_TUNER,             // tv/fm
-       [  4 ] = KEY_REWIND,            // fm tuning left or function left
-       [ 12 ] = KEY_FORWARD,           // fm tuning right or function right
-
-       [  0 ] = KEY_RECORD,
-       [  8 ] = KEY_STOP,
-       [ 17 ] = KEY_PLAY,
-
-       [ 25 ] = KEY_ZOOM,
-       [ 14 ] = KEY_MENU,              // function
-       [ 19 ] = KEY_AGAIN,             // recall
-       [ 29 ] = KEY_RESTART,           // reset
-       [ 26 ] = KEY_SHUFFLE,           // snapshot/shuffle
-
-// FIXME
-       [ 13 ] = KEY_F21,               // mts
-       [ 15 ] = KEY_F22,               // min
-};
-
-/* Alex Hermann <gaaf@gmx.net> */
-static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = {
-       [ 40 ] = KEY_KP1,
-       [ 24 ] = KEY_KP2,
-       [ 56 ] = KEY_KP3,
-       [ 36 ] = KEY_KP4,
-       [ 20 ] = KEY_KP5,
-       [ 52 ] = KEY_KP6,
-       [ 44 ] = KEY_KP7,
-       [ 28 ] = KEY_KP8,
-       [ 60 ] = KEY_KP9,
-       [ 34 ] = KEY_KP0,
-
-       [ 32 ] = KEY_TV,                // TV/FM
-       [ 16 ] = KEY_CD,                // CD
-       [ 48 ] = KEY_TEXT,              // TELETEXT
-       [  0 ] = KEY_POWER,             // POWER
-
-       [  8 ] = KEY_VIDEO,             // VIDEO
-       [  4 ] = KEY_AUDIO,             // AUDIO
-       [ 12 ] = KEY_ZOOM,              // FULL SCREEN
-
-       [ 18 ] = KEY_SUBTITLE,          // DISPLAY      - ???
-       [ 50 ] = KEY_REWIND,            // LOOP         - ???
-       [  2 ] = KEY_PRINT,             // PREVIEW      - ???
-
-       [ 42 ] = KEY_SEARCH,            // AUTOSCAN
-       [ 26 ] = KEY_SLEEP,             // FREEZE       - ???
-       [ 58 ] = KEY_SHUFFLE,           // SNAPSHOT     - ???
-       [ 10 ] = KEY_MUTE,              // MUTE
-
-       [ 38 ] = KEY_RECORD,            // RECORD
-       [ 22 ] = KEY_PAUSE,             // PAUSE
-       [ 54 ] = KEY_STOP,              // STOP
-       [  6 ] = KEY_PLAY,              // PLAY
-
-       [ 46 ] = KEY_RED,               // <RED>
-       [ 33 ] = KEY_GREEN,             // <GREEN>
-       [ 14 ] = KEY_YELLOW,            // <YELLOW>
-       [  1 ] = KEY_BLUE,              // <BLUE>
-
-       [ 30 ] = KEY_VOLUMEDOWN,        // VOLUME-
-       [ 62 ] = KEY_VOLUMEUP,          // VOLUME+
-       [ 17 ] = KEY_CHANNELDOWN,       // CHANNEL/PAGE-
-       [ 49 ] = KEY_CHANNELUP          // CHANNEL/PAGE+
-};
-
-static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
-       [ 20 ] = KEY_MUTE,
-       [ 36 ] = KEY_ZOOM,
-
-       [  1 ] = KEY_DVD,
-       [ 35 ] = KEY_RADIO,
-       [  0 ] = KEY_TV,
-
-       [ 10 ] = KEY_REWIND,
-       [  8 ] = KEY_PLAYPAUSE,
-       [ 15 ] = KEY_FORWARD,
-
-       [  2 ] = KEY_PREVIOUS,
-       [  7 ] = KEY_STOP,
-       [  6 ] = KEY_NEXT,
-
-       [ 12 ] = KEY_UP,
-       [ 14 ] = KEY_DOWN,
-       [ 11 ] = KEY_LEFT,
-       [ 13 ] = KEY_RIGHT,
-       [ 17 ] = KEY_OK,
-
-       [  3 ] = KEY_MENU,
-       [  9 ] = KEY_SETUP,
-       [  5 ] = KEY_VIDEO,
-       [ 34 ] = KEY_CHANNEL,
-
-       [ 18 ] = KEY_VOLUMEUP,
-       [ 21 ] = KEY_VOLUMEDOWN,
-       [ 16 ] = KEY_CHANNELUP,
-       [ 19 ] = KEY_CHANNELDOWN,
-
-       [  4 ] = KEY_RECORD,
-
-       [ 22 ] = KEY_KP1,
-       [ 23 ] = KEY_KP2,
-       [ 24 ] = KEY_KP3,
-       [ 25 ] = KEY_KP4,
-       [ 26 ] = KEY_KP5,
-       [ 27 ] = KEY_KP6,
-       [ 28 ] = KEY_KP7,
-       [ 29 ] = KEY_KP8,
-       [ 30 ] = KEY_KP9,
-       [ 31 ] = KEY_KP0,
-
-       [ 32 ] = KEY_LANGUAGE,
-       [ 33 ] = KEY_SLEEP,
-};
-
-/* Michael Tokarev <mjt@tls.msk.ru>
-   http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
-   keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at
-   least, and probably other cards too.
-   The "ascii-art picture" below (in comments, first row
-   is the keycode in hex, and subsequent row(s) shows
-   the button labels (several variants when appropriate)
-   helps to descide which keycodes to assign to the buttons.
- */
-static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
-
-       /*  0x1c            0x12  *
-        * FUNCTION         POWER *
-        *   FM              (|)  *
-        *                        */
-       [ 0x1c ] = KEY_RADIO,   /*XXX*/
-       [ 0x12 ] = KEY_POWER,
-
-       /*  0x01    0x02    0x03  *
-        *   1       2       3    *
-        *                        *
-        *  0x04    0x05    0x06  *
-        *   4       5       6    *
-        *                        *
-        *  0x07    0x08    0x09  *
-        *   7       8       9    *
-        *                        */
-       [ 0x01 ] = KEY_KP1,
-       [ 0x02 ] = KEY_KP2,
-       [ 0x03 ] = KEY_KP3,
-       [ 0x04 ] = KEY_KP4,
-       [ 0x05 ] = KEY_KP5,
-       [ 0x06 ] = KEY_KP6,
-       [ 0x07 ] = KEY_KP7,
-       [ 0x08 ] = KEY_KP8,
-       [ 0x09 ] = KEY_KP9,
-
-       /*  0x0a    0x00    0x17  *
-        * RECALL    0      +100  *
-        *                  PLUS  *
-        *                        */
-       [ 0x0a ] = KEY_AGAIN,   /*XXX KEY_REWIND? */
-       [ 0x00 ] = KEY_KP0,
-       [ 0x17 ] = KEY_DIGITS,  /*XXX*/
-
-       /*  0x14            0x10  *
-        *  MENU            INFO  *
-        *  OSD                   */
-       [ 0x14 ] = KEY_MENU,
-       [ 0x10 ] = KEY_INFO,
-
-       /*          0x0b          *
-        *           Up           *
-        *                        *
-        *  0x18    0x16    0x0c  *
-        *  Left     Ok     Right *
-        *                        *
-        *         0x015          *
-        *         Down           *
-        *                        */
-       [ 0x0b ] = KEY_UP,      /*XXX KEY_SCROLLUP? */
-       [ 0x18 ] = KEY_LEFT,    /*XXX KEY_BACK? */
-       [ 0x16 ] = KEY_OK,      /*XXX KEY_SELECT? KEY_ENTER? */
-       [ 0x0c ] = KEY_RIGHT,   /*XXX KEY_FORWARD? */
-       [ 0x15 ] = KEY_DOWN,    /*XXX KEY_SCROLLDOWN? */
-
-       /*  0x11            0x0d  *
-        *  TV/AV           MODE  *
-        *  SOURCE         STEREO *
-        *                        */
-       [ 0x11 ] = KEY_TV,      /*XXX*/
-       [ 0x0d ] = KEY_MODE,    /*XXX there's no KEY_STEREO */
-
-       /*  0x0f    0x1b    0x1a  *
-        *  AUDIO   Vol+    Chan+ *
-        *        TIMESHIFT???    *
-        *                        *
-        *  0x0e    0x1f    0x1e  *
-        *  SLEEP   Vol-    Chan- *
-        *                        */
-       [ 0x0f ] = KEY_AUDIO,
-       [ 0x1b ] = KEY_VOLUMEUP,
-       [ 0x1a ] = KEY_CHANNELUP,
-       [ 0x0e ] = KEY_SLEEP,   /*XXX maybe KEY_PAUSE */
-       [ 0x1f ] = KEY_VOLUMEDOWN,
-       [ 0x1e ] = KEY_CHANNELDOWN,
-
-       /*         0x13     0x19  *
-        *         MUTE   SNAPSHOT*
-        *                        */
-       [ 0x13 ] = KEY_MUTE,
-       [ 0x19 ] = KEY_RECORD,  /*XXX*/
-
-       // 0x1d unused ?
-};
-
-
-/* Mike Baikov <mike@baikov.com> */
-static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = {
-
-       [ 33 ] = KEY_POWER,
-       [ 105] = KEY_TV,
-       [ 51 ] = KEY_KP0,
-       [ 81 ] = KEY_KP1,
-       [ 49 ] = KEY_KP2,
-       [ 113] = KEY_KP3,
-       [ 59 ] = KEY_KP4,
-       [ 88 ] = KEY_KP5,
-       [ 65 ] = KEY_KP6,
-       [ 72 ] = KEY_KP7,
-       [ 48 ] = KEY_KP8,
-       [ 83 ] = KEY_KP9,
-       [ 115] = KEY_AGAIN, /* LOOP */
-       [ 10 ] = KEY_AUDIO,
-       [ 97 ] = KEY_PRINT, /* PREVIEW */
-       [ 122] = KEY_VIDEO,
-       [ 32 ] = KEY_CHANNELUP,
-       [ 64 ] = KEY_CHANNELDOWN,
-       [ 24 ] = KEY_VOLUMEDOWN,
-       [ 80 ] = KEY_VOLUMEUP,
-       [ 16 ] = KEY_MUTE,
-       [ 74 ] = KEY_SEARCH,
-       [ 123] = KEY_SHUFFLE, /* SNAPSHOT */
-       [ 34 ] = KEY_RECORD,
-       [ 98 ] = KEY_STOP,
-       [ 120] = KEY_PLAY,
-       [ 57 ] = KEY_REWIND,
-       [ 89 ] = KEY_PAUSE,
-       [ 25 ] = KEY_FORWARD,
-       [  9 ] = KEY_ZOOM,
-
-       [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */
-       [ 26 ] = KEY_F22, /* MIN TIMESHIFT */
-       [ 58 ] = KEY_F23, /* TIMESHIFT */
-       [ 112] = KEY_F24, /* NORMAL TIMESHIFT */
-};
-
-static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
-       [ 0x3  ] = KEY_POWER,
-       [ 0x6f ] = KEY_MUTE,
-       [ 0x10 ] = KEY_BACKSPACE,       /* Recall */
-
-       [ 0x11 ] = KEY_KP0,
-       [ 0x4  ] = KEY_KP1,
-       [ 0x5  ] = KEY_KP2,
-       [ 0x6  ] = KEY_KP3,
-       [ 0x8  ] = KEY_KP4,
-       [ 0x9  ] = KEY_KP5,
-       [ 0xa  ] = KEY_KP6,
-       [ 0xc  ] = KEY_KP7,
-       [ 0xd  ] = KEY_KP8,
-       [ 0xe  ] = KEY_KP9,
-       [ 0x12 ] = KEY_KPDOT,           /* 100+ */
-
-       [ 0x7  ] = KEY_VOLUMEUP,
-       [ 0xb  ] = KEY_VOLUMEDOWN,
-       [ 0x1a ] = KEY_KPPLUS,
-       [ 0x18 ] = KEY_KPMINUS,
-       [ 0x15 ] = KEY_UP,
-       [ 0x1d ] = KEY_DOWN,
-       [ 0xf  ] = KEY_CHANNELUP,
-       [ 0x13 ] = KEY_CHANNELDOWN,
-       [ 0x48 ] = KEY_ZOOM,
-
-       [ 0x1b ] = KEY_VIDEO,           /* Video source */
-       [ 0x49 ] = KEY_LANGUAGE,        /* MTS Select */
-       [ 0x19 ] = KEY_SEARCH,          /* Auto Scan */
-
-       [ 0x4b ] = KEY_RECORD,
-       [ 0x46 ] = KEY_PLAY,
-       [ 0x45 ] = KEY_PAUSE,           /* Pause */
-       [ 0x44 ] = KEY_STOP,
-       [ 0x40 ] = KEY_FORWARD,         /* Forward ? */
-       [ 0x42 ] = KEY_REWIND,          /* Backward ? */
-
-};
-
-/* Mapping for the 28 key remote control as seen at
-   http://www.sednacomputer.com/photo/cardbus-tv.jpg
-   Pavel Mihaylov <bin@bash.info> */
-static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = {
-       [    0 ] = KEY_KP0,
-       [    1 ] = KEY_KP1,
-       [    2 ] = KEY_KP2,
-       [    3 ] = KEY_KP3,
-       [    4 ] = KEY_KP4,
-       [    5 ] = KEY_KP5,
-       [    6 ] = KEY_KP6,
-       [    7 ] = KEY_KP7,
-       [    8 ] = KEY_KP8,
-       [    9 ] = KEY_KP9,
-
-       [ 0x0a ] = KEY_AGAIN,          /* Recall */
-       [ 0x0b ] = KEY_CHANNELUP,
-       [ 0x0c ] = KEY_VOLUMEUP,
-       [ 0x0d ] = KEY_MODE,           /* Stereo */
-       [ 0x0e ] = KEY_STOP,
-       [ 0x0f ] = KEY_PREVIOUSSONG,
-       [ 0x10 ] = KEY_ZOOM,
-       [ 0x11 ] = KEY_TUNER,          /* Source */
-       [ 0x12 ] = KEY_POWER,
-       [ 0x13 ] = KEY_MUTE,
-       [ 0x15 ] = KEY_CHANNELDOWN,
-       [ 0x18 ] = KEY_VOLUMEDOWN,
-       [ 0x19 ] = KEY_SHUFFLE,        /* Snapshot */
-       [ 0x1a ] = KEY_NEXTSONG,
-       [ 0x1b ] = KEY_TEXT,           /* Time Shift */
-       [ 0x1c ] = KEY_RADIO,          /* FM Radio */
-       [ 0x1d ] = KEY_RECORD,
-       [ 0x1e ] = KEY_PAUSE,
-};
-
-
 /* -------------------- GPIO generic keycode builder -------------------- */
 
 static int build_key(struct saa7134_dev *dev)
@@ -628,27 +149,27 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        case SAA7134_BOARD_FLYVIDEO3000:
        case SAA7134_BOARD_FLYTVPLATINUM_FM:
        case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
-               ir_codes     = flyvideo_codes;
+               ir_codes     = ir_codes_flyvideo;
                mask_keycode = 0xEC00000;
                mask_keydown = 0x0040000;
                break;
        case SAA7134_BOARD_CINERGY400:
        case SAA7134_BOARD_CINERGY600:
        case SAA7134_BOARD_CINERGY600_MK3:
-               ir_codes     = cinergy_codes;
+               ir_codes     = ir_codes_cinergy;
                mask_keycode = 0x00003f;
                mask_keyup   = 0x040000;
                break;
        case SAA7134_BOARD_ECS_TVP3XP:
        case SAA7134_BOARD_ECS_TVP3XP_4CB5:
-               ir_codes     = eztv_codes;
+               ir_codes     = ir_codes_eztv;
                mask_keycode = 0x00017c;
                mask_keyup   = 0x000002;
                polling      = 50; // ms
                break;
        case SAA7134_BOARD_KWORLD_XPERT:
        case SAA7134_BOARD_AVACSSMARTTV:
-               ir_codes     = avacssmart_codes;
+               ir_codes     = ir_codes_pixelview;
                mask_keycode = 0x00001F;
                mask_keyup   = 0x000020;
                polling      = 50; // ms
@@ -660,7 +181,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
        case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
        case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
-               ir_codes     = md2819_codes;
+               ir_codes     = ir_codes_avermedia;
                mask_keycode = 0x0007C8;
                mask_keydown = 0x000010;
                polling      = 50; // ms
@@ -669,7 +190,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
                saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
                break;
        case SAA7134_BOARD_KWORLD_TERMINATOR:
-               ir_codes     = avacssmart_codes;
+               ir_codes     = ir_codes_pixelview;
                mask_keycode = 0x00001f;
                mask_keyup   = 0x000060;
                polling      = 50; // ms
@@ -677,19 +198,19 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        case SAA7134_BOARD_MANLI_MTV001:
        case SAA7134_BOARD_MANLI_MTV002:
        case SAA7134_BOARD_BEHOLD_409FM:
-               ir_codes     = manli_codes;
+               ir_codes     = ir_codes_manli;
                mask_keycode = 0x001f00;
                mask_keyup   = 0x004000;
                polling      = 50; // ms
                break;
        case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
-               ir_codes     = pctv_sedna_codes;
+               ir_codes     = ir_codes_pctv_sedna;
                mask_keycode = 0x001f00;
                mask_keyup   = 0x004000;
                polling      = 50; // ms
                break;
        case SAA7134_BOARD_GOTVIEW_7135:
-               ir_codes     = gotview7135_codes;
+               ir_codes     = ir_codes_gotview7135;
                mask_keycode = 0x0003EC;
                mask_keyup   = 0x008000;
                mask_keydown = 0x000010;
@@ -698,17 +219,23 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        case SAA7134_BOARD_VIDEOMATE_TV_PVR:
        case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
        case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
-               ir_codes     = videomate_tv_pvr_codes;
+               ir_codes     = ir_codes_videomate_tv_pvr;
                mask_keycode = 0x00003F;
                mask_keyup   = 0x400000;
                polling      = 50; // ms
                break;
        case SAA7134_BOARD_VIDEOMATE_DVBT_300:
        case SAA7134_BOARD_VIDEOMATE_DVBT_200:
-               ir_codes     = videomate_tv_pvr_codes;
+               ir_codes     = ir_codes_videomate_tv_pvr;
                mask_keycode = 0x003F00;
                mask_keyup   = 0x040000;
                break;
+       case SAA7134_BOARD_FLYDVBT_LR301:
+       case SAA7134_BOARD_FLYDVBTDUO:
+               ir_codes     = ir_codes_flydvb;
+               mask_keycode = 0x0001F00;
+               mask_keydown = 0x0040000;
+               break;
        }
        if (NULL == ir_codes) {
                printk("%s: Oops: IR config error [card=%d]\n",
index 7448e386a804cf0f6b50f202859d2fb9bcadb65b..d79d05f88705026216e2efa3aa9a2de786268d32 100644 (file)
@@ -84,8 +84,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
 {
        int err;
 
-       if (!dev->dmasound.bufsize)
-               BUG();
+       BUG_ON(!dev->dmasound.bufsize);
        videobuf_dma_init(&dev->dmasound.dma);
        err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
                                       (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
@@ -96,8 +95,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
 
 static int dsp_buffer_free(struct saa7134_dev *dev)
 {
-       if (!dev->dmasound.blksize)
-               BUG();
+       BUG_ON(!dev->dmasound.blksize);
        videobuf_dma_free(&dev->dmasound.dma);
        dev->dmasound.blocks  = 0;
        dev->dmasound.blksize = 0;
@@ -254,7 +252,7 @@ static int dsp_open(struct inode *inode, struct file *file)
        if (NULL == dev)
                return -ENODEV;
 
-       down(&dev->dmasound.lock);
+       mutex_lock(&dev->dmasound.lock);
        err = -EBUSY;
        if (dev->dmasound.users_dsp)
                goto fail1;
@@ -270,13 +268,13 @@ static int dsp_open(struct inode *inode, struct file *file)
        if (0 != err)
                goto fail2;
 
-       up(&dev->dmasound.lock);
+       mutex_unlock(&dev->dmasound.lock);
        return 0;
 
  fail2:
        dev->dmasound.users_dsp--;
  fail1:
-       up(&dev->dmasound.lock);
+       mutex_unlock(&dev->dmasound.lock);
        return err;
 }
 
@@ -284,13 +282,13 @@ static int dsp_release(struct inode *inode, struct file *file)
 {
        struct saa7134_dev *dev = file->private_data;
 
-       down(&dev->dmasound.lock);
+       mutex_lock(&dev->dmasound.lock);
        if (dev->dmasound.recording_on)
                dsp_rec_stop(dev);
        dsp_buffer_free(dev);
        dev->dmasound.users_dsp--;
        file->private_data = NULL;
-       up(&dev->dmasound.lock);
+       mutex_unlock(&dev->dmasound.lock);
        return 0;
 }
 
@@ -304,7 +302,7 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
        int err,ret = 0;
 
        add_wait_queue(&dev->dmasound.wq, &wait);
-       down(&dev->dmasound.lock);
+       mutex_lock(&dev->dmasound.lock);
        while (count > 0) {
                /* wait for data if needed */
                if (0 == dev->dmasound.read_count) {
@@ -328,12 +326,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
                                        ret = -EAGAIN;
                                break;
                        }
-                       up(&dev->dmasound.lock);
+                       mutex_unlock(&dev->dmasound.lock);
                        set_current_state(TASK_INTERRUPTIBLE);
                        if (0 == dev->dmasound.read_count)
                                schedule();
                        set_current_state(TASK_RUNNING);
-                       down(&dev->dmasound.lock);
+                       mutex_lock(&dev->dmasound.lock);
                        if (signal_pending(current)) {
                                if (0 == ret)
                                        ret = -EINTR;
@@ -362,7 +360,7 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
                if (dev->dmasound.read_offset == dev->dmasound.bufsize)
                        dev->dmasound.read_offset = 0;
        }
-       up(&dev->dmasound.lock);
+       mutex_unlock(&dev->dmasound.lock);
        remove_wait_queue(&dev->dmasound.wq, &wait);
        return ret;
 }
@@ -435,13 +433,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
        case SNDCTL_DSP_STEREO:
                if (get_user(val, p))
                        return -EFAULT;
-               down(&dev->dmasound.lock);
+               mutex_lock(&dev->dmasound.lock);
                dev->dmasound.channels = val ? 2 : 1;
                if (dev->dmasound.recording_on) {
                        dsp_rec_stop(dev);
                        dsp_rec_start(dev);
                }
-               up(&dev->dmasound.lock);
+               mutex_unlock(&dev->dmasound.lock);
                return put_user(dev->dmasound.channels-1, p);
 
        case SNDCTL_DSP_CHANNELS:
@@ -449,13 +447,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
                        return -EFAULT;
                if (val != 1 && val != 2)
                        return -EINVAL;
-               down(&dev->dmasound.lock);
+               mutex_lock(&dev->dmasound.lock);
                dev->dmasound.channels = val;
                if (dev->dmasound.recording_on) {
                        dsp_rec_stop(dev);
                        dsp_rec_start(dev);
                }
-               up(&dev->dmasound.lock);
+               mutex_unlock(&dev->dmasound.lock);
                /* fall through */
        case SOUND_PCM_READ_CHANNELS:
                return put_user(dev->dmasound.channels, p);
@@ -478,13 +476,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
                case AFMT_U16_BE:
                case AFMT_S16_LE:
                case AFMT_S16_BE:
-                       down(&dev->dmasound.lock);
+                       mutex_lock(&dev->dmasound.lock);
                        dev->dmasound.afmt = val;
                        if (dev->dmasound.recording_on) {
                                dsp_rec_stop(dev);
                                dsp_rec_start(dev);
                        }
-                       up(&dev->dmasound.lock);
+                       mutex_unlock(&dev->dmasound.lock);
                        return put_user(dev->dmasound.afmt, p);
                default:
                        return -EINVAL;
@@ -509,10 +507,10 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
                return 0;
 
        case SNDCTL_DSP_RESET:
-               down(&dev->dmasound.lock);
+               mutex_lock(&dev->dmasound.lock);
                if (dev->dmasound.recording_on)
                        dsp_rec_stop(dev);
-               up(&dev->dmasound.lock);
+               mutex_unlock(&dev->dmasound.lock);
                return 0;
        case SNDCTL_DSP_GETBLKSIZE:
                return put_user(dev->dmasound.blksize, p);
@@ -556,10 +554,10 @@ static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
        poll_wait(file, &dev->dmasound.wq, wait);
 
        if (0 == dev->dmasound.read_count) {
-               down(&dev->dmasound.lock);
+               mutex_lock(&dev->dmasound.lock);
                if (!dev->dmasound.recording_on)
                        dsp_rec_start(dev);
-               up(&dev->dmasound.lock);
+               mutex_unlock(&dev->dmasound.lock);
        } else
                mask |= (POLLIN | POLLRDNORM);
        return mask;
@@ -852,7 +850,7 @@ int saa7134_oss_init1(struct saa7134_dev *dev)
                return -1;
 
        /* general */
-       init_MUTEX(&dev->dmasound.lock);
+       mutex_init(&dev->dmasound.lock);
        init_waitqueue_head(&dev->dmasound.wq);
 
        switch (dev->pci->device) {
index afa4dcb3f96dde118b377034ddb2aede5016afc1..3043233a8b6e2d7e0f70cb159061e9cead7295db 100644 (file)
@@ -139,6 +139,12 @@ static struct saa7134_tvaudio tvaudio[] = {
                .carr1         = 6500,
                .carr2         = 5850,
                .mode          = TVAUDIO_NICAM_AM,
+       },{
+               .name          = "SECAM-L MONO",
+               .std           = V4L2_STD_SECAM,
+               .carr1         = 6500,
+               .carr2         = -1,
+               .mode          = TVAUDIO_AM_MONO,
        },{
                .name          = "SECAM-D/K",
                .std           = V4L2_STD_SECAM,
@@ -334,6 +340,12 @@ static void tvaudio_setmode(struct saa7134_dev *dev,
                saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT,  0xa1);
                saa_writeb(SAA7134_NICAM_CONFIG,              0x00);
                break;
+       case TVAUDIO_AM_MONO:
+               saa_writeb(SAA7134_DEMODULATOR,               0x12);
+               saa_writeb(SAA7134_DCXO_IDENT_CTRL,           0x00);
+               saa_writeb(SAA7134_FM_DEEMPHASIS,             0x44);
+               saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT,  0xa0);
+               break;
        case TVAUDIO_FM_SAT_STEREO:
                /* not implemented (yet) */
                break;
@@ -414,6 +426,7 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au
 
        switch (audio->mode) {
        case TVAUDIO_FM_MONO:
+       case TVAUDIO_AM_MONO:
                return V4L2_TUNER_SUB_MONO;
        case TVAUDIO_FM_K_STEREO:
        case TVAUDIO_FM_BG_STEREO:
@@ -480,6 +493,7 @@ static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au
 
        switch (audio->mode) {
        case TVAUDIO_FM_MONO:
+       case TVAUDIO_AM_MONO:
                /* nothing to do ... */
                break;
        case TVAUDIO_FM_K_STEREO:
index e97426bc85df6aece8d49fd7aa639a0a36b7b5f8..57a11e71d9969ec3b164c8fbf8876ee35fec85db 100644 (file)
@@ -460,17 +460,17 @@ static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int
                return 1;
 
        /* is it free? */
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        if (dev->resources & bit) {
                /* no, someone else uses it */
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        }
        /* it's free, grab it */
        fh->resources  |= bit;
        dev->resources |= bit;
        dprintk("res: get %d\n",bit);
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
        return 1;
 }
 
@@ -489,14 +489,13 @@ int res_locked(struct saa7134_dev *dev, unsigned int bit)
 static
 void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
 {
-       if ((fh->resources & bits) != bits)
-               BUG();
+       BUG_ON((fh->resources & bits) != bits);
 
-       down(&dev->lock);
+       mutex_lock(&dev->lock);
        fh->resources  &= ~bits;
        dev->resources &= ~bits;
        dprintk("res: put %d\n",bits);
-       up(&dev->lock);
+       mutex_unlock(&dev->lock);
 }
 
 /* ------------------------------------------------------------------ */
@@ -1340,21 +1339,21 @@ video_poll(struct file *file, struct poll_table_struct *wait)
                if (!list_empty(&fh->cap.stream))
                        buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
        } else {
-               down(&fh->cap.lock);
+               mutex_lock(&fh->cap.lock);
                if (UNSET == fh->cap.read_off) {
                        /* need to capture a new frame */
                        if (res_locked(fh->dev,RESOURCE_VIDEO)) {
-                               up(&fh->cap.lock);
+                               mutex_unlock(&fh->cap.lock);
                                return POLLERR;
                        }
                        if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
-                               up(&fh->cap.lock);
+                               mutex_unlock(&fh->cap.lock);
                                return POLLERR;
                        }
                        fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
                        fh->cap.read_off = 0;
                }
-               up(&fh->cap.lock);
+               mutex_unlock(&fh->cap.lock);
                buf = fh->cap.read_buf;
        }
 
@@ -1463,6 +1462,10 @@ static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
                        f->fmt.pix.height * f->fmt.pix.bytesperline;
                return 0;
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+               if (saa7134_no_overlay > 0) {
+                       printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+                       return -EINVAL;
+               }
                f->fmt.win = fh->win;
                return 0;
        case V4L2_BUF_TYPE_VBI_CAPTURE:
@@ -1527,6 +1530,10 @@ static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
                return 0;
        }
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+               if (saa7134_no_overlay > 0) {
+                       printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+                       return -EINVAL;
+               }
                err = verify_preview(dev,&f->fmt.win);
                if (0 != err)
                        return err;
@@ -1557,18 +1564,22 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
                fh->cap.field = f->fmt.pix.field;
                return 0;
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+               if (saa7134_no_overlay > 0) {
+                       printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+                       return -EINVAL;
+               }
                err = verify_preview(dev,&f->fmt.win);
                if (0 != err)
                        return err;
 
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                fh->win    = f->fmt.win;
                fh->nclips = f->fmt.win.clipcount;
                if (fh->nclips > 8)
                        fh->nclips = 8;
                if (copy_from_user(fh->clips,f->fmt.win.clips,
                                   sizeof(struct v4l2_clip)*fh->nclips)) {
-                       up(&dev->lock);
+                       mutex_unlock(&dev->lock);
                        return -EFAULT;
                }
 
@@ -1578,7 +1589,7 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
                        start_preview(dev,fh);
                        spin_unlock_irqrestore(&dev->slock,flags);
                }
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        case V4L2_BUF_TYPE_VBI_CAPTURE:
                saa7134_vbi_fmt(dev,f);
@@ -1612,9 +1623,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev,
                return get_control(dev,arg);
        case VIDIOC_S_CTRL:
        {
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                err = set_control(dev,NULL,arg);
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return err;
        }
        /* --- input switching --------------------------------------- */
@@ -1664,9 +1675,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev,
                        return -EINVAL;
                if (NULL == card_in(dev,*i).name)
                        return -EINVAL;
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                video_mux(dev,*i);
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        }
 
@@ -1716,11 +1727,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                cap->version = SAA7134_VERSION_CODE;
                cap->capabilities =
                        V4L2_CAP_VIDEO_CAPTURE |
-                       V4L2_CAP_VIDEO_OVERLAY |
                        V4L2_CAP_VBI_CAPTURE |
                        V4L2_CAP_READWRITE |
                        V4L2_CAP_STREAMING |
                        V4L2_CAP_TUNER;
+               if (saa7134_no_overlay <= 0) {
+                       cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
+               }
 
                if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
                        cap->capabilities &= ~V4L2_CAP_TUNER;
@@ -1766,7 +1779,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                if (i == TVNORMS)
                        return -EINVAL;
 
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                if (res_check(fh, RESOURCE_OVERLAY)) {
                        spin_lock_irqsave(&dev->slock,flags);
                        stop_preview(dev,fh);
@@ -1776,7 +1789,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                } else
                        set_tvnorm(dev,&tvnorms[i]);
                saa7134_tvaudio_do_scan(dev);
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        }
 
@@ -1909,13 +1922,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                        return -EINVAL;
                if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
                        return -EINVAL;
-               down(&dev->lock);
+               mutex_lock(&dev->lock);
                dev->ctl_freq = f->frequency;
 
                saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);
 
                saa7134_tvaudio_do_scan(dev);
-               up(&dev->lock);
+               mutex_unlock(&dev->lock);
                return 0;
        }
 
@@ -1971,6 +1984,10 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                switch (type) {
                case V4L2_BUF_TYPE_VIDEO_CAPTURE:
                case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+                       if (saa7134_no_overlay > 0) {
+                               printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+                               return -EINVAL;
+                       }
                        if (index >= FORMATS)
                                return -EINVAL;
                        if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY &&
@@ -2031,6 +2048,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                int *on = arg;
 
                if (*on) {
+                       if (saa7134_no_overlay > 0) {
+                               printk ("no_overlay\n");
+                               return -EINVAL;
+                       }
+
                        if (!res_get(dev,fh,RESOURCE_OVERLAY))
                                return -EBUSY;
                        spin_lock_irqsave(&dev->slock,flags);
@@ -2282,7 +2304,7 @@ static struct file_operations radio_fops =
 struct video_device saa7134_video_template =
 {
        .name          = "saa7134-video",
-       .type          = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
+       .type          = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
                         VID_TYPE_CLIPPING|VID_TYPE_SCALES,
        .hardware      = 0,
        .fops          = &video_fops,
index 3261d8bebdd1ce828611708b2ba566fa6d41f6ad..17ba34f30760e915dff740505c44281f8a9ce486 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/input.h>
 #include <linux/notifier.h>
 #include <linux/delay.h>
+#include <linux/mutex.h>
 
 #include <asm/io.h>
 
@@ -60,6 +61,7 @@ enum saa7134_tvaudio_mode {
        TVAUDIO_FM_K_STEREO   = 4,
        TVAUDIO_NICAM_AM      = 5,
        TVAUDIO_NICAM_FM      = 6,
+       TVAUDIO_AM_MONO       = 7
 };
 
 enum saa7134_audio_in {
@@ -210,6 +212,15 @@ struct saa7134_format {
 #define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS  82
 #define SAA7134_BOARD_CINERGY250PCI 83
 #define SAA7134_BOARD_FLYDVB_TRIO 84
+#define SAA7134_BOARD_AVERMEDIA_777 85
+#define SAA7134_BOARD_FLYDVBT_LR301 86
+#define SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331 87
+#define SAA7134_BOARD_TEVION_DVBT_220RF 88
+#define SAA7134_BOARD_ELSA_700TV       89
+#define SAA7134_BOARD_KWORLD_ATSC110   90
+#define SAA7134_BOARD_AVERMEDIA_A169_B 91
+#define SAA7134_BOARD_AVERMEDIA_A169_B1 92
+#define SAA7134_BOARD_MD7134_BRIDGE_2     93
 
 #define SAA7134_MAXBOARDS 8
 #define SAA7134_INPUT_MAX 8
@@ -359,7 +370,7 @@ struct saa7134_fh {
 
 /* dmasound dsp status */
 struct saa7134_dmasound {
-       struct semaphore           lock;
+       struct mutex               lock;
        int                        minor_mixer;
        int                        minor_dsp;
        unsigned int               users_dsp;
@@ -423,7 +434,7 @@ struct saa7134_mpeg_ops {
 /* global device status */
 struct saa7134_dev {
        struct list_head           devlist;
-       struct semaphore           lock;
+       struct mutex               lock;
        spinlock_t                 slock;
 #ifdef VIDIOC_G_PRIORITY
        struct v4l2_prio_state     prio;
@@ -546,6 +557,7 @@ struct saa7134_dev {
 /* saa7134-core.c                                              */
 
 extern struct list_head  saa7134_devlist;
+extern int saa7134_no_overlay;
 
 void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
 
index a796a4e1917cb04ed1356f20028cf5cc91805cd7..027c8a074dfe6bc2d0fcaee90b3c230bfbda6366 100644 (file)
@@ -281,7 +281,7 @@ static void tda827xa_agcf(struct i2c_client *c)
 static void tda8290_i2c_bridge(struct i2c_client *c, int close)
 {
        unsigned char  enable[2] = { 0x21, 0xC0 };
-       unsigned char disable[2] = { 0x21, 0x80 };
+       unsigned char disable[2] = { 0x21, 0x00 };
        unsigned char *msg;
        if(close) {
                msg = enable;
@@ -302,6 +302,7 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
        unsigned char soft_reset[]  = { 0x00, 0x00 };
        unsigned char easy_mode[]   = { 0x01, t->tda8290_easy_mode };
        unsigned char expert_mode[] = { 0x01, 0x80 };
+       unsigned char agc_out_on[]  = { 0x02, 0x00 };
        unsigned char gainset_off[] = { 0x28, 0x14 };
        unsigned char if_agc_spd[]  = { 0x0f, 0x88 };
        unsigned char adc_head_6[]  = { 0x05, 0x04 };
@@ -320,6 +321,7 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
                      pll_stat;
 
        i2c_master_send(c, easy_mode, 2);
+       i2c_master_send(c, agc_out_on, 2);
        i2c_master_send(c, soft_reset, 2);
        msleep(1);
 
@@ -470,6 +472,7 @@ static void standby(struct i2c_client *c)
        struct tuner *t = i2c_get_clientdata(c);
        unsigned char cb1[] = { 0x30, 0xD0 };
        unsigned char tda8290_standby[] = { 0x00, 0x02 };
+       unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
        struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
 
        tda8290_i2c_bridge(c, 1);
@@ -477,6 +480,7 @@ static void standby(struct i2c_client *c)
                cb1[1] = 0x90;
        i2c_transfer(c->adapter, &msg, 1);
        tda8290_i2c_bridge(c, 0);
+       i2c_master_send(c, tda8290_agc_tri, 2);
        i2c_master_send(c, tda8290_standby, 2);
 }
 
@@ -565,7 +569,7 @@ int tda8290_init(struct i2c_client *c)
                strlcpy(c->name, "tda8290+75a", sizeof(c->name));
                t->tda827x_ver = 2;
        }
-       tuner_info("tuner: type set to %s\n", c->name);
+       tuner_info("type set to %s\n", c->name);
 
        t->set_tv_freq    = set_tv_freq;
        t->set_radio_freq = set_radio_freq;
index ed4c04119ccc11aa06a119a669fe073f3e567aa4..0243700f58ae28579008a9309e68af434d857946 100644 (file)
@@ -24,6 +24,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   */
 
+
 #include <linux/module.h>
 #include <linux/ioctl.h>
 #include <linux/i2c.h>
@@ -222,7 +223,7 @@ static int detach(struct i2c_client *client)
 
 static struct i2c_driver driver = {
        .driver = {
-               .name   = "tda9840",
+               .name = "tda9840",
        },
        .id     = I2C_DRIVERID_TDA9840,
        .attach_adapter = attach,
index bb35844e3842a2e192b140d8e685670567b24321..774ed0dbc56d85a3ff10a536f8cd6c47e4714093 100644 (file)
@@ -26,6 +26,7 @@
     Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA.
   */
 
+
 #include <linux/module.h>
 #include <linux/ioctl.h>
 #include <linux/i2c.h>
@@ -107,7 +108,7 @@ static int switch_matrix(struct i2c_client *client, int i, int o)
 {
        u8 byte = 0;
        int ret;
-       
+
        dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o);
 
        /* check if the pins are valid */
@@ -191,7 +192,7 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg)
 
 static struct i2c_driver driver = {
        .driver = {
-               .name   = "tea6415c",
+               .name = "tea6415c",
        },
        .id     = I2C_DRIVERID_TEA6415C,
        .attach_adapter = attach,
index 4dcba5a4fff099d95a19b61391c4925e6df47f92..ad7d2872cfbfb33c3b42e20d63ee74f24a4e0b6c 100644 (file)
@@ -26,6 +26,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   */
 
+
 #include <linux/module.h>
 #include <linux/ioctl.h>
 #include <linux/i2c.h>
@@ -83,7 +84,7 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
                dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret);
                return -EIO;
        }
-       
+
        return 0;
 }
 
@@ -167,7 +168,7 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg)
 
 static struct i2c_driver driver = {
        .driver = {
-               .name   = "tea6420",
+               .name = "tea6420",
        },
        .id     = I2C_DRIVERID_TEA6420,
        .attach_adapter = attach,
index b6101bf446d4897e62d85e215ae27e290140087c..32e1849441fb45947bd5b2be561bed1e6950d048 100644 (file)
@@ -173,7 +173,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
        }
 
        t->type = type;
-
        switch (t->type) {
        case TUNER_MT2032:
                microtune_init(c);
@@ -404,15 +403,16 @@ static void tuner_status(struct i2c_client *client)
        tuner_info("Tuner mode:      %s\n", p);
        tuner_info("Frequency:       %lu.%02lu MHz\n", freq, freq_fraction);
        tuner_info("Standard:        0x%08llx\n", t->std);
-       if (t->mode == V4L2_TUNER_RADIO) {
-               if (t->has_signal) {
-                       tuner_info("Signal strength: %d\n", t->has_signal(client));
-               }
-               if (t->is_stereo) {
-                       tuner_info("Stereo:          %s\n", t->is_stereo(client) ? "yes" : "no");
-               }
+       if (t->mode != V4L2_TUNER_RADIO)
+              return;
+       if (t->has_signal) {
+               tuner_info("Signal strength: %d\n", t->has_signal(client));
+       }
+       if (t->is_stereo) {
+               tuner_info("Stereo:          %s\n", t->is_stereo(client) ? "yes" : "no");
        }
 }
+
 /* ---------------------------------------------------------------------- */
 
 /* static var Used only in tuner_attach and tuner_probe */
@@ -744,33 +744,29 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                                return 0;
                        switch_v4l2();
 
-                       if (V4L2_TUNER_RADIO == t->mode) {
-
-                               if (t->has_signal)
-                                       tuner->signal = t->has_signal(client);
-
-                               if (t->is_stereo) {
-                                       if (t->is_stereo(client)) {
-                                               tuner->rxsubchans =
-                                                   V4L2_TUNER_SUB_STEREO |
-                                                   V4L2_TUNER_SUB_MONO;
-                                       } else {
-                                               tuner->rxsubchans =
-                                                   V4L2_TUNER_SUB_MONO;
-                                       }
-                               }
-
-                               tuner->capability |=
-                                   V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
-
-                               tuner->audmode = t->audmode;
-
-                               tuner->rangelow = radio_range[0] * 16000;
-                               tuner->rangehigh = radio_range[1] * 16000;
-                       } else {
+                       tuner->type = t->mode;
+                       if (t->mode != V4L2_TUNER_RADIO) {
                                tuner->rangelow = tv_range[0] * 16;
                                tuner->rangehigh = tv_range[1] * 16;
+                               break;
                        }
+
+                       /* radio mode */
+                       if (t->has_signal)
+                               tuner->signal = t->has_signal(client);
+
+                       tuner->rxsubchans =
+                               V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+                       if (t->is_stereo) {
+                               tuner->rxsubchans = t->is_stereo(client) ?
+                                       V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
+                       }
+
+                       tuner->capability |=
+                           V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+                       tuner->audmode = t->audmode;
+                       tuner->rangelow = radio_range[0] * 16000;
+                       tuner->rangehigh = radio_range[1] * 16000;
                        break;
                }
        case VIDIOC_S_TUNER:
@@ -782,10 +778,11 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
 
                        switch_v4l2();
 
-                       if (V4L2_TUNER_RADIO == t->mode) {
-                               t->audmode = tuner->audmode;
-                               set_radio_freq(client, t->radio_freq);
-                       }
+                       /* do nothing unless we're a radio tuner */
+                       if (t->mode != V4L2_TUNER_RADIO)
+                               break;
+                       t->audmode = tuner->audmode;
+                       set_radio_freq(client, t->radio_freq);
                        break;
                }
        case VIDIOC_LOG_STATUS:
index 37977ff49780f61477bfcc45fd69362d8044aa09..5d7abed71674f179ee6797a21b33ab89ee4ea5ff 100644 (file)
@@ -79,17 +79,6 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner");
 #define TUNER_PLL_LOCKED   0x40
 #define TUNER_STEREO_MK3   0x04
 
-#define TUNER_PARAM_ANALOG 0  /* to be removed */
-/* FIXME:
- * Right now, all tuners are using the first tuner_params[] array element
- * for analog mode. In the future, we will be merging similar tuner
- * definitions together, such that each tuner definition will have a
- * tuner_params struct for each available video standard. At that point,
- * TUNER_PARAM_ANALOG will be removed, and the tuner_params[] array
- * element will be chosen based on the video standard in use.
- *
- */
-
 /* ---------------------------------------------------------------------- */
 
 static int tuner_getstatus(struct i2c_client *c)
@@ -133,14 +122,53 @@ static int tuner_stereo(struct i2c_client *c)
 static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
 {
        struct tuner *t = i2c_get_clientdata(c);
-       u8 config, tuneraddr;
+       u8 config, cb, tuneraddr;
        u16 div;
        struct tunertype *tun;
        u8 buffer[4];
        int rc, IFPCoff, i, j;
+       enum param_type desired_type;
 
        tun = &tuners[t->type];
-       j = TUNER_PARAM_ANALOG;
+
+       /* IFPCoff = Video Intermediate Frequency - Vif:
+               940  =16*58.75  NTSC/J (Japan)
+               732  =16*45.75  M/N STD
+               704  =16*44     ATSC (at DVB code)
+               632  =16*39.50  I U.K.
+               622.4=16*38.90  B/G D/K I, L STD
+               592  =16*37.00  D China
+               590  =16.36.875 B Australia
+               543.2=16*33.95  L' STD
+               171.2=16*10.70  FM Radio (at set_radio_freq)
+       */
+
+       if (t->std == V4L2_STD_NTSC_M_JP) {
+               IFPCoff      = 940;
+               desired_type = TUNER_PARAM_TYPE_NTSC;
+       } else if ((t->std & V4L2_STD_MN) &&
+                 !(t->std & ~V4L2_STD_MN)) {
+               IFPCoff      = 732;
+               desired_type = TUNER_PARAM_TYPE_NTSC;
+       } else if (t->std == V4L2_STD_SECAM_LC) {
+               IFPCoff      = 543;
+               desired_type = TUNER_PARAM_TYPE_SECAM;
+       } else {
+               IFPCoff      = 623;
+               desired_type = TUNER_PARAM_TYPE_PAL;
+       }
+
+       for (j = 0; j < tun->count-1; j++) {
+               if (desired_type != tun->params[j].type)
+                       continue;
+               break;
+       }
+       /* use default tuner_params if desired_type not available */
+       if (desired_type != tun->params[j].type) {
+               tuner_dbg("IFPCoff = %d: tuner_params undefined for tuner %d\n",
+                         IFPCoff,t->type);
+               j = 0;
+       }
 
        for (i = 0; i < tun->params[j].count; i++) {
                if (freq > tun->params[j].ranges[i].limit)
@@ -152,11 +180,20 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                                freq, tun->params[j].ranges[i - 1].limit);
                freq = tun->params[j].ranges[--i].limit;
        }
-       config = tun->params[j].ranges[i].cb;
-       /*  i == 0 -> VHF_LO  */
-       /*  i == 1 -> VHF_HI  */
-       /*  i == 2 -> UHF     */
-       tuner_dbg("tv: range %d\n",i);
+       config = tun->params[j].ranges[i].config;
+       cb     = tun->params[j].ranges[i].cb;
+       /*  i == 0 -> VHF_LO
+        *  i == 1 -> VHF_HI
+        *  i == 2 -> UHF     */
+       tuner_dbg("tv: param %d, range %d\n",j,i);
+
+       div=freq + IFPCoff + offset;
+
+       tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n",
+                                       freq / 16, freq % 16 * 100 / 16,
+                                       IFPCoff / 16, IFPCoff % 16 * 100 / 16,
+                                       offset / 16, offset % 16 * 100 / 16,
+                                       div);
 
        /* tv norm specific stuff for multi-norm tuners */
        switch (t->type) {
@@ -164,40 +201,40 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                /* 0x01 -> ??? no change ??? */
                /* 0x02 -> PAL BDGHI / SECAM L */
                /* 0x04 -> ??? PAL others / SECAM others ??? */
-               config &= ~0x02;
+               cb &= ~0x02;
                if (t->std & V4L2_STD_SECAM)
-                       config |= 0x02;
+                       cb |= 0x02;
                break;
 
        case TUNER_TEMIC_4046FM5:
-               config &= ~0x0f;
+               cb &= ~0x0f;
 
                if (t->std & V4L2_STD_PAL_BG) {
-                       config |= TEMIC_SET_PAL_BG;
+                       cb |= TEMIC_SET_PAL_BG;
 
                } else if (t->std & V4L2_STD_PAL_I) {
-                       config |= TEMIC_SET_PAL_I;
+                       cb |= TEMIC_SET_PAL_I;
 
                } else if (t->std & V4L2_STD_PAL_DK) {
-                       config |= TEMIC_SET_PAL_DK;
+                       cb |= TEMIC_SET_PAL_DK;
 
                } else if (t->std & V4L2_STD_SECAM_L) {
-                       config |= TEMIC_SET_PAL_L;
+                       cb |= TEMIC_SET_PAL_L;
 
                }
                break;
 
        case TUNER_PHILIPS_FQ1216ME:
-               config &= ~0x0f;
+               cb &= ~0x0f;
 
                if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
-                       config |= PHILIPS_SET_PAL_BGDK;
+                       cb |= PHILIPS_SET_PAL_BGDK;
 
                } else if (t->std & V4L2_STD_PAL_I) {
-                       config |= PHILIPS_SET_PAL_I;
+                       cb |= PHILIPS_SET_PAL_I;
 
                } else if (t->std & V4L2_STD_SECAM_L) {
-                       config |= PHILIPS_SET_PAL_L;
+                       cb |= PHILIPS_SET_PAL_L;
 
                }
                break;
@@ -207,15 +244,15 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                /* 0x01 -> ATSC antenna input 2 */
                /* 0x02 -> NTSC antenna input 1 */
                /* 0x03 -> NTSC antenna input 2 */
-               config &= ~0x03;
+               cb &= ~0x03;
                if (!(t->std & V4L2_STD_ATSC))
-                       config |= 2;
+                       cb |= 2;
                /* FIXME: input */
                break;
 
        case TUNER_MICROTUNE_4042FI5:
                /* Set the charge pump for fast tuning */
-               tun->params[j].config |= TUNER_CHARGE_PUMP;
+               config |= TUNER_CHARGE_PUMP;
                break;
 
        case TUNER_PHILIPS_TUV1236D:
@@ -227,9 +264,9 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                buffer[1] = 0x00;
                buffer[2] = 0x17;
                buffer[3] = 0x00;
-               config &= ~0x40;
+               cb &= ~0x40;
                if (t->std & V4L2_STD_ATSC) {
-                       config |= 0x40;
+                       cb |= 0x40;
                        buffer[1] = 0x04;
                }
                /* set to the correct mode (analog or digital) */
@@ -244,47 +281,16 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                break;
        }
 
-       /* IFPCoff = Video Intermediate Frequency - Vif:
-               940  =16*58.75  NTSC/J (Japan)
-               732  =16*45.75  M/N STD
-               704  =16*44     ATSC (at DVB code)
-               632  =16*39.50  I U.K.
-               622.4=16*38.90  B/G D/K I, L STD
-               592  =16*37.00  D China
-               590  =16.36.875 B Australia
-               543.2=16*33.95  L' STD
-               171.2=16*10.70  FM Radio (at set_radio_freq)
-       */
-
-       if (t->std == V4L2_STD_NTSC_M_JP) {
-               IFPCoff = 940;
-       } else if ((t->std & V4L2_STD_MN) &&
-                 !(t->std & ~V4L2_STD_MN)) {
-               IFPCoff = 732;
-       } else if (t->std == V4L2_STD_SECAM_LC) {
-               IFPCoff = 543;
-       } else {
-               IFPCoff = 623;
-       }
-
-       div=freq + IFPCoff + offset;
-
-       tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n",
-                                       freq / 16, freq % 16 * 100 / 16,
-                                       IFPCoff / 16, IFPCoff % 16 * 100 / 16,
-                                       offset / 16, offset % 16 * 100 / 16,
-                                       div);
-
        if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) {
-               buffer[0] = tun->params[j].config;
-               buffer[1] = config;
+               buffer[0] = config;
+               buffer[1] = cb;
                buffer[2] = (div>>8) & 0x7f;
                buffer[3] = div      & 0xff;
        } else {
                buffer[0] = (div>>8) & 0x7f;
                buffer[1] = div      & 0xff;
-               buffer[2] = tun->params[j].config;
-               buffer[3] = config;
+               buffer[2] = config;
+               buffer[3] = cb;
        }
        t->last_div = div;
        tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
@@ -312,11 +318,11 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                }
 
                /* Set the charge pump for optimized phase noise figure */
-               tun->params[j].config &= ~TUNER_CHARGE_PUMP;
+               config &= ~TUNER_CHARGE_PUMP;
                buffer[0] = (div>>8) & 0x7f;
                buffer[1] = div      & 0xff;
-               buffer[2] = tun->params[j].config;
-               buffer[3] = config;
+               buffer[2] = config;
+               buffer[3] = cb;
                tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
                       buffer[0],buffer[1],buffer[2],buffer[3]);
 
@@ -332,12 +338,21 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
        u8 buffer[4];
        u16 div;
        int rc, j;
+       enum param_type desired_type = TUNER_PARAM_TYPE_RADIO;
 
        tun = &tuners[t->type];
-       j = TUNER_PARAM_ANALOG;
+
+       for (j = 0; j < tun->count-1; j++) {
+               if (desired_type != tun->params[j].type)
+                       continue;
+               break;
+       }
+       /* use default tuner_params if desired_type not available */
+       if (desired_type != tun->params[j].type)
+               j = 0;
 
        div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */
-       buffer[2] = (tun->params[j].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
+       buffer[2] = (tun->params[j].ranges[0].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
 
        switch (t->type) {
        case TUNER_TENA_9533_DI:
@@ -349,6 +364,9 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
        case TUNER_PHILIPS_FMD1216ME_MK3:
                buffer[3] = 0x19;
                break;
+       case TUNER_TNF_5335MF:
+               buffer[3] = 0x11;
+               break;
        case TUNER_PHILIPS_FM1256_IH3:
                div = (20 * freq) / 16000 + (int)(33.3 * 20);  /* IF 33.3 MHz */
                buffer[3] = 0x19;
index 6fe781798d89e14dcea1a2b00f6165afa9ca7ad3..72e0f01db563597315d3811ef5854a46cde8b912 100644 (file)
  *     Each tuner_params array may contain one or more elements, one
  *     for each video standard.
  *
- *     FIXME: Some tuner_range definitions are duplicated, and
- *     should be eliminated.
+ *     FIXME: tuner_params struct contains an element, tda988x. We must
+ *     set this for all tuners that contain a tda988x chip, and then we
+ *     can remove this setting from the various card structs.
  *
- *     FIXME: tunertype struct contains an element, has_tda988x.
- *     We must set this for all tunertypes that contain a tda988x
- *     chip, and then we can remove this setting from the various
- *     card structs.
+ *     FIXME: Right now, all tuners are using the first tuner_params[]
+ *     array element for analog mode. In the future, we will be merging
+ *     similar tuner definitions together, such that each tuner definition
+ *     will have a tuner_params struct for each available video standard.
+ *     At that point, the tuner_params[] array element will be chosen
+ *     based on the video standard in use.
  */
 
 /* 0-9 */
 /* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */
 
 static struct tuner_range tuner_temic_pal_ranges[] = {
-       { 16 * 140.25 /*MHz*/, 0x02, },
-       { 16 * 463.25 /*MHz*/, 0x04, },
-       { 16 * 999.99        , 0x01, },
+       { 16 * 140.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0x04, },
+       { 16 * 999.99        , 0x8e, 0x01, },
 };
 
 static struct tuner_params tuner_temic_pal_params[] = {
@@ -46,16 +49,15 @@ static struct tuner_params tuner_temic_pal_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_temic_pal_ranges,
                .count  = ARRAY_SIZE(tuner_temic_pal_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_PHILIPS_PAL_I - Philips PAL_I ------------ */
 
 static struct tuner_range tuner_philips_pal_i_ranges[] = {
-       { 16 * 140.25 /*MHz*/, 0xa0, },
-       { 16 * 463.25 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+       { 16 * 140.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_philips_pal_i_params[] = {
@@ -63,16 +65,15 @@ static struct tuner_params tuner_philips_pal_i_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_philips_pal_i_ranges,
                .count  = ARRAY_SIZE(tuner_philips_pal_i_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_PHILIPS_NTSC - Philips NTSC ------------ */
 
 static struct tuner_range tuner_philips_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0xa0, },
-       { 16 * 451.25 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+       { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 451.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_philips_ntsc_params[] = {
@@ -80,7 +81,6 @@ static struct tuner_params tuner_philips_ntsc_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_philips_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_philips_ntsc_ranges),
-               .config = 0x8e,
                .cb_first_if_lower_freq = 1,
        },
 };
@@ -88,9 +88,9 @@ static struct tuner_params tuner_philips_ntsc_params[] = {
 /* ------------ TUNER_PHILIPS_SECAM - Philips SECAM ------------ */
 
 static struct tuner_range tuner_philips_secam_ranges[] = {
-       { 16 * 168.25 /*MHz*/, 0xa7, },
-       { 16 * 447.25 /*MHz*/, 0x97, },
-       { 16 * 999.99        , 0x37, },
+       { 16 * 168.25 /*MHz*/, 0x8e, 0xa7, },
+       { 16 * 447.25 /*MHz*/, 0x8e, 0x97, },
+       { 16 * 999.99        , 0x8e, 0x37, },
 };
 
 static struct tuner_params tuner_philips_secam_params[] = {
@@ -98,7 +98,6 @@ static struct tuner_params tuner_philips_secam_params[] = {
                .type   = TUNER_PARAM_TYPE_SECAM,
                .ranges = tuner_philips_secam_ranges,
                .count  = ARRAY_SIZE(tuner_philips_secam_ranges),
-               .config = 0x8e,
                .cb_first_if_lower_freq = 1,
        },
 };
@@ -106,9 +105,9 @@ static struct tuner_params tuner_philips_secam_params[] = {
 /* ------------ TUNER_PHILIPS_PAL - Philips PAL ------------ */
 
 static struct tuner_range tuner_philips_pal_ranges[] = {
-       { 16 * 168.25 /*MHz*/, 0xa0, },
-       { 16 * 447.25 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+       { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 447.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_philips_pal_params[] = {
@@ -116,7 +115,6 @@ static struct tuner_params tuner_philips_pal_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_philips_pal_ranges,
                .count  = ARRAY_SIZE(tuner_philips_pal_ranges),
-               .config = 0x8e,
                .cb_first_if_lower_freq = 1,
        },
 };
@@ -124,9 +122,9 @@ static struct tuner_params tuner_philips_pal_params[] = {
 /* ------------ TUNER_TEMIC_NTSC - TEMIC NTSC ------------ */
 
 static struct tuner_range tuner_temic_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0x02, },
-       { 16 * 463.25 /*MHz*/, 0x04, },
-       { 16 * 999.99        , 0x01, },
+       { 16 * 157.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0x04, },
+       { 16 * 999.99        , 0x8e, 0x01, },
 };
 
 static struct tuner_params tuner_temic_ntsc_params[] = {
@@ -134,16 +132,15 @@ static struct tuner_params tuner_temic_ntsc_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_temic_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_temic_ntsc_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_TEMIC_PAL_I - TEMIC PAL_I ------------ */
 
 static struct tuner_range tuner_temic_pal_i_ranges[] = {
-       { 16 * 170.00 /*MHz*/, 0x02, },
-       { 16 * 450.00 /*MHz*/, 0x04, },
-       { 16 * 999.99        , 0x01, },
+       { 16 * 170.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 450.00 /*MHz*/, 0x8e, 0x04, },
+       { 16 * 999.99        , 0x8e, 0x01, },
 };
 
 static struct tuner_params tuner_temic_pal_i_params[] = {
@@ -151,16 +148,15 @@ static struct tuner_params tuner_temic_pal_i_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_temic_pal_i_ranges,
                .count  = ARRAY_SIZE(tuner_temic_pal_i_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_TEMIC_4036FY5_NTSC - TEMIC NTSC ------------ */
 
 static struct tuner_range tuner_temic_4036fy5_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0xa0, },
-       { 16 * 463.25 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+       { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = {
@@ -168,16 +164,15 @@ static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_temic_4036fy5_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_ALPS_TSBH1_NTSC - TEMIC NTSC ------------ */
 
 static struct tuner_range tuner_alps_tsb_1_ranges[] = {
-       { 16 * 137.25 /*MHz*/, 0x01, },
-       { 16 * 385.25 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x08, },
+       { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 385.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
 };
 
 static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = {
@@ -185,7 +180,6 @@ static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_alps_tsb_1_ranges,
                .count  = ARRAY_SIZE(tuner_alps_tsb_1_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -197,16 +191,15 @@ static struct tuner_params tuner_alps_tsb_1_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_alps_tsb_1_ranges,
                .count  = ARRAY_SIZE(tuner_alps_tsb_1_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_ALPS_TSBB5_PAL_I - Alps PAL_I ------------ */
 
 static struct tuner_range tuner_alps_tsb_5_pal_ranges[] = {
-       { 16 * 133.25 /*MHz*/, 0x01, },
-       { 16 * 351.25 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x08, },
+       { 16 * 133.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 351.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
 };
 
 static struct tuner_params tuner_alps_tsbb5_params[] = {
@@ -214,7 +207,6 @@ static struct tuner_params tuner_alps_tsbb5_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_alps_tsb_5_pal_ranges,
                .count  = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -225,7 +217,6 @@ static struct tuner_params tuner_alps_tsbe5_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_alps_tsb_5_pal_ranges,
                .count  = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -236,33 +227,31 @@ static struct tuner_params tuner_alps_tsbc5_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_alps_tsb_5_pal_ranges,
                .count  = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_TEMIC_4006FH5_PAL - TEMIC PAL ------------ */
 
-static struct tuner_range tuner_temic_4006fh5_pal_ranges[] = {
-       { 16 * 170.00 /*MHz*/, 0xa0, },
-       { 16 * 450.00 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+static struct tuner_range tuner_lg_pal_ranges[] = {
+       { 16 * 170.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 450.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_temic_4006fh5_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_4006fh5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4006fh5_pal_ranges),
-               .config = 0x8e,
+               .ranges = tuner_lg_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
        },
 };
 
 /* ------------ TUNER_ALPS_TSHC6_NTSC - Alps NTSC ------------ */
 
 static struct tuner_range tuner_alps_tshc6_ntsc_ranges[] = {
-       { 16 * 137.25 /*MHz*/, 0x14, },
-       { 16 * 385.25 /*MHz*/, 0x12, },
-       { 16 * 999.99        , 0x11, },
+       { 16 * 137.25 /*MHz*/, 0x8e, 0x14, },
+       { 16 * 385.25 /*MHz*/, 0x8e, 0x12, },
+       { 16 * 999.99        , 0x8e, 0x11, },
 };
 
 static struct tuner_params tuner_alps_tshc6_params[] = {
@@ -270,16 +259,15 @@ static struct tuner_params tuner_alps_tshc6_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_alps_tshc6_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_alps_tshc6_ntsc_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_TEMIC_PAL_DK - TEMIC PAL ------------ */
 
 static struct tuner_range tuner_temic_pal_dk_ranges[] = {
-       { 16 * 168.25 /*MHz*/, 0xa0, },
-       { 16 * 456.25 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+       { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 456.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_temic_pal_dk_params[] = {
@@ -287,16 +275,15 @@ static struct tuner_params tuner_temic_pal_dk_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_temic_pal_dk_ranges,
                .count  = ARRAY_SIZE(tuner_temic_pal_dk_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_PHILIPS_NTSC_M - Philips NTSC ------------ */
 
 static struct tuner_range tuner_philips_ntsc_m_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0xa0, },
-       { 16 * 454.00 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+       { 16 * 160.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 454.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_philips_ntsc_m_params[] = {
@@ -304,16 +291,15 @@ static struct tuner_params tuner_philips_ntsc_m_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_philips_ntsc_m_ranges,
                .count  = ARRAY_SIZE(tuner_philips_ntsc_m_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_TEMIC_4066FY5_PAL_I - TEMIC PAL_I ------------ */
 
 static struct tuner_range tuner_temic_40x6f_5_pal_ranges[] = {
-       { 16 * 169.00 /*MHz*/, 0xa0, },
-       { 16 * 454.00 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+       { 16 * 169.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 454.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = {
@@ -321,7 +307,6 @@ static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_temic_40x6f_5_pal_ranges,
                .count  = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -332,7 +317,6 @@ static struct tuner_params tuner_temic_4006fn5_multi_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_temic_40x6f_5_pal_ranges,
                .count  = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -340,9 +324,9 @@ static struct tuner_params tuner_temic_4006fn5_multi_params[] = {
 /* ------------ TUNER_TEMIC_4009FR5_PAL - TEMIC PAL ------------ */
 
 static struct tuner_range tuner_temic_4009f_5_pal_ranges[] = {
-       { 16 * 141.00 /*MHz*/, 0xa0, },
-       { 16 * 464.00 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+       { 16 * 141.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 464.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_temic_4009f_5_params[] = {
@@ -350,58 +334,42 @@ static struct tuner_params tuner_temic_4009f_5_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_temic_4009f_5_pal_ranges,
                .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_TEMIC_4039FR5_NTSC - TEMIC NTSC ------------ */
 
-static struct tuner_range tuner_temic_4039fr5_ntsc_ranges[] = {
-       { 16 * 158.00 /*MHz*/, 0xa0, },
-       { 16 * 453.00 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+static struct tuner_range tuner_temic_4x3x_f_5_ntsc_ranges[] = {
+       { 16 * 158.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 453.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_temic_4039fr5_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_temic_4039fr5_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4039fr5_ntsc_ranges),
-               .config = 0x8e,
+               .ranges = tuner_temic_4x3x_f_5_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges),
        },
 };
 
 /* ------------ TUNER_TEMIC_4046FM5 - TEMIC PAL ------------ */
 
-static struct tuner_range tuner_temic_4046fm5_pal_ranges[] = {
-       { 16 * 169.00 /*MHz*/, 0xa0, },
-       { 16 * 454.00 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
-};
-
 static struct tuner_params tuner_temic_4046fm5_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_4046fm5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4046fm5_pal_ranges),
-               .config = 0x8e,
+               .ranges = tuner_temic_40x6f_5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
        },
 };
 
 /* ------------ TUNER_PHILIPS_PAL_DK - Philips PAL ------------ */
 
-static struct tuner_range tuner_lg_pal_ranges[] = {
-       { 16 * 170.00 /*MHz*/, 0xa0, },
-       { 16 * 450.00 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
-};
-
 static struct tuner_params tuner_philips_pal_dk_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_lg_pal_ranges,
                .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -412,7 +380,6 @@ static struct tuner_params tuner_philips_fq1216me_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_lg_pal_ranges,
                .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -423,7 +390,6 @@ static struct tuner_params tuner_lg_pal_i_fm_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_lg_pal_ranges,
                .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -434,16 +400,15 @@ static struct tuner_params tuner_lg_pal_i_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_lg_pal_ranges,
                .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_LG_NTSC_FM - LGINNOTEK NTSC ------------ */
 
 static struct tuner_range tuner_lg_ntsc_fm_ranges[] = {
-       { 16 * 210.00 /*MHz*/, 0xa0, },
-       { 16 * 497.00 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+       { 16 * 210.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 497.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_lg_ntsc_fm_params[] = {
@@ -451,7 +416,6 @@ static struct tuner_params tuner_lg_ntsc_fm_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_lg_ntsc_fm_ranges,
                .count  = ARRAY_SIZE(tuner_lg_ntsc_fm_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -462,7 +426,6 @@ static struct tuner_params tuner_lg_pal_fm_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_lg_pal_ranges,
                .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -473,7 +436,6 @@ static struct tuner_params tuner_lg_pal_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_lg_pal_ranges,
                .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -485,16 +447,15 @@ static struct tuner_params tuner_temic_4009_fn5_multi_pal_fm_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_temic_4009f_5_pal_ranges,
                .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_SHARP_2U5JF5540_NTSC - SHARP NTSC ------------ */
 
 static struct tuner_range tuner_sharp_2u5jf5540_ntsc_ranges[] = {
-       { 16 * 137.25 /*MHz*/, 0x01, },
-       { 16 * 317.25 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x08, },
+       { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 317.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
 };
 
 static struct tuner_params tuner_sharp_2u5jf5540_params[] = {
@@ -502,16 +463,15 @@ static struct tuner_params tuner_sharp_2u5jf5540_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_sharp_2u5jf5540_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_sharp_2u5jf5540_ntsc_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_Samsung_PAL_TCPM9091PD27 - Samsung PAL ------------ */
 
 static struct tuner_range tuner_samsung_pal_tcpm9091pd27_ranges[] = {
-       { 16 * 169 /*MHz*/, 0xa0, },
-       { 16 * 464 /*MHz*/, 0x90, },
-       { 16 * 999.99     , 0x30, },
+       { 16 * 169 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 464 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99     , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = {
@@ -519,7 +479,6 @@ static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_samsung_pal_tcpm9091pd27_ranges,
                .count  = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -530,50 +489,35 @@ static struct tuner_params tuner_temic_4106fh5_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_temic_4009f_5_pal_ranges,
                .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_TEMIC_4012FY5 - TEMIC PAL ------------ */
 
-static struct tuner_range tuner_temic_4012fy5_pal_ranges[] = {
-       { 16 * 140.25 /*MHz*/, 0x02, },
-       { 16 * 463.25 /*MHz*/, 0x04, },
-       { 16 * 999.99        , 0x01, },
-};
-
 static struct tuner_params tuner_temic_4012fy5_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_4012fy5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4012fy5_pal_ranges),
-               .config = 0x8e,
+               .ranges = tuner_temic_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_pal_ranges),
        },
 };
 
 /* ------------ TUNER_TEMIC_4136FY5 - TEMIC NTSC ------------ */
 
-static struct tuner_range tuner_temic_4136_fy5_ntsc_ranges[] = {
-       { 16 * 158.00 /*MHz*/, 0xa0, },
-       { 16 * 453.00 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
-};
-
 static struct tuner_params tuner_temic_4136_fy5_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_temic_4136_fy5_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4136_fy5_ntsc_ranges),
-               .config = 0x8e,
+               .ranges = tuner_temic_4x3x_f_5_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges),
        },
 };
 
 /* ------------ TUNER_LG_PAL_NEW_TAPC - LGINNOTEK PAL ------------ */
 
 static struct tuner_range tuner_lg_new_tapc_ranges[] = {
-       { 16 * 170.00 /*MHz*/, 0x01, },
-       { 16 * 450.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x08, },
+       { 16 * 170.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 450.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
 };
 
 static struct tuner_params tuner_lg_pal_new_tapc_params[] = {
@@ -581,16 +525,15 @@ static struct tuner_params tuner_lg_pal_new_tapc_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_lg_new_tapc_ranges,
                .count  = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_PHILIPS_FM1216ME_MK3 - Philips PAL ------------ */
 
 static struct tuner_range tuner_fm1216me_mk3_pal_ranges[] = {
-       { 16 * 158.00 /*MHz*/, 0x01, },
-       { 16 * 442.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x04, },
+       { 16 * 158.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 442.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x04, },
 };
 
 static struct tuner_params tuner_fm1216me_mk3_params[] = {
@@ -598,7 +541,6 @@ static struct tuner_params tuner_fm1216me_mk3_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_fm1216me_mk3_pal_ranges,
                .count  = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
-               .config = 0x8e,
                .cb_first_if_lower_freq = 1,
        },
 };
@@ -610,7 +552,6 @@ static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_lg_new_tapc_ranges,
                .count  = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -622,16 +563,15 @@ static struct tuner_params tuner_hitachi_ntsc_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_lg_new_tapc_ranges,
                .count  = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_PHILIPS_PAL_MK - Philips PAL ------------ */
 
 static struct tuner_range tuner_philips_pal_mk_pal_ranges[] = {
-       { 16 * 140.25 /*MHz*/, 0x01, },
-       { 16 * 463.25 /*MHz*/, 0xc2, },
-       { 16 * 999.99        , 0xcf, },
+       { 16 * 140.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0xc2, },
+       { 16 * 999.99        , 0x8e, 0xcf, },
 };
 
 static struct tuner_params tuner_philips_pal_mk_params[] = {
@@ -639,16 +579,15 @@ static struct tuner_params tuner_philips_pal_mk_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_philips_pal_mk_pal_ranges,
                .count  = ARRAY_SIZE(tuner_philips_pal_mk_pal_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_PHILIPS_ATSC - Philips ATSC ------------ */
 
 static struct tuner_range tuner_philips_atsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0xa0, },
-       { 16 * 454.00 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+       { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 454.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_philips_atsc_params[] = {
@@ -656,16 +595,15 @@ static struct tuner_params tuner_philips_atsc_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_philips_atsc_ranges,
                .count  = ARRAY_SIZE(tuner_philips_atsc_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_PHILIPS_FM1236_MK3 - Philips NTSC ------------ */
 
 static struct tuner_range tuner_fm1236_mk3_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x01, },
-       { 16 * 442.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x04, },
+       { 16 * 160.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 442.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x04, },
 };
 
 static struct tuner_params tuner_fm1236_mk3_params[] = {
@@ -673,25 +611,17 @@ static struct tuner_params tuner_fm1236_mk3_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_fm1236_mk3_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
-               .config = 0x8e,
                .cb_first_if_lower_freq = 1,
        },
 };
 
 /* ------------ TUNER_PHILIPS_4IN1 - Philips NTSC ------------ */
 
-static struct tuner_range tuner_philips_4in1_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x01, },
-       { 16 * 442.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x04, },
-};
-
 static struct tuner_params tuner_philips_4in1_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_philips_4in1_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_4in1_ntsc_ranges),
-               .config = 0x8e,
+               .ranges = tuner_fm1236_mk3_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
        },
 };
 
@@ -702,16 +632,15 @@ static struct tuner_params tuner_microtune_4049_fm5_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_temic_4009f_5_pal_ranges,
                .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_PANASONIC_VP27 - Panasonic NTSC ------------ */
 
 static struct tuner_range tuner_panasonic_vp27_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x01, },
-       { 16 * 454.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x08, },
+       { 16 * 160.00 /*MHz*/, 0xce, 0x01, },
+       { 16 * 454.00 /*MHz*/, 0xce, 0x02, },
+       { 16 * 999.99        , 0xce, 0x08, },
 };
 
 static struct tuner_params tuner_panasonic_vp27_params[] = {
@@ -719,33 +648,25 @@ static struct tuner_params tuner_panasonic_vp27_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_panasonic_vp27_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges),
-               .config = 0xce,
        },
 };
 
 /* ------------ TUNER_LG_NTSC_TAPE - LGINNOTEK NTSC ------------ */
 
-static struct tuner_range tuner_lg_ntsc_tape_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x01, },
-       { 16 * 442.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x04, },
-};
-
 static struct tuner_params tuner_lg_ntsc_tape_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_lg_ntsc_tape_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_ntsc_tape_ranges),
-               .config = 0x8e,
+               .ranges = tuner_fm1236_mk3_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
        },
 };
 
 /* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */
 
 static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = {
-       { 16 * 161.25 /*MHz*/, 0xa0, },
-       { 16 * 463.25 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
+       { 16 * 161.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
 };
 
 static struct tuner_params tuner_tnf_8831bgff_params[] = {
@@ -753,16 +674,15 @@ static struct tuner_params tuner_tnf_8831bgff_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_tnf_8831bgff_pal_ranges,
                .count  = ARRAY_SIZE(tuner_tnf_8831bgff_pal_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_MICROTUNE_4042FI5 - Microtune NTSC ------------ */
 
 static struct tuner_range tuner_microtune_4042fi5_ntsc_ranges[] = {
-       { 16 * 162.00 /*MHz*/, 0xa2, },
-       { 16 * 457.00 /*MHz*/, 0x94, },
-       { 16 * 999.99        , 0x31, },
+       { 16 * 162.00 /*MHz*/, 0x8e, 0xa2, },
+       { 16 * 457.00 /*MHz*/, 0x8e, 0x94, },
+       { 16 * 999.99        , 0x8e, 0x31, },
 };
 
 static struct tuner_params tuner_microtune_4042fi5_params[] = {
@@ -770,7 +690,6 @@ static struct tuner_params tuner_microtune_4042fi5_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_microtune_4042fi5_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_microtune_4042fi5_ntsc_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -778,9 +697,9 @@ static struct tuner_params tuner_microtune_4042fi5_params[] = {
 /* ------------ TUNER_TCL_2002N - TCL NTSC ------------ */
 
 static struct tuner_range tuner_tcl_2002n_ntsc_ranges[] = {
-       { 16 * 172.00 /*MHz*/, 0x01, },
-       { 16 * 448.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x08, },
+       { 16 * 172.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 448.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
 };
 
 static struct tuner_params tuner_tcl_2002n_params[] = {
@@ -788,34 +707,26 @@ static struct tuner_params tuner_tcl_2002n_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_tcl_2002n_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges),
-               .config = 0x8e,
                .cb_first_if_lower_freq = 1,
        },
 };
 
 /* ------------ TUNER_PHILIPS_FM1256_IH3 - Philips PAL ------------ */
 
-static struct tuner_range tuner_philips_fm1256_ih3_pal_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x01, },
-       { 16 * 442.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x04, },
-};
-
 static struct tuner_params tuner_philips_fm1256_ih3_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_philips_fm1256_ih3_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_fm1256_ih3_pal_ranges),
-               .config = 0x8e,
+               .ranges = tuner_fm1236_mk3_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
        },
 };
 
 /* ------------ TUNER_THOMSON_DTT7610 - THOMSON ATSC ------------ */
 
 static struct tuner_range tuner_thomson_dtt7610_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0x39, },
-       { 16 * 454.00 /*MHz*/, 0x3a, },
-       { 16 * 999.99        , 0x3c, },
+       { 16 * 157.25 /*MHz*/, 0x8e, 0x39, },
+       { 16 * 454.00 /*MHz*/, 0x8e, 0x3a, },
+       { 16 * 999.99        , 0x8e, 0x3c, },
 };
 
 static struct tuner_params tuner_thomson_dtt7610_params[] = {
@@ -823,16 +734,15 @@ static struct tuner_params tuner_thomson_dtt7610_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_thomson_dtt7610_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_PHILIPS_FQ1286 - Philips NTSC ------------ */
 
 static struct tuner_range tuner_philips_fq1286_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x41, },
-       { 16 * 454.00 /*MHz*/, 0x42, },
-       { 16 * 999.99        , 0x04, },
+       { 16 * 160.00 /*MHz*/, 0x8e, 0x41, },
+       { 16 * 454.00 /*MHz*/, 0x8e, 0x42, },
+       { 16 * 999.99        , 0x8e, 0x04, },
 };
 
 static struct tuner_params tuner_philips_fq1286_params[] = {
@@ -840,16 +750,15 @@ static struct tuner_params tuner_philips_fq1286_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_philips_fq1286_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_philips_fq1286_ntsc_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_TCL_2002MB - TCL PAL ------------ */
 
 static struct tuner_range tuner_tcl_2002mb_pal_ranges[] = {
-       { 16 * 170.00 /*MHz*/, 0x01, },
-       { 16 * 450.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x08, },
+       { 16 * 170.00 /*MHz*/, 0xce, 0x01, },
+       { 16 * 450.00 /*MHz*/, 0xce, 0x02, },
+       { 16 * 999.99        , 0xce, 0x08, },
 };
 
 static struct tuner_params tuner_tcl_2002mb_params[] = {
@@ -857,24 +766,22 @@ static struct tuner_params tuner_tcl_2002mb_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_tcl_2002mb_pal_ranges,
                .count  = ARRAY_SIZE(tuner_tcl_2002mb_pal_ranges),
-               .config = 0xce,
        },
 };
 
 /* ------------ TUNER_PHILIPS_FQ1216AME_MK4 - Philips PAL ------------ */
 
-static struct tuner_range tuner_philips_fq12_6a___mk4_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x01, },
-       { 16 * 442.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x04, },
+static struct tuner_range tuner_philips_fq12_6a___mk4_pal_ranges[] = {
+       { 16 * 160.00 /*MHz*/, 0xce, 0x01, },
+       { 16 * 442.00 /*MHz*/, 0xce, 0x02, },
+       { 16 * 999.99        , 0xce, 0x04, },
 };
 
 static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_philips_fq12_6a___mk4_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_ranges),
-               .config = 0xce,
+               .ranges = tuner_philips_fq12_6a___mk4_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_pal_ranges),
        },
 };
 
@@ -883,35 +790,27 @@ static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = {
 static struct tuner_params tuner_philips_fq1236a_mk4_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_philips_fq12_6a___mk4_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_ranges),
-               .config = 0x8e,
+               .ranges = tuner_fm1236_mk3_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
        },
 };
 
 /* ------------ TUNER_YMEC_TVF_8531MF - Philips NTSC ------------ */
 
-static struct tuner_range tuner_ymec_tvf_8531mf_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0xa0, },
-       { 16 * 454.00 /*MHz*/, 0x90, },
-       { 16 * 999.99        , 0x30, },
-};
-
 static struct tuner_params tuner_ymec_tvf_8531mf_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_ymec_tvf_8531mf_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_ymec_tvf_8531mf_ntsc_ranges),
-               .config = 0x8e,
+               .ranges = tuner_philips_ntsc_m_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_ntsc_m_ranges),
        },
 };
 
 /* ------------ TUNER_YMEC_TVF_5533MF - Philips NTSC ------------ */
 
 static struct tuner_range tuner_ymec_tvf_5533mf_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x01, },
-       { 16 * 454.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x04, },
+       { 16 * 160.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 454.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x04, },
 };
 
 static struct tuner_params tuner_ymec_tvf_5533mf_params[] = {
@@ -919,7 +818,6 @@ static struct tuner_params tuner_ymec_tvf_5533mf_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_ymec_tvf_5533mf_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_ymec_tvf_5533mf_ntsc_ranges),
-               .config = 0x8e,
        },
 };
 
@@ -928,9 +826,9 @@ static struct tuner_params tuner_ymec_tvf_5533mf_params[] = {
 /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
 
 static struct tuner_range tuner_thomson_dtt761x_ntsc_ranges[] = {
-       { 16 * 145.25 /*MHz*/, 0x39, },
-       { 16 * 415.25 /*MHz*/, 0x3a, },
-       { 16 * 999.99        , 0x3c, },
+       { 16 * 145.25 /*MHz*/, 0x8e, 0x39, },
+       { 16 * 415.25 /*MHz*/, 0x8e, 0x3a, },
+       { 16 * 999.99        , 0x8e, 0x3c, },
 };
 
 
@@ -939,42 +837,39 @@ static struct tuner_params tuner_thomson_dtt761x_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_thomson_dtt761x_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_TENA_9533_DI - Philips PAL ------------ */
 
-static struct tuner_range tuner_tuner_tena_9533_di_pal_ranges[] = {
-       { 16 * 160.25 /*MHz*/, 0x01, },
-       { 16 * 464.25 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x04, },
+static struct tuner_range tuner_tena_9533_di_pal_ranges[] = {
+       { 16 * 160.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 464.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x04, },
 };
 
 static struct tuner_params tuner_tena_9533_di_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_tuner_tena_9533_di_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_tuner_tena_9533_di_pal_ranges),
-               .config = 0x8e,
+               .ranges = tuner_tena_9533_di_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges),
        },
 };
 
 /* ------------ TUNER_PHILIPS_FMD1216ME_MK3 - Philips PAL ------------ */
 
 static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x51, },
-       { 16 * 442.00 /*MHz*/, 0x52, },
-       { 16 * 999.99        , 0x54, },
+       { 16 * 160.00 /*MHz*/, 0x86, 0x51, },
+       { 16 * 442.00 /*MHz*/, 0x86, 0x52, },
+       { 16 * 999.99        , 0x86, 0x54, },
 };
 
 
-static struct tuner_params tuner_tuner_philips_fmd1216me_mk3_params[] = {
+static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
                .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
-               .config = 0x86,
        },
 };
 
@@ -982,9 +877,9 @@ static struct tuner_params tuner_tuner_philips_fmd1216me_mk3_params[] = {
 /* ------------ TUNER_LG_TDVS_H062F - INFINEON ATSC ------------ */
 
 static struct tuner_range tuner_tua6034_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x01 },
-       { 16 * 455.00 /*MHz*/, 0x02 },
-       { 16 * 999.99        , 0x04 },
+       { 16 * 160.00 /*MHz*/, 0x8e, 0x01 },
+       { 16 * 455.00 /*MHz*/, 0x8e, 0x02 },
+       { 16 * 999.99        , 0x8e, 0x04 },
 };
 
 
@@ -993,50 +888,51 @@ static struct tuner_params tuner_tua6034_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_tua6034_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_tua6034_ntsc_ranges),
-               .config = 0x8e,
        },
 };
 
 /* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */
 
-static struct tuner_range tuner_ymec_tvf66t5_b_dff_pal_ranges[] = {
-       { 16 * 160.25 /*MHz*/, 0x01, },
-       { 16 * 464.25 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x08, },
-};
-
 static struct tuner_params tuner_ymec_tvf66t5_b_dff_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_ymec_tvf66t5_b_dff_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_pal_ranges),
-               .config = 0x8e,
+               .ranges = tuner_tena_9533_di_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges),
        },
 };
 
 /* ------------ TUNER_LG_NTSC_TALN_MINI - LGINNOTEK NTSC ------------ */
 
-static struct tuner_range tuner_lg_taln_mini_ntsc_ranges[] = {
-       { 16 * 137.25 /*MHz*/, 0x01, },
-       { 16 * 373.25 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x08, },
+static struct tuner_range tuner_lg_taln_ntsc_ranges[] = {
+       { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 373.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
+
+static struct tuner_range tuner_lg_taln_pal_secam_ranges[] = {
+       { 16 * 150.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 425.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
 };
 
-static struct tuner_params tuner_lg_taln_mini_params[] = {
+static struct tuner_params tuner_lg_taln_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_lg_taln_mini_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_taln_mini_ntsc_ranges),
-               .config = 0x8e,
+               .ranges = tuner_lg_taln_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_taln_ntsc_ranges),
+       },{
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_lg_taln_pal_secam_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_taln_pal_secam_ranges),
        },
 };
 
 /* ------------ TUNER_PHILIPS_TD1316 - Philips PAL ------------ */
 
 static struct tuner_range tuner_philips_td1316_pal_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0xa1, },
-       { 16 * 442.00 /*MHz*/, 0xa2, },
-       { 16 * 999.99        , 0xa4, },
+       { 16 * 160.00 /*MHz*/, 0xc8, 0xa1, },
+       { 16 * 442.00 /*MHz*/, 0xc8, 0xa2, },
+       { 16 * 999.99        , 0xc8, 0xa4, },
 };
 
 static struct tuner_params tuner_philips_td1316_params[] = {
@@ -1044,34 +940,42 @@ static struct tuner_params tuner_philips_td1316_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_philips_td1316_pal_ranges,
                .count  = ARRAY_SIZE(tuner_philips_td1316_pal_ranges),
-               .config = 0xc8,
        },
 };
 
 /* ------------ TUNER_PHILIPS_TUV1236D - Philips ATSC ------------ */
 
 static struct tuner_range tuner_tuv1236d_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0x01, },
-       { 16 * 454.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x04, },
+       { 16 * 157.25 /*MHz*/, 0xce, 0x01, },
+       { 16 * 454.00 /*MHz*/, 0xce, 0x02, },
+       { 16 * 999.99        , 0xce, 0x04, },
 };
 
 
-static struct tuner_params tuner_tuner_tuv1236d_params[] = {
+static struct tuner_params tuner_tuv1236d_params[] = {
        {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_tuv1236d_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_tuv1236d_ntsc_ranges),
-               .config = 0xce,
        },
 };
 
-/* ------------ TUNER_TNF_5335MF - Philips NTSC ------------ */
+/* ------------ TUNER_TNF_xxx5  - Texas Instruments--------- */
+/* This is known to work with Tenna TVF58t5-MFF and TVF5835 MFF
+ *     but it is expected to work also with other Tenna/Ymec
+ *     models based on TI SN 761677 chip on both PAL and NTSC
+ */
+
+static struct tuner_range tuner_tnf_5335_d_if_pal_ranges[] = {
+       { 16 * 168.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 471.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
 
 static struct tuner_range tuner_tnf_5335mf_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0x01, },
-       { 16 * 454.00 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x04, },
+       { 16 * 169.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 469.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
 };
 
 static struct tuner_params tuner_tnf_5335mf_params[] = {
@@ -1079,7 +983,11 @@ static struct tuner_params tuner_tnf_5335mf_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_tnf_5335mf_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_tnf_5335mf_ntsc_ranges),
-               .config = 0x8e,
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_tnf_5335_d_if_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_tnf_5335_d_if_pal_ranges),
        },
 };
 
@@ -1087,9 +995,9 @@ static struct tuner_params tuner_tnf_5335mf_params[] = {
 /* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */
 
 static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = {
-       { 16 * 175.75 /*MHz*/, 0x01, },
-       { 16 * 410.25 /*MHz*/, 0x02, },
-       { 16 * 999.99        , 0x08, },
+       { 16 * 130.00 /*MHz*/, 0xce, 0x01, },
+       { 16 * 364.50 /*MHz*/, 0xce, 0x02, },
+       { 16 * 999.99        , 0xce, 0x08, },
 };
 
 static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = {
@@ -1097,7 +1005,22 @@ static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges),
-               .config = 0xce,
+       },
+};
+
+/* ------------ TUNER_THOMSON_FE6600 - DViCO Hybrid PAL ------------ */
+
+static struct tuner_range tuner_thomson_fe6600_ranges[] = {
+       { 16 * 160.00 /*MHz*/, 0xfe, 0x11, },
+       { 16 * 442.00 /*MHz*/, 0xf6, 0x12, },
+       { 16 * 999.99        , 0xf6, 0x18, },
+};
+
+static struct tuner_params tuner_thomson_fe6600_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_thomson_fe6600_ranges,
+               .count  = ARRAY_SIZE(tuner_thomson_fe6600_ranges),
        },
 };
 
@@ -1108,18 +1031,22 @@ struct tunertype tuners[] = {
        [TUNER_TEMIC_PAL] = { /* TEMIC PAL */
                .name   = "Temic PAL (4002 FH5)",
                .params = tuner_temic_pal_params,
+               .count  = ARRAY_SIZE(tuner_temic_pal_params),
        },
        [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */
                .name   = "Philips PAL_I (FI1246 and compatibles)",
                .params = tuner_philips_pal_i_params,
+               .count  = ARRAY_SIZE(tuner_philips_pal_i_params),
        },
        [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */
                .name   = "Philips NTSC (FI1236,FM1236 and compatibles)",
                .params = tuner_philips_ntsc_params,
+               .count  = ARRAY_SIZE(tuner_philips_ntsc_params),
        },
        [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */
                .name   = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)",
                .params = tuner_philips_secam_params,
+               .count  = ARRAY_SIZE(tuner_philips_secam_params),
        },
        [TUNER_ABSENT] = { /* Tuner Absent */
                .name   = "NoTuner",
@@ -1127,120 +1054,148 @@ struct tunertype tuners[] = {
        [TUNER_PHILIPS_PAL] = { /* Philips PAL */
                .name   = "Philips PAL_BG (FI1216 and compatibles)",
                .params = tuner_philips_pal_params,
+               .count  = ARRAY_SIZE(tuner_philips_pal_params),
        },
        [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */
                .name   = "Temic NTSC (4032 FY5)",
                .params = tuner_temic_ntsc_params,
+               .count  = ARRAY_SIZE(tuner_temic_ntsc_params),
        },
        [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */
                .name   = "Temic PAL_I (4062 FY5)",
                .params = tuner_temic_pal_i_params,
+               .count  = ARRAY_SIZE(tuner_temic_pal_i_params),
        },
        [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */
                .name   = "Temic NTSC (4036 FY5)",
                .params = tuner_temic_4036fy5_ntsc_params,
+               .count  = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_params),
        },
        [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */
                .name   = "Alps HSBH1",
                .params = tuner_alps_tsbh1_ntsc_params,
+               .count  = ARRAY_SIZE(tuner_alps_tsbh1_ntsc_params),
        },
 
        /* 10-19 */
        [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */
                .name   = "Alps TSBE1",
                .params = tuner_alps_tsb_1_params,
+               .count  = ARRAY_SIZE(tuner_alps_tsb_1_params),
        },
        [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */
                .name   = "Alps TSBB5",
                .params = tuner_alps_tsbb5_params,
+               .count  = ARRAY_SIZE(tuner_alps_tsbb5_params),
        },
        [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */
                .name   = "Alps TSBE5",
                .params = tuner_alps_tsbe5_params,
+               .count  = ARRAY_SIZE(tuner_alps_tsbe5_params),
        },
        [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */
                .name   = "Alps TSBC5",
                .params = tuner_alps_tsbc5_params,
+               .count  = ARRAY_SIZE(tuner_alps_tsbc5_params),
        },
        [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */
                .name   = "Temic PAL_BG (4006FH5)",
                .params = tuner_temic_4006fh5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4006fh5_params),
        },
        [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */
                .name   = "Alps TSCH6",
                .params = tuner_alps_tshc6_params,
+               .count  = ARRAY_SIZE(tuner_alps_tshc6_params),
        },
        [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */
                .name   = "Temic PAL_DK (4016 FY5)",
                .params = tuner_temic_pal_dk_params,
+               .count  = ARRAY_SIZE(tuner_temic_pal_dk_params),
        },
        [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */
                .name   = "Philips NTSC_M (MK2)",
                .params = tuner_philips_ntsc_m_params,
+               .count  = ARRAY_SIZE(tuner_philips_ntsc_m_params),
        },
        [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */
                .name   = "Temic PAL_I (4066 FY5)",
                .params = tuner_temic_4066fy5_pal_i_params,
+               .count  = ARRAY_SIZE(tuner_temic_4066fy5_pal_i_params),
        },
        [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */
                .name   = "Temic PAL* auto (4006 FN5)",
                .params = tuner_temic_4006fn5_multi_params,
+               .count  = ARRAY_SIZE(tuner_temic_4006fn5_multi_params),
        },
 
        /* 20-29 */
        [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */
                .name   = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)",
                .params = tuner_temic_4009f_5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4009f_5_params),
        },
        [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */
                .name   = "Temic NTSC (4039 FR5)",
                .params = tuner_temic_4039fr5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4039fr5_params),
        },
        [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */
                .name   = "Temic PAL/SECAM multi (4046 FM5)",
                .params = tuner_temic_4046fm5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4046fm5_params),
        },
        [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */
                .name   = "Philips PAL_DK (FI1256 and compatibles)",
                .params = tuner_philips_pal_dk_params,
+               .count  = ARRAY_SIZE(tuner_philips_pal_dk_params),
        },
        [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */
                .name   = "Philips PAL/SECAM multi (FQ1216ME)",
                .params = tuner_philips_fq1216me_params,
+               .count  = ARRAY_SIZE(tuner_philips_fq1216me_params),
        },
        [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */
                .name   = "LG PAL_I+FM (TAPC-I001D)",
                .params = tuner_lg_pal_i_fm_params,
+               .count  = ARRAY_SIZE(tuner_lg_pal_i_fm_params),
        },
        [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */
                .name   = "LG PAL_I (TAPC-I701D)",
                .params = tuner_lg_pal_i_params,
+               .count  = ARRAY_SIZE(tuner_lg_pal_i_params),
        },
        [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */
                .name   = "LG NTSC+FM (TPI8NSR01F)",
                .params = tuner_lg_ntsc_fm_params,
+               .count  = ARRAY_SIZE(tuner_lg_ntsc_fm_params),
        },
        [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */
                .name   = "LG PAL_BG+FM (TPI8PSB01D)",
                .params = tuner_lg_pal_fm_params,
+               .count  = ARRAY_SIZE(tuner_lg_pal_fm_params),
        },
        [TUNER_LG_PAL] = { /* LGINNOTEK PAL */
                .name   = "LG PAL_BG (TPI8PSB11D)",
                .params = tuner_lg_pal_params,
+               .count  = ARRAY_SIZE(tuner_lg_pal_params),
        },
 
        /* 30-39 */
        [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */
                .name   = "Temic PAL* auto + FM (4009 FN5)",
                .params = tuner_temic_4009_fn5_multi_pal_fm_params,
+               .count  = ARRAY_SIZE(tuner_temic_4009_fn5_multi_pal_fm_params),
        },
        [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */
                .name   = "SHARP NTSC_JP (2U5JF5540)",
                .params = tuner_sharp_2u5jf5540_params,
+               .count  = ARRAY_SIZE(tuner_sharp_2u5jf5540_params),
        },
        [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */
                .name   = "Samsung PAL TCPM9091PD27",
                .params = tuner_samsung_pal_tcpm9091pd27_params,
+               .count  = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_params),
        },
        [TUNER_MT2032] = { /* Microtune PAL|NTSC */
                .name   = "MT20xx universal",
@@ -1248,86 +1203,106 @@ struct tunertype tuners[] = {
        [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */
                .name   = "Temic PAL_BG (4106 FH5)",
                .params = tuner_temic_4106fh5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4106fh5_params),
        },
        [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */
                .name   = "Temic PAL_DK/SECAM_L (4012 FY5)",
                .params = tuner_temic_4012fy5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4012fy5_params),
        },
        [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */
                .name   = "Temic NTSC (4136 FY5)",
                .params = tuner_temic_4136_fy5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4136_fy5_params),
        },
        [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */
                .name   = "LG PAL (newer TAPC series)",
                .params = tuner_lg_pal_new_tapc_params,
+               .count  = ARRAY_SIZE(tuner_lg_pal_new_tapc_params),
        },
        [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */
                .name   = "Philips PAL/SECAM multi (FM1216ME MK3)",
                .params = tuner_fm1216me_mk3_params,
+               .count  = ARRAY_SIZE(tuner_fm1216me_mk3_params),
        },
        [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */
                .name   = "LG NTSC (newer TAPC series)",
                .params = tuner_lg_ntsc_new_tapc_params,
+               .count  = ARRAY_SIZE(tuner_lg_ntsc_new_tapc_params),
        },
 
        /* 40-49 */
        [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */
                .name   = "HITACHI V7-J180AT",
                .params = tuner_hitachi_ntsc_params,
+               .count  = ARRAY_SIZE(tuner_hitachi_ntsc_params),
        },
        [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */
                .name   = "Philips PAL_MK (FI1216 MK)",
                .params = tuner_philips_pal_mk_params,
+               .count  = ARRAY_SIZE(tuner_philips_pal_mk_params),
        },
        [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */
                .name   = "Philips 1236D ATSC/NTSC dual in",
                .params = tuner_philips_atsc_params,
+               .count  = ARRAY_SIZE(tuner_philips_atsc_params),
        },
        [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */
                .name   = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)",
                .params = tuner_fm1236_mk3_params,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_params),
        },
        [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */
                .name   = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)",
                .params = tuner_philips_4in1_params,
+               .count  = ARRAY_SIZE(tuner_philips_4in1_params),
        },
        [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */
                .name   = "Microtune 4049 FM5",
                .params = tuner_microtune_4049_fm5_params,
+               .count  = ARRAY_SIZE(tuner_microtune_4049_fm5_params),
        },
        [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */
                .name   = "Panasonic VP27s/ENGE4324D",
                .params = tuner_panasonic_vp27_params,
+               .count  = ARRAY_SIZE(tuner_panasonic_vp27_params),
        },
        [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */
                .name   = "LG NTSC (TAPE series)",
                .params = tuner_lg_ntsc_tape_params,
+               .count  = ARRAY_SIZE(tuner_lg_ntsc_tape_params),
        },
        [TUNER_TNF_8831BGFF] = { /* Philips PAL */
                .name   = "Tenna TNF 8831 BGFF)",
                .params = tuner_tnf_8831bgff_params,
+               .count  = ARRAY_SIZE(tuner_tnf_8831bgff_params),
        },
        [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */
                .name   = "Microtune 4042 FI5 ATSC/NTSC dual in",
                .params = tuner_microtune_4042fi5_params,
+               .count  = ARRAY_SIZE(tuner_microtune_4042fi5_params),
        },
 
        /* 50-59 */
        [TUNER_TCL_2002N] = { /* TCL NTSC */
                .name   = "TCL 2002N",
                .params = tuner_tcl_2002n_params,
+               .count  = ARRAY_SIZE(tuner_tcl_2002n_params),
        },
        [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */
                .name   = "Philips PAL/SECAM_D (FM 1256 I-H3)",
                .params = tuner_philips_fm1256_ih3_params,
+               .count  = ARRAY_SIZE(tuner_philips_fm1256_ih3_params),
        },
        [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */
                .name   = "Thomson DTT 7610 (ATSC/NTSC)",
                .params = tuner_thomson_dtt7610_params,
+               .count  = ARRAY_SIZE(tuner_thomson_dtt7610_params),
        },
        [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */
                .name   = "Philips FQ1286",
                .params = tuner_philips_fq1286_params,
+               .count  = ARRAY_SIZE(tuner_philips_fq1286_params),
        },
        [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */
                .name   = "tda8290+75",
@@ -1335,22 +1310,27 @@ struct tunertype tuners[] = {
        [TUNER_TCL_2002MB] = { /* TCL PAL */
                .name   = "TCL 2002MB",
                .params = tuner_tcl_2002mb_params,
+               .count  = ARRAY_SIZE(tuner_tcl_2002mb_params),
        },
        [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */
                .name   = "Philips PAL/SECAM multi (FQ1216AME MK4)",
                .params = tuner_philips_fq1216ame_mk4_params,
+               .count  = ARRAY_SIZE(tuner_philips_fq1216ame_mk4_params),
        },
        [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */
                .name   = "Philips FQ1236A MK4",
                .params = tuner_philips_fq1236a_mk4_params,
+               .count  = ARRAY_SIZE(tuner_philips_fq1236a_mk4_params),
        },
        [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */
                .name   = "Ymec TVision TVF-8531MF/8831MF/8731MF",
                .params = tuner_ymec_tvf_8531mf_params,
+               .count  = ARRAY_SIZE(tuner_ymec_tvf_8531mf_params),
        },
        [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */
                .name   = "Ymec TVision TVF-5533MF",
                .params = tuner_ymec_tvf_5533mf_params,
+               .count  = ARRAY_SIZE(tuner_ymec_tvf_5533mf_params),
        },
 
        /* 60-69 */
@@ -1358,10 +1338,12 @@ struct tunertype tuners[] = {
                /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
                .name   = "Thomson DTT 761X (ATSC/NTSC)",
                .params = tuner_thomson_dtt761x_params,
+               .count  = ARRAY_SIZE(tuner_thomson_dtt761x_params),
        },
        [TUNER_TENA_9533_DI] = { /* Philips PAL */
                .name   = "Tena TNF9533-D/IF/TNF9533-B/DF",
                .params = tuner_tena_9533_di_params,
+               .count  = ARRAY_SIZE(tuner_tena_9533_di_params),
        },
        [TUNER_TEA5767] = { /* Philips RADIO */
                .name   = "Philips TEA5767HN FM Radio",
@@ -1369,37 +1351,54 @@ struct tunertype tuners[] = {
        },
        [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */
                .name   = "Philips FMD1216ME MK3 Hybrid Tuner",
-               .params = tuner_tuner_philips_fmd1216me_mk3_params,
+               .params = tuner_philips_fmd1216me_mk3_params,
+               .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params),
        },
        [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */
                .name   = "LG TDVS-H062F/TUA6034",
                .params = tuner_tua6034_params,
+               .count  = ARRAY_SIZE(tuner_tua6034_params),
        },
        [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */
                .name   = "Ymec TVF66T5-B/DFF",
                .params = tuner_ymec_tvf66t5_b_dff_params,
+               .count  = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_params),
        },
-       [TUNER_LG_NTSC_TALN_MINI] = { /* LGINNOTEK NTSC */
-               .name   = "LG NTSC (TALN mini series)",
-               .params = tuner_lg_taln_mini_params,
+       [TUNER_LG_TALN] = { /* LGINNOTEK NTSC / PAL / SECAM */
+               .name   = "LG TALN series",
+               .params = tuner_lg_taln_params,
+               .count  = ARRAY_SIZE(tuner_lg_taln_params),
        },
        [TUNER_PHILIPS_TD1316] = { /* Philips PAL */
                .name   = "Philips TD1316 Hybrid Tuner",
                .params = tuner_philips_td1316_params,
+               .count  = ARRAY_SIZE(tuner_philips_td1316_params),
        },
        [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */
                .name   = "Philips TUV1236D ATSC/NTSC dual in",
-               .params = tuner_tuner_tuv1236d_params,
+               .params = tuner_tuv1236d_params,
+               .count  = ARRAY_SIZE(tuner_tuv1236d_params),
        },
-       [TUNER_TNF_5335MF] = { /* Philips NTSC */
-               .name   = "Tena TNF 5335 MF",
+       [TUNER_TNF_5335MF] = { /* Tenna PAL/NTSC */
+               .name   = "Tena TNF 5335 and similar models",
                .params = tuner_tnf_5335mf_params,
+               .count  = ARRAY_SIZE(tuner_tnf_5335mf_params),
        },
 
        /* 70-79 */
        [TUNER_SAMSUNG_TCPN_2121P30A] = { /* Samsung NTSC */
                .name   = "Samsung TCPN 2121P30A",
                .params = tuner_samsung_tcpn_2121p30a_params,
+               .count  = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_params),
+       },
+       [TUNER_XCEIVE_XC3028] = { /* Xceive 3028 */
+               .name   = "Xceive xc3028",
+               /* see xc3028.c for details */
+       },
+       [TUNER_THOMSON_FE6600] = { /* Thomson PAL / DVB-T */
+               .name   = "Thomson FE6600",
+               .params = tuner_thomson_fe6600_params,
+               .count  = ARRAY_SIZE(tuner_thomson_fe6600_params),
        },
 };
 
index c8e5ad0e8185a0c2f3cea24be094148db2b928a4..4efb01bb44ac1cdce5212c69caa745116c3a7a73 100644 (file)
@@ -130,6 +130,7 @@ struct CHIPSTATE {
        struct timer_list    wt;
        int                  done;
        int                  watch_stereo;
+       int                  audmode;
 };
 
 /* ---------------------------------------------------------------------- */
@@ -1514,6 +1515,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
        chip->type = desc-chiplist;
        chip->shadow.count = desc->registers+1;
        chip->prevmode = -1;
+       chip->audmode = V4L2_TUNER_MODE_LANG1;
        /* register */
        i2c_attach_client(&chip->c);
 
@@ -1671,6 +1673,8 @@ static int chip_command(struct i2c_client *client,
                struct v4l2_tuner *vt = arg;
                int mode = 0;
 
+               if (chip->radio)
+                       break;
                switch (vt->audmode) {
                case V4L2_TUNER_MODE_MONO:
                        mode = VIDEO_SOUND_MONO;
@@ -1685,8 +1689,9 @@ static int chip_command(struct i2c_client *client,
                        mode = VIDEO_SOUND_LANG2;
                        break;
                default:
-                       break;
+                       return -EINVAL;
                }
+               chip->audmode = vt->audmode;
 
                if (desc->setmode && mode) {
                        chip->watch_stereo = 0;
@@ -1704,7 +1709,7 @@ static int chip_command(struct i2c_client *client,
 
                if (chip->radio)
                        break;
-               vt->audmode = 0;
+               vt->audmode = chip->audmode;
                vt->rxsubchans = 0;
                vt->capability = V4L2_TUNER_CAP_STEREO |
                        V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
@@ -1716,19 +1721,12 @@ static int chip_command(struct i2c_client *client,
                        vt->rxsubchans |= V4L2_TUNER_SUB_MONO;
                if (mode & VIDEO_SOUND_STEREO)
                        vt->rxsubchans |= V4L2_TUNER_SUB_STEREO;
+               /* Note: for SAP it should be mono/lang2 or stereo/lang2.
+                  When this module is converted fully to v4l2, then this
+                  should change for those chips that can detect SAP. */
                if (mode & VIDEO_SOUND_LANG1)
-                       vt->rxsubchans |= V4L2_TUNER_SUB_LANG1 |
-                                         V4L2_TUNER_SUB_LANG2;
-
-               mode = chip->mode;
-               if (mode & VIDEO_SOUND_MONO)
-                       vt->audmode = V4L2_TUNER_MODE_MONO;
-               if (mode & VIDEO_SOUND_STEREO)
-                       vt->audmode = V4L2_TUNER_MODE_STEREO;
-               if (mode & VIDEO_SOUND_LANG1)
-                       vt->audmode = V4L2_TUNER_MODE_LANG1;
-               if (mode & VIDEO_SOUND_LANG2)
-                       vt->audmode = V4L2_TUNER_MODE_LANG2;
+                       vt->rxsubchans = V4L2_TUNER_SUB_LANG1 |
+                                        V4L2_TUNER_SUB_LANG2;
                break;
        }
 
index 1864423b30465c032d347614b5b0271044e940e8..69d0fe159f4dc02e461ab8aa1c145098d68b7644 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * tvp5150 - Texas Instruments TVP5150A(M) video decoder driver
+ * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder driver
  *
- * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
- * This code is placed under the terms of the GNU General Public License
+ * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org)
+ * This code is placed under the terms of the GNU General Public License v2
  */
 
 #include <linux/i2c.h>
 
 #include "tvp5150_reg.h"
 
-MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); /* standard i2c insmod options */
+MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver");
 MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_LICENSE("GPL");
 
+/* standard i2c insmod options */
 static unsigned short normal_i2c[] = {
        0xb8 >> 1,
        0xba >> 1,
@@ -29,6 +30,9 @@ static int debug = 0;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
+#define tvp5150_err(fmt, arg...) do { \
+       printk(KERN_ERR "%s %d-%04x: " fmt, c->driver->driver.name, \
+              i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0)
 #define tvp5150_info(fmt, arg...) do { \
        printk(KERN_INFO "%s %d-%04x: " fmt, c->driver->driver.name, \
               i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0)
@@ -84,7 +88,7 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = {
 struct tvp5150 {
        struct i2c_client *client;
 
-       int norm;
+       v4l2_std_id norm;       /* Current set standard */
        int input;
        int enable;
        int bright;
@@ -125,310 +129,155 @@ static inline void tvp5150_write(struct i2c_client *c, unsigned char addr,
                tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 2)\n", rc);
 }
 
+static void dump_reg_range(struct i2c_client *c, char *s, u8 init, const u8 end,int max_line)
+{
+       int i=0;
+
+       while (init!=(u8)(end+1)) {
+               if ((i%max_line) == 0) {
+                       if (i>0)
+                               printk("\n");
+                       printk("tvp5150: %s reg 0x%02x = ",s,init);
+               }
+               printk("%02x ",tvp5150_read(c, init));
+
+               init++;
+               i++;
+       }
+       printk("\n");
+}
+
 static void dump_reg(struct i2c_client *c)
 {
        printk("tvp5150: Video input source selection #1 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1));
+                                       tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1));
        printk("tvp5150: Analog channel controls = 0x%02x\n",
-              tvp5150_read(c, TVP5150_ANAL_CHL_CTL));
+                                       tvp5150_read(c, TVP5150_ANAL_CHL_CTL));
        printk("tvp5150: Operation mode controls = 0x%02x\n",
-              tvp5150_read(c, TVP5150_OP_MODE_CTL));
+                                       tvp5150_read(c, TVP5150_OP_MODE_CTL));
        printk("tvp5150: Miscellaneous controls = 0x%02x\n",
-              tvp5150_read(c, TVP5150_MISC_CTL));
-       printk("tvp5150: Autoswitch mask: TVP5150A / TVP5150AM = 0x%02x\n",
-              tvp5150_read(c, TVP5150_AUTOSW_MSK));
+                                       tvp5150_read(c, TVP5150_MISC_CTL));
+       printk("tvp5150: Autoswitch mask= 0x%02x\n",
+                                       tvp5150_read(c, TVP5150_AUTOSW_MSK));
        printk("tvp5150: Color killer threshold control = 0x%02x\n",
-              tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL));
-       printk("tvp5150: Luminance processing control #1 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1));
-       printk("tvp5150: Luminance processing control #2 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2));
+                                       tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL));
+       printk("tvp5150: Luminance processing controls #1 #2 and #3 = %02x %02x %02x\n",
+                                       tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1),
+                                       tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2),
+                                       tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3));
        printk("tvp5150: Brightness control = 0x%02x\n",
-              tvp5150_read(c, TVP5150_BRIGHT_CTL));
+                                       tvp5150_read(c, TVP5150_BRIGHT_CTL));
        printk("tvp5150: Color saturation control = 0x%02x\n",
-              tvp5150_read(c, TVP5150_SATURATION_CTL));
+                                       tvp5150_read(c, TVP5150_SATURATION_CTL));
        printk("tvp5150: Hue control = 0x%02x\n",
-              tvp5150_read(c, TVP5150_HUE_CTL));
+                                       tvp5150_read(c, TVP5150_HUE_CTL));
        printk("tvp5150: Contrast control = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CONTRAST_CTL));
+                                       tvp5150_read(c, TVP5150_CONTRAST_CTL));
        printk("tvp5150: Outputs and data rates select = 0x%02x\n",
-              tvp5150_read(c, TVP5150_DATA_RATE_SEL));
-       printk("tvp5150: Luminance processing control #3 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3));
+                                       tvp5150_read(c, TVP5150_DATA_RATE_SEL));
        printk("tvp5150: Configuration shared pins = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CONF_SHARED_PIN));
-       printk("tvp5150: Active video cropping start MSB = 0x%02x\n",
-              tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB));
-       printk("tvp5150: Active video cropping start LSB = 0x%02x\n",
-              tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB));
-       printk("tvp5150: Active video cropping stop MSB = 0x%02x\n",
-              tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB));
-       printk("tvp5150: Active video cropping stop LSB = 0x%02x\n",
-              tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB));
+                                       tvp5150_read(c, TVP5150_CONF_SHARED_PIN));
+       printk("tvp5150: Active video cropping start = 0x%02x%02x\n",
+                                       tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB),
+                                       tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB));
+       printk("tvp5150: Active video cropping stop  = 0x%02x%02x\n",
+                                       tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB),
+                                       tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB));
        printk("tvp5150: Genlock/RTC = 0x%02x\n",
-              tvp5150_read(c, TVP5150_GENLOCK));
+                                       tvp5150_read(c, TVP5150_GENLOCK));
        printk("tvp5150: Horizontal sync start = 0x%02x\n",
-              tvp5150_read(c, TVP5150_HORIZ_SYNC_START));
+                                       tvp5150_read(c, TVP5150_HORIZ_SYNC_START));
        printk("tvp5150: Vertical blanking start = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VERT_BLANKING_START));
+                                       tvp5150_read(c, TVP5150_VERT_BLANKING_START));
        printk("tvp5150: Vertical blanking stop = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VERT_BLANKING_STOP));
-       printk("tvp5150: Chrominance processing control #1 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1));
-       printk("tvp5150: Chrominance processing control #2 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2));
+                                       tvp5150_read(c, TVP5150_VERT_BLANKING_STOP));
+       printk("tvp5150: Chrominance processing control #1 and #2 = %02x %02x\n",
+                                       tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1),
+                                       tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2));
        printk("tvp5150: Interrupt reset register B = 0x%02x\n",
-              tvp5150_read(c, TVP5150_INT_RESET_REG_B));
+                                       tvp5150_read(c, TVP5150_INT_RESET_REG_B));
        printk("tvp5150: Interrupt enable register B = 0x%02x\n",
-              tvp5150_read(c, TVP5150_INT_ENABLE_REG_B));
+                                       tvp5150_read(c, TVP5150_INT_ENABLE_REG_B));
        printk("tvp5150: Interrupt configuration register B = 0x%02x\n",
-              tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B));
+                                       tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B));
        printk("tvp5150: Video standard = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VIDEO_STD));
-       printk("tvp5150: Cb gain factor = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CB_GAIN_FACT));
-       printk("tvp5150: Cr gain factor = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CR_GAIN_FACTOR));
+                                       tvp5150_read(c, TVP5150_VIDEO_STD));
+       printk("tvp5150: Chroma gain factor: Cb=0x%02x Cr=0x%02x\n",
+                                       tvp5150_read(c, TVP5150_CB_GAIN_FACT),
+                                       tvp5150_read(c, TVP5150_CR_GAIN_FACTOR));
        printk("tvp5150: Macrovision on counter = 0x%02x\n",
-              tvp5150_read(c, TVP5150_MACROVISION_ON_CTR));
+                                       tvp5150_read(c, TVP5150_MACROVISION_ON_CTR));
        printk("tvp5150: Macrovision off counter = 0x%02x\n",
-              tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR));
-       printk("tvp5150: revision select (TVP5150AM1 only) = 0x%02x\n",
-              tvp5150_read(c, TVP5150_REV_SELECT));
-       printk("tvp5150: MSB of device ID = 0x%02x\n",
-              tvp5150_read(c, TVP5150_MSB_DEV_ID));
-       printk("tvp5150: LSB of device ID = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LSB_DEV_ID));
-       printk("tvp5150: ROM major version = 0x%02x\n",
-              tvp5150_read(c, TVP5150_ROM_MAJOR_VER));
-       printk("tvp5150: ROM minor version = 0x%02x\n",
-              tvp5150_read(c, TVP5150_ROM_MINOR_VER));
-       printk("tvp5150: Vertical line count MSB = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB));
-       printk("tvp5150: Vertical line count LSB = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB));
+                                       tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR));
+       printk("tvp5150: ITU-R BT.656.%d timing(TVP5150AM1 only)\n",
+                                       (tvp5150_read(c, TVP5150_REV_SELECT)&1)?3:4);
+       printk("tvp5150: Device ID = %02x%02x\n",
+                                       tvp5150_read(c, TVP5150_MSB_DEV_ID),
+                                       tvp5150_read(c, TVP5150_LSB_DEV_ID));
+       printk("tvp5150: ROM version = (hex) %02x.%02x\n",
+                                       tvp5150_read(c, TVP5150_ROM_MAJOR_VER),
+                                       tvp5150_read(c, TVP5150_ROM_MINOR_VER));
+       printk("tvp5150: Vertical line count = 0x%02x%02x\n",
+                                       tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB),
+                                       tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB));
        printk("tvp5150: Interrupt status register B = 0x%02x\n",
-              tvp5150_read(c, TVP5150_INT_STATUS_REG_B));
+                                       tvp5150_read(c, TVP5150_INT_STATUS_REG_B));
        printk("tvp5150: Interrupt active register B = 0x%02x\n",
-              tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B));
-       printk("tvp5150: Status register #1 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_STATUS_REG_1));
-       printk("tvp5150: Status register #2 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_STATUS_REG_2));
-       printk("tvp5150: Status register #3 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_STATUS_REG_3));
-       printk("tvp5150: Status register #4 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_STATUS_REG_4));
-       printk("tvp5150: Status register #5 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_STATUS_REG_5));
-       printk("tvp5150: Closed caption data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CC_DATA_REG1));
-       printk("tvp5150: Closed caption data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CC_DATA_REG2));
-       printk("tvp5150: Closed caption data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CC_DATA_REG3));
-       printk("tvp5150: Closed caption data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CC_DATA_REG4));
-       printk("tvp5150: WSS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_WSS_DATA_REG1));
-       printk("tvp5150: WSS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_WSS_DATA_REG2));
-       printk("tvp5150: WSS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_WSS_DATA_REG3));
-       printk("tvp5150: WSS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_WSS_DATA_REG4));
-       printk("tvp5150: WSS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_WSS_DATA_REG5));
-       printk("tvp5150: WSS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_WSS_DATA_REG6));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG1));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG2));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG3));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG4));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG5));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG6));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG7));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG8));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG9));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG10));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG11));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG12));
-       printk("tvp5150: VPS data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VPS_DATA_REG13));
-       printk("tvp5150: VITC data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VITC_DATA_REG1));
-       printk("tvp5150: VITC data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VITC_DATA_REG2));
-       printk("tvp5150: VITC data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VITC_DATA_REG3));
-       printk("tvp5150: VITC data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VITC_DATA_REG4));
-       printk("tvp5150: VITC data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VITC_DATA_REG5));
-       printk("tvp5150: VITC data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VITC_DATA_REG6));
-       printk("tvp5150: VITC data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VITC_DATA_REG7));
-       printk("tvp5150: VITC data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VITC_DATA_REG8));
-       printk("tvp5150: VITC data registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VITC_DATA_REG9));
-       printk("tvp5150: VBI FIFO read data = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VBI_FIFO_READ_DATA));
-       printk("tvp5150: Teletext filter 1 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_TELETEXT_FIL_1_1));
-       printk("tvp5150: Teletext filter 1 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_TELETEXT_FIL_1_2));
-       printk("tvp5150: Teletext filter 1 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_TELETEXT_FIL_1_3));
-       printk("tvp5150: Teletext filter 1 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_TELETEXT_FIL_1_4));
-       printk("tvp5150: Teletext filter 1 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_TELETEXT_FIL_1_5));
-       printk("tvp5150: Teletext filter 2 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_TELETEXT_FIL_2_1));
-       printk("tvp5150: Teletext filter 2 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_TELETEXT_FIL_2_2));
-       printk("tvp5150: Teletext filter 2 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_TELETEXT_FIL_2_3));
-       printk("tvp5150: Teletext filter 2 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_TELETEXT_FIL_2_4));
-       printk("tvp5150: Teletext filter 2 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_TELETEXT_FIL_2_5));
+                                       tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B));
+       printk("tvp5150: Status regs #1 to #5 = %02x %02x %02x %02x %02x\n",
+                                       tvp5150_read(c, TVP5150_STATUS_REG_1),
+                                       tvp5150_read(c, TVP5150_STATUS_REG_2),
+                                       tvp5150_read(c, TVP5150_STATUS_REG_3),
+                                       tvp5150_read(c, TVP5150_STATUS_REG_4),
+                                       tvp5150_read(c, TVP5150_STATUS_REG_5));
+
+       dump_reg_range(c,"Teletext filter 1",   TVP5150_TELETEXT_FIL1_INI,
+                                               TVP5150_TELETEXT_FIL1_END,8);
+       dump_reg_range(c,"Teletext filter 2",   TVP5150_TELETEXT_FIL2_INI,
+                                               TVP5150_TELETEXT_FIL2_END,8);
+
        printk("tvp5150: Teletext filter enable = 0x%02x\n",
-              tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA));
+                                       tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA));
        printk("tvp5150: Interrupt status register A = 0x%02x\n",
-              tvp5150_read(c, TVP5150_INT_STATUS_REG_A));
+                                       tvp5150_read(c, TVP5150_INT_STATUS_REG_A));
        printk("tvp5150: Interrupt enable register A = 0x%02x\n",
-              tvp5150_read(c, TVP5150_INT_ENABLE_REG_A));
+                                       tvp5150_read(c, TVP5150_INT_ENABLE_REG_A));
        printk("tvp5150: Interrupt configuration = 0x%02x\n",
-              tvp5150_read(c, TVP5150_INT_CONF));
-       printk("tvp5150: VDP configuration RAM data = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VDP_CONF_RAM_DATA));
-       printk("tvp5150: Configuration RAM address low byte = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CONF_RAM_ADDR_LOW));
-       printk("tvp5150: Configuration RAM address high byte = 0x%02x\n",
-              tvp5150_read(c, TVP5150_CONF_RAM_ADDR_HIGH));
+                                       tvp5150_read(c, TVP5150_INT_CONF));
        printk("tvp5150: VDP status register = 0x%02x\n",
-              tvp5150_read(c, TVP5150_VDP_STATUS_REG));
+                                       tvp5150_read(c, TVP5150_VDP_STATUS_REG));
        printk("tvp5150: FIFO word count = 0x%02x\n",
-              tvp5150_read(c, TVP5150_FIFO_WORD_COUNT));
+                                       tvp5150_read(c, TVP5150_FIFO_WORD_COUNT));
        printk("tvp5150: FIFO interrupt threshold = 0x%02x\n",
-              tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD));
+                                       tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD));
        printk("tvp5150: FIFO reset = 0x%02x\n",
-              tvp5150_read(c, TVP5150_FIFO_RESET));
+                                       tvp5150_read(c, TVP5150_FIFO_RESET));
        printk("tvp5150: Line number interrupt = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_NUMBER_INT));
-       printk("tvp5150: Pixel alignment register low byte = 0x%02x\n",
-              tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW));
-       printk("tvp5150: Pixel alignment register high byte = 0x%02x\n",
-              tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH));
+                                       tvp5150_read(c, TVP5150_LINE_NUMBER_INT));
+       printk("tvp5150: Pixel alignment register = 0x%02x%02x\n",
+                                       tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH),
+                                       tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW));
        printk("tvp5150: FIFO output control = 0x%02x\n",
-              tvp5150_read(c, TVP5150_FIFO_OUT_CTRL));
-       printk("tvp5150: Full field enable 1 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_FULL_FIELD_ENA_1));
-       printk("tvp5150: Full field enable 2 = 0x%02x\n",
-              tvp5150_read(c, TVP5150_FULL_FIELD_ENA_2));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_1));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_2));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_3));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_4));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_5));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_6));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_7));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_8));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_9));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_10));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_11));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_12));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_13));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_14));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_15));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_16));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_17));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_18));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_19));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_20));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_21));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_22));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_23));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_24));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_25));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_27));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_28));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_29));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_30));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_31));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_32));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_33));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_34));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_35));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_36));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_37));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_38));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_39));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_40));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_41));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_42));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_43));
-       printk("tvp5150: Line mode registers = 0x%02x\n",
-              tvp5150_read(c, TVP5150_LINE_MODE_REG_44));
+                                       tvp5150_read(c, TVP5150_FIFO_OUT_CTRL));
+       printk("tvp5150: Full field enable = 0x%02x\n",
+                                       tvp5150_read(c, TVP5150_FULL_FIELD_ENA));
        printk("tvp5150: Full field mode register = 0x%02x\n",
-              tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG));
+                                       tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG));
+
+       dump_reg_range(c,"CC   data",   TVP5150_CC_DATA_INI,
+                                       TVP5150_CC_DATA_END,8);
+
+       dump_reg_range(c,"WSS  data",   TVP5150_WSS_DATA_INI,
+                                       TVP5150_WSS_DATA_END,8);
+
+       dump_reg_range(c,"VPS  data",   TVP5150_VPS_DATA_INI,
+                                       TVP5150_VPS_DATA_END,8);
+
+       dump_reg_range(c,"VITC data",   TVP5150_VITC_DATA_INI,
+                                       TVP5150_VITC_DATA_END,10);
+
+       dump_reg_range(c,"Line mode",   TVP5150_LINE_MODE_INI,
+                                       TVP5150_LINE_MODE_END,8);
 }
 
 /****************************************************************************
@@ -593,10 +442,10 @@ static const struct i2c_reg_value tvp5150_init_default[] = {
                TVP5150_FIFO_OUT_CTRL,0x01
        },
        { /* 0xcf */
-               TVP5150_FULL_FIELD_ENA_1,0x00
+               TVP5150_FULL_FIELD_ENA,0x00
        },
        { /* 0xd0 */
-               TVP5150_FULL_FIELD_ENA_2,0x00
+               TVP5150_LINE_MODE_INI,0x00
        },
        { /* 0xfc */
                TVP5150_FULL_FIELD_MODE_REG,0x7f
@@ -629,54 +478,101 @@ static const struct i2c_reg_value tvp5150_init_enable[] = {
        }
 };
 
+struct tvp5150_vbi_type {
+       unsigned int vbi_type;
+       unsigned int ini_line;
+       unsigned int end_line;
+       unsigned int by_field :1;
+};
+
 struct i2c_vbi_ram_value {
        u16 reg;
-       unsigned char values[26];
+       struct tvp5150_vbi_type type;
+       unsigned char values[16];
 };
 
+/* This struct have the values for each supported VBI Standard
+ * by
+ tvp5150_vbi_types should follow the same order as vbi_ram_default
+ * value 0 means rom position 0x10, value 1 means rom position 0x30
+ * and so on. There are 16 possible locations from 0 to 15.
+ */
+
 static struct i2c_vbi_ram_value vbi_ram_default[] =
 {
-       {0x010, /* WST SECAM 6 */
-               { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x26, 0xe6, 0xb4, 0x0e, 0x0, 0x0, 0x0, 0x10, 0x0 }
+       {0x010, /* Teletext, SECAM, WST System A */
+               {V4L2_SLICED_TELETEXT_SECAM,6,23,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26,
+                 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x030, /* WST PAL B 6 */
-               { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x2b, 0xa6, 0x72, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0 }
+       {0x030, /* Teletext, PAL, WST System B */
+               {V4L2_SLICED_TELETEXT_PAL_B,6,22,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b,
+                 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x050, /* WST PAL C 6 */
-               { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0xa6, 0x98, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
+       {0x050, /* Teletext, PAL, WST System C */
+               {V4L2_SLICED_TELETEXT_PAL_C,6,22,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
+                 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x070, /* WST NTSC 6 */
-               { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
+       {0x070, /* Teletext, NTSC, WST System B */
+               {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23,
+                 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x090, /* NABTS, NTSC 6 */
-               { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x15, 0x0 }
+       {0x090, /* Tetetext, NTSC NABTS System C */
+               {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
+                 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 }
        },
-       {0x0b0, /* NABTS, NTSC-J 6 */
-               { 0xaa, 0xaa, 0xff, 0xff , 0xa7, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
+       {0x0b0, /* Teletext, NTSC-J, NABTS System D */
+               {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1},
+               { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23,
+                 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x0d0, /* CC, PAL/SECAM 6 */
-               { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0xa6, 0x7b, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 }
+       {0x0d0, /* Closed Caption, PAL/SECAM */
+               {V4L2_SLICED_CAPTION_625,22,22,1},
+               { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
+                 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
        },
-       {0x0f0, /* CC, NTSC 6 */
-               { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0x69, 0x8c, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 }
+       {0x0f0, /* Closed Caption, NTSC */
+               {V4L2_SLICED_CAPTION_525,21,21,1},
+               { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
+                 0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
        },
-       {0x110, /* WSS, PAL/SECAM 6 */
-               { 0x5b, 0x55, 0xc5, 0xff , 0x0, 0x71, 0x6e, 0x42, 0xa6, 0xcd, 0x0f, 0x0, 0x0, 0x0, 0x3a, 0x0 }
+       {0x110, /* Wide Screen Signal, PAL/SECAM */
+               {V4L2_SLICED_WSS_625,23,23,1},
+               { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42,
+                 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 }
        },
-       {0x130, /* WSS, NTSC C */
-               { 0x38, 0x00, 0x3f, 0x00 , 0x0, 0x71, 0x6e, 0x43, 0x69, 0x7c, 0x08, 0x0, 0x0, 0x0, 0x39, 0x0 }
+       {0x130, /* Wide Screen Signal, NTSC C */
+               {V4L2_SLICED_WSS_525,20,20,1},
+               { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43,
+                 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 }
        },
-       {0x150, /* VITC, PAL/SECAM 6 */
-               { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0xa6, 0x85, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 }
+       {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */
+               {V4l2_SLICED_VITC_625,6,22,0},
+               { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
+                 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
        },
-       {0x170, /* VITC, NTSC 6 */
-               { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0x69, 0x94, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 }
+       {0x170, /* Vertical Interval Timecode (VITC), NTSC */
+               {V4l2_SLICED_VITC_525,10,20,0},
+               { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
+                 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
        },
+       {0x190, /* Video Program System (VPS), PAL */
+               {V4L2_SLICED_VPS,16,16,0},
+               { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d,
+                 0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 }
+       },
+       /* 0x1d0 User programmable */
+
+       /* End of struct */
        { (u16)-1 }
 };
 
 static int tvp5150_write_inittab(struct i2c_client *c,
-                                const struct i2c_reg_value *regs)
+                               const struct i2c_reg_value *regs)
 {
        while (regs->reg != 0xff) {
                tvp5150_write(c, regs->reg, regs->value);
@@ -686,15 +582,15 @@ static int tvp5150_write_inittab(struct i2c_client *c,
 }
 
 static int tvp5150_vdp_init(struct i2c_client *c,
-                                const struct i2c_vbi_ram_value *regs)
+                               const struct i2c_vbi_ram_value *regs)
 {
        unsigned int i;
 
        /* Disable Full Field */
-       tvp5150_write(c, TVP5150_FULL_FIELD_ENA_1, 0);
+       tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0);
 
        /* Before programming, Line mode should be at 0xff */
-       for (i=TVP5150_FULL_FIELD_ENA_2; i<=TVP5150_LINE_MODE_REG_44; i++)
+       for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++)
                tvp5150_write(c, i, 0xff);
 
        /* Load Ram Table */
@@ -710,6 +606,117 @@ static int tvp5150_vdp_init(struct i2c_client *c,
        return 0;
 }
 
+/* Fills VBI capabilities based on i2c_vbi_ram_value struct */
+static void tvp5150_vbi_get_cap(const struct i2c_vbi_ram_value *regs,
+                               struct v4l2_sliced_vbi_cap *cap)
+{
+       int line;
+
+       memset(cap, 0, sizeof *cap);
+
+       while (regs->reg != (u16)-1 ) {
+               for (line=regs->type.ini_line;line<=regs->type.end_line;line++) {
+                       cap->service_lines[0][line] |= regs->type.vbi_type;
+               }
+               cap->service_set |= regs->type.vbi_type;
+
+               regs++;
+       }
+}
+
+/* Set vbi processing
+ * type - one of tvp5150_vbi_types
+ * line - line to gather data
+ * fields: bit 0 field1, bit 1, field2
+ * flags (default=0xf0) is a bitmask, were set means:
+ *     bit 7: enable filtering null bytes on CC
+ *     bit 6: send data also to FIFO
+ *     bit 5: don't allow data with errors on FIFO
+ *     bit 4: enable ECC when possible
+ * pix_align = pix alignment:
+ *     LSB = field1
+ *     MSB = field2
+ */
+static int tvp5150_set_vbi(struct i2c_client *c,
+                       const struct i2c_vbi_ram_value *regs,
+                       unsigned int type,u8 flags, int line,
+                       const int fields)
+{
+       struct tvp5150 *decoder = i2c_get_clientdata(c);
+       v4l2_std_id std=decoder->norm;
+       u8 reg;
+       int pos=0;
+
+       if (std == V4L2_STD_ALL) {
+               tvp5150_err("VBI can't be configured without knowing number of lines\n");
+               return 0;
+       } else if (std && V4L2_STD_625_50) {
+               /* Don't follow NTSC Line number convension */
+               line += 3;
+       }
+
+       if (line<6||line>27)
+               return 0;
+
+       while (regs->reg != (u16)-1 ) {
+               if ((type & regs->type.vbi_type) &&
+                   (line>=regs->type.ini_line) &&
+                   (line<=regs->type.end_line)) {
+                       type=regs->type.vbi_type;
+                       break;
+               }
+
+               regs++;
+               pos++;
+       }
+       if (regs->reg == (u16)-1)
+               return 0;
+
+       type=pos | (flags & 0xf0);
+       reg=((line-6)<<1)+TVP5150_LINE_MODE_INI;
+
+       if (fields&1) {
+               tvp5150_write(c, reg, type);
+       }
+
+       if (fields&2) {
+               tvp5150_write(c, reg+1, type);
+       }
+
+       return type;
+}
+
+static int tvp5150_get_vbi(struct i2c_client *c,
+                       const struct i2c_vbi_ram_value *regs, int line)
+{
+       struct tvp5150 *decoder = i2c_get_clientdata(c);
+       v4l2_std_id std=decoder->norm;
+       u8 reg;
+       int pos, type=0;
+
+       if (std == V4L2_STD_ALL) {
+               tvp5150_err("VBI can't be configured without knowing number of lines\n");
+               return 0;
+       } else if (std && V4L2_STD_625_50) {
+               /* Don't follow NTSC Line number convension */
+               line += 3;
+       }
+
+       if (line<6||line>27)
+               return 0;
+
+       reg=((line-6)<<1)+TVP5150_LINE_MODE_INI;
+
+       pos=tvp5150_read(c, reg)&0x0f;
+       if (pos<0x0f)
+               type=regs[pos].type.vbi_type;
+
+       pos=tvp5150_read(c, reg+1)&0x0f;
+       if (pos<0x0f)
+               type|=regs[pos].type.vbi_type;
+
+       return type;
+}
 static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std)
 {
        struct tvp5150 *decoder = i2c_get_clientdata(c);
@@ -854,6 +861,69 @@ static int tvp5150_command(struct i2c_client *c,
                *(v4l2_std_id *)arg = decoder->norm;
                break;
 
+       case VIDIOC_G_SLICED_VBI_CAP:
+       {
+               struct v4l2_sliced_vbi_cap *cap = arg;
+               tvp5150_dbg(1, "VIDIOC_G_SLICED_VBI_CAP\n");
+
+               tvp5150_vbi_get_cap(vbi_ram_default, cap);
+               break;
+       }
+       case VIDIOC_S_FMT:
+       {
+               struct v4l2_format *fmt;
+               struct v4l2_sliced_vbi_format *svbi;
+               int i;
+
+               fmt = arg;
+               if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+                       return -EINVAL;
+               svbi = &fmt->fmt.sliced;
+               if (svbi->service_set != 0) {
+                       for (i = 0; i <= 23; i++) {
+                               svbi->service_lines[1][i] = 0;
+
+                               svbi->service_lines[0][i]=tvp5150_set_vbi(c,
+                                        vbi_ram_default,
+                                        svbi->service_lines[0][i],0xf0,i,3);
+                       }
+                       /* Enables FIFO */
+                       tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,1);
+               } else {
+                       /* Disables FIFO*/
+                       tvp5150_write(c, TVP5150_FIFO_OUT_CTRL,0);
+
+                       /* Disable Full Field */
+                       tvp5150_write(c, TVP5150_FULL_FIELD_ENA, 0);
+
+                       /* Disable Line modes */
+                       for (i=TVP5150_LINE_MODE_INI; i<=TVP5150_LINE_MODE_END; i++)
+                               tvp5150_write(c, i, 0xff);
+               }
+               break;
+       }
+       case VIDIOC_G_FMT:
+       {
+               struct v4l2_format *fmt;
+               struct v4l2_sliced_vbi_format *svbi;
+
+               int i, mask=0;
+
+               fmt = arg;
+               if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+                       return -EINVAL;
+               svbi = &fmt->fmt.sliced;
+               memset(svbi, 0, sizeof(*svbi));
+
+               for (i = 0; i <= 23; i++) {
+                       svbi->service_lines[0][i]=tvp5150_get_vbi(c,
+                               vbi_ram_default,i);
+                       mask|=svbi->service_lines[0][i];
+               }
+               svbi->service_set=mask;
+               break;
+       }
+
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        case VIDIOC_INT_G_REGISTER:
        {
@@ -878,6 +948,7 @@ static int tvp5150_command(struct i2c_client *c,
        }
 #endif
 
+       case VIDIOC_LOG_STATUS:
        case DECODER_DUMP:
                dump_reg(c);
                break;
@@ -1097,7 +1168,7 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter,
 
        rv = i2c_attach_client(c);
 
-       core->norm = V4L2_STD_ALL;
+       core->norm = V4L2_STD_ALL;      /* Default is autodetect */
        core->input = 2;
        core->enable = 1;
        core->bright = 32768;
index cd45c1ded786fb231e8bba5b82b73ec8f9dba6e3..4240043c0b2a5ea445c2bd2247a3037722cc9e43 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder registers
+ *
+ * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org)
+ * This code is placed under the terms of the GNU General Public License v2
+ */
+
 #define TVP5150_VD_IN_SRC_SEL_1      0x00 /* Video input source selection #1 */
 #define TVP5150_ANAL_CHL_CTL         0x01 /* Analog channel controls */
 #define TVP5150_OP_MODE_CTL          0x02 /* Operation mode controls */
 #define TVP5150_STATUS_REG_4        0x8b /* Status register #4 */
 #define TVP5150_STATUS_REG_5        0x8c /* Status register #5 */
 /* Reserved    8Dh-8Fh */
-#define TVP5150_CC_DATA_REG1        0x90 /* Closed caption data registers */
-#define TVP5150_CC_DATA_REG2        0x91 /* Closed caption data registers */
-#define TVP5150_CC_DATA_REG3        0x92 /* Closed caption data registers */
-#define TVP5150_CC_DATA_REG4        0x93 /* Closed caption data registers */
-#define TVP5150_WSS_DATA_REG1       0X94 /* WSS data registers */
-#define TVP5150_WSS_DATA_REG2       0X95 /* WSS data registers */
-#define TVP5150_WSS_DATA_REG3       0X96 /* WSS data registers */
-#define TVP5150_WSS_DATA_REG4       0X97 /* WSS data registers */
-#define TVP5150_WSS_DATA_REG5       0X98 /* WSS data registers */
-#define TVP5150_WSS_DATA_REG6       0X99 /* WSS data registers */
-#define TVP5150_VPS_DATA_REG1       0x9a /* VPS data registers */
-#define TVP5150_VPS_DATA_REG2       0x9b /* VPS data registers */
-#define TVP5150_VPS_DATA_REG3       0x9c /* VPS data registers */
-#define TVP5150_VPS_DATA_REG4       0x9d /* VPS data registers */
-#define TVP5150_VPS_DATA_REG5       0x9e /* VPS data registers */
-#define TVP5150_VPS_DATA_REG6       0x9f /* VPS data registers */
-#define TVP5150_VPS_DATA_REG7       0xa0 /* VPS data registers */
-#define TVP5150_VPS_DATA_REG8       0xa1 /* VPS data registers */
-#define TVP5150_VPS_DATA_REG9       0xa2 /* VPS data registers */
-#define TVP5150_VPS_DATA_REG10      0xa3 /* VPS data registers */
-#define TVP5150_VPS_DATA_REG11      0xa4 /* VPS data registers */
-#define TVP5150_VPS_DATA_REG12      0xa5 /* VPS data registers */
-#define TVP5150_VPS_DATA_REG13      0xa6 /* VPS data registers */
-#define TVP5150_VITC_DATA_REG1      0xa7 /* VITC data registers */
-#define TVP5150_VITC_DATA_REG2      0xa8 /* VITC data registers */
-#define TVP5150_VITC_DATA_REG3      0xa9 /* VITC data registers */
-#define TVP5150_VITC_DATA_REG4      0xaa /* VITC data registers */
-#define TVP5150_VITC_DATA_REG5      0xab /* VITC data registers */
-#define TVP5150_VITC_DATA_REG6      0xac /* VITC data registers */
-#define TVP5150_VITC_DATA_REG7      0xad /* VITC data registers */
-#define TVP5150_VITC_DATA_REG8      0xae /* VITC data registers */
-#define TVP5150_VITC_DATA_REG9      0xaf /* VITC data registers */
+ /* Closed caption data registers */
+#define TVP5150_CC_DATA_INI         0x90
+#define TVP5150_CC_DATA_END         0x93
+
+ /* WSS data registers */
+#define TVP5150_WSS_DATA_INI        0x94
+#define TVP5150_WSS_DATA_END        0x99
+
+/* VPS data registers */
+#define TVP5150_VPS_DATA_INI        0x9a
+#define TVP5150_VPS_DATA_END        0xa6
+
+/* VITC data registers */
+#define TVP5150_VITC_DATA_INI       0xa7
+#define TVP5150_VITC_DATA_END       0xaf
+
 #define TVP5150_VBI_FIFO_READ_DATA  0xb0 /* VBI FIFO read data */
-#define TVP5150_TELETEXT_FIL_1_1    0xb1 /* Teletext filter 1 */
-#define TVP5150_TELETEXT_FIL_1_2    0xb2 /* Teletext filter 1 */
-#define TVP5150_TELETEXT_FIL_1_3    0xb3 /* Teletext filter 1 */
-#define TVP5150_TELETEXT_FIL_1_4    0xb4 /* Teletext filter 1 */
-#define TVP5150_TELETEXT_FIL_1_5    0xb5 /* Teletext filter 1 */
-#define TVP5150_TELETEXT_FIL_2_1    0xb6 /* Teletext filter 2 */
-#define TVP5150_TELETEXT_FIL_2_2    0xb7 /* Teletext filter 2 */
-#define TVP5150_TELETEXT_FIL_2_3    0xb8 /* Teletext filter 2 */
-#define TVP5150_TELETEXT_FIL_2_4    0xb9 /* Teletext filter 2 */
-#define TVP5150_TELETEXT_FIL_2_5    0xba /* Teletext filter 2 */
+
+/* Teletext filter 1 */
+#define TVP5150_TELETEXT_FIL1_INI  0xb1
+#define TVP5150_TELETEXT_FIL1_END  0xb5
+
+/* Teletext filter 2 */
+#define TVP5150_TELETEXT_FIL2_INI  0xb6
+#define TVP5150_TELETEXT_FIL2_END  0xba
+
 #define TVP5150_TELETEXT_FIL_ENA    0xbb /* Teletext filter enable */
 /* Reserved    BCh-BFh */
 #define TVP5150_INT_STATUS_REG_A    0xc0 /* Interrupt status register A */
 #define TVP5150_PIX_ALIGN_REG_HIGH  0xcc /* Pixel alignment register high byte */
 #define TVP5150_FIFO_OUT_CTRL       0xcd /* FIFO output control */
 /* Reserved    CEh */
-#define TVP5150_FULL_FIELD_ENA_1    0xcf /* Full field enable 1 */
-#define TVP5150_FULL_FIELD_ENA_2    0xd0 /* Full field enable 2 */
-#define TVP5150_LINE_MODE_REG_1     0xd1 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_2     0xd2 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_3     0xd3 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_4     0xd4 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_5     0xd5 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_6     0xd6 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_7     0xd7 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_8     0xd8 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_9     0xd9 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_10    0xda /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_11    0xdb /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_12    0xdc /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_13    0xdd /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_14    0xde /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_15    0xdf /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_16    0xe0 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_17    0xe1 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_18    0xe2 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_19    0xe3 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_20    0xe4 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_21    0xe5 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_22    0xe6 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_23    0xe7 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_24    0xe8 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_25    0xe9 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_27    0xea /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_28    0xeb /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_29    0xec /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_30    0xed /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_31    0xee /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_32    0xef /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_33    0xf0 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_34    0xf1 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_35    0xf2 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_36    0xf3 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_37    0xf4 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_38    0xf5 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_39    0xf6 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_40    0xf7 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_41    0xf8 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_42    0xf9 /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_43    0xfa /* Line mode registers */
-#define TVP5150_LINE_MODE_REG_44    0xfb /* Line mode registers */
+#define TVP5150_FULL_FIELD_ENA      0xcf /* Full field enable 1 */
+
+/* Line mode registers */
+#define TVP5150_LINE_MODE_INI       0xd0
+#define TVP5150_LINE_MODE_END       0xfb
+
 #define TVP5150_FULL_FIELD_MODE_REG 0xfc /* Full field mode register */
 /* Reserved    FDh-FFh */
index cd2c4475525e5ad28a02df302c1e7ff2d457488b..95a6e47c99f185f41d2165d554b6cefb4379beca 100644 (file)
@@ -97,7 +97,7 @@ int v4l2_video_std_construct(struct v4l2_standard *vs,
        memset(vs, 0, sizeof(struct v4l2_standard));
        vs->index = index;
        vs->id    = id;
-       if (id & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) {
+       if (id & V4L2_STD_525_60) {
                vs->frameperiod.numerator = 1001;
                vs->frameperiod.denominator = 30000;
                vs->framelines = 525;
@@ -110,7 +110,6 @@ int v4l2_video_std_construct(struct v4l2_standard *vs,
        return 0;
 }
 
-
 /* ----------------------------------------------------------------- */
 /* priority handling                                                 */
 
@@ -171,7 +170,7 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
 
 
 /* ----------------------------------------------------------------- */
-/* some arrays for pretty-printing debug messages                    */
+/* some arrays for pretty-printing debug messages of enum types      */
 
 char *v4l2_field_names[] = {
        [V4L2_FIELD_ANY]        = "any",
@@ -192,6 +191,14 @@ char *v4l2_type_names[] = {
        [V4L2_BUF_TYPE_VBI_OUTPUT]    = "vbi-out",
 };
 
+static char *v4l2_memory_names[] = {
+       [V4L2_MEMORY_MMAP]    = "mmap",
+       [V4L2_MEMORY_USERPTR] = "userptr",
+       [V4L2_MEMORY_OVERLAY] = "overlay",
+};
+
+#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
+
 /* ------------------------------------------------------------------ */
 /* debug help functions                                               */
 
@@ -324,6 +331,15 @@ static const char *v4l2_int_ioctls[] = {
 };
 #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
 
+static void v4l_print_pix_fmt (char *s, struct v4l2_pix_format *fmt)
+{
+       printk ("%s: width=%d, height=%d, format=%d, field=%s, "
+               "bytesperline=%d sizeimage=%d, colorspace=%d\n", s,
+               fmt->width,fmt->height,fmt->pixelformat,
+               prt_names(fmt->field,v4l2_field_names),
+               fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
+};
+
 /* Common ioctl debug function. This function can be used by
    external ioctl messages as well as internal V4L ioctl */
 void v4l_printk_ioctl(unsigned int cmd)
@@ -362,6 +378,541 @@ void v4l_printk_ioctl(unsigned int cmd)
        }
 }
 
+/* Common ioctl debug function. This function can be used by
+   external ioctl messages as well as internal V4L ioctl and its
+   arguments */
+void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
+{
+       printk(s);
+       printk(": ");
+       v4l_printk_ioctl(cmd);
+       switch (cmd) {
+       case VIDIOC_INT_G_CHIP_IDENT:
+       {
+               enum v4l2_chip_ident  *p=arg;
+               printk ("%s: chip ident=%d\n", s, *p);
+               break;
+       }
+       case VIDIOC_G_PRIORITY:
+       case VIDIOC_S_PRIORITY:
+       {
+               enum v4l2_priority *p=arg;
+               printk ("%s: priority=%d\n", s, *p);
+               break;
+       }
+       case VIDIOC_INT_S_TUNER_MODE:
+       {
+               enum v4l2_tuner_type *p=arg;
+               printk ("%s: tuner type=%d\n", s, *p);
+               break;
+       }
+       case DECODER_SET_VBI_BYPASS:
+       case DECODER_ENABLE_OUTPUT:
+       case DECODER_GET_STATUS:
+       case DECODER_SET_OUTPUT:
+       case DECODER_SET_INPUT:
+       case DECODER_SET_GPIO:
+       case DECODER_SET_NORM:
+       case VIDIOCCAPTURE:
+       case VIDIOCSYNC:
+       case VIDIOCSWRITEMODE:
+       case TUNER_SET_TYPE_ADDR:
+       case TUNER_SET_STANDBY:
+       case TDA9887_SET_CONFIG:
+       case AUDC_SET_INPUT:
+       case VIDIOC_OVERLAY_OLD:
+       case VIDIOC_STREAMOFF:
+       case VIDIOC_G_OUTPUT:
+       case VIDIOC_S_OUTPUT:
+       case VIDIOC_STREAMON:
+       case VIDIOC_G_INPUT:
+       case VIDIOC_OVERLAY:
+       case VIDIOC_S_INPUT:
+       {
+               int *p=arg;
+               printk ("%s: value=%d\n", s, *p);
+               break;
+       }
+       case MSP_SET_MATRIX:
+       {
+               struct msp_matrix *p=arg;
+               printk ("%s: input=%d, output=%d\n", s, p->input, p->output);
+               break;
+       }
+       case VIDIOC_G_AUDIO:
+       case VIDIOC_S_AUDIO:
+       case VIDIOC_ENUMAUDIO:
+       case VIDIOC_G_AUDIO_OLD:
+       {
+               struct v4l2_audio *p=arg;
+
+               printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n",
+                       s,p->index, p->name,p->capability, p->mode);
+               break;
+       }
+       case VIDIOC_G_AUDOUT:
+       case VIDIOC_S_AUDOUT:
+       case VIDIOC_ENUMAUDOUT:
+       case VIDIOC_G_AUDOUT_OLD:
+       {
+               struct v4l2_audioout *p=arg;
+               printk ("%s: index=%d, name=%s, capability=%d, mode=%d\n", s,
+                               p->index, p->name, p->capability,p->mode);
+               break;
+       }
+       case VIDIOC_QBUF:
+       case VIDIOC_DQBUF:
+       case VIDIOC_QUERYBUF:
+       {
+               struct v4l2_buffer *p=arg;
+               struct v4l2_timecode *tc=&p->timecode;
+               printk ("%s: %02ld:%02d:%02d.%08ld index=%d, type=%s, "
+                       "bytesused=%d, flags=0x%08d, "
+                       "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n",
+                               s,
+                               (p->timestamp.tv_sec/3600),
+                               (int)(p->timestamp.tv_sec/60)%60,
+                               (int)(p->timestamp.tv_sec%60),
+                               p->timestamp.tv_usec,
+                               p->index,
+                               prt_names(p->type,v4l2_type_names),
+                               p->bytesused,p->flags,
+                               p->field,p->sequence,
+                               prt_names(p->memory,v4l2_memory_names),
+                               p->m.userptr);
+               printk ("%s: timecode= %02d:%02d:%02d type=%d, "
+                       "flags=0x%08d, frames=%d, userbits=0x%08x",
+                               s,tc->hours,tc->minutes,tc->seconds,
+                               tc->type, tc->flags, tc->frames, (__u32) tc->userbits);
+               break;
+       }
+       case VIDIOC_QUERYCAP:
+       {
+               struct v4l2_capability *p=arg;
+               printk ("%s: driver=%s, card=%s, bus=%s, version=%d, "
+                       "capabilities=%d\n", s,
+                               p->driver,p->card,p->bus_info,
+                               p->version,
+                               p->capabilities);
+               break;
+       }
+       case VIDIOC_G_CTRL:
+       case VIDIOC_S_CTRL:
+       case VIDIOC_S_CTRL_OLD:
+       {
+               struct v4l2_control *p=arg;
+               printk ("%s: id=%d, value=%d\n", s, p->id, p->value);
+               break;
+       }
+       case VIDIOC_G_CROP:
+       case VIDIOC_S_CROP:
+       {
+               struct v4l2_crop *p=arg;
+               /*FIXME: Should also show rect structs */
+               printk ("%s: type=%d\n", s, p->type);
+               break;
+       }
+       case VIDIOC_CROPCAP:
+       case VIDIOC_CROPCAP_OLD:
+       {
+               struct v4l2_cropcap *p=arg;
+               /*FIXME: Should also show rect structs */
+               printk ("%s: type=%d\n", s, p->type);
+               break;
+       }
+       case VIDIOC_INT_DECODE_VBI_LINE:
+       {
+               struct v4l2_decode_vbi_line *p=arg;
+               printk ("%s: is_second_field=%d, ptr=0x%08lx, line=%d, "
+                       "type=%d\n", s,
+                               p->is_second_field,(unsigned long)p->p,p->line,p->type);
+               break;
+       }
+       case VIDIOC_ENUM_FMT:
+       {
+               struct v4l2_fmtdesc *p=arg;
+               printk ("%s: index=%d, type=%d, flags=%d, description=%s,"
+                       " pixelformat=%d\n", s,
+                               p->index, p->type, p->flags,p->description,
+                               p->pixelformat);
+
+               break;
+       }
+       case VIDIOC_G_FMT:
+       case VIDIOC_S_FMT:
+       case VIDIOC_TRY_FMT:
+       {
+               struct v4l2_format *p=arg;
+               printk ("%s: type=%s\n", s,
+                               prt_names(p->type,v4l2_type_names));
+               switch (p->type) {
+               case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+                       v4l_print_pix_fmt (s, &p->fmt.pix);
+                       break;
+               default:
+                       break;
+               }
+       }
+       case VIDIOC_G_FBUF:
+       case VIDIOC_S_FBUF:
+       {
+               struct v4l2_framebuffer *p=arg;
+               printk ("%s: capability=%d, flags=%d, base=0x%08lx\n", s,
+                               p->capability,p->flags, (unsigned long)p->base);
+               v4l_print_pix_fmt (s, &p->fmt);
+               break;
+       }
+       case VIDIOC_G_FREQUENCY:
+       case VIDIOC_S_FREQUENCY:
+       {
+               struct v4l2_frequency *p=arg;
+               printk ("%s: tuner=%d, type=%d, frequency=%d\n", s,
+                               p->tuner,p->type,p->frequency);
+               break;
+       }
+       case VIDIOC_ENUMINPUT:
+       {
+               struct v4l2_input *p=arg;
+               printk ("%s: index=%d, name=%s, type=%d, audioset=%d, "
+                       "tuner=%d, std=%lld, status=%d\n", s,
+                               p->index,p->name,p->type,p->audioset,
+                               p->tuner,p->std,
+                               p->status);
+               break;
+       }
+       case VIDIOC_G_JPEGCOMP:
+       case VIDIOC_S_JPEGCOMP:
+       {
+               struct v4l2_jpegcompression *p=arg;
+               printk ("%s: quality=%d, APPn=%d, APP_len=%d, COM_len=%d,"
+                       " jpeg_markers=%d\n", s,
+                               p->quality,p->APPn,p->APP_len,
+                               p->COM_len,p->jpeg_markers);
+               break;
+       }
+       case VIDIOC_G_MODULATOR:
+       case VIDIOC_S_MODULATOR:
+       {
+               struct v4l2_modulator *p=arg;
+               printk ("%s: index=%d, name=%s, capability=%d, rangelow=%d,"
+                       " rangehigh=%d, txsubchans=%d\n", s,
+                               p->index, p->name,p->capability,p->rangelow,
+                               p->rangehigh,p->txsubchans);
+               break;
+       }
+       case VIDIOC_G_MPEGCOMP:
+       case VIDIOC_S_MPEGCOMP:
+       {
+               struct v4l2_mpeg_compression *p=arg;
+               /*FIXME: Several fields not shown */
+               printk ("%s: ts_pid_pmt=%d, ts_pid_audio=%d, ts_pid_video=%d, "
+                       "ts_pid_pcr=%d, ps_size=%d, au_sample_rate=%d, "
+                       "au_pesid=%c, vi_frame_rate=%d, vi_frames_per_gop=%d, "
+                       "vi_bframes_count=%d, vi_pesid=%c\n", s,
+                               p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
+                               p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
+                               p->au_pesid, p->vi_frame_rate,
+                               p->vi_frames_per_gop, p->vi_bframes_count,
+                               p->vi_pesid);
+               break;
+       }
+       case VIDIOC_ENUMOUTPUT:
+       {
+               struct v4l2_output *p=arg;
+               printk ("%s: index=%d, name=%s,type=%d, audioset=%d, "
+                       "modulator=%d, std=%lld\n",
+                               s,p->index,p->name,p->type,p->audioset,
+                               p->modulator,p->std);
+               break;
+       }
+       case VIDIOC_QUERYCTRL:
+       {
+               struct v4l2_queryctrl *p=arg;
+               printk ("%s: id=%d, type=%d, name=%s, min/max=%d/%d,"
+                       " step=%d, default=%d, flags=0x%08x\n", s,
+                               p->id,p->type,p->name,p->minimum,p->maximum,
+                               p->step,p->default_value,p->flags);
+               break;
+       }
+       case VIDIOC_QUERYMENU:
+       {
+               struct v4l2_querymenu *p=arg;
+               printk ("%s: id=%d, index=%d, name=%s\n", s,
+                               p->id,p->index,p->name);
+               break;
+       }
+       case VIDIOC_INT_G_REGISTER:
+       case VIDIOC_INT_S_REGISTER:
+       {
+               struct v4l2_register *p=arg;
+               printk ("%s: i2c_id=%d, reg=%lu, val=%d\n", s,
+                               p->i2c_id,p->reg,p->val);
+
+               break;
+       }
+       case VIDIOC_REQBUFS:
+       {
+               struct v4l2_requestbuffers *p=arg;
+               printk ("%s: count=%d, type=%s, memory=%s\n", s,
+                               p->count,
+                               prt_names(p->type,v4l2_type_names),
+                               prt_names(p->memory,v4l2_memory_names));
+               break;
+       }
+       case VIDIOC_INT_S_AUDIO_ROUTING:
+       case VIDIOC_INT_S_VIDEO_ROUTING:
+       case VIDIOC_INT_G_AUDIO_ROUTING:
+       case VIDIOC_INT_G_VIDEO_ROUTING:
+       {
+               struct v4l2_routing  *p=arg;
+               printk ("%s: input=%d, output=%d\n", s, p->input, p->output);
+               break;
+       }
+       case VIDIOC_G_SLICED_VBI_CAP:
+       {
+               struct v4l2_sliced_vbi_cap *p=arg;
+               printk ("%s: service_set=%d\n", s,
+                               p->service_set);
+               break;
+       }
+       case VIDIOC_INT_S_VBI_DATA:
+       case VIDIOC_INT_G_VBI_DATA:
+       {
+               struct v4l2_sliced_vbi_data  *p=arg;
+               printk ("%s: id=%d, field=%d, line=%d\n", s,
+                               p->id, p->field, p->line);
+               break;
+       }
+       case VIDIOC_ENUMSTD:
+       {
+               struct v4l2_standard *p=arg;
+               printk ("%s: index=%d, id=%lld, name=%s, fps=%d/%d, framelines=%d\n", s,
+                               p->index, p->id, p->name,
+                               p->frameperiod.numerator,
+                               p->frameperiod.denominator,
+                               p->framelines);
+
+               break;
+       }
+       case VIDIOC_G_PARM:
+       case VIDIOC_S_PARM:
+       case VIDIOC_S_PARM_OLD:
+       {
+               struct v4l2_streamparm *p=arg;
+               printk ("%s: type=%d\n", s, p->type);
+
+               break;
+       }
+       case VIDIOC_G_TUNER:
+       case VIDIOC_S_TUNER:
+       {
+               struct v4l2_tuner *p=arg;
+               printk ("%s: index=%d, name=%s, type=%d, capability=%d, "
+                       "rangelow=%d, rangehigh=%d, signal=%d, afc=%d, "
+                       "rxsubchans=%d, audmode=%d\n", s,
+                               p->index, p->name, p->type,
+                               p->capability, p->rangelow,p->rangehigh,
+                               p->rxsubchans, p->audmode, p->signal,
+                               p->afc);
+               break;
+       }
+       case VIDIOCGVBIFMT:
+       case VIDIOCSVBIFMT:
+       {
+               struct vbi_format *p=arg;
+               printk ("%s: sampling_rate=%d, samples_per_line=%d, "
+                       "sample_format=%d, start=%d/%d, count=%d/%d, flags=%d\n", s,
+                               p->sampling_rate,p->samples_per_line,
+                               p->sample_format,p->start[0],p->start[1],
+                               p->count[0],p->count[1],p->flags);
+               break;
+       }
+       case VIDIOCGAUDIO:
+       case VIDIOCSAUDIO:
+       {
+               struct video_audio *p=arg;
+               printk ("%s: audio=%d, volume=%d, bass=%d, treble=%d, "
+                       "flags=%d, name=%s, mode=%d, balance=%d, step=%d\n",
+                               s,p->audio,p->volume,p->bass, p->treble,
+                               p->flags,p->name,p->mode,p->balance,p->step);
+               break;
+       }
+       case VIDIOCGFBUF:
+       case VIDIOCSFBUF:
+       {
+               struct video_buffer *p=arg;
+               printk ("%s: base=%08lx, height=%d, width=%d, depth=%d, "
+                       "bytesperline=%d\n", s,
+                               (unsigned long) p->base, p->height, p->width,
+                               p->depth,p->bytesperline);
+               break;
+       }
+       case VIDIOCGCAP:
+       {
+               struct video_capability *p=arg;
+               printk ("%s: name=%s, type=%d, channels=%d, audios=%d, "
+                       "maxwidth=%d, maxheight=%d, minwidth=%d, minheight=%d\n",
+                               s,p->name,p->type,p->channels,p->audios,
+                               p->maxwidth,p->maxheight,p->minwidth,
+                               p->minheight);
+
+               break;
+       }
+       case VIDIOCGCAPTURE:
+       case VIDIOCSCAPTURE:
+       {
+               struct video_capture *p=arg;
+               printk ("%s: x=%d, y=%d, width=%d, height=%d, decimation=%d,"
+                       " flags=%d\n", s,
+                               p->x, p->y,p->width, p->height,
+                               p->decimation,p->flags);
+               break;
+       }
+       case VIDIOCGCHAN:
+       case VIDIOCSCHAN:
+       {
+               struct video_channel *p=arg;
+               printk ("%s: channel=%d, name=%s, tuners=%d, flags=%d, "
+                       "type=%d, norm=%d\n", s,
+                               p->channel,p->name,p->tuners,
+                               p->flags,p->type,p->norm);
+
+               break;
+       }
+       case VIDIOCSMICROCODE:
+       {
+               struct video_code *p=arg;
+               printk ("%s: loadwhat=%s, datasize=%d\n", s,
+                               p->loadwhat,p->datasize);
+               break;
+       }
+       case DECODER_GET_CAPABILITIES:
+       {
+               struct video_decoder_capability *p=arg;
+               printk ("%s: flags=%d, inputs=%d, outputs=%d\n", s,
+                               p->flags,p->inputs,p->outputs);
+               break;
+       }
+       case DECODER_INIT:
+       {
+               struct video_decoder_init *p=arg;
+               printk ("%s: len=%c\n", s, p->len);
+               break;
+       }
+       case VIDIOCGPLAYINFO:
+       {
+               struct video_info *p=arg;
+               printk ("%s: frame_count=%d, h_size=%d, v_size=%d, "
+                       "smpte_timecode=%d, picture_type=%d, "
+                       "temporal_reference=%d, user_data=%s\n", s,
+                               p->frame_count, p->h_size,
+                               p->v_size, p->smpte_timecode,
+                               p->picture_type, p->temporal_reference,
+                               p->user_data);
+               break;
+       }
+       case VIDIOCKEY:
+       {
+               struct video_key *p=arg;
+               printk ("%s: key=%s, flags=%d\n", s,
+                               p->key, p->flags);
+               break;
+       }
+       case VIDIOCGMBUF:
+       {
+               struct video_mbuf *p=arg;
+               printk ("%s: size=%d, frames=%d, offsets=0x%08lx\n", s,
+                               p->size,
+                               p->frames,
+                               (unsigned long)p->offsets);
+               break;
+       }
+       case VIDIOCMCAPTURE:
+       {
+               struct video_mmap *p=arg;
+               printk ("%s: frame=%d, height=%d, width=%d, format=%d\n", s,
+                               p->frame,
+                               p->height, p->width,
+                               p->format);
+               break;
+       }
+       case VIDIOCGPICT:
+       case VIDIOCSPICT:
+       case DECODER_SET_PICTURE:
+       {
+               struct video_picture *p=arg;
+
+               printk ("%s: brightness=%d, hue=%d, colour=%d, contrast=%d,"
+                       " whiteness=%d, depth=%d, palette=%d\n", s,
+                               p->brightness, p->hue, p->colour,
+                               p->contrast, p->whiteness, p->depth,
+                               p->palette);
+               break;
+       }
+       case VIDIOCSPLAYMODE:
+       {
+               struct video_play_mode *p=arg;
+               printk ("%s: mode=%d, p1=%d, p2=%d\n", s,
+                               p->mode,p->p1,p->p2);
+               break;
+       }
+       case VIDIOCGTUNER:
+       case VIDIOCSTUNER:
+       {
+               struct video_tuner *p=arg;
+               printk ("%s: tuner=%d, name=%s, rangelow=%ld, rangehigh=%ld, "
+                       "flags=%d, mode=%d, signal=%d\n", s,
+                               p->tuner, p->name,p->rangelow, p->rangehigh,
+                               p->flags,p->mode, p->signal);
+               break;
+       }
+       case VIDIOCGUNIT:
+       {
+               struct video_unit *p=arg;
+               printk ("%s: video=%d, vbi=%d, radio=%d, audio=%d, "
+                       "teletext=%d\n", s,
+                               p->video,p->vbi,p->radio,p->audio,p->teletext);
+               break;
+       }
+       case VIDIOCGWIN:
+       case VIDIOCSWIN:
+       {
+               struct video_window *p=arg;
+               printk ("%s: x=%d, y=%d, width=%d, height=%d, chromakey=%d,"
+                       " flags=%d, clipcount=%d\n", s,
+                               p->x, p->y,p->width, p->height,
+                               p->chromakey,p->flags,
+                               p->clipcount);
+               break;
+       }
+       case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+       case VIDIOC_INT_I2S_CLOCK_FREQ:
+       case VIDIOC_INT_S_STANDBY:
+       {
+               u32 *p=arg;
+
+               printk ("%s: value=%d\n", s, *p);
+               break;
+       }
+       case VIDIOCGFREQ:
+       case VIDIOCSFREQ:
+       {
+               unsigned long *p=arg;
+               printk ("%s: value=%lu\n", s, *p);
+               break;
+       }
+       case VIDIOC_G_STD:
+       case VIDIOC_S_STD:
+       case VIDIOC_QUERYSTD:
+       {
+               v4l2_std_id *p=arg;
+
+               printk ("%s: value=%llu\n", s, *p);
+               break;
+       }
+       }
+}
+
 /* ----------------------------------------------------------------- */
 
 EXPORT_SYMBOL(v4l2_video_std_construct);
@@ -376,6 +927,7 @@ EXPORT_SYMBOL(v4l2_prio_check);
 EXPORT_SYMBOL(v4l2_field_names);
 EXPORT_SYMBOL(v4l2_type_names);
 EXPORT_SYMBOL(v4l_printk_ioctl);
+EXPORT_SYMBOL(v4l_printk_ioctl_arg);
 
 /*
  * Local variables:
index 0a4004a4393c7cf3af7c4f4c013c64b9cdb96633..caf3e7e2f21989cac195c23e88d07beb53194a64 100644 (file)
@@ -96,7 +96,7 @@ static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed)
        if (!demux->dmx.frontend)
                return -EINVAL;
 
-       down(&dvb->lock);
+       mutex_lock(&dvb->lock);
        dvb->nfeeds++;
        rc = dvb->nfeeds;
 
@@ -110,7 +110,7 @@ static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed)
        }
 
 out:
-       up(&dvb->lock);
+       mutex_unlock(&dvb->lock);
        return rc;
 }
 
@@ -120,14 +120,14 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
        struct videobuf_dvb *dvb = demux->priv;
        int err = 0;
 
-       down(&dvb->lock);
+       mutex_lock(&dvb->lock);
        dvb->nfeeds--;
        if (0 == dvb->nfeeds  &&  NULL != dvb->thread) {
                // FIXME: cx8802_cancel_buffers(dev);
                err = kthread_stop(dvb->thread);
                dvb->thread = NULL;
        }
-       up(&dvb->lock);
+       mutex_unlock(&dvb->lock);
        return err;
 }
 
@@ -139,7 +139,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
 {
        int result;
 
-       init_MUTEX(&dvb->lock);
+       mutex_init(&dvb->lock);
 
        /* register adapter */
        result = dvb_register_adapter(&dvb->adapter, dvb->name, module);
index 9ef477523d27ecba4789ed4607bcb959ec335440..87e937581d5aa679a837cb5ff0ec3deb1d68d070 100644 (file)
@@ -59,8 +59,7 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
                pg = vmalloc_to_page(virt);
                if (NULL == pg)
                        goto err;
-               if (PageHighMem(pg))
-                       BUG();
+               BUG_ON(PageHighMem(pg));
                sglist[i].page   = pg;
                sglist[i].length = PAGE_SIZE;
        }
@@ -385,7 +384,7 @@ void videobuf_queue_init(struct videobuf_queue* q,
        q->ops     = ops;
        q->priv_data = priv;
 
-       init_MUTEX(&q->lock);
+       mutex_init(&q->lock);
        INIT_LIST_HEAD(&q->stream);
 }
 
@@ -428,7 +427,7 @@ videobuf_queue_is_busy(struct videobuf_queue *q)
 void
 videobuf_queue_cancel(struct videobuf_queue *q)
 {
-       unsigned long flags;
+       unsigned long flags=0;
        int i;
 
        /* remove queued buffers from list */
@@ -549,7 +548,7 @@ videobuf_reqbufs(struct videobuf_queue *q,
        if (!list_empty(&q->stream))
                return -EBUSY;
 
-       down(&q->lock);
+       mutex_lock(&q->lock);
        count = req->count;
        if (count > VIDEO_MAX_FRAME)
                count = VIDEO_MAX_FRAME;
@@ -566,7 +565,7 @@ videobuf_reqbufs(struct videobuf_queue *q,
        req->count = count;
 
  done:
-       up(&q->lock);
+       mutex_unlock(&q->lock);
        return retval;
 }
 
@@ -589,10 +588,10 @@ videobuf_qbuf(struct videobuf_queue *q,
 {
        struct videobuf_buffer *buf;
        enum v4l2_field field;
-       unsigned long flags;
+       unsigned long flags=0;
        int retval;
 
-       down(&q->lock);
+       mutex_lock(&q->lock);
        retval = -EBUSY;
        if (q->reading)
                goto done;
@@ -652,7 +651,7 @@ videobuf_qbuf(struct videobuf_queue *q,
        retval = 0;
 
  done:
-       up(&q->lock);
+       mutex_unlock(&q->lock);
        return retval;
 }
 
@@ -663,7 +662,7 @@ videobuf_dqbuf(struct videobuf_queue *q,
        struct videobuf_buffer *buf;
        int retval;
 
-       down(&q->lock);
+       mutex_lock(&q->lock);
        retval = -EBUSY;
        if (q->reading)
                goto done;
@@ -693,7 +692,7 @@ videobuf_dqbuf(struct videobuf_queue *q,
        videobuf_status(b,buf,q->type);
 
  done:
-       up(&q->lock);
+       mutex_unlock(&q->lock);
        return retval;
 }
 
@@ -701,10 +700,10 @@ int videobuf_streamon(struct videobuf_queue *q)
 {
        struct videobuf_buffer *buf;
        struct list_head *list;
-       unsigned long flags;
+       unsigned long flags=0;
        int retval;
 
-       down(&q->lock);
+       mutex_lock(&q->lock);
        retval = -EBUSY;
        if (q->reading)
                goto done;
@@ -721,7 +720,7 @@ int videobuf_streamon(struct videobuf_queue *q)
        spin_unlock_irqrestore(q->irqlock,flags);
 
  done:
-       up(&q->lock);
+       mutex_unlock(&q->lock);
        return retval;
 }
 
@@ -729,7 +728,7 @@ int videobuf_streamoff(struct videobuf_queue *q)
 {
        int retval = -EINVAL;
 
-       down(&q->lock);
+       mutex_lock(&q->lock);
        if (!q->streaming)
                goto done;
        videobuf_queue_cancel(q);
@@ -737,7 +736,7 @@ int videobuf_streamoff(struct videobuf_queue *q)
        retval = 0;
 
  done:
-       up(&q->lock);
+       mutex_unlock(&q->lock);
        return retval;
 }
 
@@ -746,7 +745,7 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
                       size_t count, loff_t *ppos)
 {
        enum v4l2_field field;
-       unsigned long flags;
+       unsigned long flags=0;
        int retval;
 
        /* setup stuff */
@@ -788,11 +787,11 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
                          int nonblocking)
 {
        enum v4l2_field field;
-       unsigned long flags;
+       unsigned long flags=0;
        unsigned size, nbufs, bytes;
        int retval;
 
-       down(&q->lock);
+       mutex_lock(&q->lock);
 
        nbufs = 1; size = 0;
        q->ops->buf_setup(q,&nbufs,&size);
@@ -860,14 +859,14 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
        }
 
  done:
-       up(&q->lock);
+       mutex_unlock(&q->lock);
        return retval;
 }
 
 int videobuf_read_start(struct videobuf_queue *q)
 {
        enum v4l2_field field;
-       unsigned long flags;
+       unsigned long flags=0;
        int count = 0, size = 0;
        int err, i;
 
@@ -919,10 +918,10 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
 {
        unsigned int *fc, bytes;
        int err, retval;
-       unsigned long flags;
+       unsigned long flags=0;
 
        dprintk(2,"%s\n",__FUNCTION__);
-       down(&q->lock);
+       mutex_lock(&q->lock);
        retval = -EBUSY;
        if (q->streaming)
                goto done;
@@ -996,7 +995,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
        }
 
  done:
-       up(&q->lock);
+       mutex_unlock(&q->lock);
        return retval;
 }
 
@@ -1007,7 +1006,7 @@ unsigned int videobuf_poll_stream(struct file *file,
        struct videobuf_buffer *buf = NULL;
        unsigned int rc = 0;
 
-       down(&q->lock);
+       mutex_lock(&q->lock);
        if (q->streaming) {
                if (!list_empty(&q->stream))
                        buf = list_entry(q->stream.next,
@@ -1035,7 +1034,7 @@ unsigned int videobuf_poll_stream(struct file *file,
                    buf->state == STATE_ERROR)
                        rc = POLLIN|POLLRDNORM;
        }
-       up(&q->lock);
+       mutex_unlock(&q->lock);
        return rc;
 }
 
@@ -1064,7 +1063,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
        map->count--;
        if (0 == map->count) {
                dprintk(1,"munmap %p q=%p\n",map,q);
-               down(&q->lock);
+               mutex_lock(&q->lock);
                for (i = 0; i < VIDEO_MAX_FRAME; i++) {
                        if (NULL == q->bufs[i])
                                continue;
@@ -1076,7 +1075,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
                        q->bufs[i]->baddr = 0;
                        q->ops->buf_release(q,q->bufs[i]);
                }
-               up(&q->lock);
+               mutex_unlock(&q->lock);
                kfree(map);
        }
        return;
@@ -1170,7 +1169,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q,
        unsigned int first,last,size,i;
        int retval;
 
-       down(&q->lock);
+       mutex_lock(&q->lock);
        retval = -EINVAL;
        if (!(vma->vm_flags & VM_WRITE)) {
                dprintk(1,"mmap app bug: PROT_WRITE please\n");
@@ -1238,7 +1237,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q,
        retval = 0;
 
  done:
-       up(&q->lock);
+       mutex_unlock(&q->lock);
        return retval;
 }
 
index 078880e4c8c0a89711a2b079d35553a0a3571e19..75e3d41382f2b1875e332d887e1d28350d627657 100644 (file)
@@ -224,13 +224,13 @@ int video_exclusive_open(struct inode *inode, struct file *file)
        struct  video_device *vfl = video_devdata(file);
        int retval = 0;
 
-       down(&vfl->lock);
+       mutex_lock(&vfl->lock);
        if (vfl->users) {
                retval = -EBUSY;
        } else {
                vfl->users++;
        }
-       up(&vfl->lock);
+       mutex_unlock(&vfl->lock);
        return retval;
 }
 
@@ -279,23 +279,23 @@ int video_register_device(struct video_device *vfd, int type, int nr)
        switch(type)
        {
                case VFL_TYPE_GRABBER:
-                       base=0;
-                       end=64;
+                       base=MINOR_VFL_TYPE_GRABBER_MIN;
+                       end=MINOR_VFL_TYPE_GRABBER_MAX+1;
                        name_base = "video";
                        break;
                case VFL_TYPE_VTX:
-                       base=192;
-                       end=224;
+                       base=MINOR_VFL_TYPE_VTX_MIN;
+                       end=MINOR_VFL_TYPE_VTX_MAX+1;
                        name_base = "vtx";
                        break;
                case VFL_TYPE_VBI:
-                       base=224;
-                       end=256;
+                       base=MINOR_VFL_TYPE_VBI_MIN;
+                       end=MINOR_VFL_TYPE_VBI_MAX+1;
                        name_base = "vbi";
                        break;
                case VFL_TYPE_RADIO:
-                       base=64;
-                       end=128;
+                       base=MINOR_VFL_TYPE_RADIO_MIN;
+                       end=MINOR_VFL_TYPE_RADIO_MAX+1;
                        name_base = "radio";
                        break;
                default:
@@ -328,7 +328,7 @@ int video_register_device(struct video_device *vfd, int type, int nr)
        sprintf(vfd->devfs_name, "v4l/%s%d", name_base, i - base);
        devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor),
                        S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name);
-       init_MUTEX(&vfd->lock);
+       mutex_init(&vfd->lock);
 
        /* sysfs class */
        memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
index c8fd8238904dbaef113c6f550dcc2396549d3c26..0229819d0aaca75d4f807cdffb40c4f275adc5a6 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/videodev.h>
 #include <linux/videodev2.h>
 #include <linux/video_decoder.h>
+#include <linux/mutex.h>
 
 #include <asm/paccess.h>
 #include <asm/io.h>
@@ -245,7 +246,7 @@ struct vino_framebuffer_queue {
        struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX];
 
        spinlock_t queue_lock;
-       struct semaphore queue_sem;
+       struct mutex queue_mutex;
        wait_queue_head_t frame_wait_queue;
 };
 
@@ -283,7 +284,7 @@ struct vino_channel_settings {
        /* the driver is currently processing the queue */
        int capturing;
 
-       struct semaphore sem;
+       struct mutex mutex;
        spinlock_t capture_lock;
 
        unsigned int users;
@@ -1131,11 +1132,11 @@ static void vino_queue_free(struct vino_framebuffer_queue *q)
        if (q->type != VINO_MEMORY_MMAP)
                return;
 
-       down(&q->queue_sem);
+       mutex_lock(&q->queue_mutex);
 
        vino_queue_free_with_count(q, q->length);
 
-       up(&q->queue_sem);
+       mutex_unlock(&q->queue_mutex);
 }
 
 static int vino_queue_init(struct vino_framebuffer_queue *q,
@@ -1159,7 +1160,7 @@ static int vino_queue_init(struct vino_framebuffer_queue *q,
        if (*length < 1)
                return -EINVAL;
 
-       down(&q->queue_sem);
+       mutex_lock(&q->queue_mutex);
 
        if (*length > VINO_FRAMEBUFFER_COUNT_MAX)
                *length = VINO_FRAMEBUFFER_COUNT_MAX;
@@ -1211,7 +1212,7 @@ static int vino_queue_init(struct vino_framebuffer_queue *q,
                q->magic = VINO_QUEUE_MAGIC;
        }
 
-       up(&q->queue_sem);
+       mutex_unlock(&q->queue_mutex);
 
        return ret;
 }
@@ -4045,7 +4046,7 @@ static int vino_open(struct inode *inode, struct file *file)
        dprintk("open(): channel = %c\n",
               (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B');
 
-       down(&vcs->sem);
+       mutex_lock(&vcs->mutex);
 
        if (vcs->users) {
                dprintk("open(): driver busy\n");
@@ -4062,7 +4063,7 @@ static int vino_open(struct inode *inode, struct file *file)
        vcs->users++;
 
  out:
-       up(&vcs->sem);
+       mutex_unlock(&vcs->mutex);
 
        dprintk("open(): %s!\n", ret ? "failed" : "complete");
 
@@ -4075,7 +4076,7 @@ static int vino_close(struct inode *inode, struct file *file)
        struct vino_channel_settings *vcs = video_get_drvdata(dev);
        dprintk("close():\n");
 
-       down(&vcs->sem);
+       mutex_lock(&vcs->mutex);
 
        vcs->users--;
 
@@ -4087,7 +4088,7 @@ static int vino_close(struct inode *inode, struct file *file)
                vino_queue_free(&vcs->fb_queue);
        }
 
-       up(&vcs->sem);
+       mutex_unlock(&vcs->mutex);
 
        return 0;
 }
@@ -4130,7 +4131,7 @@ static int vino_mmap(struct file *file, struct vm_area_struct *vma)
 
        // TODO: reject mmap if already mapped
 
-       if (down_interruptible(&vcs->sem))
+       if (mutex_lock_interruptible(&vcs->mutex))
                return -EINTR;
 
        if (vcs->reading) {
@@ -4214,7 +4215,7 @@ found:
        vma->vm_ops = &vino_vm_ops;
 
 out:
-       up(&vcs->sem);
+       mutex_unlock(&vcs->mutex);
 
        return ret;
 }
@@ -4374,12 +4375,12 @@ static int vino_ioctl(struct inode *inode, struct file *file,
        struct vino_channel_settings *vcs = video_get_drvdata(dev);
        int ret;
 
-       if (down_interruptible(&vcs->sem))
+       if (mutex_lock_interruptible(&vcs->mutex))
                return -EINTR;
 
        ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl);
 
-       up(&vcs->sem);
+       mutex_unlock(&vcs->mutex);
 
        return ret;
 }
@@ -4564,10 +4565,10 @@ static int vino_init_channel_settings(struct vino_channel_settings *vcs,
 
        vcs->capturing = 0;
 
-       init_MUTEX(&vcs->sem);
+       mutex_init(&vcs->mutex);
        spin_lock_init(&vcs->capture_lock);
 
-       init_MUTEX(&vcs->fb_queue.queue_sem);
+       mutex_init(&vcs->fb_queue.queue_mutex);
        spin_lock_init(&vcs->fb_queue.queue_lock);
        init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);
 
index 285d7d0680977a6fbba99139a71a77fe7645d168..c32fad1ce51c88e0f75d9296d49ad17e47daae74 100644 (file)
@@ -438,7 +438,7 @@ static int pxamci_probe(struct platform_device *pdev)
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       if (!r || irq == NO_IRQ)
+       if (!r || irq < 0)
                return -ENXIO;
 
        r = request_mem_region(r->start, SZ_4K, DRIVER_NAME);
index 53e3afc1b7b7c865c850906d4601865fe33ae49d..09d5c3f26985a804e34b49e9ef6c6b0c84677b51 100644 (file)
@@ -696,7 +696,9 @@ static int __init am79c961_probe(struct platform_device *pdev)
        dev->base_addr = res->start;
        dev->irq = platform_get_irq(pdev, 0);
 
-       ret = -ENODEV;
+       ret = -ENODEV;
+       if (dev->irq < 0)
+               goto nodev;
        if (!request_region(dev->base_addr, 0x18, dev->name))
                goto nodev;
 
index e67b1d06611cfb84bf44ce65bf35bba4852f63a9..95e2bb8dd7b415cacb3a770dc1dfc9e135e566d9 100644 (file)
@@ -118,6 +118,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
 
        /* Fill out IRQ field */
        fep->interrupt = platform_get_irq(pdev, 0);
+       if (fep->interrupt < 0)
+               return -EINVAL;
 
        /* Attach the memory for the FCC Parameter RAM */
        r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram");
index 2e8f444696999312562430600ecb55d4c0f096aa..3dad69dfdb2ccd90c407837906d085fdca42cbf2 100644 (file)
@@ -144,6 +144,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
        
        /* Fill out IRQ field */
        fep->interrupt = platform_get_irq_byname(pdev,"interrupt");
+       if (fep->interrupt < 0)
+               return -EINVAL;
        
        r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
        fep->fec.fecp =(void*)r->start;
index a3897fda71fa448c4f5d341e084da0ae87ad2569..a772b286f96d842e8c3391a6b50f10254e976d0b 100644 (file)
@@ -118,6 +118,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
 
        /* Fill out IRQ field */
        fep->interrupt = platform_get_irq_byname(pdev, "interrupt");
+       if (fep->interrupt < 0)
+               return -EINVAL;
 
        r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
        fep->scc.sccp = (void *)r->start;
index 0e8e3fcde9ff9dc865a9c2170a5a4154aea52264..771e25d8c417440dd4c24dfee3f42bb326b532ef 100644 (file)
@@ -193,8 +193,12 @@ static int gfar_probe(struct platform_device *pdev)
                priv->interruptTransmit = platform_get_irq_byname(pdev, "tx");
                priv->interruptReceive = platform_get_irq_byname(pdev, "rx");
                priv->interruptError = platform_get_irq_byname(pdev, "error");
+               if (priv->interruptTransmit < 0 || priv->interruptReceive < 0 || priv->interruptError < 0)
+                       goto regs_fail;
        } else {
                priv->interruptTransmit = platform_get_irq(pdev, 0);
+               if (priv->interruptTransmit < 0)
+                       goto regs_fail;
        }
 
        /* get a pointer to the register memory */
index 7ec08127c9d6c4f8594d805392155e3bddccd875..75e9b3b910cc31ba9d18ff8d4c5deb281c402d14 100644 (file)
@@ -2221,6 +2221,10 @@ static int smc_drv_probe(struct platform_device *pdev)
 
        ndev->dma = (unsigned char)-1;
        ndev->irq = platform_get_irq(pdev, 0);
+       if (ndev->irq < 0) {
+               ret = -ENODEV;
+               goto out_free_netdev;
+       }
 
        ret = smc_request_attrib(pdev);
        if (ret)
index 47b5ade95bde5ae8093997c208f79ed242a4aaa7..2c23d758439982be6eb765667e586596a44dea08 100644 (file)
@@ -218,7 +218,7 @@ static int __init omap_cf_probe(struct device *dev)
 
        /* either CFLASH.IREQ (INT_1610_CF) or some GPIO */
        irq = platform_get_irq(pdev, 0);
-       if (!irq)
+       if (irq < 0)
                return -EINVAL;
 
        cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
index 3c606cf8c8cabc7518e44ce44a3e5ec877359a3a..5c94a5d4efc05d7528aaaeb49ff0f1bb7136c4a5 100644 (file)
@@ -379,6 +379,14 @@ config SCSI_AHA1740
 config SCSI_AACRAID
        tristate "Adaptec AACRAID support"
        depends on SCSI && PCI
+       help
+         This driver supports a variety of Dell, HP, Adaptec, IBM and
+         ICP storage products. For a list of supported products, refer
+         to <file:Documentation/scsi/aacraid.txt>.
+
+         To compile this driver as a module, choose M here: the module
+         will be called aacraid.
+
 
 source "drivers/scsi/aic7xxx/Kconfig.aic7xxx"
 
index 320e765fa0cd97b873e62b6c805d07c52aab67d1..15dc2e00e1b26a0ab1439e68fddc4d9037d8b8bb 100644 (file)
@@ -163,7 +163,7 @@ ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \
 CFLAGS_ncr53c8xx.o     := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m)
 zalon7xx-objs  := zalon.o ncr53c8xx.o
 NCR_Q720_mod-objs      := NCR_Q720.o ncr53c8xx.o
-libata-objs    := libata-core.o libata-scsi.o
+libata-objs    := libata-core.o libata-scsi.o libata-bmdma.o
 oktagon_esp_mod-objs   := oktagon_esp.o oktagon_io.o
 
 # Files generated that shall be removed upon make clean
index 559ff7aae3f113e4f61e551050c289b73f7fa6d6..e97ab3e6de4d19c847a6546b58c134c99e62f75f 100644 (file)
@@ -66,6 +66,9 @@ enum {
        AHCI_IRQ_ON_SG          = (1 << 31),
        AHCI_CMD_ATAPI          = (1 << 5),
        AHCI_CMD_WRITE          = (1 << 6),
+       AHCI_CMD_PREFETCH       = (1 << 7),
+       AHCI_CMD_RESET          = (1 << 8),
+       AHCI_CMD_CLR_BUSY       = (1 << 10),
 
        RX_FIS_D2H_REG          = 0x40, /* offset of D2H Register FIS data */
 
@@ -85,6 +88,7 @@ enum {
 
        /* HOST_CAP bits */
        HOST_CAP_64             = (1 << 31), /* PCI DAC (64-bit DMA) support */
+       HOST_CAP_CLO            = (1 << 24), /* Command List Override support */
 
        /* registers for each SATA port */
        PORT_LST_ADDR           = 0x00, /* command list DMA addr */
@@ -138,6 +142,7 @@ enum {
        PORT_CMD_LIST_ON        = (1 << 15), /* cmd list DMA engine running */
        PORT_CMD_FIS_ON         = (1 << 14), /* FIS DMA engine running */
        PORT_CMD_FIS_RX         = (1 << 4), /* Enable FIS receive DMA engine */
+       PORT_CMD_CLO            = (1 << 3), /* Command list override */
        PORT_CMD_POWER_ON       = (1 << 2), /* Power up device */
        PORT_CMD_SPIN_UP        = (1 << 1), /* Spin up device */
        PORT_CMD_START          = (1 << 0), /* Enable port DMA engine */
@@ -184,9 +189,9 @@ struct ahci_port_priv {
 static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static int ahci_qc_issue(struct ata_queued_cmd *qc);
+static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
 static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
-static void ahci_phy_reset(struct ata_port *ap);
+static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes);
 static void ahci_irq_clear(struct ata_port *ap);
 static void ahci_eng_timeout(struct ata_port *ap);
 static int ahci_port_start(struct ata_port *ap);
@@ -202,11 +207,11 @@ static struct scsi_host_template ahci_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = AHCI_MAX_SG,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = AHCI_USE_CLUSTERING,
@@ -225,7 +230,7 @@ static const struct ata_port_operations ahci_ops = {
 
        .tf_read                = ahci_tf_read,
 
-       .phy_reset              = ahci_phy_reset,
+       .probe_reset            = ahci_probe_reset,
 
        .qc_prep                = ahci_qc_prep,
        .qc_issue               = ahci_qc_issue,
@@ -247,8 +252,7 @@ static const struct ata_port_info ahci_port_info[] = {
        {
                .sht            = &ahci_sht,
                .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
-                                 ATA_FLAG_PIO_DMA,
+                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &ahci_ops,
@@ -450,17 +454,48 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
        writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
 }
 
-static void ahci_phy_reset(struct ata_port *ap)
+static int ahci_stop_engine(struct ata_port *ap)
 {
-       void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
-       struct ata_taskfile tf;
-       struct ata_device *dev = &ap->device[0];
-       u32 new_tmp, tmp;
+       void __iomem *mmio = ap->host_set->mmio_base;
+       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       int work;
+       u32 tmp;
 
-       __sata_phy_reset(ap);
+       tmp = readl(port_mmio + PORT_CMD);
+       tmp &= ~PORT_CMD_START;
+       writel(tmp, port_mmio + PORT_CMD);
 
-       if (ap->flags & ATA_FLAG_PORT_DISABLED)
-               return;
+       /* wait for engine to stop.  TODO: this could be
+        * as long as 500 msec
+        */
+       work = 1000;
+       while (work-- > 0) {
+               tmp = readl(port_mmio + PORT_CMD);
+               if ((tmp & PORT_CMD_LIST_ON) == 0)
+                       return 0;
+               udelay(10);
+       }
+
+       return -EIO;
+}
+
+static void ahci_start_engine(struct ata_port *ap)
+{
+       void __iomem *mmio = ap->host_set->mmio_base;
+       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       u32 tmp;
+
+       tmp = readl(port_mmio + PORT_CMD);
+       tmp |= PORT_CMD_START;
+       writel(tmp, port_mmio + PORT_CMD);
+       readl(port_mmio + PORT_CMD); /* flush */
+}
+
+static unsigned int ahci_dev_classify(struct ata_port *ap)
+{
+       void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+       struct ata_taskfile tf;
+       u32 tmp;
 
        tmp = readl(port_mmio + PORT_SIG);
        tf.lbah         = (tmp >> 24)   & 0xff;
@@ -468,15 +503,46 @@ static void ahci_phy_reset(struct ata_port *ap)
        tf.lbal         = (tmp >> 8)    & 0xff;
        tf.nsect        = (tmp)         & 0xff;
 
-       dev->class = ata_dev_classify(&tf);
-       if (!ata_dev_present(dev)) {
-               ata_port_disable(ap);
-               return;
-       }
+       return ata_dev_classify(&tf);
+}
+
+static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts)
+{
+       pp->cmd_slot[0].opts = cpu_to_le32(opts);
+       pp->cmd_slot[0].status = 0;
+       pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff);
+       pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
+}
+
+static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
+{
+       int rc;
+
+       DPRINTK("ENTER\n");
+
+       ahci_stop_engine(ap);
+       rc = sata_std_hardreset(ap, verbose, class);
+       ahci_start_engine(ap);
+
+       if (rc == 0)
+               *class = ahci_dev_classify(ap);
+       if (*class == ATA_DEV_UNKNOWN)
+               *class = ATA_DEV_NONE;
+
+       DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
+       return rc;
+}
+
+static void ahci_postreset(struct ata_port *ap, unsigned int *class)
+{
+       void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+       u32 new_tmp, tmp;
+
+       ata_std_postreset(ap, class);
 
        /* Make sure port's ATAPI bit is set appropriately */
        new_tmp = tmp = readl(port_mmio + PORT_CMD);
-       if (dev->class == ATA_DEV_ATAPI)
+       if (*class == ATA_DEV_ATAPI)
                new_tmp |= PORT_CMD_ATAPI;
        else
                new_tmp &= ~PORT_CMD_ATAPI;
@@ -486,6 +552,12 @@ static void ahci_phy_reset(struct ata_port *ap)
        }
 }
 
+static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes)
+{
+       return ata_drive_probe_reset(ap, NULL, NULL, ahci_hardreset,
+                                    ahci_postreset, classes);
+}
+
 static u8 ahci_check_status(struct ata_port *ap)
 {
        void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
@@ -533,42 +605,36 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        struct ahci_port_priv *pp = ap->private_data;
+       int is_atapi = is_atapi_taskfile(&qc->tf);
        u32 opts;
        const u32 cmd_fis_len = 5; /* five dwords */
        unsigned int n_elem;
 
-       /*
-        * Fill in command slot information (currently only one slot,
-        * slot 0, is currently since we don't do queueing)
-        */
-
-       opts = cmd_fis_len;
-       if (qc->tf.flags & ATA_TFLAG_WRITE)
-               opts |= AHCI_CMD_WRITE;
-       if (is_atapi_taskfile(&qc->tf))
-               opts |= AHCI_CMD_ATAPI;
-
-       pp->cmd_slot[0].opts = cpu_to_le32(opts);
-       pp->cmd_slot[0].status = 0;
-       pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff);
-       pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
-
        /*
         * Fill in command table information.  First, the header,
         * a SATA Register - Host to Device command FIS.
         */
        ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0);
-       if (opts & AHCI_CMD_ATAPI) {
+       if (is_atapi) {
                memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
-               memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len);
+               memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb,
+                      qc->dev->cdb_len);
        }
 
-       if (!(qc->flags & ATA_QCFLAG_DMAMAP))
-               return;
+       n_elem = 0;
+       if (qc->flags & ATA_QCFLAG_DMAMAP)
+               n_elem = ahci_fill_sg(qc);
 
-       n_elem = ahci_fill_sg(qc);
+       /*
+        * Fill in command slot information.
+        */
+       opts = cmd_fis_len | n_elem << 16;
+       if (qc->tf.flags & ATA_TFLAG_WRITE)
+               opts |= AHCI_CMD_WRITE;
+       if (is_atapi)
+               opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH;
 
-       pp->cmd_slot[0].opts |= cpu_to_le32(n_elem << 16);
+       ahci_fill_cmd_slot(pp, opts);
 }
 
 static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
@@ -576,7 +642,6 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
        void __iomem *mmio = ap->host_set->mmio_base;
        void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        u32 tmp;
-       int work;
 
        if ((ap->device[0].class != ATA_DEV_ATAPI) ||
            ((irq_stat & PORT_IRQ_TF_ERR) == 0))
@@ -592,20 +657,7 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
                        readl(port_mmio + PORT_SCR_ERR));
 
        /* stop DMA */
-       tmp = readl(port_mmio + PORT_CMD);
-       tmp &= ~PORT_CMD_START;
-       writel(tmp, port_mmio + PORT_CMD);
-
-       /* wait for engine to stop.  TODO: this could be
-        * as long as 500 msec
-        */
-       work = 1000;
-       while (work-- > 0) {
-               tmp = readl(port_mmio + PORT_CMD);
-               if ((tmp & PORT_CMD_LIST_ON) == 0)
-                       break;
-               udelay(10);
-       }
+       ahci_stop_engine(ap);
 
        /* clear SATA phy error, if any */
        tmp = readl(port_mmio + PORT_SCR_ERR);
@@ -624,10 +676,7 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat)
        }
 
        /* re-start DMA */
-       tmp = readl(port_mmio + PORT_CMD);
-       tmp |= PORT_CMD_START;
-       writel(tmp, port_mmio + PORT_CMD);
-       readl(port_mmio + PORT_CMD); /* flush */
+       ahci_start_engine(ap);
 }
 
 static void ahci_eng_timeout(struct ata_port *ap)
@@ -642,25 +691,13 @@ static void ahci_eng_timeout(struct ata_port *ap)
 
        spin_lock_irqsave(&host_set->lock, flags);
 
+       ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT));
        qc = ata_qc_from_tag(ap, ap->active_tag);
-       if (!qc) {
-               printk(KERN_ERR "ata%u: BUG: timeout without command\n",
-                      ap->id);
-       } else {
-               ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT));
-
-               /* hack alert!  We cannot use the supplied completion
-                * function from inside the ->eh_strategy_handler() thread.
-                * libata is the only user of ->eh_strategy_handler() in
-                * any kernel, so the default scsi_done() assumes it is
-                * not being called from the SCSI EH.
-                */
-               qc->scsidone = scsi_finish_command;
-               qc->err_mask |= AC_ERR_OTHER;
-               ata_qc_complete(qc);
-       }
+       qc->err_mask |= AC_ERR_TIMEOUT;
 
        spin_unlock_irqrestore(&host_set->lock, flags);
+
+       ata_eh_qc_complete(qc);
 }
 
 static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
@@ -678,7 +715,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
        ci = readl(port_mmio + PORT_CMD_ISSUE);
        if (likely((ci & 0x1) == 0)) {
                if (qc) {
-                       assert(qc->err_mask == 0);
+                       WARN_ON(qc->err_mask);
                        ata_qc_complete(qc);
                        qc = NULL;
                }
@@ -697,7 +734,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
                ahci_restart_port(ap, status);
 
                if (qc) {
-                       qc->err_mask |= AC_ERR_OTHER;
+                       qc->err_mask |= err_mask;
                        ata_qc_complete(qc);
                }
        }
@@ -770,7 +807,7 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *
        return IRQ_RETVAL(handled);
 }
 
-static int ahci_qc_issue(struct ata_queued_cmd *qc)
+static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
index fc3ca051ceed36dd431bcd0dab1dcf29dbc36cd9..9327b62f97de8136a8503bd25a9e8b067119dfa1 100644 (file)
@@ -101,36 +101,54 @@ enum {
        ICH5_PCS                = 0x92, /* port control and status */
        PIIX_SCC                = 0x0A, /* sub-class code register */
 
-       PIIX_FLAG_AHCI          = (1 << 28), /* AHCI possible */
-       PIIX_FLAG_CHECKINTR     = (1 << 29), /* make sure PCI INTx enabled */
-       PIIX_FLAG_COMBINED      = (1 << 30), /* combined mode possible */
+       PIIX_FLAG_IGNORE_PCS    = (1 << 25), /* ignore PCS present bits */
+       PIIX_FLAG_SCR           = (1 << 26), /* SCR available */
+       PIIX_FLAG_AHCI          = (1 << 27), /* AHCI possible */
+       PIIX_FLAG_CHECKINTR     = (1 << 28), /* make sure PCI INTx enabled */
+       PIIX_FLAG_COMBINED      = (1 << 29), /* combined mode possible */
+       /* ICH6/7 use different scheme for map value */
+       PIIX_FLAG_COMBINED_ICH6 = PIIX_FLAG_COMBINED | (1 << 30),
 
        /* combined mode.  if set, PATA is channel 0.
         * if clear, PATA is channel 1.
         */
-       PIIX_COMB_PATA_P0       = (1 << 1),
-       PIIX_COMB               = (1 << 2), /* combined mode enabled? */
-
        PIIX_PORT_ENABLED       = (1 << 0),
        PIIX_PORT_PRESENT       = (1 << 4),
 
        PIIX_80C_PRI            = (1 << 5) | (1 << 4),
        PIIX_80C_SEC            = (1 << 7) | (1 << 6),
 
-       ich5_pata               = 0,
-       ich5_sata               = 1,
-       piix4_pata              = 2,
-       ich6_sata               = 3,
-       ich6_sata_ahci          = 4,
+       /* controller IDs */
+       piix4_pata              = 0,
+       ich5_pata               = 1,
+       ich5_sata               = 2,
+       esb_sata                = 3,
+       ich6_sata               = 4,
+       ich6_sata_ahci          = 5,
+       ich6m_sata_ahci         = 6,
+
+       /* constants for mapping table */
+       P0                      = 0,  /* port 0 */
+       P1                      = 1,  /* port 1 */
+       P2                      = 2,  /* port 2 */
+       P3                      = 3,  /* port 3 */
+       IDE                     = -1, /* IDE */
+       NA                      = -2, /* not avaliable */
+       RV                      = -3, /* reserved */
 
        PIIX_AHCI_DEVICE        = 6,
 };
 
+struct piix_map_db {
+       const u32 mask;
+       const int map[][4];
+};
+
 static int piix_init_one (struct pci_dev *pdev,
                                    const struct pci_device_id *ent);
 
-static void piix_pata_phy_reset(struct ata_port *ap);
-static void piix_sata_phy_reset(struct ata_port *ap);
+static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes);
+static int piix_sata_probe_reset(struct ata_port *ap, unsigned int *classes);
 static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
 static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
 
@@ -147,19 +165,32 @@ static const struct pci_device_id piix_pci_tbl[] = {
         * list in drivers/pci/quirks.c.
         */
 
+       /* 82801EB (ICH5) */
        { 0x8086, 0x24d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
+       /* 82801EB (ICH5) */
        { 0x8086, 0x24df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
-       { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
-       { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
+       /* 6300ESB (ICH5 variant with broken PCS present bits) */
+       { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata },
+       /* 6300ESB pretending RAID */
+       { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata },
+       /* 82801FB/FW (ICH6/ICH6W) */
        { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
+       /* 82801FR/FRW (ICH6R/ICH6RW) */
        { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
-       { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+       /* 82801FBM ICH6M (ICH6R with only port 0 and 2 implemented) */
+       { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
+       /* 82801GB/GR/GH (ICH7, identical to ICH6) */
        { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
-       { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+       /* 2801GBM/GHM (ICH7M, identical to ICH6M) */
+       { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
+       /* Enterprise Southbridge 2 (where's the datasheet?) */
        { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+       /* SATA Controller 1 IDE (ICH8, no datasheet yet) */
        { 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+       /* SATA Controller 2 IDE (ICH8, ditto) */
        { 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
-       { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+       /* Mobile SATA Controller IDE (ICH8M, ditto) */
+       { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
 
        { }     /* terminate list */
 };
@@ -178,11 +209,11 @@ static struct scsi_host_template piix_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -205,7 +236,7 @@ static const struct ata_port_operations piix_pata_ops = {
        .exec_command           = ata_exec_command,
        .dev_select             = ata_std_dev_select,
 
-       .phy_reset              = piix_pata_phy_reset,
+       .probe_reset            = piix_pata_probe_reset,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
@@ -233,7 +264,7 @@ static const struct ata_port_operations piix_sata_ops = {
        .exec_command           = ata_exec_command,
        .dev_select             = ata_std_dev_select,
 
-       .phy_reset              = piix_sata_phy_reset,
+       .probe_reset            = piix_sata_probe_reset,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
@@ -252,12 +283,62 @@ static const struct ata_port_operations piix_sata_ops = {
        .host_stop              = ata_host_stop,
 };
 
+static struct piix_map_db ich5_map_db = {
+       .mask = 0x7,
+       .map = {
+               /* PM   PS   SM   SS       MAP  */
+               {  P0,  NA,  P1,  NA }, /* 000b */
+               {  P1,  NA,  P0,  NA }, /* 001b */
+               {  RV,  RV,  RV,  RV },
+               {  RV,  RV,  RV,  RV },
+               {  P0,  P1, IDE, IDE }, /* 100b */
+               {  P1,  P0, IDE, IDE }, /* 101b */
+               { IDE, IDE,  P0,  P1 }, /* 110b */
+               { IDE, IDE,  P1,  P0 }, /* 111b */
+       },
+};
+
+static struct piix_map_db ich6_map_db = {
+       .mask = 0x3,
+       .map = {
+               /* PM   PS   SM   SS       MAP */
+               {  P0,  P1,  P2,  P3 }, /* 00b */
+               { IDE, IDE,  P1,  P3 }, /* 01b */
+               {  P0,  P2, IDE, IDE }, /* 10b */
+               {  RV,  RV,  RV,  RV },
+       },
+};
+
+static struct piix_map_db ich6m_map_db = {
+       .mask = 0x3,
+       .map = {
+               /* PM   PS   SM   SS       MAP */
+               {  P0,  P1,  P2,  P3 }, /* 00b */
+               {  RV,  RV,  RV,  RV },
+               {  P0,  P2, IDE, IDE }, /* 10b */
+               {  RV,  RV,  RV,  RV },
+       },
+};
+
 static struct ata_port_info piix_port_info[] = {
+       /* piix4_pata */
+       {
+               .sht            = &piix_sht,
+               .host_flags     = ATA_FLAG_SLAVE_POSS,
+               .pio_mask       = 0x1f, /* pio0-4 */
+#if 0
+               .mwdma_mask     = 0x06, /* mwdma1-2 */
+#else
+               .mwdma_mask     = 0x00, /* mwdma broken */
+#endif
+               .udma_mask      = ATA_UDMA_MASK_40C,
+               .port_ops       = &piix_pata_ops,
+       },
+
        /* ich5_pata */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
-                                 PIIX_FLAG_CHECKINTR,
+               .host_flags     = ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR,
                .pio_mask       = 0x1f, /* pio0-4 */
 #if 0
                .mwdma_mask     = 0x06, /* mwdma1-2 */
@@ -271,50 +352,63 @@ static struct ata_port_info piix_port_info[] = {
        /* ich5_sata */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_SRST |
-                                 PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR,
+               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_COMBINED |
+                                 PIIX_FLAG_CHECKINTR,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &piix_sata_ops,
+               .private_data   = &ich5_map_db,
        },
 
-       /* piix4_pata */
+       /* i6300esb_sata */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_COMBINED |
+                                 PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS,
                .pio_mask       = 0x1f, /* pio0-4 */
-#if 0
-               .mwdma_mask     = 0x06, /* mwdma1-2 */
-#else
-               .mwdma_mask     = 0x00, /* mwdma broken */
-#endif
-               .udma_mask      = ATA_UDMA_MASK_40C,
-               .port_ops       = &piix_pata_ops,
+               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .udma_mask      = 0x7f, /* udma0-6 */
+               .port_ops       = &piix_sata_ops,
+               .private_data   = &ich5_map_db,
        },
 
        /* ich6_sata */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_SRST |
-                                 PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
-                                 ATA_FLAG_SLAVE_POSS,
+               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
+                                 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &piix_sata_ops,
+               .private_data   = &ich6_map_db,
        },
 
        /* ich6_sata_ahci */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_SRST |
-                                 PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
-                                 ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
+               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
+                                 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
+                                 PIIX_FLAG_AHCI,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .udma_mask      = 0x7f, /* udma0-6 */
+               .port_ops       = &piix_sata_ops,
+               .private_data   = &ich6_map_db,
+       },
+
+       /* ich6m_sata_ahci */
+       {
+               .sht            = &piix_sht,
+               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
+                                 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
+                                 PIIX_FLAG_AHCI,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &piix_sata_ops,
+               .private_data   = &ich6m_map_db,
        },
 };
 
@@ -363,102 +457,123 @@ cbl40:
 }
 
 /**
- *     piix_pata_phy_reset - Probe specified port on PATA host controller
- *     @ap: Port to probe
+ *     piix_pata_probeinit - probeinit for PATA host controller
+ *     @ap: Target port
  *
- *     Probe PATA phy.
+ *     Probeinit including cable detection.
  *
  *     LOCKING:
  *     None (inherited from caller).
  */
+static void piix_pata_probeinit(struct ata_port *ap)
+{
+       piix_pata_cbl_detect(ap);
+       ata_std_probeinit(ap);
+}
 
-static void piix_pata_phy_reset(struct ata_port *ap)
+/**
+ *     piix_pata_probe_reset - Perform reset on PATA port and classify
+ *     @ap: Port to reset
+ *     @classes: Resulting classes of attached devices
+ *
+ *     Reset PATA phy and classify attached devices.
+ *
+ *     LOCKING:
+ *     None (inherited from caller).
+ */
+static int piix_pata_probe_reset(struct ata_port *ap, unsigned int *classes)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
 
        if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) {
-               ata_port_disable(ap);
                printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
-               return;
+               return 0;
        }
 
-       piix_pata_cbl_detect(ap);
-
-       ata_port_probe(ap);
-
-       ata_bus_reset(ap);
+       return ata_drive_probe_reset(ap, piix_pata_probeinit,
+                                    ata_std_softreset, NULL,
+                                    ata_std_postreset, classes);
 }
 
 /**
  *     piix_sata_probe - Probe PCI device for present SATA devices
  *     @ap: Port associated with the PCI device we wish to probe
  *
- *     Reads SATA PCI device's PCI config register Port Configuration
- *     and Status (PCS) to determine port and device availability.
+ *     Reads and configures SATA PCI device's PCI config register
+ *     Port Configuration and Status (PCS) to determine port and
+ *     device availability.
  *
  *     LOCKING:
  *     None (inherited from caller).
  *
  *     RETURNS:
- *     Non-zero if port is enabled, it may or may not have a device
- *     attached in that case (PRESENT bit would only be set if BIOS probe
- *     was done). Zero is returned if port is disabled.
+ *     Mask of avaliable devices on the port.
  */
-static int piix_sata_probe (struct ata_port *ap)
+static unsigned int piix_sata_probe (struct ata_port *ap)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
-       int combined = (ap->flags & ATA_FLAG_SLAVE_POSS);
-       int orig_mask, mask, i;
+       const unsigned int *map = ap->host_set->private_data;
+       int base = 2 * ap->hard_port_no;
+       unsigned int present_mask = 0;
+       int port, i;
        u8 pcs;
 
-       mask = (PIIX_PORT_PRESENT << ap->hard_port_no) |
-              (PIIX_PORT_ENABLED << ap->hard_port_no);
-
        pci_read_config_byte(pdev, ICH5_PCS, &pcs);
-       orig_mask = (int) pcs & 0xff;
-
-       /* TODO: this is vaguely wrong for ICH6 combined mode,
-        * where only two of the four SATA ports are mapped
-        * onto a single ATA channel.  It is also vaguely inaccurate
-        * for ICH5, which has only two ports.  However, this is ok,
-        * as further device presence detection code will handle
-        * any false positives produced here.
-        */
+       DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base);
 
-       for (i = 0; i < 4; i++) {
-               mask = (PIIX_PORT_ENABLED << i);
+       /* enable all ports on this ap and wait for them to settle */
+       for (i = 0; i < 2; i++) {
+               port = map[base + i];
+               if (port >= 0)
+                       pcs |= 1 << port;
+       }
+
+       pci_write_config_byte(pdev, ICH5_PCS, pcs);
+       msleep(100);
 
-               if ((orig_mask & mask) == mask)
-                       if (combined || (i == ap->hard_port_no))
-                               return 1;
+       /* let's see which devices are present */
+       pci_read_config_byte(pdev, ICH5_PCS, &pcs);
+
+       for (i = 0; i < 2; i++) {
+               port = map[base + i];
+               if (port < 0)
+                       continue;
+               if (ap->flags & PIIX_FLAG_IGNORE_PCS || pcs & 1 << (4 + port))
+                       present_mask |= 1 << i;
+               else
+                       pcs &= ~(1 << port);
        }
 
-       return 0;
+       /* disable offline ports on non-AHCI controllers */
+       if (!(ap->flags & PIIX_FLAG_AHCI))
+               pci_write_config_byte(pdev, ICH5_PCS, pcs);
+
+       DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
+               ap->id, pcs, present_mask);
+
+       return present_mask;
 }
 
 /**
- *     piix_sata_phy_reset - Probe specified port on SATA host controller
- *     @ap: Port to probe
+ *     piix_sata_probe_reset - Perform reset on SATA port and classify
+ *     @ap: Port to reset
+ *     @classes: Resulting classes of attached devices
  *
- *     Probe SATA phy.
+ *     Reset SATA phy and classify attached devices.
  *
  *     LOCKING:
  *     None (inherited from caller).
  */
-
-static void piix_sata_phy_reset(struct ata_port *ap)
+static int piix_sata_probe_reset(struct ata_port *ap, unsigned int *classes)
 {
        if (!piix_sata_probe(ap)) {
-               ata_port_disable(ap);
                printk(KERN_INFO "ata%u: SATA port has no device.\n", ap->id);
-               return;
+               return 0;
        }
 
-       ap->cbl = ATA_CBL_SATA;
-
-       ata_port_probe(ap);
-
-       ata_bus_reset(ap);
+       return ata_drive_probe_reset(ap, ata_std_probeinit,
+                                    ata_std_softreset, NULL,
+                                    ata_std_postreset, classes);
 }
 
 /**
@@ -627,6 +742,7 @@ static int piix_disable_ahci(struct pci_dev *pdev)
 
 /**
  *     piix_check_450nx_errata -       Check for problem 450NX setup
+ *     @ata_dev: the PCI device to check
  *     
  *     Check for the present of 450NX errata #19 and errata #25. If
  *     they are found return an error code so we can turn off DMA
@@ -659,6 +775,54 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
        return no_piix_dma;
 }              
 
+static void __devinit piix_init_sata_map(struct pci_dev *pdev,
+                                        struct ata_port_info *pinfo)
+{
+       struct piix_map_db *map_db = pinfo[0].private_data;
+       const unsigned int *map;
+       int i, invalid_map = 0;
+       u8 map_value;
+
+       pci_read_config_byte(pdev, ICH5_PMR, &map_value);
+
+       map = map_db->map[map_value & map_db->mask];
+
+       dev_printk(KERN_INFO, &pdev->dev, "MAP [");
+       for (i = 0; i < 4; i++) {
+               switch (map[i]) {
+               case RV:
+                       invalid_map = 1;
+                       printk(" XX");
+                       break;
+
+               case NA:
+                       printk(" --");
+                       break;
+
+               case IDE:
+                       WARN_ON((i & 1) || map[i + 1] != IDE);
+                       pinfo[i / 2] = piix_port_info[ich5_pata];
+                       i++;
+                       printk(" IDE IDE");
+                       break;
+
+               default:
+                       printk(" P%d", map[i]);
+                       if (i & 1)
+                               pinfo[i / 2].host_flags |= ATA_FLAG_SLAVE_POSS;
+                       break;
+               }
+       }
+       printk(" ]\n");
+
+       if (invalid_map)
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "invalid MAP value %u\n", map_value);
+
+       pinfo[0].private_data = (void *)map;
+       pinfo[1].private_data = (void *)map;
+}
+
 /**
  *     piix_init_one - Register PIIX ATA PCI device with kernel services
  *     @pdev: PCI device to register
@@ -677,9 +841,9 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
 static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_port_info *port_info[2];
-       unsigned int combined = 0;
-       unsigned int pata_chan = 0, sata_chan = 0;
+       struct ata_port_info port_info[2];
+       struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] };
+       unsigned long host_flags;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev,
@@ -689,10 +853,12 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!in_module_init)
                return -ENODEV;
 
-       port_info[0] = &piix_port_info[ent->driver_data];
-       port_info[1] = &piix_port_info[ent->driver_data];
+       port_info[0] = piix_port_info[ent->driver_data];
+       port_info[1] = piix_port_info[ent->driver_data];
+
+       host_flags = port_info[0].host_flags;
 
-       if (port_info[0]->host_flags & PIIX_FLAG_AHCI) {
+       if (host_flags & PIIX_FLAG_AHCI) {
                u8 tmp;
                pci_read_config_byte(pdev, PIIX_SCC, &tmp);
                if (tmp == PIIX_AHCI_DEVICE) {
@@ -702,18 +868,9 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                }
        }
 
-       if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) {
-               u8 tmp;
-               pci_read_config_byte(pdev, ICH5_PMR, &tmp);
-
-               if (tmp & PIIX_COMB) {
-                       combined = 1;
-                       if (tmp & PIIX_COMB_PATA_P0)
-                               sata_chan = 1;
-                       else
-                               pata_chan = 1;
-               }
-       }
+       /* Initialize SATA map */
+       if (host_flags & ATA_FLAG_SATA)
+               piix_init_sata_map(pdev, port_info);
 
        /* On ICH5, some BIOSen disable the interrupt using the
         * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.
@@ -721,28 +878,19 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
         * MSI is disabled (and it is disabled, as we don't use
         * message-signalled interrupts currently).
         */
-       if (port_info[0]->host_flags & PIIX_FLAG_CHECKINTR)
+       if (host_flags & PIIX_FLAG_CHECKINTR)
                pci_intx(pdev, 1);
 
-       if (combined) {
-               port_info[sata_chan] = &piix_port_info[ent->driver_data];
-               port_info[sata_chan]->host_flags |= ATA_FLAG_SLAVE_POSS;
-               port_info[pata_chan] = &piix_port_info[ich5_pata];
-
-               dev_printk(KERN_WARNING, &pdev->dev,
-                          "combined mode detected (p=%u, s=%u)\n",
-                          pata_chan, sata_chan);
-       }
        if (piix_check_450nx_errata(pdev)) {
                /* This writes into the master table but it does not
                   really matter for this errata as we will apply it to
                   all the PIIX devices on the board */
-               port_info[0]->mwdma_mask = 0;
-               port_info[0]->udma_mask = 0;
-               port_info[1]->mwdma_mask = 0;
-               port_info[1]->udma_mask = 0;
+               port_info[0].mwdma_mask = 0;
+               port_info[0].udma_mask = 0;
+               port_info[1].mwdma_mask = 0;
+               port_info[1].udma_mask = 0;
        }
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppinfo, 2);
 }
 
 static int __init piix_init(void)
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
new file mode 100644 (file)
index 0000000..a93336a
--- /dev/null
@@ -0,0 +1,703 @@
+/*
+ *  libata-bmdma.c - helper library for PCI IDE BMDMA
+ *
+ *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *                 Please ALWAYS copy linux-ide@vger.kernel.org
+ *                 on emails.
+ *
+ *  Copyright 2003-2006 Red Hat, Inc.  All rights reserved.
+ *  Copyright 2003-2006 Jeff Garzik
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ *  libata documentation is available via 'make {ps|pdf}docs',
+ *  as Documentation/DocBook/libata.*
+ *
+ *  Hardware documentation available from http://www.t13.org/ and
+ *  http://www.sata-io.org/
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/libata.h>
+
+#include "libata.h"
+
+/**
+ *     ata_tf_load_pio - send taskfile registers to host controller
+ *     @ap: Port to which output is sent
+ *     @tf: ATA taskfile register set
+ *
+ *     Outputs ATA taskfile to standard ATA host controller.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+
+static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+       unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+
+       if (tf->ctl != ap->last_ctl) {
+               outb(tf->ctl, ioaddr->ctl_addr);
+               ap->last_ctl = tf->ctl;
+               ata_wait_idle(ap);
+       }
+
+       if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
+               outb(tf->hob_feature, ioaddr->feature_addr);
+               outb(tf->hob_nsect, ioaddr->nsect_addr);
+               outb(tf->hob_lbal, ioaddr->lbal_addr);
+               outb(tf->hob_lbam, ioaddr->lbam_addr);
+               outb(tf->hob_lbah, ioaddr->lbah_addr);
+               VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
+                       tf->hob_feature,
+                       tf->hob_nsect,
+                       tf->hob_lbal,
+                       tf->hob_lbam,
+                       tf->hob_lbah);
+       }
+
+       if (is_addr) {
+               outb(tf->feature, ioaddr->feature_addr);
+               outb(tf->nsect, ioaddr->nsect_addr);
+               outb(tf->lbal, ioaddr->lbal_addr);
+               outb(tf->lbam, ioaddr->lbam_addr);
+               outb(tf->lbah, ioaddr->lbah_addr);
+               VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
+                       tf->feature,
+                       tf->nsect,
+                       tf->lbal,
+                       tf->lbam,
+                       tf->lbah);
+       }
+
+       if (tf->flags & ATA_TFLAG_DEVICE) {
+               outb(tf->device, ioaddr->device_addr);
+               VPRINTK("device 0x%X\n", tf->device);
+       }
+
+       ata_wait_idle(ap);
+}
+
+/**
+ *     ata_tf_load_mmio - send taskfile registers to host controller
+ *     @ap: Port to which output is sent
+ *     @tf: ATA taskfile register set
+ *
+ *     Outputs ATA taskfile to standard ATA host controller using MMIO.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+
+static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+       unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+
+       if (tf->ctl != ap->last_ctl) {
+               writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
+               ap->last_ctl = tf->ctl;
+               ata_wait_idle(ap);
+       }
+
+       if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
+               writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr);
+               writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr);
+               writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr);
+               writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr);
+               writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr);
+               VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
+                       tf->hob_feature,
+                       tf->hob_nsect,
+                       tf->hob_lbal,
+                       tf->hob_lbam,
+                       tf->hob_lbah);
+       }
+
+       if (is_addr) {
+               writeb(tf->feature, (void __iomem *) ioaddr->feature_addr);
+               writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
+               writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
+               writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
+               writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
+               VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
+                       tf->feature,
+                       tf->nsect,
+                       tf->lbal,
+                       tf->lbam,
+                       tf->lbah);
+       }
+
+       if (tf->flags & ATA_TFLAG_DEVICE) {
+               writeb(tf->device, (void __iomem *) ioaddr->device_addr);
+               VPRINTK("device 0x%X\n", tf->device);
+       }
+
+       ata_wait_idle(ap);
+}
+
+
+/**
+ *     ata_tf_load - send taskfile registers to host controller
+ *     @ap: Port to which output is sent
+ *     @tf: ATA taskfile register set
+ *
+ *     Outputs ATA taskfile to standard ATA host controller using MMIO
+ *     or PIO as indicated by the ATA_FLAG_MMIO flag.
+ *     Writes the control, feature, nsect, lbal, lbam, and lbah registers.
+ *     Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
+ *     hob_lbal, hob_lbam, and hob_lbah.
+ *
+ *     This function waits for idle (!BUSY and !DRQ) after writing
+ *     registers.  If the control register has a new value, this
+ *     function also waits for idle after writing control and before
+ *     writing the remaining registers.
+ *
+ *     May be used as the tf_load() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+       if (ap->flags & ATA_FLAG_MMIO)
+               ata_tf_load_mmio(ap, tf);
+       else
+               ata_tf_load_pio(ap, tf);
+}
+
+/**
+ *     ata_exec_command_pio - issue ATA command to host controller
+ *     @ap: port to which command is being issued
+ *     @tf: ATA taskfile register set
+ *
+ *     Issues PIO write to ATA command register, with proper
+ *     synchronization with interrupt handler / other threads.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
+
+static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+       DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
+
+               outb(tf->command, ap->ioaddr.command_addr);
+       ata_pause(ap);
+}
+
+
+/**
+ *     ata_exec_command_mmio - issue ATA command to host controller
+ *     @ap: port to which command is being issued
+ *     @tf: ATA taskfile register set
+ *
+ *     Issues MMIO write to ATA command register, with proper
+ *     synchronization with interrupt handler / other threads.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
+
+static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+       DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
+
+               writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr);
+       ata_pause(ap);
+}
+
+
+/**
+ *     ata_exec_command - issue ATA command to host controller
+ *     @ap: port to which command is being issued
+ *     @tf: ATA taskfile register set
+ *
+ *     Issues PIO/MMIO write to ATA command register, with proper
+ *     synchronization with interrupt handler / other threads.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
+void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+       if (ap->flags & ATA_FLAG_MMIO)
+               ata_exec_command_mmio(ap, tf);
+       else
+               ata_exec_command_pio(ap, tf);
+}
+
+/**
+ *     ata_tf_read_pio - input device's ATA taskfile shadow registers
+ *     @ap: Port from which input is read
+ *     @tf: ATA taskfile register set for storing input
+ *
+ *     Reads ATA taskfile registers for currently-selected device
+ *     into @tf.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+
+static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+
+       tf->command = ata_check_status(ap);
+       tf->feature = inb(ioaddr->error_addr);
+       tf->nsect = inb(ioaddr->nsect_addr);
+       tf->lbal = inb(ioaddr->lbal_addr);
+       tf->lbam = inb(ioaddr->lbam_addr);
+       tf->lbah = inb(ioaddr->lbah_addr);
+       tf->device = inb(ioaddr->device_addr);
+
+       if (tf->flags & ATA_TFLAG_LBA48) {
+               outb(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
+               tf->hob_feature = inb(ioaddr->error_addr);
+               tf->hob_nsect = inb(ioaddr->nsect_addr);
+               tf->hob_lbal = inb(ioaddr->lbal_addr);
+               tf->hob_lbam = inb(ioaddr->lbam_addr);
+               tf->hob_lbah = inb(ioaddr->lbah_addr);
+       }
+}
+
+/**
+ *     ata_tf_read_mmio - input device's ATA taskfile shadow registers
+ *     @ap: Port from which input is read
+ *     @tf: ATA taskfile register set for storing input
+ *
+ *     Reads ATA taskfile registers for currently-selected device
+ *     into @tf via MMIO.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+
+static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+
+       tf->command = ata_check_status(ap);
+       tf->feature = readb((void __iomem *)ioaddr->error_addr);
+       tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
+       tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
+       tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
+       tf->lbah = readb((void __iomem *)ioaddr->lbah_addr);
+       tf->device = readb((void __iomem *)ioaddr->device_addr);
+
+       if (tf->flags & ATA_TFLAG_LBA48) {
+               writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr);
+               tf->hob_feature = readb((void __iomem *)ioaddr->error_addr);
+               tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr);
+               tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr);
+               tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr);
+               tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr);
+       }
+}
+
+
+/**
+ *     ata_tf_read - input device's ATA taskfile shadow registers
+ *     @ap: Port from which input is read
+ *     @tf: ATA taskfile register set for storing input
+ *
+ *     Reads ATA taskfile registers for currently-selected device
+ *     into @tf.
+ *
+ *     Reads nsect, lbal, lbam, lbah, and device.  If ATA_TFLAG_LBA48
+ *     is set, also reads the hob registers.
+ *
+ *     May be used as the tf_read() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       if (ap->flags & ATA_FLAG_MMIO)
+               ata_tf_read_mmio(ap, tf);
+       else
+               ata_tf_read_pio(ap, tf);
+}
+
+/**
+ *     ata_check_status_pio - Read device status reg & clear interrupt
+ *     @ap: port where the device is
+ *
+ *     Reads ATA taskfile status register for currently-selected device
+ *     and return its value. This also clears pending interrupts
+ *      from this device
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+static u8 ata_check_status_pio(struct ata_port *ap)
+{
+       return inb(ap->ioaddr.status_addr);
+}
+
+/**
+ *     ata_check_status_mmio - Read device status reg & clear interrupt
+ *     @ap: port where the device is
+ *
+ *     Reads ATA taskfile status register for currently-selected device
+ *     via MMIO and return its value. This also clears pending interrupts
+ *      from this device
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+static u8 ata_check_status_mmio(struct ata_port *ap)
+{
+               return readb((void __iomem *) ap->ioaddr.status_addr);
+}
+
+
+/**
+ *     ata_check_status - Read device status reg & clear interrupt
+ *     @ap: port where the device is
+ *
+ *     Reads ATA taskfile status register for currently-selected device
+ *     and return its value. This also clears pending interrupts
+ *      from this device
+ *
+ *     May be used as the check_status() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+u8 ata_check_status(struct ata_port *ap)
+{
+       if (ap->flags & ATA_FLAG_MMIO)
+               return ata_check_status_mmio(ap);
+       return ata_check_status_pio(ap);
+}
+
+
+/**
+ *     ata_altstatus - Read device alternate status reg
+ *     @ap: port where the device is
+ *
+ *     Reads ATA taskfile alternate status register for
+ *     currently-selected device and return its value.
+ *
+ *     Note: may NOT be used as the check_altstatus() entry in
+ *     ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+u8 ata_altstatus(struct ata_port *ap)
+{
+       if (ap->ops->check_altstatus)
+               return ap->ops->check_altstatus(ap);
+
+       if (ap->flags & ATA_FLAG_MMIO)
+               return readb((void __iomem *)ap->ioaddr.altstatus_addr);
+       return inb(ap->ioaddr.altstatus_addr);
+}
+
+#ifdef CONFIG_PCI
+static struct ata_probe_ent *
+ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
+{
+       struct ata_probe_ent *probe_ent;
+
+       probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
+       if (!probe_ent) {
+               printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
+                      kobject_name(&(dev->kobj)));
+               return NULL;
+       }
+
+       INIT_LIST_HEAD(&probe_ent->node);
+       probe_ent->dev = dev;
+
+       probe_ent->sht = port->sht;
+       probe_ent->host_flags = port->host_flags;
+       probe_ent->pio_mask = port->pio_mask;
+       probe_ent->mwdma_mask = port->mwdma_mask;
+       probe_ent->udma_mask = port->udma_mask;
+       probe_ent->port_ops = port->port_ops;
+
+       return probe_ent;
+}
+
+
+/**
+ *     ata_pci_init_native_mode - Initialize native-mode driver
+ *     @pdev:  pci device to be initialized
+ *     @port:  array[2] of pointers to port info structures.
+ *     @ports: bitmap of ports present
+ *
+ *     Utility function which allocates and initializes an
+ *     ata_probe_ent structure for a standard dual-port
+ *     PIO-based IDE controller.  The returned ata_probe_ent
+ *     structure can be passed to ata_device_add().  The returned
+ *     ata_probe_ent structure should then be freed with kfree().
+ *
+ *     The caller need only pass the address of the primary port, the
+ *     secondary will be deduced automatically. If the device has non
+ *     standard secondary port mappings this function can be called twice,
+ *     once for each interface.
+ */
+
+struct ata_probe_ent *
+ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
+{
+       struct ata_probe_ent *probe_ent =
+               ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
+       int p = 0;
+
+       if (!probe_ent)
+               return NULL;
+
+       probe_ent->irq = pdev->irq;
+       probe_ent->irq_flags = SA_SHIRQ;
+       probe_ent->private_data = port[0]->private_data;
+
+       if (ports & ATA_PORT_PRIMARY) {
+               probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
+               probe_ent->port[p].altstatus_addr =
+               probe_ent->port[p].ctl_addr =
+                       pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
+               probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4);
+               ata_std_ports(&probe_ent->port[p]);
+               p++;
+       }
+
+       if (ports & ATA_PORT_SECONDARY) {
+               probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2);
+               probe_ent->port[p].altstatus_addr =
+               probe_ent->port[p].ctl_addr =
+                       pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
+               probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8;
+               ata_std_ports(&probe_ent->port[p]);
+               p++;
+       }
+
+       probe_ent->n_ports = p;
+       return probe_ent;
+}
+
+
+static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
+                               struct ata_port_info *port, int port_num)
+{
+       struct ata_probe_ent *probe_ent;
+
+       probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
+       if (!probe_ent)
+               return NULL;
+
+       probe_ent->legacy_mode = 1;
+       probe_ent->n_ports = 1;
+       probe_ent->hard_port_no = port_num;
+       probe_ent->private_data = port->private_data;
+
+       switch(port_num)
+       {
+               case 0:
+                       probe_ent->irq = 14;
+                       probe_ent->port[0].cmd_addr = 0x1f0;
+                       probe_ent->port[0].altstatus_addr =
+                       probe_ent->port[0].ctl_addr = 0x3f6;
+                       break;
+               case 1:
+                       probe_ent->irq = 15;
+                       probe_ent->port[0].cmd_addr = 0x170;
+                       probe_ent->port[0].altstatus_addr =
+                       probe_ent->port[0].ctl_addr = 0x376;
+                       break;
+       }
+
+       probe_ent->port[0].bmdma_addr =
+               pci_resource_start(pdev, 4) + 8 * port_num;
+       ata_std_ports(&probe_ent->port[0]);
+
+       return probe_ent;
+}
+
+
+/**
+ *     ata_pci_init_one - Initialize/register PCI IDE host controller
+ *     @pdev: Controller to be initialized
+ *     @port_info: Information from low-level host driver
+ *     @n_ports: Number of ports attached to host controller
+ *
+ *     This is a helper function which can be called from a driver's
+ *     xxx_init_one() probe function if the hardware uses traditional
+ *     IDE taskfile registers.
+ *
+ *     This function calls pci_enable_device(), reserves its register
+ *     regions, sets the dma mask, enables bus master mode, and calls
+ *     ata_device_add()
+ *
+ *     LOCKING:
+ *     Inherited from PCI layer (may sleep).
+ *
+ *     RETURNS:
+ *     Zero on success, negative on errno-based value on error.
+ */
+
+int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
+                     unsigned int n_ports)
+{
+       struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
+       struct ata_port_info *port[2];
+       u8 tmp8, mask;
+       unsigned int legacy_mode = 0;
+       int disable_dev_on_err = 1;
+       int rc;
+
+       DPRINTK("ENTER\n");
+
+       port[0] = port_info[0];
+       if (n_ports > 1)
+               port[1] = port_info[1];
+       else
+               port[1] = port[0];
+
+       if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0
+           && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
+               /* TODO: What if one channel is in native mode ... */
+               pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
+               mask = (1 << 2) | (1 << 0);
+               if ((tmp8 & mask) != mask)
+                       legacy_mode = (1 << 3);
+       }
+
+       /* FIXME... */
+       if ((!legacy_mode) && (n_ports > 2)) {
+               printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n");
+               n_ports = 2;
+               /* For now */
+       }
+
+       /* FIXME: Really for ATA it isn't safe because the device may be
+          multi-purpose and we want to leave it alone if it was already
+          enabled. Secondly for shared use as Arjan says we want refcounting
+
+          Checking dev->is_enabled is insufficient as this is not set at
+          boot for the primary video which is BIOS enabled
+         */
+
+       rc = pci_enable_device(pdev);
+       if (rc)
+               return rc;
+
+       rc = pci_request_regions(pdev, DRV_NAME);
+       if (rc) {
+               disable_dev_on_err = 0;
+               goto err_out;
+       }
+
+       /* FIXME: Should use platform specific mappers for legacy port ranges */
+       if (legacy_mode) {
+               if (!request_region(0x1f0, 8, "libata")) {
+                       struct resource *conflict, res;
+                       res.start = 0x1f0;
+                       res.end = 0x1f0 + 8 - 1;
+                       conflict = ____request_resource(&ioport_resource, &res);
+                       if (!strcmp(conflict->name, "libata"))
+                               legacy_mode |= (1 << 0);
+                       else {
+                               disable_dev_on_err = 0;
+                               printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n");
+                       }
+               } else
+                       legacy_mode |= (1 << 0);
+
+               if (!request_region(0x170, 8, "libata")) {
+                       struct resource *conflict, res;
+                       res.start = 0x170;
+                       res.end = 0x170 + 8 - 1;
+                       conflict = ____request_resource(&ioport_resource, &res);
+                       if (!strcmp(conflict->name, "libata"))
+                               legacy_mode |= (1 << 1);
+                       else {
+                               disable_dev_on_err = 0;
+                               printk(KERN_WARNING "ata: 0x170 IDE port busy\n");
+                       }
+               } else
+                       legacy_mode |= (1 << 1);
+       }
+
+       /* we have legacy mode, but all ports are unavailable */
+       if (legacy_mode == (1 << 3)) {
+               rc = -EBUSY;
+               goto err_out_regions;
+       }
+
+       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+       if (rc)
+               goto err_out_regions;
+       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+       if (rc)
+               goto err_out_regions;
+
+       if (legacy_mode) {
+               if (legacy_mode & (1 << 0))
+                       probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0);
+               if (legacy_mode & (1 << 1))
+                       probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1);
+       } else {
+               if (n_ports == 2)
+                       probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
+               else
+                       probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
+       }
+       if (!probe_ent && !probe_ent2) {
+               rc = -ENOMEM;
+               goto err_out_regions;
+       }
+
+       pci_set_master(pdev);
+
+       /* FIXME: check ata_device_add return */
+       if (legacy_mode) {
+               if (legacy_mode & (1 << 0))
+                       ata_device_add(probe_ent);
+               if (legacy_mode & (1 << 1))
+                       ata_device_add(probe_ent2);
+       } else
+               ata_device_add(probe_ent);
+
+       kfree(probe_ent);
+       kfree(probe_ent2);
+
+       return 0;
+
+err_out_regions:
+       if (legacy_mode & (1 << 0))
+               release_region(0x1f0, 8);
+       if (legacy_mode & (1 << 1))
+               release_region(0x170, 8);
+       pci_release_regions(pdev);
+err_out:
+       if (disable_dev_on_err)
+               pci_disable_device(pdev);
+       return rc;
+}
+
+#endif /* CONFIG_PCI */
+
index 4f91b0dc572bb5b1aea66a6aed56df874808eac8..714b42bad935739af2e3aef58b0856215c029c1b 100644 (file)
 
 #include "libata.h"
 
-static unsigned int ata_busy_sleep (struct ata_port *ap,
-                                   unsigned long tmout_pat,
-                                   unsigned long tmout);
-static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev);
-static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev);
+static unsigned int ata_dev_init_params(struct ata_port *ap,
+                                       struct ata_device *dev);
 static void ata_set_mode(struct ata_port *ap);
 static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
-static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift);
-static int fgb(u32 bitmap);
-static int ata_choose_xfer_mode(const struct ata_port *ap,
-                               u8 *xfer_mode_out,
-                               unsigned int *xfer_shift_out);
-static void __ata_qc_complete(struct ata_queued_cmd *qc);
+static unsigned int ata_dev_xfermask(struct ata_port *ap,
+                                    struct ata_device *dev);
 
 static unsigned int ata_unique_id = 1;
 static struct workqueue_struct *ata_wq;
 
-int atapi_enabled = 0;
+int atapi_enabled = 1;
 module_param(atapi_enabled, int, 0444);
 MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
 
@@ -91,403 +84,6 @@ MODULE_DESCRIPTION("Library module for ATA devices");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
-/**
- *     ata_tf_load_pio - send taskfile registers to host controller
- *     @ap: Port to which output is sent
- *     @tf: ATA taskfile register set
- *
- *     Outputs ATA taskfile to standard ATA host controller.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-
-static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-
-       if (tf->ctl != ap->last_ctl) {
-               outb(tf->ctl, ioaddr->ctl_addr);
-               ap->last_ctl = tf->ctl;
-               ata_wait_idle(ap);
-       }
-
-       if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
-               outb(tf->hob_feature, ioaddr->feature_addr);
-               outb(tf->hob_nsect, ioaddr->nsect_addr);
-               outb(tf->hob_lbal, ioaddr->lbal_addr);
-               outb(tf->hob_lbam, ioaddr->lbam_addr);
-               outb(tf->hob_lbah, ioaddr->lbah_addr);
-               VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
-                       tf->hob_feature,
-                       tf->hob_nsect,
-                       tf->hob_lbal,
-                       tf->hob_lbam,
-                       tf->hob_lbah);
-       }
-
-       if (is_addr) {
-               outb(tf->feature, ioaddr->feature_addr);
-               outb(tf->nsect, ioaddr->nsect_addr);
-               outb(tf->lbal, ioaddr->lbal_addr);
-               outb(tf->lbam, ioaddr->lbam_addr);
-               outb(tf->lbah, ioaddr->lbah_addr);
-               VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
-                       tf->feature,
-                       tf->nsect,
-                       tf->lbal,
-                       tf->lbam,
-                       tf->lbah);
-       }
-
-       if (tf->flags & ATA_TFLAG_DEVICE) {
-               outb(tf->device, ioaddr->device_addr);
-               VPRINTK("device 0x%X\n", tf->device);
-       }
-
-       ata_wait_idle(ap);
-}
-
-/**
- *     ata_tf_load_mmio - send taskfile registers to host controller
- *     @ap: Port to which output is sent
- *     @tf: ATA taskfile register set
- *
- *     Outputs ATA taskfile to standard ATA host controller using MMIO.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-
-static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-
-       if (tf->ctl != ap->last_ctl) {
-               writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
-               ap->last_ctl = tf->ctl;
-               ata_wait_idle(ap);
-       }
-
-       if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
-               writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr);
-               writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr);
-               writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr);
-               writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr);
-               writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr);
-               VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
-                       tf->hob_feature,
-                       tf->hob_nsect,
-                       tf->hob_lbal,
-                       tf->hob_lbam,
-                       tf->hob_lbah);
-       }
-
-       if (is_addr) {
-               writeb(tf->feature, (void __iomem *) ioaddr->feature_addr);
-               writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
-               writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
-               writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
-               writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
-               VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
-                       tf->feature,
-                       tf->nsect,
-                       tf->lbal,
-                       tf->lbam,
-                       tf->lbah);
-       }
-
-       if (tf->flags & ATA_TFLAG_DEVICE) {
-               writeb(tf->device, (void __iomem *) ioaddr->device_addr);
-               VPRINTK("device 0x%X\n", tf->device);
-       }
-
-       ata_wait_idle(ap);
-}
-
-
-/**
- *     ata_tf_load - send taskfile registers to host controller
- *     @ap: Port to which output is sent
- *     @tf: ATA taskfile register set
- *
- *     Outputs ATA taskfile to standard ATA host controller using MMIO
- *     or PIO as indicated by the ATA_FLAG_MMIO flag.
- *     Writes the control, feature, nsect, lbal, lbam, and lbah registers.
- *     Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
- *     hob_lbal, hob_lbam, and hob_lbah.
- *
- *     This function waits for idle (!BUSY and !DRQ) after writing
- *     registers.  If the control register has a new value, this
- *     function also waits for idle after writing control and before
- *     writing the remaining registers.
- *
- *     May be used as the tf_load() entry in ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
-{
-       if (ap->flags & ATA_FLAG_MMIO)
-               ata_tf_load_mmio(ap, tf);
-       else
-               ata_tf_load_pio(ap, tf);
-}
-
-/**
- *     ata_exec_command_pio - issue ATA command to host controller
- *     @ap: port to which command is being issued
- *     @tf: ATA taskfile register set
- *
- *     Issues PIO write to ATA command register, with proper
- *     synchronization with interrupt handler / other threads.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
- */
-
-static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf)
-{
-       DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
-
-               outb(tf->command, ap->ioaddr.command_addr);
-       ata_pause(ap);
-}
-
-
-/**
- *     ata_exec_command_mmio - issue ATA command to host controller
- *     @ap: port to which command is being issued
- *     @tf: ATA taskfile register set
- *
- *     Issues MMIO write to ATA command register, with proper
- *     synchronization with interrupt handler / other threads.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
- */
-
-static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
-{
-       DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
-
-               writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr);
-       ata_pause(ap);
-}
-
-
-/**
- *     ata_exec_command - issue ATA command to host controller
- *     @ap: port to which command is being issued
- *     @tf: ATA taskfile register set
- *
- *     Issues PIO/MMIO write to ATA command register, with proper
- *     synchronization with interrupt handler / other threads.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
- */
-void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
-{
-       if (ap->flags & ATA_FLAG_MMIO)
-               ata_exec_command_mmio(ap, tf);
-       else
-               ata_exec_command_pio(ap, tf);
-}
-
-/**
- *     ata_tf_to_host - issue ATA taskfile to host controller
- *     @ap: port to which command is being issued
- *     @tf: ATA taskfile register set
- *
- *     Issues ATA taskfile register set to ATA host controller,
- *     with proper synchronization with interrupt handler and
- *     other threads.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
- */
-
-static inline void ata_tf_to_host(struct ata_port *ap,
-                                 const struct ata_taskfile *tf)
-{
-       ap->ops->tf_load(ap, tf);
-       ap->ops->exec_command(ap, tf);
-}
-
-/**
- *     ata_tf_read_pio - input device's ATA taskfile shadow registers
- *     @ap: Port from which input is read
- *     @tf: ATA taskfile register set for storing input
- *
- *     Reads ATA taskfile registers for currently-selected device
- *     into @tf.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-
-static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-
-       tf->command = ata_check_status(ap);
-       tf->feature = inb(ioaddr->error_addr);
-       tf->nsect = inb(ioaddr->nsect_addr);
-       tf->lbal = inb(ioaddr->lbal_addr);
-       tf->lbam = inb(ioaddr->lbam_addr);
-       tf->lbah = inb(ioaddr->lbah_addr);
-       tf->device = inb(ioaddr->device_addr);
-
-       if (tf->flags & ATA_TFLAG_LBA48) {
-               outb(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
-               tf->hob_feature = inb(ioaddr->error_addr);
-               tf->hob_nsect = inb(ioaddr->nsect_addr);
-               tf->hob_lbal = inb(ioaddr->lbal_addr);
-               tf->hob_lbam = inb(ioaddr->lbam_addr);
-               tf->hob_lbah = inb(ioaddr->lbah_addr);
-       }
-}
-
-/**
- *     ata_tf_read_mmio - input device's ATA taskfile shadow registers
- *     @ap: Port from which input is read
- *     @tf: ATA taskfile register set for storing input
- *
- *     Reads ATA taskfile registers for currently-selected device
- *     into @tf via MMIO.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-
-static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-
-       tf->command = ata_check_status(ap);
-       tf->feature = readb((void __iomem *)ioaddr->error_addr);
-       tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
-       tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
-       tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
-       tf->lbah = readb((void __iomem *)ioaddr->lbah_addr);
-       tf->device = readb((void __iomem *)ioaddr->device_addr);
-
-       if (tf->flags & ATA_TFLAG_LBA48) {
-               writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr);
-               tf->hob_feature = readb((void __iomem *)ioaddr->error_addr);
-               tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr);
-               tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr);
-               tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr);
-               tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr);
-       }
-}
-
-
-/**
- *     ata_tf_read - input device's ATA taskfile shadow registers
- *     @ap: Port from which input is read
- *     @tf: ATA taskfile register set for storing input
- *
- *     Reads ATA taskfile registers for currently-selected device
- *     into @tf.
- *
- *     Reads nsect, lbal, lbam, lbah, and device.  If ATA_TFLAG_LBA48
- *     is set, also reads the hob registers.
- *
- *     May be used as the tf_read() entry in ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
-       if (ap->flags & ATA_FLAG_MMIO)
-               ata_tf_read_mmio(ap, tf);
-       else
-               ata_tf_read_pio(ap, tf);
-}
-
-/**
- *     ata_check_status_pio - Read device status reg & clear interrupt
- *     @ap: port where the device is
- *
- *     Reads ATA taskfile status register for currently-selected device
- *     and return its value. This also clears pending interrupts
- *      from this device
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-static u8 ata_check_status_pio(struct ata_port *ap)
-{
-       return inb(ap->ioaddr.status_addr);
-}
-
-/**
- *     ata_check_status_mmio - Read device status reg & clear interrupt
- *     @ap: port where the device is
- *
- *     Reads ATA taskfile status register for currently-selected device
- *     via MMIO and return its value. This also clears pending interrupts
- *      from this device
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-static u8 ata_check_status_mmio(struct ata_port *ap)
-{
-               return readb((void __iomem *) ap->ioaddr.status_addr);
-}
-
-
-/**
- *     ata_check_status - Read device status reg & clear interrupt
- *     @ap: port where the device is
- *
- *     Reads ATA taskfile status register for currently-selected device
- *     and return its value. This also clears pending interrupts
- *      from this device
- *
- *     May be used as the check_status() entry in ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-u8 ata_check_status(struct ata_port *ap)
-{
-       if (ap->flags & ATA_FLAG_MMIO)
-               return ata_check_status_mmio(ap);
-       return ata_check_status_pio(ap);
-}
-
-
-/**
- *     ata_altstatus - Read device alternate status reg
- *     @ap: port where the device is
- *
- *     Reads ATA taskfile alternate status register for
- *     currently-selected device and return its value.
- *
- *     Note: may NOT be used as the check_altstatus() entry in
- *     ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-u8 ata_altstatus(struct ata_port *ap)
-{
-       if (ap->ops->check_altstatus)
-               return ap->ops->check_altstatus(ap);
-
-       if (ap->flags & ATA_FLAG_MMIO)
-               return readb((void __iomem *)ap->ioaddr.altstatus_addr);
-       return inb(ap->ioaddr.altstatus_addr);
-}
-
 
 /**
  *     ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
@@ -632,58 +228,148 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
        return -1;
 }
 
-static const char * const xfer_mode_str[] = {
-       "UDMA/16",
-       "UDMA/25",
-       "UDMA/33",
-       "UDMA/44",
-       "UDMA/66",
-       "UDMA/100",
-       "UDMA/133",
-       "UDMA7",
-       "MWDMA0",
-       "MWDMA1",
-       "MWDMA2",
-       "PIO0",
-       "PIO1",
-       "PIO2",
-       "PIO3",
-       "PIO4",
+/**
+ *     ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask
+ *     @pio_mask: pio_mask
+ *     @mwdma_mask: mwdma_mask
+ *     @udma_mask: udma_mask
+ *
+ *     Pack @pio_mask, @mwdma_mask and @udma_mask into a single
+ *     unsigned int xfer_mask.
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     Packed xfer_mask.
+ */
+static unsigned int ata_pack_xfermask(unsigned int pio_mask,
+                                     unsigned int mwdma_mask,
+                                     unsigned int udma_mask)
+{
+       return ((pio_mask << ATA_SHIFT_PIO) & ATA_MASK_PIO) |
+               ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) |
+               ((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA);
+}
+
+static const struct ata_xfer_ent {
+       unsigned int shift, bits;
+       u8 base;
+} ata_xfer_tbl[] = {
+       { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
+       { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 },
+       { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 },
+       { -1, },
 };
 
 /**
- *     ata_udma_string - convert UDMA bit offset to string
- *     @mask: mask of bits supported; only highest bit counts.
+ *     ata_xfer_mask2mode - Find matching XFER_* for the given xfer_mask
+ *     @xfer_mask: xfer_mask of interest
  *
- *     Determine string which represents the highest speed
- *     (highest bit in @udma_mask).
+ *     Return matching XFER_* value for @xfer_mask.  Only the highest
+ *     bit of @xfer_mask is considered.
  *
  *     LOCKING:
  *     None.
  *
  *     RETURNS:
- *     Constant C string representing highest speed listed in
- *     @udma_mask, or the constant C string "<n/a>".
+ *     Matching XFER_* value, 0 if no match found.
+ */
+static u8 ata_xfer_mask2mode(unsigned int xfer_mask)
+{
+       int highbit = fls(xfer_mask) - 1;
+       const struct ata_xfer_ent *ent;
+
+       for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
+               if (highbit >= ent->shift && highbit < ent->shift + ent->bits)
+                       return ent->base + highbit - ent->shift;
+       return 0;
+}
+
+/**
+ *     ata_xfer_mode2mask - Find matching xfer_mask for XFER_*
+ *     @xfer_mode: XFER_* of interest
+ *
+ *     Return matching xfer_mask for @xfer_mode.
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     Matching xfer_mask, 0 if no match found.
  */
+static unsigned int ata_xfer_mode2mask(u8 xfer_mode)
+{
+       const struct ata_xfer_ent *ent;
+
+       for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
+               if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits)
+                       return 1 << (ent->shift + xfer_mode - ent->base);
+       return 0;
+}
 
-static const char *ata_mode_string(unsigned int mask)
+/**
+ *     ata_xfer_mode2shift - Find matching xfer_shift for XFER_*
+ *     @xfer_mode: XFER_* of interest
+ *
+ *     Return matching xfer_shift for @xfer_mode.
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     Matching xfer_shift, -1 if no match found.
+ */
+static int ata_xfer_mode2shift(unsigned int xfer_mode)
 {
-       int i;
+       const struct ata_xfer_ent *ent;
 
-       for (i = 7; i >= 0; i--)
-               if (mask & (1 << i))
-                       goto out;
-       for (i = ATA_SHIFT_MWDMA + 2; i >= ATA_SHIFT_MWDMA; i--)
-               if (mask & (1 << i))
-                       goto out;
-       for (i = ATA_SHIFT_PIO + 4; i >= ATA_SHIFT_PIO; i--)
-               if (mask & (1 << i))
-                       goto out;
+       for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
+               if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits)
+                       return ent->shift;
+       return -1;
+}
 
+/**
+ *     ata_mode_string - convert xfer_mask to string
+ *     @xfer_mask: mask of bits supported; only highest bit counts.
+ *
+ *     Determine string which represents the highest speed
+ *     (highest bit in @modemask).
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     Constant C string representing highest speed listed in
+ *     @mode_mask, or the constant C string "<n/a>".
+ */
+static const char *ata_mode_string(unsigned int xfer_mask)
+{
+       static const char * const xfer_mode_str[] = {
+               "PIO0",
+               "PIO1",
+               "PIO2",
+               "PIO3",
+               "PIO4",
+               "MWDMA0",
+               "MWDMA1",
+               "MWDMA2",
+               "UDMA/16",
+               "UDMA/25",
+               "UDMA/33",
+               "UDMA/44",
+               "UDMA/66",
+               "UDMA/100",
+               "UDMA/133",
+               "UDMA7",
+       };
+       int highbit;
+
+       highbit = fls(xfer_mask) - 1;
+       if (highbit >= 0 && highbit < ARRAY_SIZE(xfer_mode_str))
+               return xfer_mode_str[highbit];
        return "<n/a>";
-
-out:
-       return xfer_mode_str[i];
 }
 
 /**
@@ -838,6 +524,7 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
  *     ata_dev_try_classify - Parse returned ATA device signature
  *     @ap: ATA channel to examine
  *     @device: Device to examine (starting at zero)
+ *     @r_err: Value of error register on completion
  *
  *     After an event -- SRST, E.D.D., or SATA COMRESET -- occurs,
  *     an ATA/ATAPI-defined set of values is placed in the ATA
@@ -850,11 +537,14 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
  *
  *     LOCKING:
  *     caller.
+ *
+ *     RETURNS:
+ *     Device type - %ATA_DEV_ATA, %ATA_DEV_ATAPI or %ATA_DEV_NONE.
  */
 
-static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
+static unsigned int
+ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err)
 {
-       struct ata_device *dev = &ap->device[device];
        struct ata_taskfile tf;
        unsigned int class;
        u8 err;
@@ -865,8 +555,8 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
 
        ap->ops->tf_read(ap, &tf);
        err = tf.feature;
-
-       dev->class = ATA_DEV_NONE;
+       if (r_err)
+               *r_err = err;
 
        /* see if device passed diags */
        if (err == 1)
@@ -874,22 +564,20 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
        else if ((device == 0) && (err == 0x81))
                /* do nothing */ ;
        else
-               return err;
+               return ATA_DEV_NONE;
 
-       /* determine if device if ATA or ATAPI */
+       /* determine if device is ATA or ATAPI */
        class = ata_dev_classify(&tf);
+
        if (class == ATA_DEV_UNKNOWN)
-               return err;
+               return ATA_DEV_NONE;
        if ((class == ATA_DEV_ATA) && (ata_chk_status(ap) == 0))
-               return err;
-
-       dev->class = class;
-
-       return err;
+               return ATA_DEV_NONE;
+       return class;
 }
 
 /**
- *     ata_dev_id_string - Convert IDENTIFY DEVICE page into string
+ *     ata_id_string - Convert IDENTIFY DEVICE page into string
  *     @id: IDENTIFY DEVICE results we will examine
  *     @s: string into which data is output
  *     @ofs: offset into identify device page
@@ -903,8 +591,8 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
  *     caller.
  */
 
-void ata_dev_id_string(const u16 *id, unsigned char *s,
-                      unsigned int ofs, unsigned int len)
+void ata_id_string(const u16 *id, unsigned char *s,
+                  unsigned int ofs, unsigned int len)
 {
        unsigned int c;
 
@@ -922,6 +610,49 @@ void ata_dev_id_string(const u16 *id, unsigned char *s,
        }
 }
 
+/**
+ *     ata_id_c_string - Convert IDENTIFY DEVICE page into C string
+ *     @id: IDENTIFY DEVICE results we will examine
+ *     @s: string into which data is output
+ *     @ofs: offset into identify device page
+ *     @len: length of string to return. must be an odd number.
+ *
+ *     This function is identical to ata_id_string except that it
+ *     trims trailing spaces and terminates the resulting string with
+ *     null.  @len must be actual maximum length (even number) + 1.
+ *
+ *     LOCKING:
+ *     caller.
+ */
+void ata_id_c_string(const u16 *id, unsigned char *s,
+                    unsigned int ofs, unsigned int len)
+{
+       unsigned char *p;
+
+       WARN_ON(!(len & 1));
+
+       ata_id_string(id, s, ofs, len - 1);
+
+       p = s + strnlen(s, len - 1);
+       while (p > s && p[-1] == ' ')
+               p--;
+       *p = '\0';
+}
+
+static u64 ata_id_n_sectors(const u16 *id)
+{
+       if (ata_id_has_lba(id)) {
+               if (ata_id_has_lba48(id))
+                       return ata_id_u64(id, 100);
+               else
+                       return ata_id_u32(id, 60);
+       } else {
+               if (ata_id_current_chs_valid(id))
+                       return ata_id_u32(id, 57);
+               else
+                       return id[1] * id[3] * id[6];
+       }
+}
 
 /**
  *     ata_noop_dev_select - Select device 0/1 on ATA bus
@@ -1011,90 +742,172 @@ void ata_dev_select(struct ata_port *ap, unsigned int device,
 
 /**
  *     ata_dump_id - IDENTIFY DEVICE info debugging output
- *     @dev: Device whose IDENTIFY DEVICE page we will dump
+ *     @id: IDENTIFY DEVICE page to dump
  *
- *     Dump selected 16-bit words from a detected device's
- *     IDENTIFY PAGE page.
+ *     Dump selected 16-bit words from the given IDENTIFY DEVICE
+ *     page.
  *
  *     LOCKING:
  *     caller.
  */
 
-static inline void ata_dump_id(const struct ata_device *dev)
+static inline void ata_dump_id(const u16 *id)
 {
        DPRINTK("49==0x%04x  "
                "53==0x%04x  "
                "63==0x%04x  "
                "64==0x%04x  "
                "75==0x%04x  \n",
-               dev->id[49],
-               dev->id[53],
-               dev->id[63],
-               dev->id[64],
-               dev->id[75]);
+               id[49],
+               id[53],
+               id[63],
+               id[64],
+               id[75]);
        DPRINTK("80==0x%04x  "
                "81==0x%04x  "
                "82==0x%04x  "
                "83==0x%04x  "
                "84==0x%04x  \n",
-               dev->id[80],
-               dev->id[81],
-               dev->id[82],
-               dev->id[83],
-               dev->id[84]);
+               id[80],
+               id[81],
+               id[82],
+               id[83],
+               id[84]);
        DPRINTK("88==0x%04x  "
                "93==0x%04x\n",
-               dev->id[88],
-               dev->id[93]);
+               id[88],
+               id[93]);
 }
 
-/*
- *     Compute the PIO modes available for this device. This is not as
- *     trivial as it seems if we must consider early devices correctly.
+/**
+ *     ata_id_xfermask - Compute xfermask from the given IDENTIFY data
+ *     @id: IDENTIFY data to compute xfer mask from
+ *
+ *     Compute the xfermask for this device. This is not as trivial
+ *     as it seems if we must consider early devices correctly.
+ *
+ *     FIXME: pre IDE drive timing (do we care ?).
  *
- *     FIXME: pre IDE drive timing (do we care ?). 
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     Computed xfermask
  */
-
-static unsigned int ata_pio_modes(const struct ata_device *adev)
+static unsigned int ata_id_xfermask(const u16 *id)
 {
-       u16 modes;
+       unsigned int pio_mask, mwdma_mask, udma_mask;
 
        /* Usual case. Word 53 indicates word 64 is valid */
-       if (adev->id[ATA_ID_FIELD_VALID] & (1 << 1)) {
-               modes = adev->id[ATA_ID_PIO_MODES] & 0x03;
-               modes <<= 3;
-               modes |= 0x7;
-               return modes;
+       if (id[ATA_ID_FIELD_VALID] & (1 << 1)) {
+               pio_mask = id[ATA_ID_PIO_MODES] & 0x03;
+               pio_mask <<= 3;
+               pio_mask |= 0x7;
+       } else {
+               /* If word 64 isn't valid then Word 51 high byte holds
+                * the PIO timing number for the maximum. Turn it into
+                * a mask.
+                */
+               pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
+
+               /* But wait.. there's more. Design your standards by
+                * committee and you too can get a free iordy field to
+                * process. However its the speeds not the modes that
+                * are supported... Note drivers using the timing API
+                * will get this right anyway
+                */
        }
 
-       /* If word 64 isn't valid then Word 51 high byte holds the PIO timing
-          number for the maximum. Turn it into a mask and return it */
-       modes = (2 << ((adev->id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF)) - 1 ;
-       return modes;
-       /* But wait.. there's more. Design your standards by committee and
-          you too can get a free iordy field to process. However its the 
-          speeds not the modes that are supported... Note drivers using the
-          timing API will get this right anyway */
+       mwdma_mask = id[ATA_ID_MWDMA_MODES] & 0x07;
+
+       udma_mask = 0;
+       if (id[ATA_ID_FIELD_VALID] & (1 << 2))
+               udma_mask = id[ATA_ID_UDMA_MODES] & 0xff;
+
+       return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask);
 }
 
-struct ata_exec_internal_arg {
-       unsigned int err_mask;
-       struct ata_taskfile *tf;
-       struct completion *waiting;
-};
+/**
+ *     ata_port_queue_task - Queue port_task
+ *     @ap: The ata_port to queue port_task for
+ *
+ *     Schedule @fn(@data) for execution after @delay jiffies using
+ *     port_task.  There is one port_task per port and it's the
+ *     user(low level driver)'s responsibility to make sure that only
+ *     one task is active at any given time.
+ *
+ *     libata core layer takes care of synchronization between
+ *     port_task and EH.  ata_port_queue_task() may be ignored for EH
+ *     synchronization.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data,
+                        unsigned long delay)
+{
+       int rc;
+
+       if (ap->flags & ATA_FLAG_FLUSH_PORT_TASK)
+               return;
+
+       PREPARE_WORK(&ap->port_task, fn, data);
+
+       if (!delay)
+               rc = queue_work(ata_wq, &ap->port_task);
+       else
+               rc = queue_delayed_work(ata_wq, &ap->port_task, delay);
+
+       /* rc == 0 means that another user is using port task */
+       WARN_ON(rc == 0);
+}
+
+/**
+ *     ata_port_flush_task - Flush port_task
+ *     @ap: The ata_port to flush port_task for
+ *
+ *     After this function completes, port_task is guranteed not to
+ *     be running or scheduled.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ */
+void ata_port_flush_task(struct ata_port *ap)
+{
+       unsigned long flags;
+
+       DPRINTK("ENTER\n");
+
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       ap->flags |= ATA_FLAG_FLUSH_PORT_TASK;
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       DPRINTK("flush #1\n");
+       flush_workqueue(ata_wq);
+
+       /*
+        * At this point, if a task is running, it's guaranteed to see
+        * the FLUSH flag; thus, it will never queue pio tasks again.
+        * Cancel and flush.
+        */
+       if (!cancel_delayed_work(&ap->port_task)) {
+               DPRINTK("flush #2\n");
+               flush_workqueue(ata_wq);
+       }
 
-int ata_qc_complete_internal(struct ata_queued_cmd *qc)
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       ap->flags &= ~ATA_FLAG_FLUSH_PORT_TASK;
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       DPRINTK("EXIT\n");
+}
+
+void ata_qc_complete_internal(struct ata_queued_cmd *qc)
 {
-       struct ata_exec_internal_arg *arg = qc->private_data;
-       struct completion *waiting = arg->waiting;
+       struct completion *waiting = qc->private_data;
 
-       if (!(qc->err_mask & ~AC_ERR_DEV))
-               qc->ap->ops->tf_read(qc->ap, arg->tf);
-       arg->err_mask = qc->err_mask;
-       arg->waiting = NULL;
+       qc->ap->ops->tf_read(qc->ap, &qc->tf);
        complete(waiting);
-
-       return 0;
 }
 
 /**
@@ -1125,7 +938,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
        struct ata_queued_cmd *qc;
        DECLARE_COMPLETION(wait);
        unsigned long flags;
-       struct ata_exec_internal_arg arg;
+       unsigned int err_mask;
 
        spin_lock_irqsave(&ap->host_set->lock, flags);
 
@@ -1139,13 +952,12 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
                qc->nsect = buflen / ATA_SECT_SIZE;
        }
 
-       arg.waiting = &wait;
-       arg.tf = tf;
-       qc->private_data = &arg;
+       qc->private_data = &wait;
        qc->complete_fn = ata_qc_complete_internal;
 
-       if (ata_qc_issue(qc))
-               goto issue_fail;
+       qc->err_mask = ata_qc_issue(qc);
+       if (qc->err_mask)
+               ata_qc_complete(qc);
 
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
 
@@ -1158,8 +970,8 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
                 * before the caller cleans up, it will result in a
                 * spurious interrupt.  We can live with that.
                 */
-               if (arg.waiting) {
-                       qc->err_mask = AC_ERR_OTHER;
+               if (qc->flags & ATA_QCFLAG_ACTIVE) {
+                       qc->err_mask = AC_ERR_TIMEOUT;
                        ata_qc_complete(qc);
                        printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n",
                               ap->id, command);
@@ -1168,12 +980,12 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
                spin_unlock_irqrestore(&ap->host_set->lock, flags);
        }
 
-       return arg.err_mask;
+       *tf = qc->tf;
+       err_mask = qc->err_mask;
 
- issue_fail:
        ata_qc_free(qc);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
-       return AC_ERR_OTHER;
+
+       return err_mask;
 }
 
 /**
@@ -1210,73 +1022,78 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
 }
 
 /**
- *     ata_dev_identify - obtain IDENTIFY x DEVICE page
- *     @ap: port on which device we wish to probe resides
- *     @device: device bus address, starting at zero
- *
- *     Following bus reset, we issue the IDENTIFY [PACKET] DEVICE
- *     command, and read back the 512-byte device information page.
- *     The device information page is fed to us via the standard
- *     PIO-IN protocol, but we hand-code it here. (TODO: investigate
- *     using standard PIO-IN paths)
- *
- *     After reading the device information page, we use several
- *     bits of information from it to initialize data structures
- *     that will be used during the lifetime of the ata_device.
- *     Other data from the info page is used to disqualify certain
- *     older ATA devices we do not wish to support.
+ *     ata_dev_read_id - Read ID data from the specified device
+ *     @ap: port on which target device resides
+ *     @dev: target device
+ *     @p_class: pointer to class of the target device (may be changed)
+ *     @post_reset: is this read ID post-reset?
+ *     @p_id: read IDENTIFY page (newly allocated)
+ *
+ *     Read ID data from the specified device.  ATA_CMD_ID_ATA is
+ *     performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI
+ *     devices.  This function also takes care of EDD signature
+ *     misreporting (to be removed once EDD support is gone) and
+ *     issues ATA_CMD_INIT_DEV_PARAMS for pre-ATA4 drives.
  *
  *     LOCKING:
- *     Inherited from caller.  Some functions called by this function
- *     obtain the host_set lock.
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
  */
-
-static void ata_dev_identify(struct ata_port *ap, unsigned int device)
+static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
+                          unsigned int *p_class, int post_reset, u16 **p_id)
 {
-       struct ata_device *dev = &ap->device[device];
-       unsigned int major_version;
-       u16 tmp;
-       unsigned long xfer_modes;
+       unsigned int class = *p_class;
        unsigned int using_edd;
        struct ata_taskfile tf;
-       unsigned int err_mask;
+       unsigned int err_mask = 0;
+       u16 *id;
+       const char *reason;
        int rc;
 
-       if (!ata_dev_present(dev)) {
-               DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n",
-                       ap->id, device);
-               return;
-       }
+       DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno);
 
-       if (ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET))
+       if (ap->ops->probe_reset ||
+           ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET))
                using_edd = 0;
        else
                using_edd = 1;
 
-       DPRINTK("ENTER, host %u, dev %u\n", ap->id, device);
-
-       assert (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ATAPI ||
-               dev->class == ATA_DEV_NONE);
+       ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
 
-       ata_dev_select(ap, device, 1, 1); /* select device 0/1 */
+       id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL);
+       if (id == NULL) {
+               rc = -ENOMEM;
+               reason = "out of memory";
+               goto err_out;
+       }
 
-retry:
-       ata_tf_init(ap, &tf, device);
+ retry:
+       ata_tf_init(ap, &tf, dev->devno);
 
-       if (dev->class == ATA_DEV_ATA) {
+       switch (class) {
+       case ATA_DEV_ATA:
                tf.command = ATA_CMD_ID_ATA;
-               DPRINTK("do ATA identify\n");
-       } else {
+               break;
+       case ATA_DEV_ATAPI:
                tf.command = ATA_CMD_ID_ATAPI;
-               DPRINTK("do ATAPI identify\n");
+               break;
+       default:
+               rc = -ENODEV;
+               reason = "unsupported class";
+               goto err_out;
        }
 
        tf.protocol = ATA_PROT_PIO;
 
        err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
-                                    dev->id, sizeof(dev->id));
+                                    id, sizeof(id[0]) * ATA_ID_WORDS);
 
        if (err_mask) {
+               rc = -EIO;
+               reason = "I/O error";
+
                if (err_mask & ~AC_ERR_DEV)
                        goto err_out;
 
@@ -1291,180 +1108,223 @@ retry:
                 * ATA software reset (SRST, the default) does not appear
                 * to have this problem.
                 */
-               if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
+               if ((using_edd) && (class == ATA_DEV_ATA)) {
                        u8 err = tf.feature;
                        if (err & ATA_ABORTED) {
-                               dev->class = ATA_DEV_ATAPI;
+                               class = ATA_DEV_ATAPI;
                                goto retry;
                        }
                }
                goto err_out;
        }
 
-       swap_buf_le16(dev->id, ATA_ID_WORDS);
+       swap_buf_le16(id, ATA_ID_WORDS);
+
+       /* sanity check */
+       if ((class == ATA_DEV_ATA) != ata_id_is_ata(id)) {
+               rc = -EINVAL;
+               reason = "device reports illegal type";
+               goto err_out;
+       }
+
+       if (post_reset && class == ATA_DEV_ATA) {
+               /*
+                * The exact sequence expected by certain pre-ATA4 drives is:
+                * SRST RESET
+                * IDENTIFY
+                * INITIALIZE DEVICE PARAMETERS
+                * anything else..
+                * Some drives were very specific about that exact sequence.
+                */
+               if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
+                       err_mask = ata_dev_init_params(ap, dev);
+                       if (err_mask) {
+                               rc = -EIO;
+                               reason = "INIT_DEV_PARAMS failed";
+                               goto err_out;
+                       }
+
+                       /* current CHS translation info (id[53-58]) might be
+                        * changed. reread the identify device info.
+                        */
+                       post_reset = 0;
+                       goto retry;
+               }
+       }
+
+       *p_class = class;
+       *p_id = id;
+       return 0;
+
+ err_out:
+       printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n",
+              ap->id, dev->devno, reason);
+       kfree(id);
+       return rc;
+}
+
+static inline u8 ata_dev_knobble(const struct ata_port *ap,
+                                struct ata_device *dev)
+{
+       return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
+}
+
+/**
+ *     ata_dev_configure - Configure the specified ATA/ATAPI device
+ *     @ap: Port on which target device resides
+ *     @dev: Target device to configure
+ *     @print_info: Enable device info printout
+ *
+ *     Configure @dev according to @dev->id.  Generic and low-level
+ *     driver specific fixups are also applied.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise
+ */
+static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
+                            int print_info)
+{
+       const u16 *id = dev->id;
+       unsigned int xfer_mask;
+       int i, rc;
+
+       if (!ata_dev_present(dev)) {
+               DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n",
+                       ap->id, dev->devno);
+               return 0;
+       }
+
+       DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno);
 
        /* print device capabilities */
-       printk(KERN_DEBUG "ata%u: dev %u cfg "
-              "49:%04x 82:%04x 83:%04x 84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n",
-              ap->id, device, dev->id[49],
-              dev->id[82], dev->id[83], dev->id[84],
-              dev->id[85], dev->id[86], dev->id[87],
-              dev->id[88]);
+       if (print_info)
+               printk(KERN_DEBUG "ata%u: dev %u cfg 49:%04x 82:%04x 83:%04x "
+                      "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n",
+                      ap->id, dev->devno, id[49], id[82], id[83],
+                      id[84], id[85], id[86], id[87], id[88]);
+
+       /* initialize to-be-configured parameters */
+       dev->flags = 0;
+       dev->max_sectors = 0;
+       dev->cdb_len = 0;
+       dev->n_sectors = 0;
+       dev->cylinders = 0;
+       dev->heads = 0;
+       dev->sectors = 0;
 
        /*
         * common ATA, ATAPI feature tests
         */
 
        /* we require DMA support (bits 8 of word 49) */
-       if (!ata_id_has_dma(dev->id)) {
+       if (!ata_id_has_dma(id)) {
                printk(KERN_DEBUG "ata%u: no dma\n", ap->id);
+               rc = -EINVAL;
                goto err_out_nosup;
        }
 
-       /* quick-n-dirty find max transfer mode; for printk only */
-       xfer_modes = dev->id[ATA_ID_UDMA_MODES];
-       if (!xfer_modes)
-               xfer_modes = (dev->id[ATA_ID_MWDMA_MODES]) << ATA_SHIFT_MWDMA;
-       if (!xfer_modes)
-               xfer_modes = ata_pio_modes(dev);
+       /* find max transfer mode; for printk only */
+       xfer_mask = ata_id_xfermask(id);
 
-       ata_dump_id(dev);
+       ata_dump_id(id);
 
        /* ATA-specific feature tests */
        if (dev->class == ATA_DEV_ATA) {
-               if (!ata_id_is_ata(dev->id))    /* sanity check */
-                       goto err_out_nosup;
-
-               /* get major version */
-               tmp = dev->id[ATA_ID_MAJOR_VER];
-               for (major_version = 14; major_version >= 1; major_version--)
-                       if (tmp & (1 << major_version))
-                               break;
-
-               /*
-                * The exact sequence expected by certain pre-ATA4 drives is:
-                * SRST RESET
-                * IDENTIFY
-                * INITIALIZE DEVICE PARAMETERS
-                * anything else..
-                * Some drives were very specific about that exact sequence.
-                */
-               if (major_version < 4 || (!ata_id_has_lba(dev->id))) {
-                       ata_dev_init_params(ap, dev);
+               dev->n_sectors = ata_id_n_sectors(id);
 
-                       /* current CHS translation info (id[53-58]) might be
-                        * changed. reread the identify device info.
-                        */
-                       ata_dev_reread_id(ap, dev);
-               }
+               if (ata_id_has_lba(id)) {
+                       const char *lba_desc;
 
-               if (ata_id_has_lba(dev->id)) {
+                       lba_desc = "LBA";
                        dev->flags |= ATA_DFLAG_LBA;
-
-                       if (ata_id_has_lba48(dev->id)) {
+                       if (ata_id_has_lba48(id)) {
                                dev->flags |= ATA_DFLAG_LBA48;
-                               dev->n_sectors = ata_id_u64(dev->id, 100);
-                       } else {
-                               dev->n_sectors = ata_id_u32(dev->id, 60);
+                               lba_desc = "LBA48";
                        }
 
                        /* print device info to dmesg */
-                       printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n",
-                              ap->id, device,
-                              major_version,
-                              ata_mode_string(xfer_modes),
-                              (unsigned long long)dev->n_sectors,
-                              dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA");
-               } else { 
+                       if (print_info)
+                               printk(KERN_INFO "ata%u: dev %u ATA-%d, "
+                                      "max %s, %Lu sectors: %s\n",
+                                      ap->id, dev->devno,
+                                      ata_id_major_version(id),
+                                      ata_mode_string(xfer_mask),
+                                      (unsigned long long)dev->n_sectors,
+                                      lba_desc);
+               } else {
                        /* CHS */
 
                        /* Default translation */
-                       dev->cylinders  = dev->id[1];
-                       dev->heads      = dev->id[3];
-                       dev->sectors    = dev->id[6];
-                       dev->n_sectors  = dev->cylinders * dev->heads * dev->sectors;
+                       dev->cylinders  = id[1];
+                       dev->heads      = id[3];
+                       dev->sectors    = id[6];
 
-                       if (ata_id_current_chs_valid(dev->id)) {
+                       if (ata_id_current_chs_valid(id)) {
                                /* Current CHS translation is valid. */
-                               dev->cylinders = dev->id[54];
-                               dev->heads     = dev->id[55];
-                               dev->sectors   = dev->id[56];
-                               
-                               dev->n_sectors = ata_id_u32(dev->id, 57);
+                               dev->cylinders = id[54];
+                               dev->heads     = id[55];
+                               dev->sectors   = id[56];
                        }
 
                        /* print device info to dmesg */
-                       printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n",
-                              ap->id, device,
-                              major_version,
-                              ata_mode_string(xfer_modes),
-                              (unsigned long long)dev->n_sectors,
-                              (int)dev->cylinders, (int)dev->heads, (int)dev->sectors);
-
+                       if (print_info)
+                               printk(KERN_INFO "ata%u: dev %u ATA-%d, "
+                                      "max %s, %Lu sectors: CHS %u/%u/%u\n",
+                                      ap->id, dev->devno,
+                                      ata_id_major_version(id),
+                                      ata_mode_string(xfer_mask),
+                                      (unsigned long long)dev->n_sectors,
+                                      dev->cylinders, dev->heads, dev->sectors);
                }
 
-               ap->host->max_cmd_len = 16;
+               dev->cdb_len = 16;
        }
 
        /* ATAPI-specific feature tests */
        else if (dev->class == ATA_DEV_ATAPI) {
-               if (ata_id_is_ata(dev->id))             /* sanity check */
-                       goto err_out_nosup;
-
-               rc = atapi_cdb_len(dev->id);
+               rc = atapi_cdb_len(id);
                if ((rc < 12) || (rc > ATAPI_CDB_LEN)) {
                        printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id);
+                       rc = -EINVAL;
                        goto err_out_nosup;
                }
-               ap->cdb_len = (unsigned int) rc;
-               ap->host->max_cmd_len = (unsigned char) ap->cdb_len;
+               dev->cdb_len = (unsigned int) rc;
 
                /* print device info to dmesg */
-               printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
-                      ap->id, device,
-                      ata_mode_string(xfer_modes));
+               if (print_info)
+                       printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
+                              ap->id, dev->devno, ata_mode_string(xfer_mask));
        }
 
-       DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap));
-       return;
-
-err_out_nosup:
-       printk(KERN_WARNING "ata%u: dev %u not supported, ignoring\n",
-              ap->id, device);
-err_out:
-       dev->class++;   /* converts ATA_DEV_xxx into ATA_DEV_xxx_UNSUP */
-       DPRINTK("EXIT, err\n");
-}
-
-
-static inline u8 ata_dev_knobble(const struct ata_port *ap)
-{
-       return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
-}
-
-/**
- *     ata_dev_config - Run device specific handlers and check for
- *                      SATA->PATA bridges
- *     @ap: Bus
- *     @i:  Device
- *
- *     LOCKING:
- */
+       ap->host->max_cmd_len = 0;
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               ap->host->max_cmd_len = max_t(unsigned int,
+                                             ap->host->max_cmd_len,
+                                             ap->device[i].cdb_len);
 
-void ata_dev_config(struct ata_port *ap, unsigned int i)
-{
        /* limit bridge transfers to udma5, 200 sectors */
-       if (ata_dev_knobble(ap)) {
-               printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
-                       ap->id, ap->device->devno);
+       if (ata_dev_knobble(ap, dev)) {
+               if (print_info)
+                       printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
+                              ap->id, dev->devno);
                ap->udma_mask &= ATA_UDMA5;
-               ap->host->max_sectors = ATA_MAX_SECTORS;
-               ap->host->hostt->max_sectors = ATA_MAX_SECTORS;
-               ap->device[i].flags |= ATA_DFLAG_LOCK_SECTORS;
+               dev->max_sectors = ATA_MAX_SECTORS;
        }
 
        if (ap->ops->dev_config)
-               ap->ops->dev_config(ap, &ap->device[i]);
+               ap->ops->dev_config(ap, dev);
+
+       DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap));
+       return 0;
+
+err_out_nosup:
+       printk(KERN_WARNING "ata%u: dev %u not supported, ignoring\n",
+              ap->id, dev->devno);
+       DPRINTK("EXIT, err\n");
+       return rc;
 }
 
 /**
@@ -1484,21 +1344,59 @@ void ata_dev_config(struct ata_port *ap, unsigned int i)
 
 static int ata_bus_probe(struct ata_port *ap)
 {
-       unsigned int i, found = 0;
+       unsigned int classes[ATA_MAX_DEVICES];
+       unsigned int i, rc, found = 0;
 
-       ap->ops->phy_reset(ap);
-       if (ap->flags & ATA_FLAG_PORT_DISABLED)
-               goto err_out;
+       ata_port_probe(ap);
+
+       /* reset and determine device classes */
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               classes[i] = ATA_DEV_UNKNOWN;
+
+       if (ap->ops->probe_reset) {
+               rc = ap->ops->probe_reset(ap, classes);
+               if (rc) {
+                       printk("ata%u: reset failed (errno=%d)\n", ap->id, rc);
+                       return rc;
+               }
+       } else {
+               ap->ops->phy_reset(ap);
+
+               if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
+                       for (i = 0; i < ATA_MAX_DEVICES; i++)
+                               classes[i] = ap->device[i].class;
+
+               ata_port_probe(ap);
+       }
+
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               if (classes[i] == ATA_DEV_UNKNOWN)
+                       classes[i] = ATA_DEV_NONE;
 
+       /* read IDENTIFY page and configure devices */
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               ata_dev_identify(ap, i);
-               if (ata_dev_present(&ap->device[i])) {
-                       found = 1;
-                       ata_dev_config(ap,i);
+               struct ata_device *dev = &ap->device[i];
+
+               dev->class = classes[i];
+
+               if (!ata_dev_present(dev))
+                       continue;
+
+               WARN_ON(dev->id != NULL);
+               if (ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id)) {
+                       dev->class = ATA_DEV_NONE;
+                       continue;
+               }
+
+               if (ata_dev_configure(ap, dev, 1)) {
+                       dev->class++;   /* disable device */
+                       continue;
                }
+
+               found = 1;
        }
 
-       if ((!found) || (ap->flags & ATA_FLAG_PORT_DISABLED))
+       if (!found)
                goto err_out_disable;
 
        ata_set_mode(ap);
@@ -1509,7 +1407,6 @@ static int ata_bus_probe(struct ata_port *ap)
 
 err_out_disable:
        ap->ops->port_disable(ap);
-err_out:
        return -1;
 }
 
@@ -1529,6 +1426,41 @@ void ata_port_probe(struct ata_port *ap)
        ap->flags &= ~ATA_FLAG_PORT_DISABLED;
 }
 
+/**
+ *     sata_print_link_status - Print SATA link status
+ *     @ap: SATA port to printk link status about
+ *
+ *     This function prints link speed and status of a SATA link.
+ *
+ *     LOCKING:
+ *     None.
+ */
+static void sata_print_link_status(struct ata_port *ap)
+{
+       u32 sstatus, tmp;
+       const char *speed;
+
+       if (!ap->ops->scr_read)
+               return;
+
+       sstatus = scr_read(ap, SCR_STATUS);
+
+       if (sata_dev_present(ap)) {
+               tmp = (sstatus >> 4) & 0xf;
+               if (tmp & (1 << 0))
+                       speed = "1.5";
+               else if (tmp & (1 << 1))
+                       speed = "3.0";
+               else
+                       speed = "<unknown>";
+               printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n",
+                      ap->id, speed, sstatus);
+       } else {
+               printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
+                      ap->id, sstatus);
+       }
+}
+
 /**
  *     __sata_phy_reset - Wake/reset a low-level SATA PHY
  *     @ap: SATA port associated with target SATA PHY.
@@ -1563,27 +1495,14 @@ void __sata_phy_reset(struct ata_port *ap)
                        break;
        } while (time_before(jiffies, timeout));
 
-       /* TODO: phy layer with polling, timeouts, etc. */
-       sstatus = scr_read(ap, SCR_STATUS);
-       if (sata_dev_present(ap)) {
-               const char *speed;
-               u32 tmp;
+       /* print link status */
+       sata_print_link_status(ap);
 
-               tmp = (sstatus >> 4) & 0xf;
-               if (tmp & (1 << 0))
-                       speed = "1.5";
-               else if (tmp & (1 << 1))
-                       speed = "3.0";
-               else
-                       speed = "<unknown>";
-               printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n",
-                      ap->id, speed, sstatus);
+       /* TODO: phy layer with polling, timeouts, etc. */
+       if (sata_dev_present(ap))
                ata_port_probe(ap);
-       } else {
-               printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
-                      ap->id, sstatus);
+       else
                ata_port_disable(ap);
-       }
 
        if (ap->flags & ATA_FLAG_PORT_DISABLED)
                return;
@@ -1756,9 +1675,9 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
        ata_timing_quantize(t, t, T, UT);
 
        /*
-        * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
-        * and some other commands. We have to ensure that the DMA cycle timing is
-        * slower/equal than the fastest PIO timing.
+        * Even in DMA/UDMA modes we still use PIO access for IDENTIFY,
+        * S.M.A.R.T * and some other commands. We have to ensure that the
+        * DMA cycle timing is slower/equal than the fastest PIO timing.
         */
 
        if (speed > XFER_PIO_4) {
@@ -1767,7 +1686,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
        }
 
        /*
-        * Lenghten active & recovery time so that cycle time is correct.
+        * Lengthen active & recovery time so that cycle time is correct.
         */
 
        if (t->act8b + t->rec8b < t->cyc8b) {
@@ -1783,31 +1702,8 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
        return 0;
 }
 
-static const struct {
-       unsigned int shift;
-       u8 base;
-} xfer_mode_classes[] = {
-       { ATA_SHIFT_UDMA,       XFER_UDMA_0 },
-       { ATA_SHIFT_MWDMA,      XFER_MW_DMA_0 },
-       { ATA_SHIFT_PIO,        XFER_PIO_0 },
-};
-
-static u8 base_from_shift(unsigned int shift)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++)
-               if (xfer_mode_classes[i].shift == shift)
-                       return xfer_mode_classes[i].base;
-
-       return 0xff;
-}
-
 static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
 {
-       int ofs, idx;
-       u8 base;
-
        if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
                return;
 
@@ -1816,65 +1712,58 @@ static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
 
        ata_dev_set_xfermode(ap, dev);
 
-       base = base_from_shift(dev->xfer_shift);
-       ofs = dev->xfer_mode - base;
-       idx = ofs + dev->xfer_shift;
-       WARN_ON(idx >= ARRAY_SIZE(xfer_mode_str));
+       if (ata_dev_revalidate(ap, dev, 0)) {
+               printk(KERN_ERR "ata%u: failed to revalidate after set "
+                      "xfermode, disabled\n", ap->id);
+               ata_port_disable(ap);
+       }
 
-       DPRINTK("idx=%d xfer_shift=%u, xfer_mode=0x%x, base=0x%x, offset=%d\n",
-               idx, dev->xfer_shift, (int)dev->xfer_mode, (int)base, ofs);
+       DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n",
+               dev->xfer_shift, (int)dev->xfer_mode);
 
        printk(KERN_INFO "ata%u: dev %u configured for %s\n",
-               ap->id, dev->devno, xfer_mode_str[idx]);
+              ap->id, dev->devno,
+              ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode)));
 }
 
 static int ata_host_set_pio(struct ata_port *ap)
 {
-       unsigned int mask;
-       int x, i;
-       u8 base, xfer_mode;
-
-       mask = ata_get_mode_mask(ap, ATA_SHIFT_PIO);
-       x = fgb(mask);
-       if (x < 0) {
-               printk(KERN_WARNING "ata%u: no PIO support\n", ap->id);
-               return -1;
-       }
-
-       base = base_from_shift(ATA_SHIFT_PIO);
-       xfer_mode = base + x;
-
-       DPRINTK("base 0x%x xfer_mode 0x%x mask 0x%x x %d\n",
-               (int)base, (int)xfer_mode, mask, x);
+       int i;
 
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *dev = &ap->device[i];
-               if (ata_dev_present(dev)) {
-                       dev->pio_mode = xfer_mode;
-                       dev->xfer_mode = xfer_mode;
-                       dev->xfer_shift = ATA_SHIFT_PIO;
-                       if (ap->ops->set_piomode)
-                               ap->ops->set_piomode(ap, dev);
+
+               if (!ata_dev_present(dev))
+                       continue;
+
+               if (!dev->pio_mode) {
+                       printk(KERN_WARNING "ata%u: no PIO support\n", ap->id);
+                       return -1;
                }
+
+               dev->xfer_mode = dev->pio_mode;
+               dev->xfer_shift = ATA_SHIFT_PIO;
+               if (ap->ops->set_piomode)
+                       ap->ops->set_piomode(ap, dev);
        }
 
        return 0;
 }
 
-static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
-                           unsigned int xfer_shift)
+static void ata_host_set_dma(struct ata_port *ap)
 {
        int i;
 
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *dev = &ap->device[i];
-               if (ata_dev_present(dev)) {
-                       dev->dma_mode = xfer_mode;
-                       dev->xfer_mode = xfer_mode;
-                       dev->xfer_shift = xfer_shift;
-                       if (ap->ops->set_dmamode)
-                               ap->ops->set_dmamode(ap, dev);
-               }
+
+               if (!ata_dev_present(dev) || !dev->dma_mode)
+                       continue;
+
+               dev->xfer_mode = dev->dma_mode;
+               dev->xfer_shift = ata_xfer_mode2shift(dev->dma_mode);
+               if (ap->ops->set_dmamode)
+                       ap->ops->set_dmamode(ap, dev);
        }
 }
 
@@ -1886,32 +1775,37 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
  *
  *     LOCKING:
  *     PCI/etc. bus probe sem.
- *
  */
 static void ata_set_mode(struct ata_port *ap)
 {
-       unsigned int xfer_shift;
-       u8 xfer_mode;
-       int rc;
+       int i, rc;
 
-       /* step 1: always set host PIO timings */
-       rc = ata_host_set_pio(ap);
-       if (rc)
-               goto err_out;
+       /* step 1: calculate xfer_mask */
+       for (i = 0; i < ATA_MAX_DEVICES; i++) {
+               struct ata_device *dev = &ap->device[i];
+               unsigned int xfer_mask;
+
+               if (!ata_dev_present(dev))
+                       continue;
+
+               xfer_mask = ata_dev_xfermask(ap, dev);
 
-       /* step 2: choose the best data xfer mode */
-       xfer_mode = xfer_shift = 0;
-       rc = ata_choose_xfer_mode(ap, &xfer_mode, &xfer_shift);
+               dev->pio_mode = ata_xfer_mask2mode(xfer_mask & ATA_MASK_PIO);
+               dev->dma_mode = ata_xfer_mask2mode(xfer_mask & (ATA_MASK_MWDMA |
+                                                               ATA_MASK_UDMA));
+       }
+
+       /* step 2: always set host PIO timings */
+       rc = ata_host_set_pio(ap);
        if (rc)
                goto err_out;
 
-       /* step 3: if that xfer mode isn't PIO, set host DMA timings */
-       if (xfer_shift != ATA_SHIFT_PIO)
-               ata_host_set_dma(ap, xfer_mode, xfer_shift);
+       /* step 3: set host DMA timings */
+       ata_host_set_dma(ap);
 
        /* step 4: update devices' xfer mode */
-       ata_dev_set_mode(ap, &ap->device[0]);
-       ata_dev_set_mode(ap, &ap->device[1]);
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               ata_dev_set_mode(ap, &ap->device[i]);
 
        if (ap->flags & ATA_FLAG_PORT_DISABLED)
                return;
@@ -1925,6 +1819,26 @@ err_out:
        ata_port_disable(ap);
 }
 
+/**
+ *     ata_tf_to_host - issue ATA taskfile to host controller
+ *     @ap: port to which command is being issued
+ *     @tf: ATA taskfile register set
+ *
+ *     Issues ATA taskfile register set to ATA host controller,
+ *     with proper synchronization with interrupt handler and
+ *     other threads.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
+
+static inline void ata_tf_to_host(struct ata_port *ap,
+                                 const struct ata_taskfile *tf)
+{
+       ap->ops->tf_load(ap, tf);
+       ap->ops->exec_command(ap, tf);
+}
+
 /**
  *     ata_busy_sleep - sleep until BSY clears, or timeout
  *     @ap: port containing status register to be polled
@@ -1935,12 +1849,10 @@ err_out:
  *     or a timeout occurs.
  *
  *     LOCKING: None.
- *
  */
 
-static unsigned int ata_busy_sleep (struct ata_port *ap,
-                                   unsigned long tmout_pat,
-                                   unsigned long tmout)
+unsigned int ata_busy_sleep (struct ata_port *ap,
+                            unsigned long tmout_pat, unsigned long tmout)
 {
        unsigned long timer_start, timeout;
        u8 status;
@@ -2090,117 +2002,552 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
         */
        msleep(150);
 
-       ata_bus_post_reset(ap, devmask);
+       ata_bus_post_reset(ap, devmask);
+
+       return 0;
+}
+
+/**
+ *     ata_bus_reset - reset host port and associated ATA channel
+ *     @ap: port to reset
+ *
+ *     This is typically the first time we actually start issuing
+ *     commands to the ATA channel.  We wait for BSY to clear, then
+ *     issue EXECUTE DEVICE DIAGNOSTIC command, polling for its
+ *     result.  Determine what devices, if any, are on the channel
+ *     by looking at the device 0/1 error register.  Look at the signature
+ *     stored in each device's taskfile registers, to determine if
+ *     the device is ATA or ATAPI.
+ *
+ *     LOCKING:
+ *     PCI/etc. bus probe sem.
+ *     Obtains host_set lock.
+ *
+ *     SIDE EFFECTS:
+ *     Sets ATA_FLAG_PORT_DISABLED if bus reset fails.
+ */
+
+void ata_bus_reset(struct ata_port *ap)
+{
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+       unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
+       u8 err;
+       unsigned int dev0, dev1 = 0, rc = 0, devmask = 0;
+
+       DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no);
+
+       /* determine if device 0/1 are present */
+       if (ap->flags & ATA_FLAG_SATA_RESET)
+               dev0 = 1;
+       else {
+               dev0 = ata_devchk(ap, 0);
+               if (slave_possible)
+                       dev1 = ata_devchk(ap, 1);
+       }
+
+       if (dev0)
+               devmask |= (1 << 0);
+       if (dev1)
+               devmask |= (1 << 1);
+
+       /* select device 0 again */
+       ap->ops->dev_select(ap, 0);
+
+       /* issue bus reset */
+       if (ap->flags & ATA_FLAG_SRST)
+               rc = ata_bus_softreset(ap, devmask);
+       else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) {
+               /* set up device control */
+               if (ap->flags & ATA_FLAG_MMIO)
+                       writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
+               else
+                       outb(ap->ctl, ioaddr->ctl_addr);
+               rc = ata_bus_edd(ap);
+       }
+
+       if (rc)
+               goto err_out;
+
+       /*
+        * determine by signature whether we have ATA or ATAPI devices
+        */
+       ap->device[0].class = ata_dev_try_classify(ap, 0, &err);
+       if ((slave_possible) && (err != 0x81))
+               ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
+
+       /* re-enable interrupts */
+       if (ap->ioaddr.ctl_addr)        /* FIXME: hack. create a hook instead */
+               ata_irq_on(ap);
+
+       /* is double-select really necessary? */
+       if (ap->device[1].class != ATA_DEV_NONE)
+               ap->ops->dev_select(ap, 1);
+       if (ap->device[0].class != ATA_DEV_NONE)
+               ap->ops->dev_select(ap, 0);
+
+       /* if no devices were detected, disable this port */
+       if ((ap->device[0].class == ATA_DEV_NONE) &&
+           (ap->device[1].class == ATA_DEV_NONE))
+               goto err_out;
+
+       if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
+               /* set up device control for ATA_FLAG_SATA_RESET */
+               if (ap->flags & ATA_FLAG_MMIO)
+                       writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
+               else
+                       outb(ap->ctl, ioaddr->ctl_addr);
+       }
+
+       DPRINTK("EXIT\n");
+       return;
+
+err_out:
+       printk(KERN_ERR "ata%u: disabling port\n", ap->id);
+       ap->ops->port_disable(ap);
+
+       DPRINTK("EXIT\n");
+}
+
+static int sata_phy_resume(struct ata_port *ap)
+{
+       unsigned long timeout = jiffies + (HZ * 5);
+       u32 sstatus;
+
+       scr_write_flush(ap, SCR_CONTROL, 0x300);
+
+       /* Wait for phy to become ready, if necessary. */
+       do {
+               msleep(200);
+               sstatus = scr_read(ap, SCR_STATUS);
+               if ((sstatus & 0xf) != 1)
+                       return 0;
+       } while (time_before(jiffies, timeout));
+
+       return -1;
+}
+
+/**
+ *     ata_std_probeinit - initialize probing
+ *     @ap: port to be probed
+ *
+ *     @ap is about to be probed.  Initialize it.  This function is
+ *     to be used as standard callback for ata_drive_probe_reset().
+ *
+ *     NOTE!!! Do not use this function as probeinit if a low level
+ *     driver implements only hardreset.  Just pass NULL as probeinit
+ *     in that case.  Using this function is probably okay but doing
+ *     so makes reset sequence different from the original
+ *     ->phy_reset implementation and Jeff nervous.  :-P
+ */
+extern void ata_std_probeinit(struct ata_port *ap)
+{
+       if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) {
+               sata_phy_resume(ap);
+               if (sata_dev_present(ap))
+                       ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+       }
+}
+
+/**
+ *     ata_std_softreset - reset host port via ATA SRST
+ *     @ap: port to reset
+ *     @verbose: fail verbosely
+ *     @classes: resulting classes of attached devices
+ *
+ *     Reset host port using ATA SRST.  This function is to be used
+ *     as standard callback for ata_drive_*_reset() functions.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
+ */
+int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes)
+{
+       unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
+       unsigned int devmask = 0, err_mask;
+       u8 err;
+
+       DPRINTK("ENTER\n");
+
+       if (ap->ops->scr_read && !sata_dev_present(ap)) {
+               classes[0] = ATA_DEV_NONE;
+               goto out;
+       }
+
+       /* determine if device 0/1 are present */
+       if (ata_devchk(ap, 0))
+               devmask |= (1 << 0);
+       if (slave_possible && ata_devchk(ap, 1))
+               devmask |= (1 << 1);
+
+       /* select device 0 again */
+       ap->ops->dev_select(ap, 0);
+
+       /* issue bus reset */
+       DPRINTK("about to softreset, devmask=%x\n", devmask);
+       err_mask = ata_bus_softreset(ap, devmask);
+       if (err_mask) {
+               if (verbose)
+                       printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n",
+                              ap->id, err_mask);
+               else
+                       DPRINTK("EXIT, softreset failed (err_mask=0x%x)\n",
+                               err_mask);
+               return -EIO;
+       }
+
+       /* determine by signature whether we have ATA or ATAPI devices */
+       classes[0] = ata_dev_try_classify(ap, 0, &err);
+       if (slave_possible && err != 0x81)
+               classes[1] = ata_dev_try_classify(ap, 1, &err);
+
+ out:
+       DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
+       return 0;
+}
+
+/**
+ *     sata_std_hardreset - reset host port via SATA phy reset
+ *     @ap: port to reset
+ *     @verbose: fail verbosely
+ *     @class: resulting class of attached device
+ *
+ *     SATA phy-reset host port using DET bits of SControl register.
+ *     This function is to be used as standard callback for
+ *     ata_drive_*_reset().
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
+ */
+int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
+{
+       DPRINTK("ENTER\n");
+
+       /* Issue phy wake/reset */
+       scr_write_flush(ap, SCR_CONTROL, 0x301);
+
+       /*
+        * Couldn't find anything in SATA I/II specs, but AHCI-1.1
+        * 10.4.2 says at least 1 ms.
+        */
+       msleep(1);
+
+       /* Bring phy back */
+       sata_phy_resume(ap);
+
+       /* TODO: phy layer with polling, timeouts, etc. */
+       if (!sata_dev_present(ap)) {
+               *class = ATA_DEV_NONE;
+               DPRINTK("EXIT, link offline\n");
+               return 0;
+       }
+
+       if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+               if (verbose)
+                       printk(KERN_ERR "ata%u: COMRESET failed "
+                              "(device not ready)\n", ap->id);
+               else
+                       DPRINTK("EXIT, device not ready\n");
+               return -EIO;
+       }
+
+       ap->ops->dev_select(ap, 0);     /* probably unnecessary */
+
+       *class = ata_dev_try_classify(ap, 0, NULL);
+
+       DPRINTK("EXIT, class=%u\n", *class);
+       return 0;
+}
+
+/**
+ *     ata_std_postreset - standard postreset callback
+ *     @ap: the target ata_port
+ *     @classes: classes of attached devices
+ *
+ *     This function is invoked after a successful reset.  Note that
+ *     the device might have been reset more than once using
+ *     different reset methods before postreset is invoked.
+ *
+ *     This function is to be used as standard callback for
+ *     ata_drive_*_reset().
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ */
+void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
+{
+       DPRINTK("ENTER\n");
+
+       /* set cable type if it isn't already set */
+       if (ap->cbl == ATA_CBL_NONE && ap->flags & ATA_FLAG_SATA)
+               ap->cbl = ATA_CBL_SATA;
+
+       /* print link status */
+       if (ap->cbl == ATA_CBL_SATA)
+               sata_print_link_status(ap);
+
+       /* re-enable interrupts */
+       if (ap->ioaddr.ctl_addr)        /* FIXME: hack. create a hook instead */
+               ata_irq_on(ap);
+
+       /* is double-select really necessary? */
+       if (classes[0] != ATA_DEV_NONE)
+               ap->ops->dev_select(ap, 1);
+       if (classes[1] != ATA_DEV_NONE)
+               ap->ops->dev_select(ap, 0);
+
+       /* bail out if no device is present */
+       if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
+               DPRINTK("EXIT, no device\n");
+               return;
+       }
+
+       /* set up device control */
+       if (ap->ioaddr.ctl_addr) {
+               if (ap->flags & ATA_FLAG_MMIO)
+                       writeb(ap->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
+               else
+                       outb(ap->ctl, ap->ioaddr.ctl_addr);
+       }
+
+       DPRINTK("EXIT\n");
+}
+
+/**
+ *     ata_std_probe_reset - standard probe reset method
+ *     @ap: prot to perform probe-reset
+ *     @classes: resulting classes of attached devices
+ *
+ *     The stock off-the-shelf ->probe_reset method.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
+ */
+int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes)
+{
+       ata_reset_fn_t hardreset;
+
+       hardreset = NULL;
+       if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read)
+               hardreset = sata_std_hardreset;
+
+       return ata_drive_probe_reset(ap, ata_std_probeinit,
+                                    ata_std_softreset, hardreset,
+                                    ata_std_postreset, classes);
+}
+
+static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset,
+                         ata_postreset_fn_t postreset,
+                         unsigned int *classes)
+{
+       int i, rc;
+
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               classes[i] = ATA_DEV_UNKNOWN;
+
+       rc = reset(ap, 0, classes);
+       if (rc)
+               return rc;
+
+       /* If any class isn't ATA_DEV_UNKNOWN, consider classification
+        * is complete and convert all ATA_DEV_UNKNOWN to
+        * ATA_DEV_NONE.
+        */
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               if (classes[i] != ATA_DEV_UNKNOWN)
+                       break;
+
+       if (i < ATA_MAX_DEVICES)
+               for (i = 0; i < ATA_MAX_DEVICES; i++)
+                       if (classes[i] == ATA_DEV_UNKNOWN)
+                               classes[i] = ATA_DEV_NONE;
+
+       if (postreset)
+               postreset(ap, classes);
+
+       return classes[0] != ATA_DEV_UNKNOWN ? 0 : -ENODEV;
+}
+
+/**
+ *     ata_drive_probe_reset - Perform probe reset with given methods
+ *     @ap: port to reset
+ *     @probeinit: probeinit method (can be NULL)
+ *     @softreset: softreset method (can be NULL)
+ *     @hardreset: hardreset method (can be NULL)
+ *     @postreset: postreset method (can be NULL)
+ *     @classes: resulting classes of attached devices
+ *
+ *     Reset the specified port and classify attached devices using
+ *     given methods.  This function prefers softreset but tries all
+ *     possible reset sequences to reset and classify devices.  This
+ *     function is intended to be used for constructing ->probe_reset
+ *     callback by low level drivers.
+ *
+ *     Reset methods should follow the following rules.
+ *
+ *     - Return 0 on sucess, -errno on failure.
+ *     - If classification is supported, fill classes[] with
+ *       recognized class codes.
+ *     - If classification is not supported, leave classes[] alone.
+ *     - If verbose is non-zero, print error message on failure;
+ *       otherwise, shut up.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     0 on success, -EINVAL if no reset method is avaliable, -ENODEV
+ *     if classification fails, and any error code from reset
+ *     methods.
+ */
+int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit,
+                         ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
+                         ata_postreset_fn_t postreset, unsigned int *classes)
+{
+       int rc = -EINVAL;
+
+       if (probeinit)
+               probeinit(ap);
+
+       if (softreset) {
+               rc = do_probe_reset(ap, softreset, postreset, classes);
+               if (rc == 0)
+                       return 0;
+       }
+
+       if (!hardreset)
+               return rc;
+
+       rc = do_probe_reset(ap, hardreset, postreset, classes);
+       if (rc == 0 || rc != -ENODEV)
+               return rc;
 
-       return 0;
+       if (softreset)
+               rc = do_probe_reset(ap, softreset, postreset, classes);
+
+       return rc;
 }
 
 /**
- *     ata_bus_reset - reset host port and associated ATA channel
- *     @ap: port to reset
+ *     ata_dev_same_device - Determine whether new ID matches configured device
+ *     @ap: port on which the device to compare against resides
+ *     @dev: device to compare against
+ *     @new_class: class of the new device
+ *     @new_id: IDENTIFY page of the new device
  *
- *     This is typically the first time we actually start issuing
- *     commands to the ATA channel.  We wait for BSY to clear, then
- *     issue EXECUTE DEVICE DIAGNOSTIC command, polling for its
- *     result.  Determine what devices, if any, are on the channel
- *     by looking at the device 0/1 error register.  Look at the signature
- *     stored in each device's taskfile registers, to determine if
- *     the device is ATA or ATAPI.
+ *     Compare @new_class and @new_id against @dev and determine
+ *     whether @dev is the device indicated by @new_class and
+ *     @new_id.
  *
  *     LOCKING:
- *     PCI/etc. bus probe sem.
- *     Obtains host_set lock.
+ *     None.
  *
- *     SIDE EFFECTS:
- *     Sets ATA_FLAG_PORT_DISABLED if bus reset fails.
+ *     RETURNS:
+ *     1 if @dev matches @new_class and @new_id, 0 otherwise.
  */
-
-void ata_bus_reset(struct ata_port *ap)
+static int ata_dev_same_device(struct ata_port *ap, struct ata_device *dev,
+                              unsigned int new_class, const u16 *new_id)
 {
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
-       u8 err;
-       unsigned int dev0, dev1 = 0, rc = 0, devmask = 0;
-
-       DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no);
+       const u16 *old_id = dev->id;
+       unsigned char model[2][41], serial[2][21];
+       u64 new_n_sectors;
 
-       /* determine if device 0/1 are present */
-       if (ap->flags & ATA_FLAG_SATA_RESET)
-               dev0 = 1;
-       else {
-               dev0 = ata_devchk(ap, 0);
-               if (slave_possible)
-                       dev1 = ata_devchk(ap, 1);
+       if (dev->class != new_class) {
+               printk(KERN_INFO
+                      "ata%u: dev %u class mismatch %d != %d\n",
+                      ap->id, dev->devno, dev->class, new_class);
+               return 0;
        }
 
-       if (dev0)
-               devmask |= (1 << 0);
-       if (dev1)
-               devmask |= (1 << 1);
+       ata_id_c_string(old_id, model[0], ATA_ID_PROD_OFS, sizeof(model[0]));
+       ata_id_c_string(new_id, model[1], ATA_ID_PROD_OFS, sizeof(model[1]));
+       ata_id_c_string(old_id, serial[0], ATA_ID_SERNO_OFS, sizeof(serial[0]));
+       ata_id_c_string(new_id, serial[1], ATA_ID_SERNO_OFS, sizeof(serial[1]));
+       new_n_sectors = ata_id_n_sectors(new_id);
 
-       /* select device 0 again */
-       ap->ops->dev_select(ap, 0);
+       if (strcmp(model[0], model[1])) {
+               printk(KERN_INFO
+                      "ata%u: dev %u model number mismatch '%s' != '%s'\n",
+                      ap->id, dev->devno, model[0], model[1]);
+               return 0;
+       }
 
-       /* issue bus reset */
-       if (ap->flags & ATA_FLAG_SRST)
-               rc = ata_bus_softreset(ap, devmask);
-       else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) {
-               /* set up device control */
-               if (ap->flags & ATA_FLAG_MMIO)
-                       writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
-               else
-                       outb(ap->ctl, ioaddr->ctl_addr);
-               rc = ata_bus_edd(ap);
+       if (strcmp(serial[0], serial[1])) {
+               printk(KERN_INFO
+                      "ata%u: dev %u serial number mismatch '%s' != '%s'\n",
+                      ap->id, dev->devno, serial[0], serial[1]);
+               return 0;
        }
 
-       if (rc)
-               goto err_out;
+       if (dev->class == ATA_DEV_ATA && dev->n_sectors != new_n_sectors) {
+               printk(KERN_INFO
+                      "ata%u: dev %u n_sectors mismatch %llu != %llu\n",
+                      ap->id, dev->devno, (unsigned long long)dev->n_sectors,
+                      (unsigned long long)new_n_sectors);
+               return 0;
+       }
 
-       /*
-        * determine by signature whether we have ATA or ATAPI devices
-        */
-       err = ata_dev_try_classify(ap, 0);
-       if ((slave_possible) && (err != 0x81))
-               ata_dev_try_classify(ap, 1);
+       return 1;
+}
 
-       /* re-enable interrupts */
-       if (ap->ioaddr.ctl_addr)        /* FIXME: hack. create a hook instead */
-               ata_irq_on(ap);
+/**
+ *     ata_dev_revalidate - Revalidate ATA device
+ *     @ap: port on which the device to revalidate resides
+ *     @dev: device to revalidate
+ *     @post_reset: is this revalidation after reset?
+ *
+ *     Re-read IDENTIFY page and make sure @dev is still attached to
+ *     the port.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     0 on success, negative errno otherwise
+ */
+int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
+                      int post_reset)
+{
+       unsigned int class;
+       u16 *id;
+       int rc;
 
-       /* is double-select really necessary? */
-       if (ap->device[1].class != ATA_DEV_NONE)
-               ap->ops->dev_select(ap, 1);
-       if (ap->device[0].class != ATA_DEV_NONE)
-               ap->ops->dev_select(ap, 0);
+       if (!ata_dev_present(dev))
+               return -ENODEV;
 
-       /* if no devices were detected, disable this port */
-       if ((ap->device[0].class == ATA_DEV_NONE) &&
-           (ap->device[1].class == ATA_DEV_NONE))
-               goto err_out;
+       class = dev->class;
+       id = NULL;
 
-       if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
-               /* set up device control for ATA_FLAG_SATA_RESET */
-               if (ap->flags & ATA_FLAG_MMIO)
-                       writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
-               else
-                       outb(ap->ctl, ioaddr->ctl_addr);
-       }
+       /* allocate & read ID data */
+       rc = ata_dev_read_id(ap, dev, &class, post_reset, &id);
+       if (rc)
+               goto fail;
 
-       DPRINTK("EXIT\n");
-       return;
+       /* is the device still there? */
+       if (!ata_dev_same_device(ap, dev, class, id)) {
+               rc = -ENODEV;
+               goto fail;
+       }
 
-err_out:
-       printk(KERN_ERR "ata%u: disabling port\n", ap->id);
-       ap->ops->port_disable(ap);
+       kfree(dev->id);
+       dev->id = id;
 
-       DPRINTK("EXIT\n");
-}
+       /* configure device according to the new ID */
+       return ata_dev_configure(ap, dev, 0);
 
-static void ata_pr_blacklisted(const struct ata_port *ap,
-                              const struct ata_device *dev)
-{
-       printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n",
-               ap->id, dev->devno);
+ fail:
+       printk(KERN_ERR "ata%u: dev %u revalidation failed (errno=%d)\n",
+              ap->id, dev->devno, rc);
+       kfree(id);
+       return rc;
 }
 
 static const char * const ata_dma_blacklist [] = {
@@ -2237,151 +2584,57 @@ static const char * const ata_dma_blacklist [] = {
 
 static int ata_dma_blacklisted(const struct ata_device *dev)
 {
-       unsigned char model_num[40];
-       char *s;
-       unsigned int len;
+       unsigned char model_num[41];
        int i;
 
-       ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
-                         sizeof(model_num));
-       s = &model_num[0];
-       len = strnlen(s, sizeof(model_num));
-
-       /* ATAPI specifies that empty space is blank-filled; remove blanks */
-       while ((len > 0) && (s[len - 1] == ' ')) {
-               len--;
-               s[len] = 0;
-       }
+       ata_id_c_string(dev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
 
        for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++)
-               if (!strncmp(ata_dma_blacklist[i], s, len))
+               if (!strcmp(ata_dma_blacklist[i], model_num))
                        return 1;
 
        return 0;
 }
 
-static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift)
-{
-       const struct ata_device *master, *slave;
-       unsigned int mask;
-
-       master = &ap->device[0];
-       slave = &ap->device[1];
-
-       assert (ata_dev_present(master) || ata_dev_present(slave));
-
-       if (shift == ATA_SHIFT_UDMA) {
-               mask = ap->udma_mask;
-               if (ata_dev_present(master)) {
-                       mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
-                       if (ata_dma_blacklisted(master)) {
-                               mask = 0;
-                               ata_pr_blacklisted(ap, master);
-                       }
-               }
-               if (ata_dev_present(slave)) {
-                       mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
-                       if (ata_dma_blacklisted(slave)) {
-                               mask = 0;
-                               ata_pr_blacklisted(ap, slave);
-                       }
-               }
-       }
-       else if (shift == ATA_SHIFT_MWDMA) {
-               mask = ap->mwdma_mask;
-               if (ata_dev_present(master)) {
-                       mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07);
-                       if (ata_dma_blacklisted(master)) {
-                               mask = 0;
-                               ata_pr_blacklisted(ap, master);
-                       }
-               }
-               if (ata_dev_present(slave)) {
-                       mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07);
-                       if (ata_dma_blacklisted(slave)) {
-                               mask = 0;
-                               ata_pr_blacklisted(ap, slave);
-                       }
-               }
-       }
-       else if (shift == ATA_SHIFT_PIO) {
-               mask = ap->pio_mask;
-               if (ata_dev_present(master)) {
-                       /* spec doesn't return explicit support for
-                        * PIO0-2, so we fake it
-                        */
-                       u16 tmp_mode = master->id[ATA_ID_PIO_MODES] & 0x03;
-                       tmp_mode <<= 3;
-                       tmp_mode |= 0x7;
-                       mask &= tmp_mode;
-               }
-               if (ata_dev_present(slave)) {
-                       /* spec doesn't return explicit support for
-                        * PIO0-2, so we fake it
-                        */
-                       u16 tmp_mode = slave->id[ATA_ID_PIO_MODES] & 0x03;
-                       tmp_mode <<= 3;
-                       tmp_mode |= 0x7;
-                       mask &= tmp_mode;
-               }
-       }
-       else {
-               mask = 0xffffffff; /* shut up compiler warning */
-               BUG();
-       }
-
-       return mask;
-}
-
-/* find greatest bit */
-static int fgb(u32 bitmap)
-{
-       unsigned int i;
-       int x = -1;
-
-       for (i = 0; i < 32; i++)
-               if (bitmap & (1 << i))
-                       x = i;
-
-       return x;
-}
-
 /**
- *     ata_choose_xfer_mode - attempt to find best transfer mode
- *     @ap: Port for which an xfer mode will be selected
- *     @xfer_mode_out: (output) SET FEATURES - XFER MODE code
- *     @xfer_shift_out: (output) bit shift that selects this mode
+ *     ata_dev_xfermask - Compute supported xfermask of the given device
+ *     @ap: Port on which the device to compute xfermask for resides
+ *     @dev: Device to compute xfermask for
  *
- *     Based on host and device capabilities, determine the
- *     maximum transfer mode that is amenable to all.
+ *     Compute supported xfermask of @dev.  This function is
+ *     responsible for applying all known limits including host
+ *     controller limits, device blacklist, etc...
  *
  *     LOCKING:
- *     PCI/etc. bus probe sem.
+ *     None.
  *
  *     RETURNS:
- *     Zero on success, negative on error.
+ *     Computed xfermask.
  */
-
-static int ata_choose_xfer_mode(const struct ata_port *ap,
-                               u8 *xfer_mode_out,
-                               unsigned int *xfer_shift_out)
+static unsigned int ata_dev_xfermask(struct ata_port *ap,
+                                    struct ata_device *dev)
 {
-       unsigned int mask, shift;
-       int x, i;
+       unsigned long xfer_mask;
+       int i;
 
-       for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) {
-               shift = xfer_mode_classes[i].shift;
-               mask = ata_get_mode_mask(ap, shift);
+       xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
+                                     ap->udma_mask);
 
-               x = fgb(mask);
-               if (x >= 0) {
-                       *xfer_mode_out = xfer_mode_classes[i].base + x;
-                       *xfer_shift_out = shift;
-                       return 0;
-               }
+       /* use port-wide xfermask for now */
+       for (i = 0; i < ATA_MAX_DEVICES; i++) {
+               struct ata_device *d = &ap->device[i];
+               if (!ata_dev_present(d))
+                       continue;
+               xfer_mask &= ata_id_xfermask(d->id);
+               if (ata_dma_blacklisted(d))
+                       xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
        }
 
-       return -1;
+       if (ata_dma_blacklisted(dev))
+               printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, "
+                      "disabling DMA\n", ap->id, dev->devno);
+
+       return xfer_mask;
 }
 
 /**
@@ -2419,64 +2672,29 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
        DPRINTK("EXIT\n");
 }
 
-/**
- *     ata_dev_reread_id - Reread the device identify device info
- *     @ap: port where the device is
- *     @dev: device to reread the identify device info
- *
- *     LOCKING:
- */
-
-static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
-{
-       struct ata_taskfile tf;
-
-       ata_tf_init(ap, &tf, dev->devno);
-
-       if (dev->class == ATA_DEV_ATA) {
-               tf.command = ATA_CMD_ID_ATA;
-               DPRINTK("do ATA identify\n");
-       } else {
-               tf.command = ATA_CMD_ID_ATAPI;
-               DPRINTK("do ATAPI identify\n");
-       }
-
-       tf.flags |= ATA_TFLAG_DEVICE;
-       tf.protocol = ATA_PROT_PIO;
-
-       if (ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
-                             dev->id, sizeof(dev->id)))
-               goto err_out;
-
-       swap_buf_le16(dev->id, ATA_ID_WORDS);
-
-       ata_dump_id(dev);
-
-       DPRINTK("EXIT\n");
-
-       return;
-err_out:
-       printk(KERN_ERR "ata%u: failed to reread ID, disabled\n", ap->id);
-       ata_port_disable(ap);
-}
-
 /**
  *     ata_dev_init_params - Issue INIT DEV PARAMS command
  *     @ap: Port associated with device @dev
  *     @dev: Device to which command will be sent
  *
  *     LOCKING:
+ *     Kernel thread context (may sleep)
+ *
+ *     RETURNS:
+ *     0 on success, AC_ERR_* mask otherwise.
  */
 
-static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
+static unsigned int ata_dev_init_params(struct ata_port *ap,
+                                       struct ata_device *dev)
 {
        struct ata_taskfile tf;
+       unsigned int err_mask;
        u16 sectors = dev->id[6];
        u16 heads   = dev->id[3];
 
        /* Number of sectors per track 1-255. Number of heads 1-16 */
        if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
-               return;
+               return 0;
 
        /* set up init dev params taskfile */
        DPRINTK("init dev params \n");
@@ -2488,13 +2706,10 @@ static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
        tf.nsect = sectors;
        tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
 
-       if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) {
-               printk(KERN_ERR "ata%u: failed to init parameters, disabled\n",
-                      ap->id);
-               ata_port_disable(ap);
-       }
+       err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
 
-       DPRINTK("EXIT\n");
+       DPRINTK("EXIT, err_mask=%x\n", err_mask);
+       return err_mask;
 }
 
 /**
@@ -2514,11 +2729,11 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
        int dir = qc->dma_dir;
        void *pad_buf = NULL;
 
-       assert(qc->flags & ATA_QCFLAG_DMAMAP);
-       assert(sg != NULL);
+       WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP));
+       WARN_ON(sg == NULL);
 
        if (qc->flags & ATA_QCFLAG_SINGLE)
-               assert(qc->n_elem <= 1);
+               WARN_ON(qc->n_elem > 1);
 
        VPRINTK("unmapping %u sg elements\n", qc->n_elem);
 
@@ -2573,8 +2788,8 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
        struct scatterlist *sg;
        unsigned int idx;
 
-       assert(qc->__sg != NULL);
-       assert(qc->n_elem > 0 || qc->pad_len > 0);
+       WARN_ON(qc->__sg == NULL);
+       WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
 
        idx = 0;
        ata_for_each_sg(sg, qc) {
@@ -2727,7 +2942,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
                void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
                struct scatterlist *psg = &qc->pad_sgent;
 
-               assert(qc->dev->class == ATA_DEV_ATAPI);
+               WARN_ON(qc->dev->class != ATA_DEV_ATAPI);
 
                memset(pad_buf, 0, ATA_DMA_PAD_SZ);
 
@@ -2791,7 +3006,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
        int n_elem, pre_n_elem, dir, trim_sg = 0;
 
        VPRINTK("ENTER, ata%u\n", ap->id);
-       assert(qc->flags & ATA_QCFLAG_SG);
+       WARN_ON(!(qc->flags & ATA_QCFLAG_SG));
 
        /* we must lengthen transfers to end on a 32-bit boundary */
        qc->pad_len = lsg->length & 3;
@@ -2800,7 +3015,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
                struct scatterlist *psg = &qc->pad_sgent;
                unsigned int offset;
 
-               assert(qc->dev->class == ATA_DEV_ATAPI);
+               WARN_ON(qc->dev->class != ATA_DEV_ATAPI);
 
                memset(pad_buf, 0, ATA_DMA_PAD_SZ);
 
@@ -2876,7 +3091,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc)
 }
 
 /**
- *     ata_pio_poll -
+ *     ata_pio_poll - poll using PIO, depending on current state
  *     @ap: the target ata_port
  *
  *     LOCKING:
@@ -2894,7 +3109,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
        unsigned int reg_state = HSM_ST_UNKNOWN;
 
        qc = ata_qc_from_tag(ap, ap->active_tag);
-       assert(qc != NULL);
+       WARN_ON(qc == NULL);
 
        switch (ap->hsm_task_state) {
        case HSM_ST:
@@ -2915,7 +3130,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
        status = ata_chk_status(ap);
        if (status & ATA_BUSY) {
                if (time_after(jiffies, ap->pio_task_timeout)) {
-                       qc->err_mask |= AC_ERR_ATA_BUS;
+                       qc->err_mask |= AC_ERR_TIMEOUT;
                        ap->hsm_task_state = HSM_ST_TMOUT;
                        return 0;
                }
@@ -2962,7 +3177,7 @@ static int ata_pio_complete (struct ata_port *ap)
        }
 
        qc = ata_qc_from_tag(ap, ap->active_tag);
-       assert(qc != NULL);
+       WARN_ON(qc == NULL);
 
        drv_stat = ata_wait_idle(ap);
        if (!ata_ok(drv_stat)) {
@@ -2973,7 +3188,7 @@ static int ata_pio_complete (struct ata_port *ap)
 
        ap->hsm_task_state = HSM_ST_IDLE;
 
-       assert(qc->err_mask == 0);
+       WARN_ON(qc->err_mask);
        ata_poll_qc_complete(qc);
 
        /* another command may start at this point */
@@ -2983,7 +3198,7 @@ static int ata_pio_complete (struct ata_port *ap)
 
 
 /**
- *     swap_buf_le16 - swap halves of 16-words in place
+ *     swap_buf_le16 - swap halves of 16-bit words in place
  *     @buf:  Buffer to swap
  *     @buf_words:  Number of 16-bit words in buffer.
  *
@@ -3293,7 +3508,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
 err_out:
        printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
              ap->id, dev->devno);
-       qc->err_mask |= AC_ERR_ATA_BUS;
+       qc->err_mask |= AC_ERR_HSM;
        ap->hsm_task_state = HSM_ST_ERR;
 }
 
@@ -3330,7 +3545,7 @@ static void ata_pio_block(struct ata_port *ap)
        }
 
        qc = ata_qc_from_tag(ap, ap->active_tag);
-       assert(qc != NULL);
+       WARN_ON(qc == NULL);
 
        /* check error */
        if (status & (ATA_ERR | ATA_DF)) {
@@ -3351,7 +3566,7 @@ static void ata_pio_block(struct ata_port *ap)
        } else {
                /* handle BSY=0, DRQ=0 as error */
                if ((status & ATA_DRQ) == 0) {
-                       qc->err_mask |= AC_ERR_ATA_BUS;
+                       qc->err_mask |= AC_ERR_HSM;
                        ap->hsm_task_state = HSM_ST_ERR;
                        return;
                }
@@ -3365,7 +3580,7 @@ static void ata_pio_error(struct ata_port *ap)
        struct ata_queued_cmd *qc;
 
        qc = ata_qc_from_tag(ap, ap->active_tag);
-       assert(qc != NULL);
+       WARN_ON(qc == NULL);
 
        if (qc->tf.command != ATA_CMD_PACKET)
                printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
@@ -3373,7 +3588,7 @@ static void ata_pio_error(struct ata_port *ap)
        /* make sure qc->err_mask is available to 
         * know what's wrong and recover
         */
-       assert(qc->err_mask);
+       WARN_ON(qc->err_mask == 0);
 
        ap->hsm_task_state = HSM_ST_IDLE;
 
@@ -3407,16 +3622,88 @@ fsm_start:
                timeout = ata_pio_poll(ap);
                break;
 
-       case HSM_ST_TMOUT:
-       case HSM_ST_ERR:
-               ata_pio_error(ap);
-               return;
+       case HSM_ST_TMOUT:
+       case HSM_ST_ERR:
+               ata_pio_error(ap);
+               return;
+       }
+
+       if (timeout)
+               ata_port_queue_task(ap, ata_pio_task, ap, timeout);
+       else if (!qc_completed)
+               goto fsm_start;
+}
+
+/**
+ *     atapi_packet_task - Write CDB bytes to hardware
+ *     @_data: Port to which ATAPI device is attached.
+ *
+ *     When device has indicated its readiness to accept
+ *     a CDB, this function is called.  Send the CDB.
+ *     If DMA is to be performed, exit immediately.
+ *     Otherwise, we are in polling mode, so poll
+ *     status under operation succeeds or fails.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep)
+ */
+
+static void atapi_packet_task(void *_data)
+{
+       struct ata_port *ap = _data;
+       struct ata_queued_cmd *qc;
+       u8 status;
+
+       qc = ata_qc_from_tag(ap, ap->active_tag);
+       WARN_ON(qc == NULL);
+       WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
+
+       /* sleep-wait for BSY to clear */
+       DPRINTK("busy wait\n");
+       if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
+               qc->err_mask |= AC_ERR_TIMEOUT;
+               goto err_out;
+       }
+
+       /* make sure DRQ is set */
+       status = ata_chk_status(ap);
+       if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) {
+               qc->err_mask |= AC_ERR_HSM;
+               goto err_out;
+       }
+
+       /* send SCSI cdb */
+       DPRINTK("send cdb\n");
+       WARN_ON(qc->dev->cdb_len < 12);
+
+       if (qc->tf.protocol == ATA_PROT_ATAPI_DMA ||
+           qc->tf.protocol == ATA_PROT_ATAPI_NODATA) {
+               unsigned long flags;
+
+               /* Once we're done issuing command and kicking bmdma,
+                * irq handler takes over.  To not lose irq, we need
+                * to clear NOINTR flag before sending cdb, but
+                * interrupt handler shouldn't be invoked before we're
+                * finished.  Hence, the following locking.
+                */
+               spin_lock_irqsave(&ap->host_set->lock, flags);
+               ap->flags &= ~ATA_FLAG_NOINTR;
+               ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
+               if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
+                       ap->ops->bmdma_start(qc);       /* initiate bmdma */
+               spin_unlock_irqrestore(&ap->host_set->lock, flags);
+       } else {
+               ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
+
+               /* PIO commands are handled by polling */
+               ap->hsm_task_state = HSM_ST;
+               ata_port_queue_task(ap, ata_pio_task, ap, 0);
        }
 
-       if (timeout)
-               queue_delayed_work(ata_wq, &ap->pio_task, timeout);
-       else if (!qc_completed)
-               goto fsm_start;
+       return;
+
+err_out:
+       ata_poll_qc_complete(qc);
 }
 
 /**
@@ -3447,15 +3734,9 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
 
        DPRINTK("ENTER\n");
 
-       spin_lock_irqsave(&host_set->lock, flags);
+       ap->hsm_task_state = HSM_ST_IDLE;
 
-       /* hack alert!  We cannot use the supplied completion
-        * function from inside the ->eh_strategy_handler() thread.
-        * libata is the only user of ->eh_strategy_handler() in
-        * any kernel, so the default scsi_done() assumes it is
-        * not being called from the SCSI EH.
-        */
-       qc->scsidone = scsi_finish_command;
+       spin_lock_irqsave(&host_set->lock, flags);
 
        switch (qc->tf.protocol) {
 
@@ -3480,12 +3761,13 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
 
                /* complete taskfile transaction */
                qc->err_mask |= ac_err_mask(drv_stat);
-               ata_qc_complete(qc);
                break;
        }
 
        spin_unlock_irqrestore(&host_set->lock, flags);
 
+       ata_eh_qc_complete(qc);
+
        DPRINTK("EXIT\n");
 }
 
@@ -3510,20 +3792,10 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
 
 void ata_eng_timeout(struct ata_port *ap)
 {
-       struct ata_queued_cmd *qc;
-
        DPRINTK("ENTER\n");
 
-       qc = ata_qc_from_tag(ap, ap->active_tag);
-       if (qc)
-               ata_qc_timeout(qc);
-       else {
-               printk(KERN_ERR "ata%u: BUG: timeout without command\n",
-                      ap->id);
-               goto out;
-       }
+       ata_qc_timeout(ata_qc_from_tag(ap, ap->active_tag));
 
-out:
        DPRINTK("EXIT\n");
 }
 
@@ -3579,21 +3851,6 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
        return qc;
 }
 
-static void __ata_qc_complete(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       unsigned int tag;
-
-       qc->flags = 0;
-       tag = qc->tag;
-       if (likely(ata_tag_valid(tag))) {
-               if (tag == ap->active_tag)
-                       ap->active_tag = ATA_TAG_POISON;
-               qc->tag = ATA_TAG_POISON;
-               clear_bit(tag, &ap->qactive);
-       }
-}
-
 /**
  *     ata_qc_free - free unused ata_queued_cmd
  *     @qc: Command to complete
@@ -3606,29 +3863,25 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
  */
 void ata_qc_free(struct ata_queued_cmd *qc)
 {
-       assert(qc != NULL);     /* ata_qc_from_tag _might_ return NULL */
+       struct ata_port *ap = qc->ap;
+       unsigned int tag;
 
-       __ata_qc_complete(qc);
-}
+       WARN_ON(qc == NULL);    /* ata_qc_from_tag _might_ return NULL */
 
-/**
- *     ata_qc_complete - Complete an active ATA command
- *     @qc: Command to complete
- *     @err_mask: ATA Status register contents
- *
- *     Indicate to the mid and upper layers that an ATA
- *     command has completed, with either an ok or not-ok status.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host_set lock)
- */
+       qc->flags = 0;
+       tag = qc->tag;
+       if (likely(ata_tag_valid(tag))) {
+               if (tag == ap->active_tag)
+                       ap->active_tag = ATA_TAG_POISON;
+               qc->tag = ATA_TAG_POISON;
+               clear_bit(tag, &ap->qactive);
+       }
+}
 
-void ata_qc_complete(struct ata_queued_cmd *qc)
+void __ata_qc_complete(struct ata_queued_cmd *qc)
 {
-       int rc;
-
-       assert(qc != NULL);     /* ata_qc_from_tag _might_ return NULL */
-       assert(qc->flags & ATA_QCFLAG_ACTIVE);
+       WARN_ON(qc == NULL);    /* ata_qc_from_tag _might_ return NULL */
+       WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
 
        if (likely(qc->flags & ATA_QCFLAG_DMAMAP))
                ata_sg_clean(qc);
@@ -3640,17 +3893,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
        qc->flags &= ~ATA_QCFLAG_ACTIVE;
 
        /* call completion callback */
-       rc = qc->complete_fn(qc);
-
-       /* if callback indicates not to complete command (non-zero),
-        * return immediately
-        */
-       if (rc != 0)
-               return;
-
-       __ata_qc_complete(qc);
-
-       VPRINTK("EXIT\n");
+       qc->complete_fn(qc);
 }
 
 static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
@@ -3690,20 +3933,20 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
  *     spin_lock_irqsave(host_set lock)
  *
  *     RETURNS:
- *     Zero on success, negative on error.
+ *     Zero on success, AC_ERR_* mask on failure
  */
 
-int ata_qc_issue(struct ata_queued_cmd *qc)
+unsigned int ata_qc_issue(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
 
        if (ata_should_dma_map(qc)) {
                if (qc->flags & ATA_QCFLAG_SG) {
                        if (ata_sg_setup(qc))
-                               goto err_out;
+                               goto sg_err;
                } else if (qc->flags & ATA_QCFLAG_SINGLE) {
                        if (ata_sg_setup_one(qc))
-                               goto err_out;
+                               goto sg_err;
                }
        } else {
                qc->flags &= ~ATA_QCFLAG_DMAMAP;
@@ -3716,8 +3959,9 @@ int ata_qc_issue(struct ata_queued_cmd *qc)
 
        return ap->ops->qc_issue(qc);
 
-err_out:
-       return -1;
+sg_err:
+       qc->flags &= ~ATA_QCFLAG_DMAMAP;
+       return AC_ERR_SYSTEM;
 }
 
 
@@ -3736,10 +3980,10 @@ err_out:
  *     spin_lock_irqsave(host_set lock)
  *
  *     RETURNS:
- *     Zero on success, negative on error.
+ *     Zero on success, AC_ERR_* mask on failure
  */
 
-int ata_qc_issue_prot(struct ata_queued_cmd *qc)
+unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
 
@@ -3760,31 +4004,31 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
                ata_qc_set_polling(qc);
                ata_tf_to_host(ap, &qc->tf);
                ap->hsm_task_state = HSM_ST;
-               queue_work(ata_wq, &ap->pio_task);
+               ata_port_queue_task(ap, ata_pio_task, ap, 0);
                break;
 
        case ATA_PROT_ATAPI:
                ata_qc_set_polling(qc);
                ata_tf_to_host(ap, &qc->tf);
-               queue_work(ata_wq, &ap->packet_task);
+               ata_port_queue_task(ap, atapi_packet_task, ap, 0);
                break;
 
        case ATA_PROT_ATAPI_NODATA:
                ap->flags |= ATA_FLAG_NOINTR;
                ata_tf_to_host(ap, &qc->tf);
-               queue_work(ata_wq, &ap->packet_task);
+               ata_port_queue_task(ap, atapi_packet_task, ap, 0);
                break;
 
        case ATA_PROT_ATAPI_DMA:
                ap->flags |= ATA_FLAG_NOINTR;
                ap->ops->tf_load(ap, &qc->tf);   /* load tf registers */
                ap->ops->bmdma_setup(qc);           /* set up bmdma */
-               queue_work(ata_wq, &ap->packet_task);
+               ata_port_queue_task(ap, atapi_packet_task, ap, 0);
                break;
 
        default:
                WARN_ON(1);
-               return -1;
+               return AC_ERR_SYSTEM;
        }
 
        return 0;
@@ -4147,91 +4391,6 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
        return IRQ_RETVAL(handled);
 }
 
-/**
- *     atapi_packet_task - Write CDB bytes to hardware
- *     @_data: Port to which ATAPI device is attached.
- *
- *     When device has indicated its readiness to accept
- *     a CDB, this function is called.  Send the CDB.
- *     If DMA is to be performed, exit immediately.
- *     Otherwise, we are in polling mode, so poll
- *     status under operation succeeds or fails.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep)
- */
-
-static void atapi_packet_task(void *_data)
-{
-       struct ata_port *ap = _data;
-       struct ata_queued_cmd *qc;
-       u8 status;
-
-       qc = ata_qc_from_tag(ap, ap->active_tag);
-       assert(qc != NULL);
-       assert(qc->flags & ATA_QCFLAG_ACTIVE);
-
-       /* sleep-wait for BSY to clear */
-       DPRINTK("busy wait\n");
-       if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
-               qc->err_mask |= AC_ERR_ATA_BUS;
-               goto err_out;
-       }
-
-       /* make sure DRQ is set */
-       status = ata_chk_status(ap);
-       if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) {
-               qc->err_mask |= AC_ERR_ATA_BUS;
-               goto err_out;
-       }
-
-       /* send SCSI cdb */
-       DPRINTK("send cdb\n");
-       assert(ap->cdb_len >= 12);
-
-       if (qc->tf.protocol == ATA_PROT_ATAPI_DMA ||
-           qc->tf.protocol == ATA_PROT_ATAPI_NODATA) {
-               unsigned long flags;
-
-               /* Once we're done issuing command and kicking bmdma,
-                * irq handler takes over.  To not lose irq, we need
-                * to clear NOINTR flag before sending cdb, but
-                * interrupt handler shouldn't be invoked before we're
-                * finished.  Hence, the following locking.
-                */
-               spin_lock_irqsave(&ap->host_set->lock, flags);
-               ap->flags &= ~ATA_FLAG_NOINTR;
-               ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
-               if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
-                       ap->ops->bmdma_start(qc);       /* initiate bmdma */
-               spin_unlock_irqrestore(&ap->host_set->lock, flags);
-       } else {
-               ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1);
-
-               /* PIO commands are handled by polling */
-               ap->hsm_task_state = HSM_ST;
-               queue_work(ata_wq, &ap->pio_task);
-       }
-
-       return;
-
-err_out:
-       ata_poll_qc_complete(qc);
-}
-
-
-/**
- *     ata_port_start - Set port up for dma.
- *     @ap: Port to initialize
- *
- *     Called just after data structures for each port are
- *     initialized.  Allocates space for PRD table.
- *
- *     May be used as the port_start() entry in ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
 
 /*
  * Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
@@ -4284,6 +4443,8 @@ static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
 
 /**
  *     ata_device_resume - wakeup a previously suspended devices
+ *     @ap: port the device is connected to
+ *     @dev: the device to resume
  *
  *     Kick the drive back into action, by sending it an idle immediate
  *     command and making sure its transfer mode matches between drive
@@ -4306,10 +4467,11 @@ int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
 
 /**
  *     ata_device_suspend - prepare a device for suspend
+ *     @ap: port the device is connected to
+ *     @dev: the device to suspend
  *
  *     Flush the cache on the drive, if appropriate, then issue a
  *     standbynow command.
- *
  */
 int ata_device_suspend(struct ata_port *ap, struct ata_device *dev)
 {
@@ -4323,6 +4485,19 @@ int ata_device_suspend(struct ata_port *ap, struct ata_device *dev)
        return 0;
 }
 
+/**
+ *     ata_port_start - Set port up for dma.
+ *     @ap: Port to initialize
+ *
+ *     Called just after data structures for each port are
+ *     initialized.  Allocates space for PRD table.
+ *
+ *     May be used as the port_start() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+
 int ata_port_start (struct ata_port *ap)
 {
        struct device *dev = ap->host_set->dev;
@@ -4436,8 +4611,8 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
        ap->active_tag = ATA_TAG_POISON;
        ap->last_ctl = 0xFF;
 
-       INIT_WORK(&ap->packet_task, atapi_packet_task, ap);
-       INIT_WORK(&ap->pio_task, ata_pio_task, ap);
+       INIT_WORK(&ap->port_task, NULL, NULL);
+       INIT_LIST_HEAD(&ap->eh_done_q);
 
        for (i = 0; i < ATA_MAX_DEVICES; i++)
                ap->device[i].devno = i;
@@ -4579,9 +4754,9 @@ int ata_device_add(const struct ata_probe_ent *ent)
 
                ap = host_set->ports[i];
 
-               DPRINTK("ata%u: probe begin\n", ap->id);
+               DPRINTK("ata%u: bus probe begin\n", ap->id);
                rc = ata_bus_probe(ap);
-               DPRINTK("ata%u: probe end\n", ap->id);
+               DPRINTK("ata%u: bus probe end\n", ap->id);
 
                if (rc) {
                        /* FIXME: do something useful here?
@@ -4605,7 +4780,7 @@ int ata_device_add(const struct ata_probe_ent *ent)
        }
 
        /* probes are done, now scan each port's disk(s) */
-       DPRINTK("probe begin\n");
+       DPRINTK("host probe begin\n");
        for (i = 0; i < count; i++) {
                struct ata_port *ap = host_set->ports[i];
 
@@ -4691,11 +4866,14 @@ void ata_host_set_remove(struct ata_host_set *host_set)
 int ata_scsi_release(struct Scsi_Host *host)
 {
        struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
+       int i;
 
        DPRINTK("ENTER\n");
 
        ap->ops->port_disable(ap);
        ata_host_remove(ap, 0);
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               kfree(ap->device[i].id);
 
        DPRINTK("EXIT\n");
        return 1;
@@ -4727,32 +4905,6 @@ void ata_std_ports(struct ata_ioports *ioaddr)
        ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD;
 }
 
-static struct ata_probe_ent *
-ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
-{
-       struct ata_probe_ent *probe_ent;
-
-       probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
-       if (!probe_ent) {
-               printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
-                      kobject_name(&(dev->kobj)));
-               return NULL;
-       }
-
-       INIT_LIST_HEAD(&probe_ent->node);
-       probe_ent->dev = dev;
-
-       probe_ent->sht = port->sht;
-       probe_ent->host_flags = port->host_flags;
-       probe_ent->pio_mask = port->pio_mask;
-       probe_ent->mwdma_mask = port->mwdma_mask;
-       probe_ent->udma_mask = port->udma_mask;
-       probe_ent->port_ops = port->port_ops;
-
-       return probe_ent;
-}
-
-
 
 #ifdef CONFIG_PCI
 
@@ -4763,256 +4915,6 @@ void ata_pci_host_stop (struct ata_host_set *host_set)
        pci_iounmap(pdev, host_set->mmio_base);
 }
 
-/**
- *     ata_pci_init_native_mode - Initialize native-mode driver
- *     @pdev:  pci device to be initialized
- *     @port:  array[2] of pointers to port info structures.
- *     @ports: bitmap of ports present
- *
- *     Utility function which allocates and initializes an
- *     ata_probe_ent structure for a standard dual-port
- *     PIO-based IDE controller.  The returned ata_probe_ent
- *     structure can be passed to ata_device_add().  The returned
- *     ata_probe_ent structure should then be freed with kfree().
- *
- *     The caller need only pass the address of the primary port, the
- *     secondary will be deduced automatically. If the device has non
- *     standard secondary port mappings this function can be called twice,
- *     once for each interface.
- */
-
-struct ata_probe_ent *
-ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
-{
-       struct ata_probe_ent *probe_ent =
-               ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
-       int p = 0;
-
-       if (!probe_ent)
-               return NULL;
-
-       probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = SA_SHIRQ;
-       probe_ent->private_data = port[0]->private_data;
-
-       if (ports & ATA_PORT_PRIMARY) {
-               probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
-               probe_ent->port[p].altstatus_addr =
-               probe_ent->port[p].ctl_addr =
-                       pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
-               probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4);
-               ata_std_ports(&probe_ent->port[p]);
-               p++;
-       }
-
-       if (ports & ATA_PORT_SECONDARY) {
-               probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2);
-               probe_ent->port[p].altstatus_addr =
-               probe_ent->port[p].ctl_addr =
-                       pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
-               probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8;
-               ata_std_ports(&probe_ent->port[p]);
-               p++;
-       }
-
-       probe_ent->n_ports = p;
-       return probe_ent;
-}
-
-static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num)
-{
-       struct ata_probe_ent *probe_ent;
-
-       probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
-       if (!probe_ent)
-               return NULL;
-
-       probe_ent->legacy_mode = 1;
-       probe_ent->n_ports = 1;
-       probe_ent->hard_port_no = port_num;
-       probe_ent->private_data = port->private_data;
-
-       switch(port_num)
-       {
-               case 0:
-                       probe_ent->irq = 14;
-                       probe_ent->port[0].cmd_addr = 0x1f0;
-                       probe_ent->port[0].altstatus_addr =
-                       probe_ent->port[0].ctl_addr = 0x3f6;
-                       break;
-               case 1:
-                       probe_ent->irq = 15;
-                       probe_ent->port[0].cmd_addr = 0x170;
-                       probe_ent->port[0].altstatus_addr =
-                       probe_ent->port[0].ctl_addr = 0x376;
-                       break;
-       }
-       probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num;
-       ata_std_ports(&probe_ent->port[0]);
-       return probe_ent;
-}
-
-/**
- *     ata_pci_init_one - Initialize/register PCI IDE host controller
- *     @pdev: Controller to be initialized
- *     @port_info: Information from low-level host driver
- *     @n_ports: Number of ports attached to host controller
- *
- *     This is a helper function which can be called from a driver's
- *     xxx_init_one() probe function if the hardware uses traditional
- *     IDE taskfile registers.
- *
- *     This function calls pci_enable_device(), reserves its register
- *     regions, sets the dma mask, enables bus master mode, and calls
- *     ata_device_add()
- *
- *     LOCKING:
- *     Inherited from PCI layer (may sleep).
- *
- *     RETURNS:
- *     Zero on success, negative on errno-based value on error.
- */
-
-int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
-                     unsigned int n_ports)
-{
-       struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
-       struct ata_port_info *port[2];
-       u8 tmp8, mask;
-       unsigned int legacy_mode = 0;
-       int disable_dev_on_err = 1;
-       int rc;
-
-       DPRINTK("ENTER\n");
-
-       port[0] = port_info[0];
-       if (n_ports > 1)
-               port[1] = port_info[1];
-       else
-               port[1] = port[0];
-
-       if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0
-           && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
-               /* TODO: What if one channel is in native mode ... */
-               pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
-               mask = (1 << 2) | (1 << 0);
-               if ((tmp8 & mask) != mask)
-                       legacy_mode = (1 << 3);
-       }
-
-       /* FIXME... */
-       if ((!legacy_mode) && (n_ports > 2)) {
-               printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n");
-               n_ports = 2;
-               /* For now */
-       }
-
-       /* FIXME: Really for ATA it isn't safe because the device may be
-          multi-purpose and we want to leave it alone if it was already
-          enabled. Secondly for shared use as Arjan says we want refcounting
-          
-          Checking dev->is_enabled is insufficient as this is not set at
-          boot for the primary video which is BIOS enabled
-         */
-         
-       rc = pci_enable_device(pdev);
-       if (rc)
-               return rc;
-
-       rc = pci_request_regions(pdev, DRV_NAME);
-       if (rc) {
-               disable_dev_on_err = 0;
-               goto err_out;
-       }
-
-       /* FIXME: Should use platform specific mappers for legacy port ranges */
-       if (legacy_mode) {
-               if (!request_region(0x1f0, 8, "libata")) {
-                       struct resource *conflict, res;
-                       res.start = 0x1f0;
-                       res.end = 0x1f0 + 8 - 1;
-                       conflict = ____request_resource(&ioport_resource, &res);
-                       if (!strcmp(conflict->name, "libata"))
-                               legacy_mode |= (1 << 0);
-                       else {
-                               disable_dev_on_err = 0;
-                               printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n");
-                       }
-               } else
-                       legacy_mode |= (1 << 0);
-
-               if (!request_region(0x170, 8, "libata")) {
-                       struct resource *conflict, res;
-                       res.start = 0x170;
-                       res.end = 0x170 + 8 - 1;
-                       conflict = ____request_resource(&ioport_resource, &res);
-                       if (!strcmp(conflict->name, "libata"))
-                               legacy_mode |= (1 << 1);
-                       else {
-                               disable_dev_on_err = 0;
-                               printk(KERN_WARNING "ata: 0x170 IDE port busy\n");
-                       }
-               } else
-                       legacy_mode |= (1 << 1);
-       }
-
-       /* we have legacy mode, but all ports are unavailable */
-       if (legacy_mode == (1 << 3)) {
-               rc = -EBUSY;
-               goto err_out_regions;
-       }
-
-       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
-       if (rc)
-               goto err_out_regions;
-       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
-       if (rc)
-               goto err_out_regions;
-
-       if (legacy_mode) {
-               if (legacy_mode & (1 << 0))
-                       probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0);
-               if (legacy_mode & (1 << 1))
-                       probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1);
-       } else {
-               if (n_ports == 2)
-                       probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
-               else
-                       probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
-       }
-       if (!probe_ent && !probe_ent2) {
-               rc = -ENOMEM;
-               goto err_out_regions;
-       }
-
-       pci_set_master(pdev);
-
-       /* FIXME: check ata_device_add return */
-       if (legacy_mode) {
-               if (legacy_mode & (1 << 0))
-                       ata_device_add(probe_ent);
-               if (legacy_mode & (1 << 1))
-                       ata_device_add(probe_ent2);
-       } else
-               ata_device_add(probe_ent);
-
-       kfree(probe_ent);
-       kfree(probe_ent2);
-
-       return 0;
-
-err_out_regions:
-       if (legacy_mode & (1 << 0))
-               release_region(0x1f0, 8);
-       if (legacy_mode & (1 << 1))
-               release_region(0x170, 8);
-       pci_release_regions(pdev);
-err_out:
-       if (disable_dev_on_err)
-               pci_disable_device(pdev);
-       return rc;
-}
-
 /**
  *     ata_pci_remove_one - PCI layer callback for device removal
  *     @pdev: PCI device that was removed
@@ -5143,7 +5045,7 @@ EXPORT_SYMBOL_GPL(ata_device_add);
 EXPORT_SYMBOL_GPL(ata_host_set_remove);
 EXPORT_SYMBOL_GPL(ata_sg_init);
 EXPORT_SYMBOL_GPL(ata_sg_init_one);
-EXPORT_SYMBOL_GPL(ata_qc_complete);
+EXPORT_SYMBOL_GPL(__ata_qc_complete);
 EXPORT_SYMBOL_GPL(ata_qc_issue_prot);
 EXPORT_SYMBOL_GPL(ata_eng_timeout);
 EXPORT_SYMBOL_GPL(ata_tf_load);
@@ -5169,18 +5071,30 @@ EXPORT_SYMBOL_GPL(ata_port_probe);
 EXPORT_SYMBOL_GPL(sata_phy_reset);
 EXPORT_SYMBOL_GPL(__sata_phy_reset);
 EXPORT_SYMBOL_GPL(ata_bus_reset);
+EXPORT_SYMBOL_GPL(ata_std_probeinit);
+EXPORT_SYMBOL_GPL(ata_std_softreset);
+EXPORT_SYMBOL_GPL(sata_std_hardreset);
+EXPORT_SYMBOL_GPL(ata_std_postreset);
+EXPORT_SYMBOL_GPL(ata_std_probe_reset);
+EXPORT_SYMBOL_GPL(ata_drive_probe_reset);
+EXPORT_SYMBOL_GPL(ata_dev_revalidate);
 EXPORT_SYMBOL_GPL(ata_port_disable);
 EXPORT_SYMBOL_GPL(ata_ratelimit);
+EXPORT_SYMBOL_GPL(ata_busy_sleep);
+EXPORT_SYMBOL_GPL(ata_port_queue_task);
 EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
 EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
+EXPORT_SYMBOL_GPL(ata_scsi_timed_out);
 EXPORT_SYMBOL_GPL(ata_scsi_error);
 EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
 EXPORT_SYMBOL_GPL(ata_scsi_release);
 EXPORT_SYMBOL_GPL(ata_host_intr);
 EXPORT_SYMBOL_GPL(ata_dev_classify);
-EXPORT_SYMBOL_GPL(ata_dev_id_string);
-EXPORT_SYMBOL_GPL(ata_dev_config);
+EXPORT_SYMBOL_GPL(ata_id_string);
+EXPORT_SYMBOL_GPL(ata_id_c_string);
 EXPORT_SYMBOL_GPL(ata_scsi_simulate);
+EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
+EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
 
 EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
 EXPORT_SYMBOL_GPL(ata_timing_compute);
index 59503c9ccac9ff794a66d29c358f4d98c4b33ed0..ccedb4536977af454a6c95a613fefc4a292d3e83 100644 (file)
@@ -151,7 +151,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
        struct scsi_sense_hdr sshdr;
        enum dma_data_direction data_dir;
 
-       if (NULL == (void *)arg)
+       if (arg == NULL)
                return -EINVAL;
 
        if (copy_from_user(args, arg, sizeof(args)))
@@ -201,7 +201,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
        /* Need code to retrieve data from check condition? */
 
        if ((argbuf)
-        && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize))
+        && copy_to_user(arg + sizeof(args), argbuf, argsize))
                rc = -EFAULT;
 error:
        if (argbuf)
@@ -228,7 +228,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
        u8 args[7];
        struct scsi_sense_hdr sshdr;
 
-       if (NULL == (void *)arg)
+       if (arg == NULL)
                return -EINVAL;
 
        if (copy_from_user(args, arg, sizeof(args)))
@@ -553,7 +553,7 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
        /*
         * Read the controller registers.
         */
-       assert(NULL != qc->ap->ops->tf_read);
+       WARN_ON(qc->ap->ops->tf_read == NULL);
        qc->ap->ops->tf_read(qc->ap, tf);
 
        /*
@@ -628,7 +628,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
        /*
         * Read the controller registers.
         */
-       assert(NULL != qc->ap->ops->tf_read);
+       WARN_ON(qc->ap->ops->tf_read == NULL);
        qc->ap->ops->tf_read(qc->ap, tf);
 
        /*
@@ -684,23 +684,23 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
        if (sdev->id < ATA_MAX_DEVICES) {
                struct ata_port *ap;
                struct ata_device *dev;
+               unsigned int max_sectors;
 
                ap = (struct ata_port *) &sdev->host->hostdata[0];
                dev = &ap->device[sdev->id];
 
-               /* TODO: 1024 is an arbitrary number, not the
+               /* TODO: 2048 is an arbitrary number, not the
                 * hardware maximum.  This should be increased to
                 * 65534 when Jens Axboe's patch for dynamically
                 * determining max_sectors is merged.
                 */
-               if ((dev->flags & ATA_DFLAG_LBA48) &&
-                   ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) {
-                       /*
-                        * do not overwrite sdev->host->max_sectors, since
-                        * other drives on this host may not support LBA48
-                        */
-                       blk_queue_max_sectors(sdev->request_queue, 2048);
-               }
+               max_sectors = ATA_MAX_SECTORS;
+               if (dev->flags & ATA_DFLAG_LBA48)
+                       max_sectors = 2048;
+               if (dev->max_sectors)
+                       max_sectors = dev->max_sectors;
+
+               blk_queue_max_sectors(sdev->request_queue, max_sectors);
 
                /*
                 * SATA DMA transfers must be multiples of 4 byte, so
@@ -716,6 +716,47 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
        return 0;       /* scsi layer doesn't check return value, sigh */
 }
 
+/**
+ *     ata_scsi_timed_out - SCSI layer time out callback
+ *     @cmd: timed out SCSI command
+ *
+ *     Handles SCSI layer timeout.  We race with normal completion of
+ *     the qc for @cmd.  If the qc is already gone, we lose and let
+ *     the scsi command finish (EH_HANDLED).  Otherwise, the qc has
+ *     timed out and EH should be invoked.  Prevent ata_qc_complete()
+ *     from finishing it by setting EH_SCHEDULED and return
+ *     EH_NOT_HANDLED.
+ *
+ *     LOCKING:
+ *     Called from timer context
+ *
+ *     RETURNS:
+ *     EH_HANDLED or EH_NOT_HANDLED
+ */
+enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
+{
+       struct Scsi_Host *host = cmd->device->host;
+       struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
+       unsigned long flags;
+       struct ata_queued_cmd *qc;
+       enum scsi_eh_timer_return ret = EH_HANDLED;
+
+       DPRINTK("ENTER\n");
+
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       qc = ata_qc_from_tag(ap, ap->active_tag);
+       if (qc) {
+               WARN_ON(qc->scsicmd != cmd);
+               qc->flags |= ATA_QCFLAG_EH_SCHEDULED;
+               qc->err_mask |= AC_ERR_TIMEOUT;
+               ret = EH_NOT_HANDLED;
+       }
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       DPRINTK("EXIT, ret=%d\n", ret);
+       return ret;
+}
+
 /**
  *     ata_scsi_error - SCSI layer error handler callback
  *     @host: SCSI host on which error occurred
@@ -732,23 +773,84 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
 int ata_scsi_error(struct Scsi_Host *host)
 {
        struct ata_port *ap;
+       unsigned long flags;
 
        DPRINTK("ENTER\n");
 
        ap = (struct ata_port *) &host->hostdata[0];
+
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       WARN_ON(ap->flags & ATA_FLAG_IN_EH);
+       ap->flags |= ATA_FLAG_IN_EH;
+       WARN_ON(ata_qc_from_tag(ap, ap->active_tag) == NULL);
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       ata_port_flush_task(ap);
+
        ap->ops->eng_timeout(ap);
 
-       /* TODO: this is per-command; when queueing is supported
-        * this code will either change or move to a more
-        * appropriate place
-        */
-       host->host_failed--;
-       INIT_LIST_HEAD(&host->eh_cmd_q);
+       WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q));
+
+       scsi_eh_flush_done_q(&ap->eh_done_q);
+
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       ap->flags &= ~ATA_FLAG_IN_EH;
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
 
        DPRINTK("EXIT\n");
        return 0;
 }
 
+static void ata_eh_scsidone(struct scsi_cmnd *scmd)
+{
+       /* nada */
+}
+
+static void __ata_eh_qc_complete(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct scsi_cmnd *scmd = qc->scsicmd;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       qc->scsidone = ata_eh_scsidone;
+       __ata_qc_complete(qc);
+       WARN_ON(ata_tag_valid(qc->tag));
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
+}
+
+/**
+ *     ata_eh_qc_complete - Complete an active ATA command from EH
+ *     @qc: Command to complete
+ *
+ *     Indicate to the mid and upper layers that an ATA command has
+ *     completed.  To be used from EH.
+ */
+void ata_eh_qc_complete(struct ata_queued_cmd *qc)
+{
+       struct scsi_cmnd *scmd = qc->scsicmd;
+       scmd->retries = scmd->allowed;
+       __ata_eh_qc_complete(qc);
+}
+
+/**
+ *     ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH
+ *     @qc: Command to retry
+ *
+ *     Indicate to the mid and upper layers that an ATA command
+ *     should be retried.  To be used from EH.
+ *
+ *     SCSI midlayer limits the number of retries to scmd->allowed.
+ *     This function might need to adjust scmd->retries for commands
+ *     which get retried due to unrelated NCQ failures.
+ */
+void ata_eh_qc_retry(struct ata_queued_cmd *qc)
+{
+       __ata_eh_qc_complete(qc);
+}
+
 /**
  *     ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
  *     @qc: Storage for translated ATA taskfile
@@ -985,9 +1087,13 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
        if (dev->flags & ATA_DFLAG_LBA) {
                tf->flags |= ATA_TFLAG_LBA;
 
-               if (dev->flags & ATA_DFLAG_LBA48) {
-                       if (n_block > (64 * 1024))
-                               goto invalid_fld;
+               if (lba_28_ok(block, n_block)) {
+                       /* use LBA28 */
+                       tf->command = ATA_CMD_VERIFY;
+                       tf->device |= (block >> 24) & 0xf;
+               } else if (lba_48_ok(block, n_block)) {
+                       if (!(dev->flags & ATA_DFLAG_LBA48))
+                               goto out_of_range;
 
                        /* use LBA48 */
                        tf->flags |= ATA_TFLAG_LBA48;
@@ -998,15 +1104,9 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
                        tf->hob_lbah = (block >> 40) & 0xff;
                        tf->hob_lbam = (block >> 32) & 0xff;
                        tf->hob_lbal = (block >> 24) & 0xff;
-               } else {
-                       if (n_block > 256)
-                               goto invalid_fld;
-
-                       /* use LBA28 */
-                       tf->command = ATA_CMD_VERIFY;
-
-                       tf->device |= (block >> 24) & 0xf;
-               }
+               } else
+                       /* request too large even for LBA48 */
+                       goto out_of_range;
 
                tf->nsect = n_block & 0xff;
 
@@ -1019,8 +1119,8 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
                /* CHS */
                u32 sect, head, cyl, track;
 
-               if (n_block > 256)
-                       goto invalid_fld;
+               if (!lba_28_ok(block, n_block))
+                       goto out_of_range;
 
                /* Convert LBA to CHS */
                track = (u32)block / dev->sectors;
@@ -1139,9 +1239,11 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
        if (dev->flags & ATA_DFLAG_LBA) {
                tf->flags |= ATA_TFLAG_LBA;
 
-               if (dev->flags & ATA_DFLAG_LBA48) {
-                       /* The request -may- be too large for LBA48. */
-                       if ((block >> 48) || (n_block > 65536))
+               if (lba_28_ok(block, n_block)) {
+                       /* use LBA28 */
+                       tf->device |= (block >> 24) & 0xf;
+               } else if (lba_48_ok(block, n_block)) {
+                       if (!(dev->flags & ATA_DFLAG_LBA48))
                                goto out_of_range;
 
                        /* use LBA48 */
@@ -1152,15 +1254,9 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
                        tf->hob_lbah = (block >> 40) & 0xff;
                        tf->hob_lbam = (block >> 32) & 0xff;
                        tf->hob_lbal = (block >> 24) & 0xff;
-               } else { 
-                       /* use LBA28 */
-
-                       /* The request -may- be too large for LBA28. */
-                       if ((block >> 28) || (n_block > 256))
-                               goto out_of_range;
-
-                       tf->device |= (block >> 24) & 0xf;
-               }
+               } else
+                       /* request too large even for LBA48 */
+                       goto out_of_range;
 
                if (unlikely(ata_rwcmd_protocol(qc) < 0))
                        goto invalid_fld;
@@ -1178,7 +1274,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
                u32 sect, head, cyl, track;
 
                /* The request -may- be too large for CHS addressing. */
-               if ((block >> 28) || (n_block > 256))
+               if (!lba_28_ok(block, n_block))
                        goto out_of_range;
 
                if (unlikely(ata_rwcmd_protocol(qc) < 0))
@@ -1225,7 +1321,7 @@ nothing_to_do:
        return 1;
 }
 
-static int ata_scsi_qc_complete(struct ata_queued_cmd *qc)
+static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 {
        struct scsi_cmnd *cmd = qc->scsicmd;
        u8 *cdb = cmd->cmnd;
@@ -1262,7 +1358,7 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 
        qc->scsidone(cmd);
 
-       return 0;
+       ata_qc_free(qc);
 }
 
 /**
@@ -1328,8 +1424,9 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
                goto early_finish;
 
        /* select device, send command to hardware */
-       if (ata_qc_issue(qc))
-               goto err_did;
+       qc->err_mask = ata_qc_issue(qc);
+       if (qc->err_mask)
+               ata_qc_complete(qc);
 
        VPRINTK("EXIT\n");
        return;
@@ -1472,8 +1569,8 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
 
        if (buflen > 35) {
                memcpy(&rbuf[8], "ATA     ", 8);
-               ata_dev_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16);
-               ata_dev_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
+               ata_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16);
+               ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
                if (rbuf[32] == 0 || rbuf[32] == ' ')
                        memcpy(&rbuf[32], "n/a ", 4);
        }
@@ -1547,8 +1644,8 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf,
        memcpy(rbuf, hdr, sizeof(hdr));
 
        if (buflen > (ATA_SERNO_LEN + 4 - 1))
-               ata_dev_id_string(args->id, (unsigned char *) &rbuf[4],
-                                 ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
+               ata_id_string(args->id, (unsigned char *) &rbuf[4],
+                             ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
 
        return 0;
 }
@@ -1713,15 +1810,12 @@ static int ata_dev_supports_fua(u16 *id)
        if (!ata_id_has_fua(id))
                return 0;
 
-       model[40] = '\0';
-       fw[8] = '\0';
-
-       ata_dev_id_string(id, model, ATA_ID_PROD_OFS, sizeof(model) - 1);
-       ata_dev_id_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw) - 1);
+       ata_id_c_string(id, model, ATA_ID_PROD_OFS, sizeof(model));
+       ata_id_c_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw));
 
-       if (strncmp(model, "Maxtor", 6))
+       if (strcmp(model, "Maxtor"))
                return 1;
-       if (strncmp(fw, "BANC1G10", 8))
+       if (strcmp(fw, "BANC1G10"))
                return 1;
 
        return 0; /* blacklisted */
@@ -2015,7 +2109,7 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8
        done(cmd);
 }
 
-static int atapi_sense_complete(struct ata_queued_cmd *qc)
+static void atapi_sense_complete(struct ata_queued_cmd *qc)
 {
        if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0))
                /* FIXME: not quite right; we don't want the
@@ -2026,7 +2120,7 @@ static int atapi_sense_complete(struct ata_queued_cmd *qc)
                ata_gen_ata_desc_sense(qc);
 
        qc->scsidone(qc->scsicmd);
-       return 0;
+       ata_qc_free(qc);
 }
 
 /* is it pointless to prefer PIO for "safety reasons"? */
@@ -2056,7 +2150,7 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
        ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
        qc->dma_dir = DMA_FROM_DEVICE;
 
-       memset(&qc->cdb, 0, ap->cdb_len);
+       memset(&qc->cdb, 0, qc->dev->cdb_len);
        qc->cdb[0] = REQUEST_SENSE;
        qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
 
@@ -2075,15 +2169,14 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
 
        qc->complete_fn = atapi_sense_complete;
 
-       if (ata_qc_issue(qc)) {
-               qc->err_mask |= AC_ERR_OTHER;
+       qc->err_mask = ata_qc_issue(qc);
+       if (qc->err_mask)
                ata_qc_complete(qc);
-       }
 
        DPRINTK("EXIT\n");
 }
 
-static int atapi_qc_complete(struct ata_queued_cmd *qc)
+static void atapi_qc_complete(struct ata_queued_cmd *qc)
 {
        struct scsi_cmnd *cmd = qc->scsicmd;
        unsigned int err_mask = qc->err_mask;
@@ -2093,7 +2186,7 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc)
        if (unlikely(err_mask & AC_ERR_DEV)) {
                cmd->result = SAM_STAT_CHECK_CONDITION;
                atapi_request_sense(qc);
-               return 1;
+               return;
        }
 
        else if (unlikely(err_mask))
@@ -2133,7 +2226,7 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc)
        }
 
        qc->scsidone(cmd);
-       return 0;
+       ata_qc_free(qc);
 }
 /**
  *     atapi_xlat - Initialize PACKET taskfile
@@ -2159,7 +2252,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
                if (ata_check_atapi_dma(qc))
                        using_pio = 1;
 
-       memcpy(&qc->cdb, scsicmd, qc->ap->cdb_len);
+       memcpy(&qc->cdb, scsicmd, dev->cdb_len);
 
        qc->complete_fn = atapi_qc_complete;
 
@@ -2519,7 +2612,8 @@ out_unlock:
 
 /**
  *     ata_scsi_simulate - simulate SCSI command on ATA device
- *     @id: current IDENTIFY data for target device.
+ *     @ap: port the device is connected to
+ *     @dev: the target device
  *     @cmd: SCSI command being sent to device.
  *     @done: SCSI command completion function.
  *
index fddaf479a5440ff08c12d6e22c49f9e373814731..f4c48c91b63d643635ee8e7779a61c76c0f5b5a4 100644 (file)
@@ -45,8 +45,9 @@ extern int libata_fua;
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
                                      struct ata_device *dev);
 extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
+extern void ata_port_flush_task(struct ata_port *ap);
 extern void ata_qc_free(struct ata_queued_cmd *qc);
-extern int ata_qc_issue(struct ata_queued_cmd *qc);
+extern unsigned int ata_qc_issue(struct ata_queued_cmd *qc);
 extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
 extern void ata_dev_select(struct ata_port *ap, unsigned int device,
                            unsigned int wait, unsigned int can_sleep);
index e8df0c9ec1e646992c5e3354d04868da4dba2d3f..5f33cc932e70dfb20dca425183238cdb406820d7 100644 (file)
@@ -131,7 +131,7 @@ static void adma_host_stop(struct ata_host_set *host_set);
 static void adma_port_stop(struct ata_port *ap);
 static void adma_phy_reset(struct ata_port *ap);
 static void adma_qc_prep(struct ata_queued_cmd *qc);
-static int adma_qc_issue(struct ata_queued_cmd *qc);
+static unsigned int adma_qc_issue(struct ata_queued_cmd *qc);
 static int adma_check_atapi_dma(struct ata_queued_cmd *qc);
 static void adma_bmdma_stop(struct ata_queued_cmd *qc);
 static u8 adma_bmdma_status(struct ata_port *ap);
@@ -143,11 +143,11 @@ static struct scsi_host_template adma_ata_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ENABLE_CLUSTERING,
@@ -419,7 +419,7 @@ static inline void adma_packet_start(struct ata_queued_cmd *qc)
        writew(aPIOMD4 | aGO, chan + ADMA_CONTROL);
 }
 
-static int adma_qc_issue(struct ata_queued_cmd *qc)
+static unsigned int adma_qc_issue(struct ata_queued_cmd *qc)
 {
        struct adma_port_priv *pp = qc->ap->private_data;
 
index 2770005324b4bac76781154ffe6543ecda049a82..e561281967dd1f6bbe76b970f56ed91476b0d349 100644 (file)
@@ -37,7 +37,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "sata_mv"
-#define DRV_VERSION    "0.5"
+#define DRV_VERSION    "0.6"
 
 enum {
        /* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -228,7 +228,9 @@ enum {
        MV_HP_ERRATA_50XXB2     = (1 << 2),
        MV_HP_ERRATA_60X1B2     = (1 << 3),
        MV_HP_ERRATA_60X1C0     = (1 << 4),
-       MV_HP_50XX              = (1 << 5),
+       MV_HP_ERRATA_XX42A0     = (1 << 5),
+       MV_HP_50XX              = (1 << 6),
+       MV_HP_GEN_IIE           = (1 << 7),
 
        /* Port private flags (pp_flags) */
        MV_PP_FLAG_EDMA_EN      = (1 << 0),
@@ -237,6 +239,9 @@ enum {
 
 #define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX)
 #define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0)
+#define IS_GEN_I(hpriv) IS_50XX(hpriv)
+#define IS_GEN_II(hpriv) IS_60XX(hpriv)
+#define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
 
 enum {
        /* Our DMA boundary is determined by an ePRD being unable to handle
@@ -255,6 +260,8 @@ enum chip_type {
        chip_5080,
        chip_604x,
        chip_608x,
+       chip_6042,
+       chip_7042,
 };
 
 /* Command ReQuest Block: 32B */
@@ -265,6 +272,14 @@ struct mv_crqb {
        u16                     ata_cmd[11];
 };
 
+struct mv_crqb_iie {
+       u32                     addr;
+       u32                     addr_hi;
+       u32                     flags;
+       u32                     len;
+       u32                     ata_cmd[4];
+};
+
 /* Command ResPonse Block: 8B */
 struct mv_crpb {
        u16                     id;
@@ -328,7 +343,8 @@ static void mv_host_stop(struct ata_host_set *host_set);
 static int mv_port_start(struct ata_port *ap);
 static void mv_port_stop(struct ata_port *ap);
 static void mv_qc_prep(struct ata_queued_cmd *qc);
-static int mv_qc_issue(struct ata_queued_cmd *qc);
+static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
+static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
 static irqreturn_t mv_interrupt(int irq, void *dev_instance,
                                struct pt_regs *regs);
 static void mv_eng_timeout(struct ata_port *ap);
@@ -362,11 +378,11 @@ static struct scsi_host_template mv_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = MV_USE_Q_DEPTH,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = MV_MAX_SG_CT / 2,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -430,6 +446,33 @@ static const struct ata_port_operations mv6_ops = {
        .host_stop              = mv_host_stop,
 };
 
+static const struct ata_port_operations mv_iie_ops = {
+       .port_disable           = ata_port_disable,
+
+       .tf_load                = ata_tf_load,
+       .tf_read                = ata_tf_read,
+       .check_status           = ata_check_status,
+       .exec_command           = ata_exec_command,
+       .dev_select             = ata_std_dev_select,
+
+       .phy_reset              = mv_phy_reset,
+
+       .qc_prep                = mv_qc_prep_iie,
+       .qc_issue               = mv_qc_issue,
+
+       .eng_timeout            = mv_eng_timeout,
+
+       .irq_handler            = mv_interrupt,
+       .irq_clear              = mv_irq_clear,
+
+       .scr_read               = mv_scr_read,
+       .scr_write              = mv_scr_write,
+
+       .port_start             = mv_port_start,
+       .port_stop              = mv_port_stop,
+       .host_stop              = mv_host_stop,
+};
+
 static const struct ata_port_info mv_port_info[] = {
        {  /* chip_504x */
                .sht            = &mv_sht,
@@ -467,6 +510,21 @@ static const struct ata_port_info mv_port_info[] = {
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv6_ops,
        },
+       {  /* chip_6042 */
+               .sht            = &mv_sht,
+               .host_flags     = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .udma_mask      = 0x7f, /* udma0-6 */
+               .port_ops       = &mv_iie_ops,
+       },
+       {  /* chip_7042 */
+               .sht            = &mv_sht,
+               .host_flags     = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+                                  MV_FLAG_DUAL_HC),
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .udma_mask      = 0x7f, /* udma0-6 */
+               .port_ops       = &mv_iie_ops,
+       },
 };
 
 static const struct pci_device_id mv_pci_tbl[] = {
@@ -477,6 +535,7 @@ static const struct pci_device_id mv_pci_tbl[] = {
 
        {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6040), 0, 0, chip_604x},
        {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6041), 0, 0, chip_604x},
+       {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6042), 0, 0, chip_6042},
        {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6080), 0, 0, chip_608x},
        {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6081), 0, 0, chip_608x},
 
@@ -572,8 +631,8 @@ static void mv_irq_clear(struct ata_port *ap)
  *      @base: port base address
  *      @pp: port private data
  *
- *      Verify the local cache of the eDMA state is accurate with an
- *      assert.
+ *      Verify the local cache of the eDMA state is accurate with a
+ *      WARN_ON.
  *
  *      LOCKING:
  *      Inherited from caller.
@@ -584,15 +643,15 @@ static void mv_start_dma(void __iomem *base, struct mv_port_priv *pp)
                writelfl(EDMA_EN, base + EDMA_CMD_OFS);
                pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
        }
-       assert(EDMA_EN & readl(base + EDMA_CMD_OFS));
+       WARN_ON(!(EDMA_EN & readl(base + EDMA_CMD_OFS)));
 }
 
 /**
  *      mv_stop_dma - Disable eDMA engine
  *      @ap: ATA channel to manipulate
  *
- *      Verify the local cache of the eDMA state is accurate with an
- *      assert.
+ *      Verify the local cache of the eDMA state is accurate with a
+ *      WARN_ON.
  *
  *      LOCKING:
  *      Inherited from caller.
@@ -610,7 +669,7 @@ static void mv_stop_dma(struct ata_port *ap)
                writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
                pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
        } else {
-               assert(!(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS)));
+               WARN_ON(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS));
        }
 
        /* now properly wait for the eDMA to stop */
@@ -773,6 +832,33 @@ static inline void mv_priv_free(struct mv_port_priv *pp, struct device *dev)
        dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma);
 }
 
+static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
+{
+       u32 cfg = readl(port_mmio + EDMA_CFG_OFS);
+
+       /* set up non-NCQ EDMA configuration */
+       cfg &= ~0x1f;           /* clear queue depth */
+       cfg &= ~EDMA_CFG_NCQ;   /* clear NCQ mode */
+       cfg &= ~(1 << 9);       /* disable equeue */
+
+       if (IS_GEN_I(hpriv))
+               cfg |= (1 << 8);        /* enab config burst size mask */
+
+       else if (IS_GEN_II(hpriv))
+               cfg |= EDMA_CFG_RD_BRST_EXT | EDMA_CFG_WR_BUFF_LEN;
+
+       else if (IS_GEN_IIE(hpriv)) {
+               cfg |= (1 << 23);       /* dis RX PM port mask */
+               cfg &= ~(1 << 16);      /* dis FIS-based switching (for now) */
+               cfg &= ~(1 << 19);      /* dis 128-entry queue (for now?) */
+               cfg |= (1 << 18);       /* enab early completion */
+               cfg |= (1 << 17);       /* enab host q cache */
+               cfg |= (1 << 22);       /* enab cutthrough */
+       }
+
+       writelfl(cfg, port_mmio + EDMA_CFG_OFS);
+}
+
 /**
  *      mv_port_start - Port specific init/start routine.
  *      @ap: ATA channel to manipulate
@@ -786,6 +872,7 @@ static inline void mv_priv_free(struct mv_port_priv *pp, struct device *dev)
 static int mv_port_start(struct ata_port *ap)
 {
        struct device *dev = ap->host_set->dev;
+       struct mv_host_priv *hpriv = ap->host_set->private_data;
        struct mv_port_priv *pp;
        void __iomem *port_mmio = mv_ap_base(ap);
        void *mem;
@@ -829,17 +916,26 @@ static int mv_port_start(struct ata_port *ap)
        pp->sg_tbl = mem;
        pp->sg_tbl_dma = mem_dma;
 
-       writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT |
-                EDMA_CFG_WR_BUFF_LEN, port_mmio + EDMA_CFG_OFS);
+       mv_edma_cfg(hpriv, port_mmio);
 
        writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
        writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK,
                 port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
 
-       writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
-       writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+       if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
+               writelfl(pp->crqb_dma & 0xffffffff,
+                        port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
+       else
+               writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
 
        writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
+
+       if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
+               writelfl(pp->crpb_dma & 0xffffffff,
+                        port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+       else
+               writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+
        writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK,
                 port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
 
@@ -960,21 +1056,19 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
        struct ata_taskfile *tf;
        u16 flags = 0;
 
-       if (ATA_PROT_DMA != qc->tf.protocol) {
+       if (ATA_PROT_DMA != qc->tf.protocol)
                return;
-       }
 
        /* the req producer index should be the same as we remember it */
-       assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >>
-                EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
-              pp->req_producer);
+       WARN_ON(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >>
+                 EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
+               pp->req_producer);
 
        /* Fill in command request block
         */
-       if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
+       if (!(qc->tf.flags & ATA_TFLAG_WRITE))
                flags |= CRQB_FLAG_READ;
-       }
-       assert(MV_MAX_Q_DEPTH > qc->tag);
+       WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
        flags |= qc->tag << CRQB_TAG_SHIFT;
 
        pp->crqb[pp->req_producer].sg_addr =
@@ -1029,9 +1123,76 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
        mv_crqb_pack_cmd(cw++, tf->device, ATA_REG_DEVICE, 0);
        mv_crqb_pack_cmd(cw++, tf->command, ATA_REG_CMD, 1);    /* last */
 
-       if (!(qc->flags & ATA_QCFLAG_DMAMAP)) {
+       if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+               return;
+       mv_fill_sg(qc);
+}
+
+/**
+ *      mv_qc_prep_iie - Host specific command preparation.
+ *      @qc: queued command to prepare
+ *
+ *      This routine simply redirects to the general purpose routine
+ *      if command is not DMA.  Else, it handles prep of the CRQB
+ *      (command request block), does some sanity checking, and calls
+ *      the SG load routine.
+ *
+ *      LOCKING:
+ *      Inherited from caller.
+ */
+static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct mv_port_priv *pp = ap->private_data;
+       struct mv_crqb_iie *crqb;
+       struct ata_taskfile *tf;
+       u32 flags = 0;
+
+       if (ATA_PROT_DMA != qc->tf.protocol)
+               return;
+
+       /* the req producer index should be the same as we remember it */
+       WARN_ON(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >>
+                 EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
+               pp->req_producer);
+
+       /* Fill in Gen IIE command request block
+        */
+       if (!(qc->tf.flags & ATA_TFLAG_WRITE))
+               flags |= CRQB_FLAG_READ;
+
+       WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
+       flags |= qc->tag << CRQB_TAG_SHIFT;
+
+       crqb = (struct mv_crqb_iie *) &pp->crqb[pp->req_producer];
+       crqb->addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
+       crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16);
+       crqb->flags = cpu_to_le32(flags);
+
+       tf = &qc->tf;
+       crqb->ata_cmd[0] = cpu_to_le32(
+                       (tf->command << 16) |
+                       (tf->feature << 24)
+               );
+       crqb->ata_cmd[1] = cpu_to_le32(
+                       (tf->lbal << 0) |
+                       (tf->lbam << 8) |
+                       (tf->lbah << 16) |
+                       (tf->device << 24)
+               );
+       crqb->ata_cmd[2] = cpu_to_le32(
+                       (tf->hob_lbal << 0) |
+                       (tf->hob_lbam << 8) |
+                       (tf->hob_lbah << 16) |
+                       (tf->hob_feature << 24)
+               );
+       crqb->ata_cmd[3] = cpu_to_le32(
+                       (tf->nsect << 0) |
+                       (tf->hob_nsect << 8)
+               );
+
+       if (!(qc->flags & ATA_QCFLAG_DMAMAP))
                return;
-       }
        mv_fill_sg(qc);
 }
 
@@ -1047,7 +1208,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
  *      LOCKING:
  *      Inherited from caller.
  */
-static int mv_qc_issue(struct ata_queued_cmd *qc)
+static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
 {
        void __iomem *port_mmio = mv_ap_base(qc->ap);
        struct mv_port_priv *pp = qc->ap->private_data;
@@ -1065,12 +1226,12 @@ static int mv_qc_issue(struct ata_queued_cmd *qc)
        in_ptr = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
 
        /* the req producer index should be the same as we remember it */
-       assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
-              pp->req_producer);
+       WARN_ON(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
+               pp->req_producer);
        /* until we do queuing, the queue should be empty at this point */
-       assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
-              ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >>
-                EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
+       WARN_ON(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
+               ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >>
+                 EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
 
        mv_inc_q_index(&pp->req_producer);      /* now incr producer index */
 
@@ -1090,7 +1251,7 @@ static int mv_qc_issue(struct ata_queued_cmd *qc)
  *
  *      This routine is for use when the port is in DMA mode, when it
  *      will be using the CRPB (command response block) method of
- *      returning command completion information.  We assert indices
+ *      returning command completion information.  We check indices
  *      are good, grab status, and bump the response consumer index to
  *      prove that we're up to date.
  *
@@ -1106,16 +1267,16 @@ static u8 mv_get_crpb_status(struct ata_port *ap)
        out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
 
        /* the response consumer index should be the same as we remember it */
-       assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
-              pp->rsp_consumer);
+       WARN_ON(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
+               pp->rsp_consumer);
 
        /* increment our consumer index... */
        pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer);
 
        /* and, until we do NCQ, there should only be 1 CRPB waiting */
-       assert(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >>
-                EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
-              pp->rsp_consumer);
+       WARN_ON(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >>
+                 EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
+               pp->rsp_consumer);
 
        /* write out our inc'd consumer index so EDMA knows we're caught up */
        out_ptr &= EDMA_RSP_Q_BASE_LO_MASK;
@@ -1192,7 +1353,6 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
        u32 hc_irq_cause;
        int shift, port, port0, hard_port, handled;
        unsigned int err_mask;
-       u8 ata_status = 0;
 
        if (hc == 0) {
                port0 = 0;
@@ -1210,6 +1370,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
                hc,relevant,hc_irq_cause);
 
        for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) {
+               u8 ata_status = 0;
                ap = host_set->ports[port];
                hard_port = port & MV_PORT_MASK;        /* range 0-3 */
                handled = 0;    /* ensure ata_status is set if handled++ */
@@ -1681,6 +1842,12 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
        m2 |= hpriv->signal[port].pre;
        m2 &= ~(1 << 16);
 
+       /* according to mvSata 3.6.1, some IIE values are fixed */
+       if (IS_GEN_IIE(hpriv)) {
+               m2 &= ~0xC30FF01F;
+               m2 |= 0x0000900F;
+       }
+
        writel(m2, port_mmio + PHY_MODE2);
 }
 
@@ -1846,7 +2013,6 @@ static void mv_phy_reset(struct ata_port *ap)
 static void mv_eng_timeout(struct ata_port *ap)
 {
        struct ata_queued_cmd *qc;
-       unsigned long flags;
 
        printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id);
        DPRINTK("All regs @ start of eng_timeout\n");
@@ -1861,22 +2027,8 @@ static void mv_eng_timeout(struct ata_port *ap)
        mv_err_intr(ap);
        mv_stop_and_reset(ap);
 
-       if (!qc) {
-               printk(KERN_ERR "ata%u: BUG: timeout without command\n",
-                      ap->id);
-       } else {
-               /* hack alert!  We cannot use the supplied completion
-                * function from inside the ->eh_strategy_handler() thread.
-                * libata is the only user of ->eh_strategy_handler() in
-                * any kernel, so the default scsi_done() assumes it is
-                * not being called from the SCSI EH.
-                */
-               spin_lock_irqsave(&ap->host_set->lock, flags);
-               qc->scsidone = scsi_finish_command;
-               qc->err_mask |= AC_ERR_OTHER;
-               ata_qc_complete(qc);
-               spin_unlock_irqrestore(&ap->host_set->lock, flags);
-       }
+       qc->err_mask |= AC_ERR_TIMEOUT;
+       ata_eh_qc_complete(qc);
 }
 
 /**
@@ -1995,6 +2147,27 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
                }
                break;
 
+       case chip_7042:
+       case chip_6042:
+               hpriv->ops = &mv6xxx_ops;
+
+               hp_flags |= MV_HP_GEN_IIE;
+
+               switch (rev_id) {
+               case 0x0:
+                       hp_flags |= MV_HP_ERRATA_XX42A0;
+                       break;
+               case 0x1:
+                       hp_flags |= MV_HP_ERRATA_60X1C0;
+                       break;
+               default:
+                       dev_printk(KERN_WARNING, &pdev->dev,
+                          "Applying 60X1C0 workarounds to unknown rev\n");
+                       hp_flags |= MV_HP_ERRATA_60X1C0;
+                       break;
+               }
+               break;
+
        default:
                printk(KERN_ERR DRV_NAME ": BUG: invalid board index %u\n", board_idx);
                return 1;
index bbbb55eeb73a521d52797bf9da858fbad7040911..caffadc2e0aed630b6ceeac6d3f6802c85cae33e 100644 (file)
@@ -229,11 +229,11 @@ static struct scsi_host_template nv_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
index b0b0a69b3563c67a896f83517ae3b609a30aa011..84cb3940ad8821a2f96aa861c131353472b7f72d 100644 (file)
@@ -46,7 +46,7 @@
 #include "sata_promise.h"
 
 #define DRV_NAME       "sata_promise"
-#define DRV_VERSION    "1.03"
+#define DRV_VERSION    "1.04"
 
 
 enum {
@@ -58,6 +58,7 @@ enum {
        PDC_GLOBAL_CTL          = 0x48, /* Global control/status (per port) */
        PDC_CTLSTAT             = 0x60, /* IDE control and status (per port) */
        PDC_SATA_PLUG_CSR       = 0x6C, /* SATA Plug control/status reg */
+       PDC2_SATA_PLUG_CSR      = 0x60, /* SATAII Plug control/status reg */
        PDC_SLEW_CTL            = 0x470, /* slew rate control reg */
 
        PDC_ERR_MASK            = (1<<19) | (1<<20) | (1<<21) | (1<<22) |
@@ -67,8 +68,10 @@ enum {
        board_20319             = 1,    /* FastTrak S150 TX4 */
        board_20619             = 2,    /* FastTrak TX4000 */
        board_20771             = 3,    /* FastTrak TX2300 */
+       board_2057x             = 4,    /* SATAII150 Tx2plus */
+       board_40518             = 5,    /* SATAII150 Tx4 */
 
-       PDC_HAS_PATA            = (1 << 1), /* PDC20375 has PATA */
+       PDC_HAS_PATA            = (1 << 1), /* PDC20375/20575 has PATA */
 
        PDC_RESET               = (1 << 11), /* HDMA reset */
 
@@ -82,6 +85,10 @@ struct pdc_port_priv {
        dma_addr_t              pkt_dma;
 };
 
+struct pdc_host_priv {
+       int                     hotplug_offset;
+};
+
 static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
@@ -95,7 +102,8 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc);
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
 static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
 static void pdc_irq_clear(struct ata_port *ap);
-static int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
+static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
+static void pdc_host_stop(struct ata_host_set *host_set);
 
 
 static struct scsi_host_template pdc_ata_sht = {
@@ -103,11 +111,11 @@ static struct scsi_host_template pdc_ata_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -137,7 +145,7 @@ static const struct ata_port_operations pdc_sata_ops = {
        .scr_write              = pdc_sata_scr_write,
        .port_start             = pdc_port_start,
        .port_stop              = pdc_port_stop,
-       .host_stop              = ata_pci_host_stop,
+       .host_stop              = pdc_host_stop,
 };
 
 static const struct ata_port_operations pdc_pata_ops = {
@@ -158,7 +166,7 @@ static const struct ata_port_operations pdc_pata_ops = {
 
        .port_start             = pdc_port_start,
        .port_stop              = pdc_port_stop,
-       .host_stop              = ata_pci_host_stop,
+       .host_stop              = pdc_host_stop,
 };
 
 static const struct ata_port_info pdc_port_info[] = {
@@ -201,6 +209,26 @@ static const struct ata_port_info pdc_port_info[] = {
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &pdc_sata_ops,
        },
+
+       /* board_2057x */
+       {
+               .sht            = &pdc_ata_sht,
+               .host_flags     = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .port_ops       = &pdc_sata_ops,
+       },
+
+       /* board_40518 */
+       {
+               .sht            = &pdc_ata_sht,
+               .host_flags     = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .port_ops       = &pdc_sata_ops,
+       },
 };
 
 static const struct pci_device_id pdc_ata_pci_tbl[] = {
@@ -217,9 +245,9 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = {
        { PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_2037x },
        { PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2037x },
+         board_2057x },
        { PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_2037x },
+         board_2057x },
        { PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_2037x },
 
@@ -227,12 +255,14 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = {
          board_20319 },
        { PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_20319 },
+       { PCI_VENDOR_ID_PROMISE, 0x3515, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+         board_20319 },
        { PCI_VENDOR_ID_PROMISE, 0x3519, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_20319 },
        { PCI_VENDOR_ID_PROMISE, 0x3d17, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_20319 },
        { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-         board_20319 },
+         board_40518 },
 
        { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
          board_20619 },
@@ -261,12 +291,11 @@ static int pdc_port_start(struct ata_port *ap)
        if (rc)
                return rc;
 
-       pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+       pp = kzalloc(sizeof(*pp), GFP_KERNEL);
        if (!pp) {
                rc = -ENOMEM;
                goto err_out;
        }
-       memset(pp, 0, sizeof(*pp));
 
        pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
        if (!pp->pkt) {
@@ -298,6 +327,16 @@ static void pdc_port_stop(struct ata_port *ap)
 }
 
 
+static void pdc_host_stop(struct ata_host_set *host_set)
+{
+       struct pdc_host_priv *hp = host_set->private_data;
+
+       ata_pci_host_stop(host_set);
+
+       kfree(hp);
+}
+
+
 static void pdc_reset_port(struct ata_port *ap)
 {
        void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT;
@@ -394,19 +433,6 @@ static void pdc_eng_timeout(struct ata_port *ap)
        spin_lock_irqsave(&host_set->lock, flags);
 
        qc = ata_qc_from_tag(ap, ap->active_tag);
-       if (!qc) {
-               printk(KERN_ERR "ata%u: BUG: timeout without command\n",
-                      ap->id);
-               goto out;
-       }
-
-       /* hack alert!  We cannot use the supplied completion
-        * function from inside the ->eh_strategy_handler() thread.
-        * libata is the only user of ->eh_strategy_handler() in
-        * any kernel, so the default scsi_done() assumes it is
-        * not being called from the SCSI EH.
-        */
-       qc->scsidone = scsi_finish_command;
 
        switch (qc->tf.protocol) {
        case ATA_PROT_DMA:
@@ -414,7 +440,6 @@ static void pdc_eng_timeout(struct ata_port *ap)
                printk(KERN_ERR "ata%u: command timeout\n", ap->id);
                drv_stat = ata_wait_idle(ap);
                qc->err_mask |= __ac_err_mask(drv_stat);
-               ata_qc_complete(qc);
                break;
 
        default:
@@ -424,12 +449,11 @@ static void pdc_eng_timeout(struct ata_port *ap)
                       ap->id, qc->tf.command, drv_stat);
 
                qc->err_mask |= ac_err_mask(drv_stat);
-               ata_qc_complete(qc);
                break;
        }
 
-out:
        spin_unlock_irqrestore(&host_set->lock, flags);
+       ata_eh_qc_complete(qc);
        DPRINTK("EXIT\n");
 }
 
@@ -495,14 +519,15 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
                VPRINTK("QUICK EXIT 2\n");
                return IRQ_NONE;
        }
+
+       spin_lock(&host_set->lock);
+
        mask &= 0xffff;         /* only 16 tags possible */
        if (!mask) {
                VPRINTK("QUICK EXIT 3\n");
-               return IRQ_NONE;
+               goto done_irq;
        }
 
-       spin_lock(&host_set->lock);
-
        writel(mask, mmio_base + PDC_INT_SEQMASK);
 
        for (i = 0; i < host_set->n_ports; i++) {
@@ -519,10 +544,10 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
                }
        }
 
-        spin_unlock(&host_set->lock);
-
        VPRINTK("EXIT\n");
 
+done_irq:
+       spin_unlock(&host_set->lock);
        return IRQ_RETVAL(handled);
 }
 
@@ -544,7 +569,7 @@ static inline void pdc_packet_start(struct ata_queued_cmd *qc)
        readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
 }
 
-static int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
 {
        switch (qc->tf.protocol) {
        case ATA_PROT_DMA:
@@ -600,6 +625,8 @@ static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
 static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
 {
        void __iomem *mmio = pe->mmio_base;
+       struct pdc_host_priv *hp = pe->private_data;
+       int hotplug_offset = hp->hotplug_offset;
        u32 tmp;
 
        /*
@@ -614,12 +641,12 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
        writel(tmp, mmio + PDC_FLASH_CTL);
 
        /* clear plug/unplug flags for all ports */
-       tmp = readl(mmio + PDC_SATA_PLUG_CSR);
-       writel(tmp | 0xff, mmio + PDC_SATA_PLUG_CSR);
+       tmp = readl(mmio + hotplug_offset);
+       writel(tmp | 0xff, mmio + hotplug_offset);
 
        /* mask plug/unplug ints */
-       tmp = readl(mmio + PDC_SATA_PLUG_CSR);
-       writel(tmp | 0xff0000, mmio + PDC_SATA_PLUG_CSR);
+       tmp = readl(mmio + hotplug_offset);
+       writel(tmp | 0xff0000, mmio + hotplug_offset);
 
        /* reduce TBG clock to 133 Mhz. */
        tmp = readl(mmio + PDC_TBG_MODE);
@@ -641,6 +668,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
 {
        static int printed_version;
        struct ata_probe_ent *probe_ent = NULL;
+       struct pdc_host_priv *hp;
        unsigned long base;
        void __iomem *mmio_base;
        unsigned int board_idx = (unsigned int) ent->driver_data;
@@ -671,13 +699,12 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        if (rc)
                goto err_out_regions;
 
-       probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+       probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
        if (probe_ent == NULL) {
                rc = -ENOMEM;
                goto err_out_regions;
        }
 
-       memset(probe_ent, 0, sizeof(*probe_ent));
        probe_ent->dev = pci_dev_to_dev(pdev);
        INIT_LIST_HEAD(&probe_ent->node);
 
@@ -688,6 +715,16 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        }
        base = (unsigned long) mmio_base;
 
+       hp = kzalloc(sizeof(*hp), GFP_KERNEL);
+       if (hp == NULL) {
+               rc = -ENOMEM;
+               goto err_out_free_ent;
+       }
+
+       /* Set default hotplug offset */
+       hp->hotplug_offset = PDC_SATA_PLUG_CSR;
+       probe_ent->private_data = hp;
+
        probe_ent->sht          = pdc_port_info[board_idx].sht;
        probe_ent->host_flags   = pdc_port_info[board_idx].host_flags;
        probe_ent->pio_mask     = pdc_port_info[board_idx].pio_mask;
@@ -707,6 +744,10 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
 
        /* notice 4-port boards */
        switch (board_idx) {
+       case board_40518:
+               /* Override hotplug offset for SATAII150 */
+               hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
+               /* Fall through */
        case board_20319:
                        probe_ent->n_ports = 4;
 
@@ -716,6 +757,10 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
                probe_ent->port[2].scr_addr = base + 0x600;
                probe_ent->port[3].scr_addr = base + 0x700;
                break;
+       case board_2057x:
+               /* Override hotplug offset for SATAII150 */
+               hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
+               /* Fall through */
        case board_2037x:
                probe_ent->n_ports = 2;
                break;
@@ -741,8 +786,10 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        /* initialize adapter */
        pdc_host_init(board_idx, probe_ent);
 
-       /* FIXME: check ata_device_add return value */
-       ata_device_add(probe_ent);
+       /* FIXME: Need any other frees than hp? */
+       if (!ata_device_add(probe_ent))
+               kfree(hp);
+
        kfree(probe_ent);
 
        return 0;
index 80480f0fb2b82abf2ebdcbe156abd994d9b9ff27..9602f43a298e1a2c7290e461ff00d7f6dcf479ef 100644 (file)
@@ -120,7 +120,7 @@ static void qs_host_stop(struct ata_host_set *host_set);
 static void qs_port_stop(struct ata_port *ap);
 static void qs_phy_reset(struct ata_port *ap);
 static void qs_qc_prep(struct ata_queued_cmd *qc);
-static int qs_qc_issue(struct ata_queued_cmd *qc);
+static unsigned int qs_qc_issue(struct ata_queued_cmd *qc);
 static int qs_check_atapi_dma(struct ata_queued_cmd *qc);
 static void qs_bmdma_stop(struct ata_queued_cmd *qc);
 static u8 qs_bmdma_status(struct ata_port *ap);
@@ -132,11 +132,11 @@ static struct scsi_host_template qs_ata_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = QS_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        //FIXME .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -276,8 +276,8 @@ static unsigned int qs_fill_sg(struct ata_queued_cmd *qc)
        unsigned int nelem;
        u8 *prd = pp->pkt + QS_CPB_BYTES;
 
-       assert(qc->__sg != NULL);
-       assert(qc->n_elem > 0 || qc->pad_len > 0);
+       WARN_ON(qc->__sg == NULL);
+       WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
 
        nelem = 0;
        ata_for_each_sg(sg, qc) {
@@ -352,7 +352,7 @@ static inline void qs_packet_start(struct ata_queued_cmd *qc)
        readl(chan + QS_CCT_CFF);          /* flush */
 }
 
-static int qs_qc_issue(struct ata_queued_cmd *qc)
+static unsigned int qs_qc_issue(struct ata_queued_cmd *qc)
 {
        struct qs_port_priv *pp = qc->ap->private_data;
 
index 9face3c6aa2144fccaaea7ef8d5754076201c0a0..4f2a67ed39d87bd765b3e69ddfbbe59a158ea909 100644 (file)
 #define DRV_VERSION    "0.9"
 
 enum {
+       /*
+        * host flags
+        */
        SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29),
        SIL_FLAG_MOD15WRITE     = (1 << 30),
+       SIL_DFL_HOST_FLAGS      = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO,
 
+       /*
+        * Controller IDs
+        */
        sil_3112                = 0,
-       sil_3112_m15w           = 1,
-       sil_3512                = 2,
-       sil_3114                = 3,
-
-       SIL_FIFO_R0             = 0x40,
-       SIL_FIFO_W0             = 0x41,
-       SIL_FIFO_R1             = 0x44,
-       SIL_FIFO_W1             = 0x45,
-       SIL_FIFO_R2             = 0x240,
-       SIL_FIFO_W2             = 0x241,
-       SIL_FIFO_R3             = 0x244,
-       SIL_FIFO_W3             = 0x245,
+       sil_3512                = 1,
+       sil_3114                = 2,
 
+       /*
+        * Register offsets
+        */
        SIL_SYSCFG              = 0x48,
+
+       /*
+        * Register bits
+        */
+       /* SYSCFG */
        SIL_MASK_IDE0_INT       = (1 << 22),
        SIL_MASK_IDE1_INT       = (1 << 23),
        SIL_MASK_IDE2_INT       = (1 << 24),
@@ -75,9 +81,12 @@ enum {
        SIL_MASK_4PORT          = SIL_MASK_2PORT |
                                  SIL_MASK_IDE2_INT | SIL_MASK_IDE3_INT,
 
-       SIL_IDE2_BMDMA          = 0x200,
-
+       /* BMDMA/BMDMA2 */
        SIL_INTR_STEERING       = (1 << 1),
+
+       /*
+        * Others
+        */
        SIL_QUIRK_MOD15WRITE    = (1 << 0),
        SIL_QUIRK_UDMA5MAX      = (1 << 1),
 };
@@ -90,13 +99,13 @@ static void sil_post_set_mode (struct ata_port *ap);
 
 
 static const struct pci_device_id sil_pci_tbl[] = {
-       { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
-       { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
+       { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+       { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
        { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 },
        { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
-       { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
-       { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
-       { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
+       { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+       { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+       { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
        { }     /* terminate list */
 };
 
@@ -137,11 +146,11 @@ static struct scsi_host_template sil_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -159,7 +168,7 @@ static const struct ata_port_operations sil_ops = {
        .check_status           = ata_check_status,
        .exec_command           = ata_exec_command,
        .dev_select             = ata_std_dev_select,
-       .phy_reset              = sata_phy_reset,
+       .probe_reset            = ata_std_probe_reset,
        .post_set_mode          = sil_post_set_mode,
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
@@ -181,19 +190,7 @@ static const struct ata_port_info sil_port_info[] = {
        /* sil_3112 */
        {
                .sht            = &sil_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SRST | ATA_FLAG_MMIO,
-               .pio_mask       = 0x1f,                 /* pio0-4 */
-               .mwdma_mask     = 0x07,                 /* mwdma0-2 */
-               .udma_mask      = 0x3f,                 /* udma0-5 */
-               .port_ops       = &sil_ops,
-       },
-       /* sil_3112_15w - keep it sync'd w/ sil_3112 */
-       {
-               .sht            = &sil_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SRST | ATA_FLAG_MMIO |
-                                 SIL_FLAG_MOD15WRITE,
+               .host_flags     = SIL_DFL_HOST_FLAGS | SIL_FLAG_MOD15WRITE,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
@@ -202,9 +199,7 @@ static const struct ata_port_info sil_port_info[] = {
        /* sil_3512 */
        {
                .sht            = &sil_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SRST | ATA_FLAG_MMIO |
-                                 SIL_FLAG_RERR_ON_DMA_ACT,
+               .host_flags     = SIL_DFL_HOST_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
@@ -213,9 +208,7 @@ static const struct ata_port_info sil_port_info[] = {
        /* sil_3114 */
        {
                .sht            = &sil_sht,
-               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SRST | ATA_FLAG_MMIO |
-                                 SIL_FLAG_RERR_ON_DMA_ACT,
+               .host_flags     = SIL_DFL_HOST_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
@@ -229,16 +222,17 @@ static const struct {
        unsigned long tf;       /* ATA taskfile register block */
        unsigned long ctl;      /* ATA control/altstatus register block */
        unsigned long bmdma;    /* DMA register block */
+       unsigned long fifo_cfg; /* FIFO Valid Byte Count and Control */
        unsigned long scr;      /* SATA control register block */
        unsigned long sien;     /* SATA Interrupt Enable register */
        unsigned long xfer_mode;/* data transfer mode register */
        unsigned long sfis_cfg; /* SATA FIS reception config register */
 } sil_port[] = {
        /* port 0 ... */
-       { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4, 0x14c },
-       { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4, 0x1cc },
-       { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4, 0x34c },
-       { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4, 0x3cc },
+       { 0x80, 0x8A, 0x00, 0x40, 0x100, 0x148, 0xb4, 0x14c },
+       { 0xC0, 0xCA, 0x08, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc },
+       { 0x280, 0x28A, 0x200, 0x240, 0x300, 0x348, 0x2b4, 0x34c },
+       { 0x2C0, 0x2CA, 0x208, 0x244, 0x380, 0x3c8, 0x2f4, 0x3cc },
        /* ... port 3 */
 };
 
@@ -354,22 +348,12 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
 static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
 {
        unsigned int n, quirks = 0;
-       unsigned char model_num[40];
-       const char *s;
-       unsigned int len;
+       unsigned char model_num[41];
 
-       ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
-                         sizeof(model_num));
-       s = &model_num[0];
-       len = strnlen(s, sizeof(model_num));
-
-       /* ATAPI specifies that empty space is blank-filled; remove blanks */
-       while ((len > 0) && (s[len - 1] == ' '))
-               len--;
+       ata_id_c_string(dev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
 
        for (n = 0; sil_blacklist[n].product; n++)
-               if (!memcmp(sil_blacklist[n].product, s,
-                           strlen(sil_blacklist[n].product))) {
+               if (!strcmp(sil_blacklist[n].product, model_num)) {
                        quirks = sil_blacklist[n].quirk;
                        break;
                }
@@ -380,16 +364,14 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
             (quirks & SIL_QUIRK_MOD15WRITE))) {
                printk(KERN_INFO "ata%u(%u): applying Seagate errata fix (mod15write workaround)\n",
                       ap->id, dev->devno);
-               ap->host->max_sectors = 15;
-               ap->host->hostt->max_sectors = 15;
-               dev->flags |= ATA_DFLAG_LOCK_SECTORS;
+               dev->max_sectors = 15;
                return;
        }
 
        /* limit to udma5 */
        if (quirks & SIL_QUIRK_UDMA5MAX) {
                printk(KERN_INFO "ata%u(%u): applying Maxtor errata fix %s\n",
-                      ap->id, dev->devno, s);
+                      ap->id, dev->devno, model_num);
                ap->udma_mask &= ATA_UDMA5;
                return;
        }
@@ -431,13 +413,12 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                goto err_out_regions;
 
-       probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+       probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
        if (probe_ent == NULL) {
                rc = -ENOMEM;
                goto err_out_regions;
        }
 
-       memset(probe_ent, 0, sizeof(*probe_ent));
        INIT_LIST_HEAD(&probe_ent->node);
        probe_ent->dev = pci_dev_to_dev(pdev);
        probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops;
@@ -474,19 +455,12 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (cls) {
                cls >>= 3;
                cls++;  /* cls = (line_size/8)+1 */
-               writeb(cls, mmio_base + SIL_FIFO_R0);
-               writeb(cls, mmio_base + SIL_FIFO_W0);
-               writeb(cls, mmio_base + SIL_FIFO_R1);
-               writeb(cls, mmio_base + SIL_FIFO_W1);
-               if (ent->driver_data == sil_3114) {
-                       writeb(cls, mmio_base + SIL_FIFO_R2);
-                       writeb(cls, mmio_base + SIL_FIFO_W2);
-                       writeb(cls, mmio_base + SIL_FIFO_R3);
-                       writeb(cls, mmio_base + SIL_FIFO_W3);
-               }
+               for (i = 0; i < probe_ent->n_ports; i++)
+                       writew(cls << 8 | cls,
+                              mmio_base + sil_port[i].fifo_cfg);
        } else
                dev_printk(KERN_WARNING, &pdev->dev,
-                        "cache line size not set.  Driver may not function\n");
+                          "cache line size not set.  Driver may not function\n");
 
        /* Apply R_ERR on DMA activate FIS errata workaround */
        if (probe_ent->host_flags & SIL_FLAG_RERR_ON_DMA_ACT) {
@@ -509,10 +483,10 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                irq_mask = SIL_MASK_4PORT;
 
                /* flip the magic "make 4 ports work" bit */
-               tmp = readl(mmio_base + SIL_IDE2_BMDMA);
+               tmp = readl(mmio_base + sil_port[2].bmdma);
                if ((tmp & SIL_INTR_STEERING) == 0)
                        writel(tmp | SIL_INTR_STEERING,
-                              mmio_base + SIL_IDE2_BMDMA);
+                              mmio_base + sil_port[2].bmdma);
 
        } else {
                irq_mask = SIL_MASK_2PORT;
index 923130185a9e417c4570c04fe88298ce265fe102..9a53a5ed38c5ae10ce28e59c1bd729c4b94c5731 100644 (file)
@@ -249,9 +249,9 @@ static u8 sil24_check_status(struct ata_port *ap);
 static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
 static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
 static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
-static void sil24_phy_reset(struct ata_port *ap);
+static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes);
 static void sil24_qc_prep(struct ata_queued_cmd *qc);
-static int sil24_qc_issue(struct ata_queued_cmd *qc);
+static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
 static void sil24_irq_clear(struct ata_port *ap);
 static void sil24_eng_timeout(struct ata_port *ap);
 static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
@@ -262,6 +262,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 static const struct pci_device_id sil24_pci_tbl[] = {
        { 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
+       { 0x8086, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
        { 0x1095, 0x3132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3132 },
        { 0x1095, 0x3131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
        { 0x1095, 0x3531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
@@ -280,11 +281,11 @@ static struct scsi_host_template sil24_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -305,7 +306,7 @@ static const struct ata_port_operations sil24_ops = {
 
        .tf_read                = sil24_tf_read,
 
-       .phy_reset              = sil24_phy_reset,
+       .probe_reset            = sil24_probe_reset,
 
        .qc_prep                = sil24_qc_prep,
        .qc_issue               = sil24_qc_issue,
@@ -335,8 +336,8 @@ static struct ata_port_info sil24_port_info[] = {
        {
                .sht            = &sil24_sht,
                .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SRST | ATA_FLAG_MMIO |
-                                 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),
+                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+                                 SIL24_NPORTS2FLAG(4),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
@@ -346,8 +347,8 @@ static struct ata_port_info sil24_port_info[] = {
        {
                .sht            = &sil24_sht,
                .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SRST | ATA_FLAG_MMIO |
-                                 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),
+                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+                                 SIL24_NPORTS2FLAG(2),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
@@ -357,8 +358,8 @@ static struct ata_port_info sil24_port_info[] = {
        {
                .sht            = &sil24_sht,
                .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SRST | ATA_FLAG_MMIO |
-                                 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),
+                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+                                 SIL24_NPORTS2FLAG(1),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
@@ -370,7 +371,7 @@ static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
 {
        void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
 
-       if (ap->cdb_len == 16)
+       if (dev->cdb_len == 16)
                writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
        else
                writel(PORT_CS_CDB16, port + PORT_CTRL_CLR);
@@ -427,14 +428,23 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
        *tf = pp->tf;
 }
 
-static int sil24_issue_SRST(struct ata_port *ap)
+static int sil24_softreset(struct ata_port *ap, int verbose,
+                          unsigned int *class)
 {
        void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
        struct sil24_port_priv *pp = ap->private_data;
        struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
        dma_addr_t paddr = pp->cmd_block_dma;
+       unsigned long timeout = jiffies + ATA_TMOUT_BOOT * HZ;
        u32 irq_enable, irq_stat;
-       int cnt;
+
+       DPRINTK("ENTER\n");
+
+       if (!sata_dev_present(ap)) {
+               DPRINTK("PHY reports no device\n");
+               *class = ATA_DEV_NONE;
+               goto out;
+       }
 
        /* temporarily turn off IRQs during SRST */
        irq_enable = readl(port + PORT_IRQ_ENABLE_SET);
@@ -451,7 +461,7 @@ static int sil24_issue_SRST(struct ata_port *ap)
 
        writel((u32)paddr, port + PORT_CMD_ACTIVATE);
 
-       for (cnt = 0; cnt < 100; cnt++) {
+       do {
                irq_stat = readl(port + PORT_IRQ_STAT);
                writel(irq_stat, port + PORT_IRQ_STAT);         /* clear irq */
 
@@ -459,36 +469,42 @@ static int sil24_issue_SRST(struct ata_port *ap)
                if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR))
                        break;
 
-               msleep(1);
-       }
+               msleep(100);
+       } while (time_before(jiffies, timeout));
 
        /* restore IRQs */
        writel(irq_enable, port + PORT_IRQ_ENABLE_SET);
 
-       if (!(irq_stat & PORT_IRQ_COMPLETE))
-               return -1;
+       if (!(irq_stat & PORT_IRQ_COMPLETE)) {
+               DPRINTK("EXIT, srst failed\n");
+               return -EIO;
+       }
 
-       /* update TF */
        sil24_update_tf(ap);
+       *class = ata_dev_classify(&pp->tf);
+
+       if (*class == ATA_DEV_UNKNOWN)
+               *class = ATA_DEV_NONE;
+
+ out:
+       DPRINTK("EXIT, class=%u\n", *class);
        return 0;
 }
 
-static void sil24_phy_reset(struct ata_port *ap)
+static int sil24_hardreset(struct ata_port *ap, int verbose,
+                          unsigned int *class)
 {
-       struct sil24_port_priv *pp = ap->private_data;
+       unsigned int dummy_class;
 
-       __sata_phy_reset(ap);
-       if (ap->flags & ATA_FLAG_PORT_DISABLED)
-               return;
-
-       if (sil24_issue_SRST(ap) < 0) {
-               printk(KERN_ERR DRV_NAME
-                      " ata%u: SRST failed, disabling port\n", ap->id);
-               ap->ops->port_disable(ap);
-               return;
-       }
+       /* sil24 doesn't report device signature after hard reset */
+       return sata_std_hardreset(ap, verbose, &dummy_class);
+}
 
-       ap->device->class = ata_dev_classify(&pp->tf);
+static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes)
+{
+       return ata_drive_probe_reset(ap, ata_std_probeinit,
+                                    sil24_softreset, sil24_hardreset,
+                                    ata_std_postreset, classes);
 }
 
 static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
@@ -533,7 +549,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
                prb = &cb->atapi.prb;
                sge = cb->atapi.sge;
                memset(cb->atapi.cdb, 0, 32);
-               memcpy(cb->atapi.cdb, qc->cdb, ap->cdb_len);
+               memcpy(cb->atapi.cdb, qc->cdb, qc->dev->cdb_len);
 
                if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) {
                        if (qc->tf.flags & ATA_TFLAG_WRITE)
@@ -557,7 +573,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
                sil24_fill_sg(qc, sge);
 }
 
-static int sil24_qc_issue(struct ata_queued_cmd *qc)
+static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
@@ -638,23 +654,10 @@ static void sil24_eng_timeout(struct ata_port *ap)
        struct ata_queued_cmd *qc;
 
        qc = ata_qc_from_tag(ap, ap->active_tag);
-       if (!qc) {
-               printk(KERN_ERR "ata%u: BUG: timeout without command\n",
-                      ap->id);
-               return;
-       }
 
-       /*
-        * hack alert!  We cannot use the supplied completion
-        * function from inside the ->eh_strategy_handler() thread.
-        * libata is the only user of ->eh_strategy_handler() in
-        * any kernel, so the default scsi_done() assumes it is
-        * not being called from the SCSI EH.
-        */
        printk(KERN_ERR "ata%u: command timeout\n", ap->id);
-       qc->scsidone = scsi_finish_command;
-       qc->err_mask |= AC_ERR_OTHER;
-       ata_qc_complete(qc);
+       qc->err_mask |= AC_ERR_TIMEOUT;
+       ata_eh_qc_complete(qc);
 
        sil24_reset_controller(ap);
 }
@@ -895,6 +898,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        probe_ent->sht          = pinfo->sht;
        probe_ent->host_flags   = pinfo->host_flags;
        probe_ent->pio_mask     = pinfo->pio_mask;
+       probe_ent->mwdma_mask   = pinfo->mwdma_mask;
        probe_ent->udma_mask    = pinfo->udma_mask;
        probe_ent->port_ops     = pinfo->port_ops;
        probe_ent->n_ports      = SIL24_FLAG2NPORTS(pinfo->host_flags);
index 2df8c5632ac367a6e7b022efa0facb6874a5bb91..7fd45f86de99b575f4a863837b2aaca9c882ee9b 100644 (file)
@@ -87,11 +87,11 @@ static struct scsi_host_template sis_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = ATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
index d8472563fde860cc0789f982bc896ab9104ba38e..4aaccd53e7367efc5069cec701f7c4da39df3be0 100644 (file)
@@ -288,11 +288,11 @@ static struct scsi_host_template k2_sata_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
index bc87c16c80d2b2377a6ff1ddabaf396d84d428f4..9f8a76815402bd831717ec7f4b8b6da944f456c8 100644 (file)
@@ -174,7 +174,7 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe,
 static void pdc20621_put_to_dimm(struct ata_probe_ent *pe,
                                 void *psource, u32 offset, u32 size);
 static void pdc20621_irq_clear(struct ata_port *ap);
-static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
+static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
 
 
 static struct scsi_host_template pdc_sata_sht = {
@@ -182,11 +182,11 @@ static struct scsi_host_template pdc_sata_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -460,7 +460,7 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
        unsigned int i, idx, total_len = 0, sgt_len;
        u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
 
-       assert(qc->flags & ATA_QCFLAG_DMAMAP);
+       WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP));
 
        VPRINTK("ata%u: ENTER\n", ap->id);
 
@@ -678,7 +678,7 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc)
        }
 }
 
-static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc)
 {
        switch (qc->tf.protocol) {
        case ATA_PROT_DMA:
@@ -866,26 +866,12 @@ static void pdc_eng_timeout(struct ata_port *ap)
        spin_lock_irqsave(&host_set->lock, flags);
 
        qc = ata_qc_from_tag(ap, ap->active_tag);
-       if (!qc) {
-               printk(KERN_ERR "ata%u: BUG: timeout without command\n",
-                      ap->id);
-               goto out;
-       }
-
-       /* hack alert!  We cannot use the supplied completion
-        * function from inside the ->eh_strategy_handler() thread.
-        * libata is the only user of ->eh_strategy_handler() in
-        * any kernel, so the default scsi_done() assumes it is
-        * not being called from the SCSI EH.
-        */
-       qc->scsidone = scsi_finish_command;
 
        switch (qc->tf.protocol) {
        case ATA_PROT_DMA:
        case ATA_PROT_NODATA:
                printk(KERN_ERR "ata%u: command timeout\n", ap->id);
                qc->err_mask |= __ac_err_mask(ata_wait_idle(ap));
-               ata_qc_complete(qc);
                break;
 
        default:
@@ -895,12 +881,11 @@ static void pdc_eng_timeout(struct ata_port *ap)
                       ap->id, qc->tf.command, drv_stat);
 
                qc->err_mask |= ac_err_mask(drv_stat);
-               ata_qc_complete(qc);
                break;
        }
 
-out:
        spin_unlock_irqrestore(&host_set->lock, flags);
+       ata_eh_qc_complete(qc);
        DPRINTK("EXIT\n");
 }
 
index 9635ca7009770b823adbc79f0fa944acf70f0186..37a487b7d655a1696a4ef2c74b011db3c16d0454 100644 (file)
@@ -75,11 +75,11 @@ static struct scsi_host_template uli_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
index 6d5b0a794cfdf056e9abcf4272cca7709b9cba2a..ff65a0b0457fa8cc914332d5392e81eef7037d63 100644 (file)
@@ -94,11 +94,11 @@ static struct scsi_host_template svia_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
index e484e8db68105f346ad38aa49247334caf5eb6d3..b574379a7a82168542cbd6914dea268148c4fd76 100644 (file)
@@ -251,11 +251,11 @@ static struct scsi_host_template vsc_sata_sht = {
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
        .sg_tablesize           = LIBATA_MAX_PRD,
-       .max_sectors            = ATA_MAX_SECTORS,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
index ff82ccfbb106b528539e112168a1aba8d250294c..5d169a2881b98dd2accf752cc784551c7f598473 100644 (file)
@@ -584,8 +584,7 @@ static int scsi_request_sense(struct scsi_cmnd *scmd)
  *    keep a list of pending commands for final completion, and once we
  *    are ready to leave error handling we handle completion for real.
  **/
-static void scsi_eh_finish_cmd(struct scsi_cmnd *scmd,
-                              struct list_head *done_q)
+void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
 {
        scmd->device->host->host_failed--;
        scmd->eh_eflags = 0;
@@ -597,6 +596,7 @@ static void scsi_eh_finish_cmd(struct scsi_cmnd *scmd,
        scsi_setup_cmd_retry(scmd);
        list_move_tail(&scmd->eh_entry, done_q);
 }
+EXPORT_SYMBOL(scsi_eh_finish_cmd);
 
 /**
  * scsi_eh_get_sense - Get device sense data.
@@ -1425,7 +1425,7 @@ static void scsi_eh_ready_devs(struct Scsi_Host *shost,
  * @done_q:    list_head of processed commands.
  *
  **/
-static void scsi_eh_flush_done_q(struct list_head *done_q)
+void scsi_eh_flush_done_q(struct list_head *done_q)
 {
        struct scsi_cmnd *scmd, *next;
 
@@ -1454,6 +1454,7 @@ static void scsi_eh_flush_done_q(struct list_head *done_q)
                }
        }
 }
+EXPORT_SYMBOL(scsi_eh_flush_done_q);
 
 /**
  * scsi_unjam_host - Attempt to fix a host which has a cmd that failed.
index 7410e093a6b9ffa733a4629c947c4d7324ecdcc7..00d7c0ad8cbfee7057dd2fed82ac91db5c9c81da 100644 (file)
@@ -1066,6 +1066,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
        port->mapbase   = res->start;
        port->membase   = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART);
        port->irq       = platform_get_irq(platdev, 0);
+       if (port->irq < 0)
+               port->irq = 0;
 
        ourport->clk    = clk_get(&platdev->dev, "uart");
 
index dce9d987f0fc474a3c0d59a1ccc4daf4def4c933..c196f38453056b54eee53634faafa3345b197552 100644 (file)
@@ -378,7 +378,7 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface,
 
        return NULL;
 }
-EXPORT_SYMBOL(usb_match_id);
+EXPORT_SYMBOL_GPL_FUTURE(usb_match_id);
 
 int usb_device_match(struct device *dev, struct device_driver *drv)
 {
@@ -446,7 +446,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner)
 
        return retval;
 }
-EXPORT_SYMBOL(usb_register_driver);
+EXPORT_SYMBOL_GPL_FUTURE(usb_register_driver);
 
 /**
  * usb_deregister - unregister a USB driver
@@ -469,4 +469,4 @@ void usb_deregister(struct usb_driver *driver)
 
        usbfs_update_special();
 }
-EXPORT_SYMBOL(usb_deregister);
+EXPORT_SYMBOL_GPL_FUTURE(usb_deregister);
index 3785b3f7df1be4e1c2cb0d95769f21ce4c04720a..ca19abe01c5331437bfb9e25e9324f05686ab964 100644 (file)
@@ -286,7 +286,7 @@ void usb_hcd_omap_remove (struct usb_hcd *, struct platform_device *);
 int usb_hcd_omap_probe (const struct hc_driver *driver,
                          struct platform_device *pdev)
 {
-       int retval;
+       int retval, irq;
        struct usb_hcd *hcd = 0;
        struct ohci_hcd *ohci;
 
@@ -329,7 +329,12 @@ int usb_hcd_omap_probe (const struct hc_driver *driver,
        if (retval < 0)
                goto err2;
 
-       retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), SA_INTERRUPT);
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               retval = -ENXIO;
+               goto err2;
+       }
+       retval = usb_add_hcd(hcd, irq, SA_INTERRUPT);
        if (retval == 0)
                return retval;
 
index f5079c78ba4e0ed51829bf4b2cc669e3c1cb4cd2..fdebd60a3250a68213f68a41ee451693351d2af1 100644 (file)
@@ -899,8 +899,6 @@ config FB_RADEON_OLD
          Choose this option if you want to use an ATI Radeon graphics card as
          a framebuffer device.  There are both PCI and AGP versions.  You
          don't need to choose this to run the Radeon in plain VGA mode.
-         There is a product page at
-         <http://www.ati.com/na/pages/products/pc/radeon32/index.html>.
 
 config FB_RADEON
        tristate "ATI Radeon display support"
index 3b0e71383448a426dc979a008502d04f2dfacb6d..082759447bf6d16ab9c881fee230f66b9841e7ea 100644 (file)
@@ -607,6 +607,7 @@ static void clearfb16(struct fb_info *info)
 
 static void epson1355fb_platform_release(struct device *device)
 {
+       dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n");
 }
 
 static int epson1355fb_remove(struct platform_device *dev)
index 8a893ce7040de1feae90633d46c5800c95357ef1..d9831fd4234184c92a0a4468839eb2612cec5388 100644 (file)
@@ -1457,7 +1457,7 @@ static int __init sa1100fb_probe(struct platform_device *pdev)
        int ret, irq;
 
        irq = platform_get_irq(pdev, 0);
-       if (irq <= 0)
+       if (irq < 0)
                return -EINVAL;
 
        if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
index 53208cb58396a8a1a047232f3de9c7ef7dd57f12..77eed1fd994366d4140ae74d319eee2a94fe396d 100644 (file)
@@ -401,6 +401,7 @@ static int __init vfb_setup(char *options)
 static void vfb_platform_release(struct device *device)
 {
        // This is called when the reference count goes to zero.
+       dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n");
 }
 
 static int __init vfb_probe(struct platform_device *dev)
index 21195c481637658ad4e676ba35c204da83d53d57..5c36345c9bf78376b6996604d98aba2679d6ed09 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kobject.h>
 #include <linux/kobj_map.h>
 #include <linux/cdev.h>
+#include <linux/mutex.h>
 
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
@@ -28,7 +29,7 @@ static struct kobj_map *cdev_map;
 
 #define MAX_PROBE_HASH 255     /* random */
 
-static DECLARE_MUTEX(chrdevs_lock);
+static DEFINE_MUTEX(chrdevs_lock);
 
 static struct char_device_struct {
        struct char_device_struct *next;
@@ -88,13 +89,13 @@ out:
 
 void *acquire_chrdev_list(void)
 {
-       down(&chrdevs_lock);
+       mutex_lock(&chrdevs_lock);
        return get_next_chrdev(NULL);
 }
 
 void release_chrdev_list(void *dev)
 {
-       up(&chrdevs_lock);
+       mutex_unlock(&chrdevs_lock);
        kfree(dev);
 }
 
@@ -151,7 +152,7 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
 
        memset(cd, 0, sizeof(struct char_device_struct));
 
-       down(&chrdevs_lock);
+       mutex_lock(&chrdevs_lock);
 
        /* temporary */
        if (major == 0) {
@@ -186,10 +187,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
        }
        cd->next = *cp;
        *cp = cd;
-       up(&chrdevs_lock);
+       mutex_unlock(&chrdevs_lock);
        return cd;
 out:
-       up(&chrdevs_lock);
+       mutex_unlock(&chrdevs_lock);
        kfree(cd);
        return ERR_PTR(ret);
 }
@@ -200,7 +201,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
        struct char_device_struct *cd = NULL, **cp;
        int i = major_to_index(major);
 
-       down(&chrdevs_lock);
+       mutex_lock(&chrdevs_lock);
        for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
                if ((*cp)->major == major &&
                    (*cp)->baseminor == baseminor &&
@@ -210,7 +211,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
                cd = *cp;
                *cp = cd->next;
        }
-       up(&chrdevs_lock);
+       mutex_unlock(&chrdevs_lock);
        return cd;
 }
 
index d575452cd9f758d510891b2b9e109c89c6332764..40c4fc973fad3125e3732b92c755f985a198a3dd 100644 (file)
@@ -251,3 +251,49 @@ struct dentry *debugfs_create_bool(const char *name, mode_t mode,
 }
 EXPORT_SYMBOL_GPL(debugfs_create_bool);
 
+static ssize_t read_file_blob(struct file *file, char __user *user_buf,
+                             size_t count, loff_t *ppos)
+{
+       struct debugfs_blob_wrapper *blob = file->private_data;
+       return simple_read_from_buffer(user_buf, count, ppos, blob->data,
+                       blob->size);
+}
+
+static struct file_operations fops_blob = {
+       .read =         read_file_blob,
+       .open =         default_open,
+};
+
+/**
+ * debugfs_create_blob - create a file in the debugfs filesystem that is
+ * used to read and write a binary blob.
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this paramater is NULL, then the
+ *          file will be created in the root of the debugfs filesystem.
+ * @blob: a pointer to a struct debugfs_blob_wrapper which contains a pointer
+ *        to the blob data and the size of the data.
+ *
+ * This function creates a file in debugfs with the given name that exports
+ * @blob->data as a binary blob. If the @mode variable is so set it can be
+ * read from. Writing is not supported.
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.)  If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned.  It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_blob(const char *name, mode_t mode,
+                                  struct dentry *parent,
+                                  struct debugfs_blob_wrapper *blob)
+{
+       return debugfs_create_file(name, mode, parent, blob, &fops_blob);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_blob);
index 49bd219275db30d6616a05ff8509045f88a39ec5..9ee956864445e54025343eab41b9ed5da4dc8665 100644 (file)
@@ -50,6 +50,32 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
        return sd;
 }
 
+/**
+ *
+ * Return -EEXIST if there is already a sysfs element with the same name for
+ * the same parent.
+ *
+ * called with parent inode's i_mutex held
+ */
+int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
+                         const unsigned char *new)
+{
+       struct sysfs_dirent * sd;
+
+       list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
+               if (sd->s_element) {
+                       const unsigned char *existing = sysfs_get_name(sd);
+                       if (strcmp(existing, new))
+                               continue;
+                       else
+                               return -EEXIST;
+               }
+       }
+
+       return 0;
+}
+
+
 int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
                        void * element, umode_t mode, int type)
 {
@@ -102,7 +128,11 @@ static int create_dir(struct kobject * k, struct dentry * p,
        mutex_lock(&p->d_inode->i_mutex);
        *d = lookup_one_len(n, p, strlen(n));
        if (!IS_ERR(*d)) {
-               error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR);
+               if (sysfs_dirent_exist(p->d_fsdata, n))
+                       error = -EEXIST;
+               else
+                       error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
+                                                               SYSFS_DIR);
                if (!error) {
                        error = sysfs_create(*d, mode, init_dir);
                        if (!error) {
@@ -302,6 +332,7 @@ void sysfs_remove_dir(struct kobject * kobj)
         * Drop reference from dget() on entrance.
         */
        dput(dentry);
+       kobj->dentry = NULL;
 }
 
 int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
@@ -479,7 +510,3 @@ struct file_operations sysfs_dir_operations = {
        .read           = generic_read_dir,
        .readdir        = sysfs_readdir,
 };
-
-EXPORT_SYMBOL_GPL(sysfs_create_dir);
-EXPORT_SYMBOL_GPL(sysfs_remove_dir);
-EXPORT_SYMBOL_GPL(sysfs_rename_dir);
index d0e3d8495165205079ad8acef894744b517cfa18..5e83e72467885a90fb88efeaf78601e70da2027f 100644 (file)
@@ -301,9 +301,8 @@ static int check_perm(struct inode * inode, struct file * file)
        /* No error? Great, allocate a buffer for the file, and store it
         * it in file->private_data for easy access.
         */
-       buffer = kmalloc(sizeof(struct sysfs_buffer),GFP_KERNEL);
+       buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
        if (buffer) {
-               memset(buffer,0,sizeof(struct sysfs_buffer));
                init_MUTEX(&buffer->sem);
                buffer->needs_read_fill = 1;
                buffer->ops = ops;
@@ -362,10 +361,12 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
 {
        struct sysfs_dirent * parent_sd = dir->d_fsdata;
        umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;
-       int error = 0;
+       int error = -EEXIST;
 
        mutex_lock(&dir->d_inode->i_mutex);
-       error = sysfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type);
+       if (!sysfs_dirent_exist(parent_sd, attr->name))
+               error = sysfs_make_dirent(parent_sd, NULL, (void *)attr,
+                                         mode, type);
        mutex_unlock(&dir->d_inode->i_mutex);
 
        return error;
index 689f7bcfaf3043b5585853f33589d59a77398008..4c29ac41ac3ec050f9f680118df5ab5aadf5a12a 100644 (file)
@@ -54,11 +54,10 @@ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
 
        if (!sd_iattr) {
                /* setting attributes for the first time, allocate now */
-               sd_iattr = kmalloc(sizeof(struct iattr), GFP_KERNEL);
+               sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
                if (!sd_iattr)
                        return -ENOMEM;
                /* assign default attributes */
-               memset(sd_iattr, 0, sizeof(struct iattr));
                sd_iattr->ia_mode = sd->s_mode;
                sd_iattr->ia_uid = 0;
                sd_iattr->ia_gid = 0;
@@ -227,12 +226,16 @@ void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
 void sysfs_hash_and_remove(struct dentry * dir, const char * name)
 {
        struct sysfs_dirent * sd;
-       struct sysfs_dirent * parent_sd = dir->d_fsdata;
+       struct sysfs_dirent * parent_sd;
+
+       if (!dir)
+               return;
 
        if (dir->d_inode == NULL)
                /* no inode means this hasn't been made visible yet */
                return;
 
+       parent_sd = dir->d_fsdata;
        mutex_lock(&dir->d_inode->i_mutex);
        list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
                if (!sd->s_element)
index e38d6338a20ddbdb27b9f0a0bd32c105c257d453..d2eac3ceed5f31cf9735a68ecc69dc4a6c6771ed 100644 (file)
@@ -66,6 +66,7 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj
        if (!error)
                return 0;
 
+       kobject_put(target);
        kfree(sl->link_name);
 exit2:
        kfree(sl);
@@ -82,12 +83,13 @@ exit1:
 int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
 {
        struct dentry * dentry = kobj->dentry;
-       int error = 0;
+       int error = -EEXIST;
 
        BUG_ON(!kobj || !kobj->dentry || !name);
 
        mutex_lock(&dentry->d_inode->i_mutex);
-       error = sysfs_add_link(dentry, name, target);
+       if (!sysfs_dirent_exist(dentry->d_fsdata, name))
+               error = sysfs_add_link(dentry, name, target);
        mutex_unlock(&dentry->d_inode->i_mutex);
        return error;
 }
index 3f8953e0e5d0021c93c31d7ddb0061b1adbb07ec..cf11d5b789d9ac2485bcb6693e3d1cbbd2d1aec6 100644 (file)
@@ -5,6 +5,7 @@ extern kmem_cache_t *sysfs_dir_cachep;
 extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
 extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
 
+extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
 extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
                                umode_t, int);
 
index 7772432d3fd7750506943eaf88ea7eda9e720a7d..60b5105c9c9325f00e6e9bcfad0cbc41a2087fa1 100644 (file)
@@ -27,7 +27,7 @@ extern void enable_irq(unsigned int);
 
 /*
  * These correspond with the SA_TRIGGER_* defines, and therefore the
- * IRQRESOURCE_IRQ_* defines.
+ * IORESOURCE_IRQ_* defines.
  */
 #define __IRQT_RISEDGE (1 << 0)
 #define __IRQT_FALEDGE (1 << 1)
index 35de20cf8facae16f267123d7958b6be22464ce6..9d11550b481810e6f459598dcac969187c1f6a4b 100644 (file)
                VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;               \
        }                                                               \
                                                                        \
+       /* Kernel symbol table: GPL-future-only symbols */              \
+       __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
+               VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .;       \
+               *(__ksymtab_gpl_future)                                 \
+               VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .;        \
+       }                                                               \
+                                                                       \
        /* Kernel symbol table: Normal symbols */                       \
        __kcrctab         : AT(ADDR(__kcrctab) - LOAD_OFFSET) {         \
                VMLINUX_SYMBOL(__start___kcrctab) = .;                  \
                VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .;               \
        }                                                               \
                                                                        \
+       /* Kernel symbol table: GPL-future-only symbols */              \
+       __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \
+               VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .;       \
+               *(__kcrctab_gpl_future)                                 \
+               VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .;        \
+       }                                                               \
+                                                                       \
        /* Kernel symbol table: strings */                              \
         __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {        \
                *(__ksymtab_strings)                                    \
index 584f8128fffdb580f9973a72590c09c48c59c0cc..aefc02f16fd84319c3cdd46ced02e60569edc8e5 100644 (file)
@@ -39,6 +39,24 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
 }
 #define __arch__swab32(x)      ___arch__swab32(x)
 
+#ifdef CONFIG_CPU_MIPS64_R2
+
+static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x)
+{
+       __asm__(
+       "       dsbh    %0, %1                  \n"
+       "       dshd    %0, %0                  \n"
+       "       drotr   %0, %0, 32              \n"
+       : "=r" (x)
+       : "r" (x));
+
+       return x;
+}
+
+#define __arch__swab64(x)      ___arch__swab64(x)
+
+#endif /* CONFIG_CPU_MIPS64_R2 */
+
 #endif /* CONFIG_CPU_MIPSR2 */
 
 #if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
index 35d2604fe69cd8dc18dfdb6181292e354d023c90..0012bd804d2dd02c0edeac13be81d4f497355e6d 100644 (file)
@@ -128,17 +128,17 @@ typedef u32               compat_sigset_word;
  */
 typedef u32            compat_uptr_t;
 
-static inline void *compat_ptr(compat_uptr_t uptr)
+static inline void __user *compat_ptr(compat_uptr_t uptr)
 {
-       return (void *)(long)uptr;
+       return (void __user *)(long)uptr;
 }
 
-static inline void *compat_alloc_user_space(long len)
+static inline void __user *compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = (struct pt_regs *)
                ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1;
 
-       return (void *) (regs->regs[29] - len);
+       return (void __user *) (regs->regs[29] - len);
 }
 #if defined (__MIPSEL__)
 #define __COMPAT_ENDIAN_SWAP__         1
index ba1d7bbc15d2e437553e2df6c818ed77a85ea0d4..546a17e56a9bf6d56e23581d79627e3bef589852 100644 (file)
  * hardware.  An example use would be for flash memory that's used for
  * execute in place.
  */
-# define __raw_ioswabb(x)      (x)
-# define __raw_ioswabw(x)      (x)
-# define __raw_ioswabl(x)      (x)
-# define __raw_ioswabq(x)      (x)
-# define ____raw_ioswabq(x)    (x)
+# define __raw_ioswabb(a,x)    (x)
+# define __raw_ioswabw(a,x)    (x)
+# define __raw_ioswabl(a,x)    (x)
+# define __raw_ioswabq(a,x)    (x)
+# define ____raw_ioswabq(a,x)  (x)
 
-/*
- * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
- * less sane hardware forces software to fiddle with this...
- *
- * Regardless, if the host bus endianness mismatches that of PCI/ISA, then
- * you can't have the numerical value of data and byte addresses within
- * multibyte quantities both preserved at the same time.  Hence two
- * variations of functions: non-prefixed ones that preserve the value
- * and prefixed ones that preserve byte addresses.  The latters are
- * typically used for moving raw data between a peripheral and memory (cf.
- * string I/O functions), hence the "__mem_" prefix.
- */
-#if defined(CONFIG_SWAP_IO_SPACE)
-
-# define ioswabb(x)            (x)
-# define __mem_ioswabb(x)      (x)
-# ifdef CONFIG_SGI_IP22
-/*
- * IP22 seems braindead enough to swap 16bits values in hardware, but
- * not 32bits.  Go figure... Can't tell without documentation.
- */
-#  define ioswabw(x)           (x)
-#  define __mem_ioswabw(x)     le16_to_cpu(x)
-# else
-#  define ioswabw(x)           le16_to_cpu(x)
-#  define __mem_ioswabw(x)     (x)
-# endif
-# define ioswabl(x)            le32_to_cpu(x)
-# define __mem_ioswabl(x)      (x)
-# define ioswabq(x)            le64_to_cpu(x)
-# define __mem_ioswabq(x)      (x)
-
-#else
-
-# define ioswabb(x)            (x)
-# define __mem_ioswabb(x)      (x)
-# define ioswabw(x)            (x)
-# define __mem_ioswabw(x)      cpu_to_le16(x)
-# define ioswabl(x)            (x)
-# define __mem_ioswabl(x)      cpu_to_le32(x)
-# define ioswabq(x)            (x)
-# define __mem_ioswabq(x)      cpu_to_le32(x)
-
-#endif
+/* ioswab[bwlq], __mem_ioswab[bwlq] are defined in mangle-port.h */
 
 #define IO_SPACE_LIMIT 0xffff
 
@@ -346,7 +303,7 @@ static inline void pfx##write##bwlq(type val,                               \
                                                                        \
        __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem));    \
                                                                        \
-       __val = pfx##ioswab##bwlq(val);                                 \
+       __val = pfx##ioswab##bwlq(__mem, val);                          \
                                                                        \
        if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
                *__mem = __val;                                         \
@@ -401,7 +358,7 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem)        \
                BUG();                                                  \
        }                                                               \
                                                                        \
-       return pfx##ioswab##bwlq(__val);                                \
+       return pfx##ioswab##bwlq(__mem, __val);                         \
 }
 
 #define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow)                        \
@@ -411,10 +368,9 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \
        volatile type *__addr;                                          \
        type __val;                                                     \
                                                                        \
-       port = __swizzle_addr_##bwlq(port);                             \
-       __addr = (void *)(mips_io_port_base + port);                    \
+       __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
                                                                        \
-       __val = pfx##ioswab##bwlq(val);                                 \
+       __val = pfx##ioswab##bwlq(__addr, val);                         \
                                                                        \
        /* Really, we want this to be atomic */                         \
        BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long));             \
@@ -428,15 +384,14 @@ static inline type pfx##in##bwlq##p(unsigned long port)                   \
        volatile type *__addr;                                          \
        type __val;                                                     \
                                                                        \
-       port = __swizzle_addr_##bwlq(port);                             \
-       __addr = (void *)(mips_io_port_base + port);                    \
+       __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
                                                                        \
        BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long));             \
                                                                        \
        __val = *__addr;                                                \
        slow;                                                           \
                                                                        \
-       return pfx##ioswab##bwlq(__val);                                \
+       return pfx##ioswab##bwlq(__addr, __val);                        \
 }
 
 #define __BUILD_MEMORY_PFX(bus, bwlq, type)                            \
index 78e1df2095fbccf103fb9c159e4317ac531c8dbf..b3c5ecbec03cc75408c516425a53560f8585c9f1 100644 (file)
@@ -113,4 +113,6 @@ do {                                                                        \
 # define COBALT_KEY_SELECT     (1 << 7)
 # define COBALT_KEY_MASK       0xfe
 
+#define COBALT_UART            ((volatile unsigned char *) CKSEG1ADDR(0x1c800000))
+
 #endif /* __ASM_COBALT_H */
index 4a98d83b8ec7f26776f50e0637f14ca22e095218..6e1b0c075de7f0f48fd04372ab9b80736c08be27 100644 (file)
 #define __swizzle_addr_l(port) (port)
 #define __swizzle_addr_q(port) (port)
 
+/*
+ * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
+ * less sane hardware forces software to fiddle with this...
+ *
+ * Regardless, if the host bus endianness mismatches that of PCI/ISA, then
+ * you can't have the numerical value of data and byte addresses within
+ * multibyte quantities both preserved at the same time.  Hence two
+ * variations of functions: non-prefixed ones that preserve the value
+ * and prefixed ones that preserve byte addresses.  The latters are
+ * typically used for moving raw data between a peripheral and memory (cf.
+ * string I/O functions), hence the "__mem_" prefix.
+ */
+#if defined(CONFIG_SWAP_IO_SPACE)
+
+# define ioswabb(a,x)          (x)
+# define __mem_ioswabb(a,x)    (x)
+# define ioswabw(a,x)          le16_to_cpu(x)
+# define __mem_ioswabw(a,x)    (x)
+# define ioswabl(a,x)          le32_to_cpu(x)
+# define __mem_ioswabl(a,x)    (x)
+# define ioswabq(a,x)          le64_to_cpu(x)
+# define __mem_ioswabq(a,x)    (x)
+
+#else
+
+# define ioswabb(a,x)          (x)
+# define __mem_ioswabb(a,x)    (x)
+# define ioswabw(a,x)          (x)
+# define __mem_ioswabw(a,x)    cpu_to_le16(x)
+# define ioswabl(a,x)          (x)
+# define __mem_ioswabl(a,x)    cpu_to_le32(x)
+# define ioswabq(a,x)          (x)
+# define __mem_ioswabq(a,x)    cpu_to_le32(x)
+
+#endif
+
 #endif /* __ASM_MACH_GENERIC_MANGLE_PORT_H */
index f76c448804513e434c918dc1daeeb0211a2e01e2..d615312a451acb9f04baa7358ce62b154498f398 100644 (file)
 #define __swizzle_addr_l(port) (port)
 #define __swizzle_addr_q(port) (port)
 
+# define ioswabb(a,x)          (x)
+# define __mem_ioswabb(a,x)    (x)
+# define ioswabw(a,x)          (x)
+# define __mem_ioswabw(a,x)    cpu_to_le16(x)
+# define ioswabl(a,x)          (x)
+# define __mem_ioswabl(a,x)    cpu_to_le32(x)
+# define ioswabq(a,x)          (x)
+# define __mem_ioswabq(a,x)    cpu_to_le32(x)
+
 #endif /* __ASM_MACH_IP27_MANGLE_PORT_H */
index 6e25b52ed8f2157c547ef1b03eb12678e947eabc..81320eb553249f6fcb8b2fdadda303ed709fd023 100644 (file)
 #define __swizzle_addr_l(port) (port)
 #define __swizzle_addr_q(port) (port)
 
+# define ioswabb(a,x)          (x)
+# define __mem_ioswabb(a,x)    (x)
+# define ioswabw(a,x)          (x)
+# define __mem_ioswabw(a,x)    cpu_to_le16(x)
+# define ioswabl(a,x)          (x)
+# define __mem_ioswabl(a,x)    cpu_to_le32(x)
+# define ioswabq(a,x)          (x)
+# define __mem_ioswabq(a,x)    cpu_to_le32(x)
+
 #endif /* __ASM_MACH_IP32_MANGLE_PORT_H */
index 19cdf7642e66c8753cc8b9fe225cc7dcd3fa357f..61cf22588137a3505c3d469c0da618734fbea190 100644 (file)
@@ -33,12 +33,7 @@ extern unsigned long pgd_current[];
        write_c0_context((unsigned long) smp_processor_id() << 25);     \
        TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 #endif
-#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
-#define TLBMISS_HANDLER_SETUP()                                                \
-       write_c0_context((unsigned long) &pgd_current[smp_processor_id()] << 23); \
-       TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
-#endif
-#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
+#ifdef CONFIG_64BIT
 #define TLBMISS_HANDLER_SETUP()                                                \
        write_c0_context((unsigned long) smp_processor_id() << 26);     \
        TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
index 0cff64ce0fb883de926c6be1db71d6e202bacdcc..4d6bc45df5947280ed1e88d17fc3ae66685fecde 100644 (file)
@@ -206,7 +206,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot)
        /* fixme */
 #define pte_to_pgoff(_pte) (((_pte).pte_high >> 6) + ((_pte).pte_high & 0x3f))
 #define pgoff_to_pte(off) \
-       ((pte_t){(((off) & 0x3f) + ((off) << 6) + _PAGE_FILE)})
+       ((pte_t){(((off) & 0x3f) + ((off) << 6) + _PAGE_FILE)})
 
 #else
 #define pte_to_pgoff(_pte) \
index 0bcb79a58ee94936966377aa32f4290eb2ac56d6..90c374700977cc87091663ac5d9ac71012ce600d 100644 (file)
@@ -303,5 +303,6 @@ __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, )
 __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, )
 /* blast_inv_dcache_range */
 __BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, )
+__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, )
 
 #endif /* _ASM_R4KCACHE_H */
index 6fe903e09c62b4eab0275d7bffba74d196ce3f47..d8349e4b55ee333f17670475420ca564fbda9bfc 100644 (file)
@@ -147,16 +147,34 @@ struct k_sigaction {
 
 /* IRIX compatible stack_t  */
 typedef struct sigaltstack {
-       void *ss_sp;
+       void __user *ss_sp;
        size_t ss_size;
        int ss_flags;
 } stack_t;
 
 #ifdef __KERNEL__
 #include <asm/sigcontext.h>
+#include <asm/siginfo.h>
 
 #define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
+struct pt_regs;
+extern void do_signal(struct pt_regs *regs);
+extern void do_signal32(struct pt_regs *regs);
+
+extern int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+        int signr, sigset_t *set);
+extern int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+        int signr, sigset_t *set, siginfo_t *info);
+
+extern int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+        int signr, sigset_t *set);
+extern int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
+        int signr, sigset_t *set, siginfo_t *info);
+
+extern int setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs,
+        int signr, sigset_t *set, siginfo_t *info);
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_SIGNAL_H */
index d028e28d6239d1609226321966fb559c673db21c..9709ff701d9be8095dcacd33049d1a18a81e2680 100644 (file)
@@ -99,7 +99,7 @@ typedef s32 klconf_off_t;
 #define ENABLE_BOARD           0x01
 #define FAILED_BOARD           0x02
 #define DUPLICATE_BOARD        0x04    /* Boards like midplanes/routers which
-                                          are discovered twice. Use one of them */
+                                          are discovered twice. Use one of them */
 #define VISITED_BOARD          0x08    /* Used for compact hub numbering. */
 #define LOCAL_MASTER_IO6       0x10    /* master io6 for that node */
 #define GLOBAL_MASTER_IO6      0x20
index 3a17846df8497d319ed7112fdff2013f4309e989..59edb20f8ec50b492fe7d2c66d7b0ffd5ad198ea 100644 (file)
 #include <linux/config.h>
 #include <asm/addrspace.h>
 
-#ifdef CONFIG_BUILD_ELF64
 #define REP_BASE       CAC_BASE
-#else
-#define REP_BASE       CKSEG0
-#endif
 
 #ifdef CONFIG_MAPPED_KERNEL
 
index 80cf6a52ed3b530f70f06a774ed4f874bbfbd0a2..f314da21b9706c81581edb6867ff3354cf7efe1e 100644 (file)
@@ -229,7 +229,7 @@ typedef union hubii_ilcsr_u {
                         icsr_llp_en:    1,     /* LLP enable bit */
                        icsr_rsvd2:      1,     /* reserver */
                         icsr_wrm_reset:         1,     /* Warm reset bit */
-                       icsr_rsvd1:      2,     /* Data ready offset */
+                       icsr_rsvd1:      2,     /* Data ready offset */
                         icsr_null_to:   6;     /* Null timeout   */
 
         } icsr_fields_s;
@@ -274,9 +274,9 @@ typedef union io_perf_sel {
        u64 perf_sel_reg;
        struct {
                u64     perf_rsvd  : 48,
-                       perf_icct  :  8,
-                       perf_ippr1 :  4,
-                       perf_ippr0 :  4;
+                       perf_icct  :  8,
+                       perf_ippr1 :  4,
+                       perf_ippr0 :  4;
        } perf_sel_bits;
 } io_perf_sel_t;
 
@@ -287,8 +287,8 @@ typedef union io_perf_cnt {
        u64     perf_cnt;
        struct {
                u64     perf_rsvd1 : 32,
-                               perf_rsvd2 : 12,
-                               perf_cnt   : 20;
+                       perf_rsvd2 : 12,
+                       perf_cnt   : 20;
        } perf_cnt_bits;
 } io_perf_cnt_t;
 
index a8919dcc93c8661ea16cffbc6fa68df5ac49f8c8..2acf3e844f0001951dcad3ed848eccdde9cba824 100644 (file)
                addu    k1, k0
                LONG_L  k1, %lo(kernelsp)(k1)
 #endif
-#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
-               MFC0    k1, CP0_CONTEXT
-               dsra    k1, 23
-               lui     k0, %hi(pgd_current)
-               addiu   k0, %lo(pgd_current)
-               dsubu   k1, k0
-               lui     k0, %hi(kernelsp)
-               daddu   k1, k0
-               LONG_L  k1, %lo(kernelsp)(k1)
-#endif
-#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
+#ifdef CONFIG_64BIT
                MFC0    k1, CP0_CONTEXT
                lui     k0, %highest(kernelsp)
                dsrl    k1, 23
                mfc0    \temp, CP0_CONTEXT
                srl     \temp, 23
 #endif
-#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
-               lw      \temp, TI_CPU(gp)
-               dsll    \temp, 3
-#endif
-#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
+#ifdef CONFIG_64BIT
                MFC0    \temp, CP0_CONTEXT
                dsrl    \temp, 23
 #endif
                .endm
 #else
                .macro  get_saved_sp    /* Uniprocessor variation */
-#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64)
+#ifdef CONFIG_64BIT
                lui     k1, %highest(kernelsp)
                daddiu  k1, %higher(kernelsp)
                dsll    k1, k1, 16
index ddae9bae31af1e084979a1c778d22b74c35c42c8..4097fac5ac3cf66874a248b18ae0cba66adffe16 100644 (file)
@@ -286,10 +286,10 @@ extern void __xchg_called_with_bad_pointer(void);
 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
 {
        switch (size) {
-               case 4:
-                       return __xchg_u32(ptr, x);
-               case 8:
-                       return __xchg_u64(ptr, x);
+       case 4:
+               return __xchg_u32(ptr, x);
+       case 8:
+               return __xchg_u64(ptr, x);
        }
        __xchg_called_with_bad_pointer();
        return x;
index fa193f861e71629d3a15d2c3ed481ea99f7b9de5..f8d97dafd2f4c7659a8e78c0ba3118032637a541 100644 (file)
@@ -31,7 +31,7 @@ struct thread_info {
        int                     preempt_count;  /* 0 => preemptable, <0 => BUG */
 
        mm_segment_t            addr_limit;     /* thread address space:
-                                                  0-0xBFFFFFFF for user-thead
+                                                  0-0xBFFFFFFF for user-thead
                                                   0-0xFFFFFFFF for kernel-thread
                                                */
        struct restart_block    restart_block;
index 6b8d73dc1ab09d269972d1373984150ebebb5c86..9cf64b1b688b58440e6f6d2e89f308ef4e1e9c1f 100644 (file)
@@ -54,6 +54,7 @@
 #define CNTL_LCDBPP4           (2 << 1)
 #define CNTL_LCDBPP8           (3 << 1)
 #define CNTL_LCDBPP16          (4 << 1)
+#define CNTL_LCDBPP16_565      (6 << 1)
 #define CNTL_LCDBPP24          (5 << 1)
 #define CNTL_LCDBW             (1 << 4)
 #define CNTL_LCDTFT            (1 << 5)
@@ -209,7 +210,16 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
                val |= CNTL_LCDBPP8;
                break;
        case 16:
-               val |= CNTL_LCDBPP16;
+               /*
+                * PL110 cannot choose between 5551 and 565 modes in
+                * its control register
+                */
+               if ((fb->dev->periphid & 0x000fffff) == 0x00041110)
+                       val |= CNTL_LCDBPP16;
+               else if (fb->fb.var.green.length == 5)
+                       val |= CNTL_LCDBPP16;
+               else
+                       val |= CNTL_LCDBPP16_565;
                break;
        case 32:
                val |= CNTL_LCDBPP24;
index 94f77cce27fa10d634b7ffdbeb415d31613833b5..b02a16c435e78b6da13376238bb345aa2ac4ab12 100644 (file)
@@ -267,6 +267,16 @@ struct ata_taskfile {
          ((u64) (id)[(n) + 1] << 16) | \
          ((u64) (id)[(n) + 0]) )
 
+static inline unsigned int ata_id_major_version(const u16 *id)
+{
+       unsigned int mver;
+
+       for (mver = 14; mver >= 1; mver--)
+               if (id[ATA_ID_MAJOR_VER] & (1 << mver))
+                       break;
+       return mver;
+}
+
 static inline int ata_id_current_chs_valid(const u16 *id)
 {
        /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command 
@@ -302,4 +312,16 @@ static inline int ata_ok(u8 status)
                        == ATA_DRDY);
 }
 
+static inline int lba_28_ok(u64 block, u32 n_block)
+{
+       /* check the ending block number */
+       return ((block + n_block - 1) < ((u64)1 << 28)) && (n_block <= 256);
+}
+
+static inline int lba_48_ok(u64 block, u32 n_block)
+{
+       /* check the ending block number */
+       return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536);
+}
+
 #endif /* __LINUX_ATA_H__ */
index 0ed1d4853c69814530920c14b9c2bb6cee445b92..d612b89dce3320db7d4edafe02dde8d50f8def56 100644 (file)
@@ -32,7 +32,7 @@ struct cpu {
 };
 
 extern int register_cpu(struct cpu *, int, struct node *);
-extern struct sys_device *get_cpu_sysdev(int cpu);
+extern struct sys_device *get_cpu_sysdev(unsigned cpu);
 #ifdef CONFIG_HOTPLUG_CPU
 extern void unregister_cpu(struct cpu *, struct node *);
 #endif
index a5fa6a6eede814ab502894736146fde295dee8c5..4b0428e335beb5b652bddf8ad77fde35f982e57a 100644 (file)
 
 struct file_operations;
 
+struct debugfs_blob_wrapper {
+       void *data;
+       unsigned long size;
+};
+
 #if defined(CONFIG_DEBUG_FS)
 struct dentry *debugfs_create_file(const char *name, mode_t mode,
                                   struct dentry *parent, void *data,
@@ -39,6 +44,9 @@ struct dentry *debugfs_create_u32(const char *name, mode_t mode,
 struct dentry *debugfs_create_bool(const char *name, mode_t mode,
                                  struct dentry *parent, u32 *value);
 
+struct dentry *debugfs_create_blob(const char *name, mode_t mode,
+                                 struct dentry *parent,
+                                 struct debugfs_blob_wrapper *blob);
 #else
 
 #include <linux/err.h>
@@ -94,6 +102,13 @@ static inline struct dentry *debugfs_create_bool(const char *name, mode_t mode,
        return ERR_PTR(-ENODEV);
 }
 
+static inline struct dentry *debugfs_create_blob(const char *name, mode_t mode,
+                                 struct dentry *parent,
+                                 struct debugfs_blob_wrapper *blob)
+{
+       return ERR_PTR(-ENODEV);
+}
+
 #endif
 
 #endif
index 58df18d9cd3ebe4f218d1d13d119293879a77088..5b595fdfb672b1ef85d296dfc35ddd2929b8735d 100644 (file)
@@ -424,6 +424,8 @@ extern void firmware_unregister(struct subsystem *);
        dev_printk(KERN_INFO , dev , format , ## arg)
 #define dev_warn(dev, format, arg...)          \
        dev_printk(KERN_WARNING , dev , format , ## arg)
+#define dev_notice(dev, format, arg...)                \
+       dev_printk(KERN_NOTICE , dev , format , ## arg)
 
 /* Create alias, so I can be autoloaded. */
 #define MODULE_ALIAS_CHARDEV(major,minor) \
index 2b8797084685fcaacbb219036e2a29dfcea2c85c..0874a67c6b922de7e5ab9e81ac2fda4907a96135 100644 (file)
@@ -121,4 +121,17 @@ typedef uint16_t audio_attributes_t;
 #define AUDIO_SET_ATTRIBUTES       _IOW('o', 17, audio_attributes_t)
 #define AUDIO_SET_KARAOKE          _IOW('o', 18, audio_karaoke_t)
 
+/**
+ * AUDIO_GET_PTS
+ *
+ * Read the 33 bit presentation time stamp as defined
+ * in ITU T-REC-H.222.0 / ISO/IEC 13818-1.
+ *
+ * The PTS should belong to the currently played
+ * frame if possible, but may also be a value close to it
+ * like the PTS of the last decoded frame or the last PTS
+ * extracted by the PES parser.
+ */
+#define AUDIO_GET_PTS              _IOR('o', 19, __u64)
+
 #endif /* _DVBAUDIO_H_ */
index b81e58b2ebf8d0ba3b39ba31399cb8756b4c63ad..faebfda397ff2086918050f9ea0cdeb14081f9dc 100644 (file)
@@ -200,4 +200,17 @@ typedef uint16_t video_attributes_t;
 #define VIDEO_GET_SIZE             _IOR('o', 55, video_size_t)
 #define VIDEO_GET_FRAME_RATE       _IOR('o', 56, unsigned int)
 
+/**
+ * VIDEO_GET_PTS
+ *
+ * Read the 33 bit presentation time stamp as defined
+ * in ITU T-REC-H.222.0 / ISO/IEC 13818-1.
+ *
+ * The PTS should belong to the currently played
+ * frame if possible, but may also be a value close to it
+ * like the PTS of the last decoded frame or the last PTS
+ * extracted by the PES parser.
+ */
+#define VIDEO_GET_PTS              _IOR('o', 57, __u64)
+
 #endif /*_DVBVIDEO_H_*/
index cbe7d8008042baa9385d3e3ec01aaf48b485b614..bafe178a381f19c98c7736370e5b31c5e8792ed2 100644 (file)
@@ -1,6 +1,6 @@
 #ifdef __KERNEL__
 
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 typedef struct kobject *kobj_probe_t(dev_t, int *, void *);
 struct kobj_map;
@@ -9,6 +9,6 @@ int kobj_map(struct kobj_map *, dev_t, unsigned long, struct module *,
             kobj_probe_t *, int (*)(dev_t, void *), void *);
 void kobj_unmap(struct kobj_map *, dev_t, unsigned long);
 struct kobject *kobj_lookup(struct kobj_map *, dev_t, int *);
-struct kobj_map *kobj_map_init(kobj_probe_t *, struct semaphore *);
+struct kobj_map *kobj_map_init(kobj_probe_t *, struct mutex *);
 
 #endif
index c374b5fa8d3bbd0c48392c7b6207346efe510113..4cb1214ec29091919215d5db84323f68b638590e 100644 (file)
@@ -80,6 +80,8 @@ extern void kobject_unregister(struct kobject *);
 extern struct kobject * kobject_get(struct kobject *);
 extern void kobject_put(struct kobject *);
 
+extern struct kobject *kobject_add_dir(struct kobject *, const char *);
+
 extern char * kobject_get_path(struct kobject *, gfp_t);
 
 struct kobj_type {
@@ -255,7 +257,7 @@ struct subsys_attribute {
 extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
 extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);
 
-#if defined(CONFIG_HOTPLUG) & defined(CONFIG_NET)
+#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
 void kobject_uevent(struct kobject *kobj, enum kobject_action action);
 
 int add_uevent_var(char **envp, int num_envp, int *cur_index,
index c91be5e64ededd7f59831bddf7bfba2b080d2db5..239408ecfddfb2d7dda2ef22d728a0c85d4c5d64 100644 (file)
@@ -35,7 +35,8 @@
 #include <linux/workqueue.h>
 
 /*
- * compile-time options
+ * compile-time options: to be removed as soon as all the drivers are
+ * converted to the new debugging mechanism
  */
 #undef ATA_DEBUG               /* debugging output */
 #undef ATA_VERBOSE_DEBUG       /* yet more debugging output */
 
 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
 
-#ifdef ATA_NDEBUG
-#define assert(expr)
-#else
-#define assert(expr) \
-        if(unlikely(!(expr))) {                                   \
-        printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
-        #expr,__FILE__,__FUNCTION__,__LINE__);          \
-        }
-#endif
+/* NEW: debug levels */
+#define HAVE_LIBATA_MSG 1
+
+enum {
+       ATA_MSG_DRV     = 0x0001,
+       ATA_MSG_INFO    = 0x0002,
+       ATA_MSG_PROBE   = 0x0004,
+       ATA_MSG_WARN    = 0x0008,
+       ATA_MSG_MALLOC  = 0x0010,
+       ATA_MSG_CTL     = 0x0020,
+       ATA_MSG_INTR    = 0x0040,
+       ATA_MSG_ERR     = 0x0080,
+};
+
+#define ata_msg_drv(p)    ((p)->msg_enable & ATA_MSG_DRV)
+#define ata_msg_info(p)   ((p)->msg_enable & ATA_MSG_INFO)
+#define ata_msg_probe(p)  ((p)->msg_enable & ATA_MSG_PROBE)
+#define ata_msg_warn(p)   ((p)->msg_enable & ATA_MSG_WARN)
+#define ata_msg_malloc(p) ((p)->msg_enable & ATA_MSG_MALLOC)
+#define ata_msg_ctl(p)    ((p)->msg_enable & ATA_MSG_CTL)
+#define ata_msg_intr(p)   ((p)->msg_enable & ATA_MSG_INTR)
+#define ata_msg_err(p)    ((p)->msg_enable & ATA_MSG_ERR)
+
+static inline u32 ata_msg_init(int dval, int default_msg_enable_bits)
+{
+       if (dval < 0 || dval >= (sizeof(u32) * 8))
+               return default_msg_enable_bits; /* should be 0x1 - only driver info msgs */
+       if (!dval)
+               return 0;
+       return (1 << dval) - 1;
+}
 
 /* defines only for the constants which don't work well as enums */
 #define ATA_TAG_POISON         0xfafbfcfdU
@@ -99,8 +122,7 @@ enum {
        /* struct ata_device stuff */
        ATA_DFLAG_LBA48         = (1 << 0), /* device supports LBA48 */
        ATA_DFLAG_PIO           = (1 << 1), /* device currently in PIO mode */
-       ATA_DFLAG_LOCK_SECTORS  = (1 << 2), /* don't adjust max_sectors */
-       ATA_DFLAG_LBA           = (1 << 3), /* device supports LBA */
+       ATA_DFLAG_LBA           = (1 << 2), /* device supports LBA */
 
        ATA_DEV_UNKNOWN         = 0,    /* unknown device */
        ATA_DEV_ATA             = 1,    /* ATA device */
@@ -115,9 +137,9 @@ enum {
        ATA_FLAG_PORT_DISABLED  = (1 << 2), /* port is disabled, ignore it */
        ATA_FLAG_SATA           = (1 << 3),
        ATA_FLAG_NO_LEGACY      = (1 << 4), /* no legacy mode check */
-       ATA_FLAG_SRST           = (1 << 5), /* use ATA SRST, not E.D.D. */
+       ATA_FLAG_SRST           = (1 << 5), /* (obsolete) use ATA SRST, not E.D.D. */
        ATA_FLAG_MMIO           = (1 << 6), /* use MMIO, not PIO */
-       ATA_FLAG_SATA_RESET     = (1 << 7), /* use COMRESET */
+       ATA_FLAG_SATA_RESET     = (1 << 7), /* (obsolete) use COMRESET */
        ATA_FLAG_PIO_DMA        = (1 << 8), /* PIO cmds via DMA */
        ATA_FLAG_NOINTR         = (1 << 9), /* FIXME: Remove this once
                                             * proper HSM is in place. */
@@ -129,10 +151,14 @@ enum {
        ATA_FLAG_PIO_LBA48      = (1 << 13), /* Host DMA engine is LBA28 only */
        ATA_FLAG_IRQ_MASK       = (1 << 14), /* Mask IRQ in PIO xfers */
 
+       ATA_FLAG_FLUSH_PORT_TASK = (1 << 15), /* Flush port task */
+       ATA_FLAG_IN_EH          = (1 << 16), /* EH in progress */
+
        ATA_QCFLAG_ACTIVE       = (1 << 1), /* cmd not yet ack'd to scsi lyer */
        ATA_QCFLAG_SG           = (1 << 3), /* have s/g table? */
        ATA_QCFLAG_SINGLE       = (1 << 4), /* no s/g, just a single buffer */
        ATA_QCFLAG_DMAMAP       = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
+       ATA_QCFLAG_EH_SCHEDULED = (1 << 5), /* EH scheduled */
 
        /* various lengths of time */
        ATA_TMOUT_EDD           = 5 * HZ,       /* heuristic */
@@ -162,11 +188,19 @@ enum {
        PORT_DISABLED           = 2,
 
        /* encoding various smaller bitmaps into a single
-        * unsigned long bitmap
+        * unsigned int bitmap
         */
-       ATA_SHIFT_UDMA          = 0,
-       ATA_SHIFT_MWDMA         = 8,
-       ATA_SHIFT_PIO           = 11,
+       ATA_BITS_PIO            = 5,
+       ATA_BITS_MWDMA          = 3,
+       ATA_BITS_UDMA           = 8,
+
+       ATA_SHIFT_PIO           = 0,
+       ATA_SHIFT_MWDMA         = ATA_SHIFT_PIO + ATA_BITS_PIO,
+       ATA_SHIFT_UDMA          = ATA_SHIFT_MWDMA + ATA_BITS_MWDMA,
+
+       ATA_MASK_PIO            = ((1 << ATA_BITS_PIO) - 1) << ATA_SHIFT_PIO,
+       ATA_MASK_MWDMA          = ((1 << ATA_BITS_MWDMA) - 1) << ATA_SHIFT_MWDMA,
+       ATA_MASK_UDMA           = ((1 << ATA_BITS_UDMA) - 1) << ATA_SHIFT_UDMA,
 
        /* size of buffer to pad xfers ending on unaligned boundaries */
        ATA_DMA_PAD_SZ          = 4,
@@ -189,10 +223,15 @@ enum hsm_task_states {
 };
 
 enum ata_completion_errors {
-       AC_ERR_OTHER            = (1 << 0),
-       AC_ERR_DEV              = (1 << 1),
-       AC_ERR_ATA_BUS          = (1 << 2),
-       AC_ERR_HOST_BUS         = (1 << 3),
+       AC_ERR_DEV              = (1 << 0), /* device reported error */
+       AC_ERR_HSM              = (1 << 1), /* host state machine violation */
+       AC_ERR_TIMEOUT          = (1 << 2), /* timeout */
+       AC_ERR_MEDIA            = (1 << 3), /* media error */
+       AC_ERR_ATA_BUS          = (1 << 4), /* ATA bus error */
+       AC_ERR_HOST_BUS         = (1 << 5), /* host bus error */
+       AC_ERR_SYSTEM           = (1 << 6), /* system error */
+       AC_ERR_INVALID          = (1 << 7), /* invalid argument */
+       AC_ERR_OTHER            = (1 << 8), /* unknown */
 };
 
 /* forward declarations */
@@ -202,7 +241,10 @@ struct ata_port;
 struct ata_queued_cmd;
 
 /* typedefs */
-typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
+typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
+typedef void (*ata_probeinit_fn_t)(struct ata_port *);
+typedef int (*ata_reset_fn_t)(struct ata_port *, int, unsigned int *);
+typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *);
 
 struct ata_ioports {
        unsigned long           cmd_addr;
@@ -305,7 +347,7 @@ struct ata_device {
        unsigned long           flags;          /* ATA_DFLAG_xxx */
        unsigned int            class;          /* ATA_DEV_xxx */
        unsigned int            devno;          /* 0 or 1 */
-       u16                     id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
+       u16                     *id;            /* IDENTIFY xxx DEVICE data */
        u8                      pio_mode;
        u8                      dma_mode;
        u8                      xfer_mode;
@@ -313,6 +355,8 @@ struct ata_device {
 
        unsigned int            multi_count;    /* sectors count for
                                                   READ/WRITE MULTIPLE */
+       unsigned int            max_sectors;    /* per-device max sectors */
+       unsigned int            cdb_len;
 
        /* for CHS addressing */
        u16                     cylinders;      /* Number of cylinders */
@@ -342,7 +386,6 @@ struct ata_port {
        unsigned int            mwdma_mask;
        unsigned int            udma_mask;
        unsigned int            cbl;    /* cable type; ATA_CBL_xxx */
-       unsigned int            cdb_len;
 
        struct ata_device       device[ATA_MAX_DEVICES];
 
@@ -353,12 +396,14 @@ struct ata_port {
        struct ata_host_stats   stats;
        struct ata_host_set     *host_set;
 
-       struct work_struct      packet_task;
+       struct work_struct      port_task;
 
-       struct work_struct      pio_task;
        unsigned int            hsm_task_state;
        unsigned long           pio_task_timeout;
 
+       u32                     msg_enable;
+       struct list_head        eh_done_q;
+
        void                    *private_data;
 };
 
@@ -378,7 +423,9 @@ struct ata_port_operations {
        u8   (*check_altstatus)(struct ata_port *ap);
        void (*dev_select)(struct ata_port *ap, unsigned int device);
 
-       void (*phy_reset) (struct ata_port *ap);
+       void (*phy_reset) (struct ata_port *ap); /* obsolete */
+       int (*probe_reset) (struct ata_port *ap, unsigned int *classes);
+
        void (*post_set_mode) (struct ata_port *ap);
 
        int (*check_atapi_dma) (struct ata_queued_cmd *qc);
@@ -387,7 +434,7 @@ struct ata_port_operations {
        void (*bmdma_start) (struct ata_queued_cmd *qc);
 
        void (*qc_prep) (struct ata_queued_cmd *qc);
-       int (*qc_issue) (struct ata_queued_cmd *qc);
+       unsigned int (*qc_issue) (struct ata_queued_cmd *qc);
 
        void (*eng_timeout) (struct ata_port *ap);
 
@@ -435,6 +482,18 @@ extern void ata_port_probe(struct ata_port *);
 extern void __sata_phy_reset(struct ata_port *ap);
 extern void sata_phy_reset(struct ata_port *ap);
 extern void ata_bus_reset(struct ata_port *ap);
+extern int ata_drive_probe_reset(struct ata_port *ap,
+                       ata_probeinit_fn_t probeinit,
+                       ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
+                       ata_postreset_fn_t postreset, unsigned int *classes);
+extern void ata_std_probeinit(struct ata_port *ap);
+extern int ata_std_softreset(struct ata_port *ap, int verbose,
+                            unsigned int *classes);
+extern int sata_std_hardreset(struct ata_port *ap, int verbose,
+                             unsigned int *class);
+extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
+extern int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
+                             int post_reset);
 extern void ata_port_disable(struct ata_port *);
 extern void ata_std_ports(struct ata_ioports *ioaddr);
 #ifdef CONFIG_PCI
@@ -449,7 +508,10 @@ extern void ata_host_set_remove(struct ata_host_set *host_set);
 extern int ata_scsi_detect(struct scsi_host_template *sht);
 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
 extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
+extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
 extern int ata_scsi_error(struct Scsi_Host *host);
+extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);
+extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
 extern int ata_scsi_release(struct Scsi_Host *host);
 extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
 extern int ata_scsi_device_resume(struct scsi_device *);
@@ -457,6 +519,11 @@ extern int ata_scsi_device_suspend(struct scsi_device *);
 extern int ata_device_resume(struct ata_port *, struct ata_device *);
 extern int ata_device_suspend(struct ata_port *, struct ata_device *);
 extern int ata_ratelimit(void);
+extern unsigned int ata_busy_sleep(struct ata_port *ap,
+                                  unsigned long timeout_pat,
+                                  unsigned long timeout);
+extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *),
+                               void *data, unsigned long delay);
 
 /*
  * Default driver ops implementations
@@ -470,26 +537,28 @@ extern void ata_std_dev_select (struct ata_port *ap, unsigned int device);
 extern u8 ata_check_status(struct ata_port *ap);
 extern u8 ata_altstatus(struct ata_port *ap);
 extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
+extern int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes);
 extern int ata_port_start (struct ata_port *ap);
 extern void ata_port_stop (struct ata_port *ap);
 extern void ata_host_stop (struct ata_host_set *host_set);
 extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
 extern void ata_qc_prep(struct ata_queued_cmd *qc);
-extern int ata_qc_issue_prot(struct ata_queued_cmd *qc);
+extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc);
 extern void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf,
                unsigned int buflen);
 extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
                 unsigned int n_elem);
 extern unsigned int ata_dev_classify(const struct ata_taskfile *tf);
-extern void ata_dev_id_string(const u16 *id, unsigned char *s,
-                             unsigned int ofs, unsigned int len);
-extern void ata_dev_config(struct ata_port *ap, unsigned int i);
+extern void ata_id_string(const u16 *id, unsigned char *s,
+                         unsigned int ofs, unsigned int len);
+extern void ata_id_c_string(const u16 *id, unsigned char *s,
+                           unsigned int ofs, unsigned int len);
 extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
 extern void ata_bmdma_start (struct ata_queued_cmd *qc);
 extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
 extern u8   ata_bmdma_status(struct ata_port *ap);
 extern void ata_bmdma_irq_clear(struct ata_port *ap);
-extern void ata_qc_complete(struct ata_queued_cmd *qc);
+extern void __ata_qc_complete(struct ata_queued_cmd *qc);
 extern void ata_eng_timeout(struct ata_port *ap);
 extern void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
                              struct scsi_cmnd *cmd,
@@ -586,10 +655,14 @@ static inline unsigned int ata_tag_valid(unsigned int tag)
        return (tag < ATA_MAX_QUEUE) ? 1 : 0;
 }
 
+static inline unsigned int ata_class_present(unsigned int class)
+{
+       return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI;
+}
+
 static inline unsigned int ata_dev_present(const struct ata_device *dev)
 {
-       return ((dev->class == ATA_DEV_ATA) ||
-               (dev->class == ATA_DEV_ATAPI));
+       return ata_class_present(dev->class);
 }
 
 static inline u8 ata_chk_status(struct ata_port *ap)
@@ -657,9 +730,9 @@ static inline u8 ata_wait_idle(struct ata_port *ap)
 
        if (status & (ATA_BUSY | ATA_DRQ)) {
                unsigned long l = ap->ioaddr.status_addr;
-               printk(KERN_WARNING
-                      "ATA: abnormal status 0x%X on port 0x%lX\n",
-                      status, l);
+               if (ata_msg_warn(ap))
+                       printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n",
+                               status, l);
        }
 
        return status;
@@ -701,6 +774,24 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
        ata_tf_init(qc->ap, &qc->tf, qc->dev->devno);
 }
 
+/**
+ *     ata_qc_complete - Complete an active ATA command
+ *     @qc: Command to complete
+ *     @err_mask: ATA Status register contents
+ *
+ *     Indicate to the mid and upper layers that an ATA
+ *     command has completed, with either an ok or not-ok status.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host_set lock)
+ */
+static inline void ata_qc_complete(struct ata_queued_cmd *qc)
+{
+       if (unlikely(qc->flags & ATA_QCFLAG_EH_SCHEDULED))
+               return;
+
+       __ata_qc_complete(qc);
+}
 
 /**
  *     ata_irq_on - Enable interrupts on a port.
@@ -751,7 +842,8 @@ static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
 
        status = ata_busy_wait(ap, bits, 1000);
        if (status & bits)
-               DPRINTK("abnormal status 0x%X\n", status);
+               if (ata_msg_err(ap))
+                       printk(KERN_ERR "abnormal status 0x%X\n", status);
 
        /* get controller status; clear intr, err bits */
        if (ap->flags & ATA_FLAG_MMIO) {
@@ -769,8 +861,10 @@ static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
                post_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
        }
 
-       VPRINTK("irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
-               host_stat, post_stat, status);
+       if (ata_msg_intr(ap))
+               printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
+                       __FUNCTION__,
+                       host_stat, post_stat, status);
 
        return status;
 }
@@ -807,7 +901,7 @@ static inline int ata_try_flush_cache(const struct ata_device *dev)
 static inline unsigned int ac_err_mask(u8 status)
 {
        if (status & ATA_BUSY)
-               return AC_ERR_ATA_BUS;
+               return AC_ERR_HSM;
        if (status & (ATA_ERR | ATA_DF))
                return AC_ERR_DEV;
        return 0;
index 84d75f3a8acab027fc1ed4a91c8878808eeb6be2..70bd843c71cb83872e7a9190365ed3a870fd5d1d 100644 (file)
@@ -198,6 +198,9 @@ void *__symbol_get_gpl(const char *symbol);
 #define EXPORT_SYMBOL_GPL(sym)                                 \
        __EXPORT_SYMBOL(sym, "_gpl")
 
+#define EXPORT_SYMBOL_GPL_FUTURE(sym)                          \
+       __EXPORT_SYMBOL(sym, "_gpl_future")
+
 #endif
 
 struct module_ref
@@ -242,6 +245,7 @@ struct module
        /* Sysfs stuff. */
        struct module_kobject mkobj;
        struct module_param_attrs *param_attrs;
+       struct module_attribute *modinfo_attrs;
        const char *version;
        const char *srcversion;
 
@@ -255,6 +259,11 @@ struct module
        unsigned int num_gpl_syms;
        const unsigned long *gpl_crcs;
 
+       /* symbols that will be GPL-only in the near future. */
+       const struct kernel_symbol *gpl_future_syms;
+       unsigned int num_gpl_future_syms;
+       const unsigned long *gpl_future_crcs;
+
        /* Exception table */
        unsigned int num_exentries;
        const struct exception_table_entry *extable;
@@ -441,6 +450,7 @@ void module_remove_driver(struct device_driver *);
 #else /* !CONFIG_MODULES... */
 #define EXPORT_SYMBOL(sym)
 #define EXPORT_SYMBOL_GPL(sym)
+#define EXPORT_SYMBOL_GPL_FUTURE(sym)
 
 /* Given an address, look for it in the exception tables. */
 static inline const struct exception_table_entry *
index 5208b12d555095cb2d246728aca9b649093b724d..724cfbf54b8afaf34edaae5593e4d6e5091107a6 100644 (file)
 #include <linux/time.h> /* need struct timeval */
 #include <linux/poll.h>
 #include <linux/device.h>
+#include <linux/mutex.h>
 #endif
 #include <linux/compiler.h> /* need __user */
 
 
-#define OBSOLETE_OWNER 1 /* It will be removed for 2.6.15 */
+#define OBSOLETE_OWNER 1 /* It will be removed for 2.6.17 */
 #define HAVE_V4L2 1
 
 /*
 
 #ifdef __KERNEL__
 
+/* Minor device allocation */
+#define MINOR_VFL_TYPE_GRABBER_MIN   0
+#define MINOR_VFL_TYPE_GRABBER_MAX  63
+#define MINOR_VFL_TYPE_RADIO_MIN    64
+#define MINOR_VFL_TYPE_RADIO_MAX   127
+#define MINOR_VFL_TYPE_VTX_MIN     192
+#define MINOR_VFL_TYPE_VTX_MAX     223
+#define MINOR_VFL_TYPE_VBI_MIN     224
+#define MINOR_VFL_TYPE_VBI_MAX     255
+
 #define VFL_TYPE_GRABBER       0
 #define VFL_TYPE_VBI           1
 #define VFL_TYPE_RADIO         2
@@ -80,7 +91,7 @@ struct video_device
 
        /* for videodev.c intenal usage -- please don't touch */
        int users;                     /* video_exclusive_{open|close} ... */
-       struct semaphore lock;         /* ... helper function uses these   */
+       struct mutex lock;             /* ... helper function uses these   */
        char devfs_name[64];           /* devfs */
        struct class_device class_dev; /* sysfs */
 };
@@ -952,13 +963,68 @@ struct v4l2_sliced_vbi_format
        __u32   reserved[2];            /* must be zero */
 };
 
-#define V4L2_SLICED_TELETEXT_B          (0x0001)
-#define V4L2_SLICED_VPS                 (0x0400)
-#define V4L2_SLICED_CAPTION_525         (0x1000)
-#define V4L2_SLICED_WSS_625             (0x4000)
-
-#define V4L2_SLICED_VBI_525             (V4L2_SLICED_CAPTION_525)
-#define V4L2_SLICED_VBI_625             (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
+/* Teletext World System Teletext
+   (WST), defined on ITU-R BT.653-2 */
+#define V4L2_SLICED_TELETEXT_PAL_B      (0x000001)
+#define V4L2_SLICED_TELETEXT_PAL_C      (0x000002)
+#define V4L2_SLICED_TELETEXT_NTSC_B     (0x000010)
+#define V4L2_SLICED_TELETEXT_SECAM      (0x000020)
+
+/* Teletext North American Broadcast Teletext Specification
+   (NABTS), defined on ITU-R BT.653-2 */
+#define V4L2_SLICED_TELETEXT_NTSC_C     (0x000040)
+#define V4L2_SLICED_TELETEXT_NTSC_D     (0x000080)
+
+/* Video Program System, defined on ETS 300 231*/
+#define V4L2_SLICED_VPS                 (0x000400)
+
+/* Closed Caption, defined on EIA-608 */
+#define V4L2_SLICED_CAPTION_525         (0x001000)
+#define V4L2_SLICED_CAPTION_625         (0x002000)
+
+/* Wide Screen System, defined on ITU-R BT1119.1 */
+#define V4L2_SLICED_WSS_625             (0x004000)
+
+/* Wide Screen System, defined on IEC 61880 */
+#define V4L2_SLICED_WSS_525             (0x008000)
+
+/* Vertical Interval Timecode (VITC), defined on SMPTE 12M */
+#define V4l2_SLICED_VITC_625           (0x010000)
+#define V4l2_SLICED_VITC_525           (0x020000)
+
+#define V4L2_SLICED_TELETEXT_B         (V4L2_SLICED_TELETEXT_PAL_B  |\
+                                        V4L2_SLICED_TELETEXT_NTSC_B)
+
+#define V4L2_SLICED_TELETEXT           (V4L2_SLICED_TELETEXT_PAL_B  |\
+                                        V4L2_SLICED_TELETEXT_PAL_C  |\
+                                        V4L2_SLICED_TELETEXT_SECAM  |\
+                                        V4L2_SLICED_TELETEXT_NTSC_B |\
+                                        V4L2_SLICED_TELETEXT_NTSC_C |\
+                                        V4L2_SLICED_TELETEXT_NTSC_D)
+
+#define V4L2_SLICED_CAPTION            (V4L2_SLICED_CAPTION_525     |\
+                                        V4L2_SLICED_CAPTION_625)
+
+#define V4L2_SLICED_WSS                        (V4L2_SLICED_WSS_525         |\
+                                        V4L2_SLICED_WSS_625)
+
+#define V4L2_SLICED_VITC               (V4L2_SLICED_VITC_525        |\
+                                        V4L2_SLICED_VITC_625)
+
+#define V4L2_SLICED_VBI_525             (V4L2_SLICED_TELETEXT_NTSC_B |\
+                                        V4L2_SLICED_TELETEXT_NTSC_C |\
+                                        V4L2_SLICED_TELETEXT_NTSC_D |\
+                                        V4L2_SLICED_CAPTION_525     |\
+                                        V4L2_SLICED_WSS_525         |\
+                                        V4l2_SLICED_VITC_525)
+
+#define V4L2_SLICED_VBI_625             (V4L2_SLICED_TELETEXT_PAL_B  |\
+                                        V4L2_SLICED_TELETEXT_PAL_C  |\
+                                        V4L2_SLICED_TELETEXT_SECAM  |\
+                                        V4L2_SLICED_VPS             |\
+                                        V4L2_SLICED_CAPTION_625     |\
+                                        V4L2_SLICED_WSS_625         |\
+                                        V4l2_SLICED_VITC_625)
 
 struct v4l2_sliced_vbi_cap
 {
index ad3e9bb670c3eb93c58e5707cd0052f35c316b6a..302d5b3946e704f37a41d1d68c53b340cbd854f4 100644 (file)
@@ -47,13 +47,6 @@ struct ir_input_state {
        int                keypressed;  /* current state */
 };
 
-extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE];
-
 void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
                   int ir_type, IR_KEYTAB_TYPE *ir_codes);
 void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir);
@@ -64,6 +57,39 @@ int  ir_dump_samples(u32 *samples, int count);
 int  ir_decode_biphase(u32 *samples, int count, int low, int high);
 int  ir_decode_pulsedistance(u32 *samples, int count, int low, int high);
 
+/* Keymaps to be used by other modules */
+
+extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_videomate_tv_pvr[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE];
+
 #endif
 
 /*
index 2bc634fcb7bbac85fe6de17b6e45769d3c867147..fee579f10b32ad11cd87bca320a6f9f59eefbb43 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/i2c.h>         /* for i2c subsystem */
 #include <asm/io.h>            /* for accessing devices */
 #include <linux/stringify.h>
+#include <linux/mutex.h>
+
 #include <linux/vmalloc.h>     /* for vmalloc() */
 #include <linux/mm.h>          /* for vmalloc_to_page() */
 
@@ -112,7 +114,7 @@ struct saa7146_dev
 
        /* different device locks */
        spinlock_t                      slock;
-       struct semaphore                lock;
+       struct mutex                    lock;
 
        unsigned char                   __iomem *mem;           /* pointer to mapped IO memory */
        int                             revision;       /* chip revision; needed for bug-workarounds*/
@@ -133,15 +135,16 @@ struct saa7146_dev
        void (*vv_callback)(struct saa7146_dev *dev, unsigned long status);
 
        /* i2c-stuff */
-       struct semaphore        i2c_lock;
-       u32                     i2c_bitrate;
-       struct saa7146_dma      d_i2c;  /* pointer to i2c memory */
-       wait_queue_head_t       i2c_wq;
-       int                     i2c_op;
+       struct mutex                    i2c_lock;
+
+       u32                             i2c_bitrate;
+       struct saa7146_dma              d_i2c;  /* pointer to i2c memory */
+       wait_queue_head_t               i2c_wq;
+       int                             i2c_op;
 
        /* memories */
-       struct saa7146_dma      d_rps0;
-       struct saa7146_dma      d_rps1;
+       struct saa7146_dma              d_rps0;
+       struct saa7146_dma              d_rps1;
 };
 
 /* from saa7146_i2c.c */
@@ -150,7 +153,7 @@ int saa7146_i2c_transfer(struct saa7146_dev *saa, const struct i2c_msg *msgs, in
 
 /* from saa7146_core.c */
 extern struct list_head saa7146_devices;
-extern struct semaphore saa7146_devices_lock;
+extern struct mutex saa7146_devices_lock;
 int saa7146_register_extension(struct saa7146_extension*);
 int saa7146_unregister_extension(struct saa7146_extension*);
 struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc);
index 15821ab14a9ec46cecd84f6444312afe71d76482..ad9c171bfa07177e0716e34a6d0c8be4e84b547d 100644 (file)
@@ -14,6 +14,7 @@ enum param_type {
 
 struct tuner_range {
        unsigned short limit;
+       unsigned char config;
        unsigned char cb;
 };
 
@@ -38,7 +39,6 @@ struct tuner_params {
         * static unless the control byte was sent first.
         */
        unsigned int cb_first_if_lower_freq:1;
-       unsigned char config; /* to be moved into struct tuner_range for dvb-pll merge */
 
        unsigned int count;
        struct tuner_range *ranges;
@@ -46,6 +46,7 @@ struct tuner_params {
 
 struct tunertype {
        char *name;
+       unsigned int count;
        struct tuner_params *params;
 };
 
index a5beeac495c78bd9a84379126a8da5399a1dec36..017fed7d5e4d24fee81d3b7a3994ab24d401939e 100644 (file)
 
 #define TUNER_LG_TDVS_H062F            64      /* DViCO FusionHDTV 5 */
 #define TUNER_YMEC_TVF66T5_B_DFF       65      /* Acorp Y878F */
-#define TUNER_LG_NTSC_TALN_MINI                66
+#define TUNER_LG_TALN                  66
 #define TUNER_PHILIPS_TD1316           67
 
 #define TUNER_PHILIPS_TUV1236D         68      /* ATI HDTV Wonder */
 #define TUNER_TNF_5335MF                69     /* Sabrent Bt848   */
 #define TUNER_SAMSUNG_TCPN_2121P30A     70     /* Hauppauge PVR-500MCE NTSC */
+#define TUNER_XCEIVE_XC3028            71
+
+#define TUNER_THOMSON_FE6600           72      /* DViCO FusionHDTV DVB-T Hybrid */
 
 /* tv card specific */
 #define TDA9887_PRESENT                (1<<0)
@@ -209,6 +212,7 @@ struct tuner {
 extern unsigned const int tuner_count;
 
 extern int microtune_init(struct i2c_client *c);
+extern int xc3028_init(struct i2c_client *c);
 extern int tda8290_init(struct i2c_client *c);
 extern int tda8290_probe(struct i2c_client *c);
 extern int tea5767_tuner_init(struct i2c_client *c);
index d4030a7e16e0b1369331dca49612800035e3c9ff..2360453e7496546b4c82cd885e2005e362096517 100644 (file)
@@ -58,6 +58,9 @@
 /* Prints the ioctl in a human-readable format */
 extern void v4l_printk_ioctl(unsigned int cmd);
 
+/* Prints the ioctl and arg in a human-readable format */
+extern void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg);
+
 /* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */
 #define v4l_print_ioctl(name, cmd)              \
        do {                                     \
@@ -100,6 +103,7 @@ enum v4l2_chip_ident {
        V4L2_IDENT_UNKNOWN = 0,
 
        /* module saa7115: reserved range 100-149 */
+       V4L2_IDENT_SAA7113 = 103,
        V4L2_IDENT_SAA7114 = 104,
        V4L2_IDENT_SAA7115 = 105,
 
@@ -115,12 +119,15 @@ enum v4l2_chip_ident {
 };
 
 /* audio ioctls */
-/* v4l device was opened in Radio mode */
+
+/* v4l device was opened in Radio mode, to be replaced by VIDIOC_INT_S_TUNER_MODE */
 #define AUDC_SET_RADIO        _IO('d',88)
-/* select from TV,radio,extern,MUTE */
+
+/* select from TV,radio,extern,MUTE, to be replaced with VIDIOC_INT_S_AUDIO_ROUTING */
 #define AUDC_SET_INPUT        _IOW('d',89,int)
 
-/* msp3400 ioctl: will be removed in the near future */
+/* msp3400 ioctl: will be removed in the near future, to be replaced by
+   VIDIOC_INT_S_AUDIO_ROUTING. */
 struct msp_matrix {
   int input;
   int output;
@@ -128,12 +135,25 @@ struct msp_matrix {
 #define MSP_SET_MATRIX     _IOW('m',17,struct msp_matrix)
 
 /* tuner ioctls */
+
 /* Sets tuner type and its I2C addr */
-#define TUNER_SET_TYPE_ADDR          _IOW('d',90,int)
-/* Puts tuner on powersaving state, disabling it, except for i2c */
-#define TUNER_SET_STANDBY            _IOW('d',91,int)
+#define TUNER_SET_TYPE_ADDR          _IOW('d', 90, int)
+
+/* Puts tuner on powersaving state, disabling it, except for i2c. To be replaced
+   by VIDIOC_INT_S_STANDBY. */
+#define TUNER_SET_STANDBY            _IOW('d', 91, int)
+
 /* Sets tda9887 specific stuff, like port1, port2 and qss */
-#define TDA9887_SET_CONFIG           _IOW('d',92,int)
+#define TDA9887_SET_CONFIG           _IOW('d', 92, int)
+
+/* Switch the tuner to a specific tuner mode. Replacement of AUDC_SET_RADIO */
+#define VIDIOC_INT_S_TUNER_MODE             _IOW('d', 93, enum v4l2_tuner_type)
+
+/* Generic standby command. Passing -1 (all bits set to 1) will put the whole
+   chip into standby mode, value 0 will make the chip fully active. Specific
+   bits can be used by certain chips to enable/disable specific subsystems.
+   Replacement of TUNER_SET_STANDBY. */
+#define VIDIOC_INT_S_STANDBY        _IOW('d', 94, u32)
 
 /* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
 #define        VIDIOC_INT_S_REGISTER           _IOR ('d', 100, struct v4l2_register)
@@ -160,7 +180,8 @@ struct msp_matrix {
 
 /* Used to generate VBI signals on a video signal. v4l2_sliced_vbi_data is
    filled with the data packets that should be output. Note that if you set
-   the line field to 0, then that VBI signal is disabled. */
+   the line field to 0, then that VBI signal is disabled. If no
+   valid VBI data was found, then the type field is set to 0 on return. */
 #define VIDIOC_INT_S_VBI_DATA          _IOW ('d', 105, struct v4l2_sliced_vbi_data)
 
 /* Used to obtain the sliced VBI packet from a readback register. Not all
@@ -168,11 +189,11 @@ struct msp_matrix {
    register contains invalid or erroneous data -EIO is returned. Note that
    you must fill in the 'id' member and the 'field' member (to determine
    whether CC data from the first or second field should be obtained). */
-#define VIDIOC_INT_G_VBI_DATA          _IOWR('d', 106, struct v4l2_sliced_vbi_data *)
+#define VIDIOC_INT_G_VBI_DATA          _IOWR('d', 106, struct v4l2_sliced_vbi_data)
 
 /* Returns the chip identifier or V4L2_IDENT_UNKNOWN if no identification can
    be made. */
-#define VIDIOC_INT_G_CHIP_IDENT                _IOR ('d', 107, enum v4l2_chip_ident *)
+#define VIDIOC_INT_G_CHIP_IDENT                _IOR ('d', 107, enum v4l2_chip_ident)
 
 /* Sets I2S speed in bps. This is used to provide a standard way to select I2S
    clock used by driving digital audio streams at some board designs.
@@ -180,4 +201,25 @@ struct msp_matrix {
    If the frequency is not supported, then -EINVAL is returned. */
 #define VIDIOC_INT_I2S_CLOCK_FREQ      _IOW ('d', 108, u32)
 
+/* Routing definition, device dependent. It specifies which inputs (if any)
+   should be routed to which outputs (if any). */
+struct v4l2_routing {
+       u32 input;
+       u32 output;
+};
+
+/* These internal commands should be used to define the inputs and outputs
+   of an audio/video chip. They will replace AUDC_SET_INPUT.
+   The v4l2 API commands VIDIOC_S/G_INPUT, VIDIOC_S/G_OUTPUT,
+   VIDIOC_S/G_AUDIO and VIDIOC_S/G_AUDOUT are meant to be used by the
+   user. Internally these commands should be used to switch inputs/outputs
+   because only the driver knows how to map a 'Television' input to the precise
+   input/output routing of an A/D converter, or a DSP, or a video digitizer.
+   These four commands should only be sent directly to an i2c device, they
+   should not be broadcast as the routing is very device specific. */
+#define        VIDIOC_INT_S_AUDIO_ROUTING      _IOW ('d', 109, struct v4l2_routing)
+#define        VIDIOC_INT_G_AUDIO_ROUTING      _IOR ('d', 110, struct v4l2_routing)
+#define        VIDIOC_INT_S_VIDEO_ROUTING      _IOW ('d', 111, struct v4l2_routing)
+#define        VIDIOC_INT_G_VIDEO_ROUTING      _IOR ('d', 112, struct v4l2_routing)
+
 #endif /* V4L2_COMMON_H_ */
index ad0a07a3a89502e08c580029e96959576c81c821..b78d90fe629fb0b816f336015e07126116ce6af8 100644 (file)
@@ -11,7 +11,7 @@ struct videobuf_dvb {
        struct videobuf_queue      dvbq;
 
        /* video-buf-dvb state info */
-       struct semaphore           lock;
+       struct mutex               lock;
        struct task_struct         *thread;
        int                        nfeeds;
 
index 8ecfd78e00276abcc8567c9a5fed40c472f3bb68..d90dec5484ee367966694c37d7db07e964282c95 100644 (file)
@@ -177,7 +177,7 @@ struct videobuf_queue_ops {
 };
 
 struct videobuf_queue {
-       struct semaphore           lock;
+       struct mutex               lock;
        spinlock_t                 *irqlock;
        struct pci_dev             *pci;
 
index 86b7e93f198b429959c70dbf20d5782bb24a351a..4ace54cd0ccee3233223e9c8b3ee7c0aac222641 100644 (file)
@@ -43,6 +43,7 @@ struct ib_fmr_pool;
 /**
  * struct ib_fmr_pool_param - Parameters for creating FMR pool
  * @max_pages_per_fmr:Maximum number of pages per map request.
+ * @page_shift: Log2 of sizeof "pages" mapped by this fmr
  * @access:Access flags for FMRs in pool.
  * @pool_size:Number of FMRs to allocate for pool.
  * @dirty_watermark:Flush is triggered when @dirty_watermark dirty
@@ -55,6 +56,7 @@ struct ib_fmr_pool;
  */
 struct ib_fmr_pool_param {
        int                     max_pages_per_fmr;
+       int                     page_shift;
        enum ib_access_flags    access;
        int                     pool_size;
        int                     dirty_watermark;
index 2c133506742bffdd588a81aeedeb1a650d4db6de..51ab8eddb295cef01401225adfb7f6c10395d011 100644 (file)
@@ -33,7 +33,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: ib_mad.h 2775 2005-07-02 13:42:12Z halr $
+ * $Id: ib_mad.h 5596 2006-03-03 01:00:07Z sean.hefty $
  */
 
 #if !defined( IB_MAD_H )
@@ -208,15 +208,23 @@ struct ib_class_port_info
 /**
  * ib_mad_send_buf - MAD data buffer and work request for sends.
  * @next: A pointer used to chain together MADs for posting.
- * @mad: References an allocated MAD data buffer.
+ * @mad: References an allocated MAD data buffer for MADs that do not have
+ *   RMPP active.  For MADs using RMPP, references the common and management
+ *   class specific headers.
  * @mad_agent: MAD agent that allocated the buffer.
  * @ah: The address handle to use when sending the MAD.
  * @context: User-controlled context fields.
+ * @hdr_len: Indicates the size of the data header of the MAD.  This length
+ *   includes the common MAD, RMPP, and class specific headers.
+ * @data_len: Indicates the total size of user-transferred data.
+ * @seg_count: The number of RMPP segments allocated for this send.
+ * @seg_size: Size of each RMPP segment.
  * @timeout_ms: Time to wait for a response.
  * @retries: Number of times to retry a request for a response.
  *
  * Users are responsible for initializing the MAD buffer itself, with the
- * exception of specifying the payload length field in any RMPP MAD.
+ * exception of any RMPP header.  Additional segment buffer space allocated
+ * beyond data_len is padding.
  */
 struct ib_mad_send_buf {
        struct ib_mad_send_buf  *next;
@@ -224,6 +232,10 @@ struct ib_mad_send_buf {
        struct ib_mad_agent     *mad_agent;
        struct ib_ah            *ah;
        void                    *context[2];
+       int                     hdr_len;
+       int                     data_len;
+       int                     seg_count;
+       int                     seg_size;
        int                     timeout_ms;
        int                     retries;
 };
@@ -299,7 +311,7 @@ typedef void (*ib_mad_snoop_handler)(struct ib_mad_agent *mad_agent,
  * @mad_recv_wc: Received work completion information on the received MAD.
  *
  * MADs received in response to a send request operation will be handed to
- * the user after the send operation completes.  All data buffers given
+ * the user before the send operation completes.  All data buffers given
  * to registered agents through this routine are owned by the receiving
  * client, except for snooping agents.  Clients snooping MADs should not
  * modify the data referenced by @mad_recv_wc.
@@ -485,17 +497,6 @@ int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent);
 int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
                     struct ib_mad_send_buf **bad_send_buf);
 
-/**
- * ib_coalesce_recv_mad - Coalesces received MAD data into a single buffer.
- * @mad_recv_wc: Work completion information for a received MAD.
- * @buf: User-provided data buffer to receive the coalesced buffers.  The
- *   referenced buffer should be at least the size of the mad_len specified
- *   by @mad_recv_wc.
- *
- * This call copies a chain of received MAD segments into a single data buffer,
- * removing duplicated headers.
- */
-void ib_coalesce_recv_mad(struct ib_mad_recv_wc *mad_recv_wc, void *buf);
 
 /**
  * ib_free_recv_mad - Returns data buffers used to receive a MAD.
@@ -590,9 +591,10 @@ int ib_process_mad_wc(struct ib_mad_agent *mad_agent,
  * with an initialized work request structure.  Users may modify the returned
  * MAD data buffer before posting the send.
  *
- * The returned data buffer will be cleared.  Users are responsible for
- * initializing the common MAD and any class specific headers.  If @rmpp_active
- * is set, the RMPP header will be initialized for sending.
+ * The returned MAD header, class specific headers, and any padding will be
+ * cleared.  Users are responsible for initializing the common MAD header,
+ * any class specific header, and MAD data area.
+ * If @rmpp_active is set, the RMPP header will be initialized for sending.
  */
 struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
                                            u32 remote_qpn, u16 pkey_index,
@@ -600,6 +602,16 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
                                            int hdr_len, int data_len,
                                            gfp_t gfp_mask);
 
+/**
+ * ib_get_rmpp_segment - returns the data buffer for a given RMPP segment.
+ * @send_buf: Previously allocated send data buffer.
+ * @seg_num: number of segment to return
+ *
+ * This routine returns a pointer to the data buffer of an RMPP MAD.
+ * Users must provide synchronization to @send_buf around this call.
+ */
+void *ib_get_rmpp_segment(struct ib_mad_send_buf *send_buf, int seg_num);
+
 /**
  * ib_free_send_mad - Returns data buffers used to send a MAD.
  * @send_buf: Previously allocated send data buffer.
index 5ff1490c08db21a0dca8b4930bc2f6eaaf7fa76c..338ed433306381c543aa963058804caddb48d7ed 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Copyright (c) 2005 Topspin Communications.  All rights reserved.
- * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
  * Copyright (c) 2005 PathScale, Inc.  All rights reserved.
+ * Copyright (c) 2006 Mellanox Technologies.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -43,7 +44,7 @@
  * Increment this value if any changes that break userspace ABI
  * compatibility are made.
  */
-#define IB_USER_VERBS_ABI_VERSION      4
+#define IB_USER_VERBS_ABI_VERSION      6
 
 enum {
        IB_USER_VERBS_CMD_GET_CONTEXT,
@@ -265,6 +266,17 @@ struct ib_uverbs_create_cq_resp {
        __u32 cqe;
 };
 
+struct ib_uverbs_resize_cq {
+       __u64 response;
+       __u32 cq_handle;
+       __u32 cqe;
+       __u64 driver_data[0];
+};
+
+struct ib_uverbs_resize_cq_resp {
+       __u32 cqe;
+};
+
 struct ib_uverbs_poll_cq {
        __u64 response;
        __u32 cq_handle;
@@ -338,6 +350,7 @@ struct ib_uverbs_create_qp_resp {
        __u32 max_send_sge;
        __u32 max_recv_sge;
        __u32 max_inline_data;
+       __u32 reserved;
 };
 
 /*
@@ -359,6 +372,47 @@ struct ib_uverbs_qp_dest {
        __u8  port_num;
 };
 
+struct ib_uverbs_query_qp {
+       __u64 response;
+       __u32 qp_handle;
+       __u32 attr_mask;
+       __u64 driver_data[0];
+};
+
+struct ib_uverbs_query_qp_resp {
+       struct ib_uverbs_qp_dest dest;
+       struct ib_uverbs_qp_dest alt_dest;
+       __u32 max_send_wr;
+       __u32 max_recv_wr;
+       __u32 max_send_sge;
+       __u32 max_recv_sge;
+       __u32 max_inline_data;
+       __u32 qkey;
+       __u32 rq_psn;
+       __u32 sq_psn;
+       __u32 dest_qp_num;
+       __u32 qp_access_flags;
+       __u16 pkey_index;
+       __u16 alt_pkey_index;
+       __u8  qp_state;
+       __u8  cur_qp_state;
+       __u8  path_mtu;
+       __u8  path_mig_state;
+       __u8  en_sqd_async_notify;
+       __u8  max_rd_atomic;
+       __u8  max_dest_rd_atomic;
+       __u8  min_rnr_timer;
+       __u8  port_num;
+       __u8  timeout;
+       __u8  retry_cnt;
+       __u8  rnr_retry;
+       __u8  alt_port_num;
+       __u8  alt_timeout;
+       __u8  sq_sig_all;
+       __u8  reserved[5];
+       __u64 driver_data[0];
+};
+
 struct ib_uverbs_modify_qp {
        struct ib_uverbs_qp_dest dest;
        struct ib_uverbs_qp_dest alt_dest;
@@ -415,7 +469,7 @@ struct ib_uverbs_sge {
 };
 
 struct ib_uverbs_send_wr {
-       __u64 wr_id; 
+       __u64 wr_id;
        __u32 num_sge;
        __u32 opcode;
        __u32 send_flags;
@@ -489,7 +543,7 @@ struct ib_uverbs_post_srq_recv_resp {
 
 struct ib_uverbs_global_route {
        __u8  dgid[16];
-       __u32 flow_label;    
+       __u32 flow_label;
        __u8  sgid_index;
        __u8  hop_limit;
        __u8  traffic_class;
@@ -551,6 +605,9 @@ struct ib_uverbs_create_srq {
 
 struct ib_uverbs_create_srq_resp {
        __u32 srq_handle;
+       __u32 max_wr;
+       __u32 max_sge;
+       __u32 reserved;
 };
 
 struct ib_uverbs_modify_srq {
@@ -561,6 +618,20 @@ struct ib_uverbs_modify_srq {
        __u64 driver_data[0];
 };
 
+struct ib_uverbs_query_srq {
+       __u64 response;
+       __u32 srq_handle;
+       __u32 reserved;
+       __u64 driver_data[0];
+};
+
+struct ib_uverbs_query_srq_resp {
+       __u32 max_wr;
+       __u32 max_sge;
+       __u32 srq_limit;
+       __u32 reserved;
+};
+
 struct ib_uverbs_destroy_srq {
        __u64 response;
        __u32 srq_handle;
index 22fc886b9695f94fdca32e4d57b36a2391de7bc4..c1ad6273ac6ca5f5fcb20d9dfd7f1bdcc08ccd6b 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
  * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -222,11 +222,13 @@ struct ib_port_attr {
 };
 
 enum ib_device_modify_flags {
-       IB_DEVICE_MODIFY_SYS_IMAGE_GUID = 1
+       IB_DEVICE_MODIFY_SYS_IMAGE_GUID = 1 << 0,
+       IB_DEVICE_MODIFY_NODE_DESC      = 1 << 1
 };
 
 struct ib_device_modify {
        u64     sys_image_guid;
+       char    node_desc[64];
 };
 
 enum ib_port_modify_flags {
@@ -649,7 +651,7 @@ struct ib_mw_bind {
 struct ib_fmr_attr {
        int     max_pages;
        int     max_maps;
-       u8      page_size;
+       u8      page_shift;
 };
 
 struct ib_ucontext {
@@ -880,7 +882,8 @@ struct ib_device {
                                                struct ib_ucontext *context,
                                                struct ib_udata *udata);
        int                        (*destroy_cq)(struct ib_cq *cq);
-       int                        (*resize_cq)(struct ib_cq *cq, int cqe);
+       int                        (*resize_cq)(struct ib_cq *cq, int cqe,
+                                               struct ib_udata *udata);
        int                        (*poll_cq)(struct ib_cq *cq, int num_entries,
                                              struct ib_wc *wc);
        int                        (*peek_cq)(struct ib_cq *cq, int wc_cnt);
@@ -950,6 +953,7 @@ struct ib_device {
        u64                          uverbs_cmd_mask;
        int                          uverbs_abi_ver;
 
+       char                         node_desc[64];
        __be64                       node_guid;
        u8                           node_type;
        u8                           phys_port_cnt;
@@ -986,6 +990,24 @@ static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len
        return copy_to_user(udata->outbuf, src, len) ? -EFAULT : 0;
 }
 
+/**
+ * ib_modify_qp_is_ok - Check that the supplied attribute mask
+ * contains all required attributes and no attributes not allowed for
+ * the given QP state transition.
+ * @cur_state: Current QP state
+ * @next_state: Next QP state
+ * @type: QP type
+ * @mask: Mask of supplied QP attributes
+ *
+ * This function is a helper function that a low-level driver's
+ * modify_qp method can use to validate the consumer's input.  It
+ * checks that cur_state and next_state are valid QP states, that a
+ * transition from cur_state to next_state is allowed by the IB spec,
+ * and that the attribute mask supplied is allowed for the transition.
+ */
+int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
+                      enum ib_qp_type type, enum ib_qp_attr_mask mask);
+
 int ib_register_event_handler  (struct ib_event_handler *event_handler);
 int ib_unregister_event_handler(struct ib_event_handler *event_handler);
 void ib_dispatch_event(struct ib_event *event);
@@ -1078,7 +1100,9 @@ int ib_destroy_ah(struct ib_ah *ah);
  * ib_create_srq - Creates a SRQ associated with the specified protection
  *   domain.
  * @pd: The protection domain associated with the SRQ.
- * @srq_init_attr: A list of initial attributes required to create the SRQ.
+ * @srq_init_attr: A list of initial attributes required to create the
+ *   SRQ.  If SRQ creation succeeds, then the attributes are updated to
+ *   the actual capabilities of the created SRQ.
  *
  * srq_attr->max_wr and srq_attr->max_sge are read the determine the
  * requested size of the SRQ, and set to the actual values allocated
@@ -1137,7 +1161,9 @@ static inline int ib_post_srq_recv(struct ib_srq *srq,
  * ib_create_qp - Creates a QP associated with the specified protection
  *   domain.
  * @pd: The protection domain associated with the QP.
- * @qp_init_attr: A list of initial attributes required to create the QP.
+ * @qp_init_attr: A list of initial attributes required to create the
+ *   QP.  If QP creation succeeds, then the attributes are updated to
+ *   the actual capabilities of the created QP.
  */
 struct ib_qp *ib_create_qp(struct ib_pd *pd,
                           struct ib_qp_init_attr *qp_init_attr);
index fabd879c2f2e13e44f41a08083241fc6a20a6914..d160880b2a8798f18d3c0772ef84281e9d0bb6bc 100644 (file)
@@ -35,6 +35,9 @@ static inline int scsi_sense_valid(struct scsi_sense_hdr *sshdr)
 }
 
 
+extern void scsi_eh_finish_cmd(struct scsi_cmnd *scmd,
+                              struct list_head *done_q);
+extern void scsi_eh_flush_done_q(struct list_head *done_q);
 extern void scsi_report_bus_reset(struct Scsi_Host *, int);
 extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
 extern int scsi_block_when_processing_errors(struct scsi_device *);
index d5eeae0fa5bc5c6de327a7c0f583c4fdaca16b50..f2690ed7453068460f432a52dc97f685a950ec0a 100644 (file)
@@ -15,9 +15,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
-u64 uevent_seqnum;
-char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug";
-
 #define KERNEL_ATTR_RO(_name) \
 static struct subsys_attribute _name##_attr = __ATTR_RO(_name)
 
index 5aad477ddc79c94567c02e9ee704f1eb71fa1b66..77764f22f021e252fe0455cfa8ba9d3316b0e6f1 100644 (file)
@@ -126,8 +126,11 @@ extern const struct kernel_symbol __start___ksymtab[];
 extern const struct kernel_symbol __stop___ksymtab[];
 extern const struct kernel_symbol __start___ksymtab_gpl[];
 extern const struct kernel_symbol __stop___ksymtab_gpl[];
+extern const struct kernel_symbol __start___ksymtab_gpl_future[];
+extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
 extern const unsigned long __start___kcrctab[];
 extern const unsigned long __start___kcrctab_gpl[];
+extern const unsigned long __start___kcrctab_gpl_future[];
 
 #ifndef CONFIG_MODVERSIONS
 #define symversion(base, idx) NULL
@@ -135,6 +138,18 @@ extern const unsigned long __start___kcrctab_gpl[];
 #define symversion(base, idx) ((base) ? ((base) + (idx)) : NULL)
 #endif
 
+/* lookup symbol in given range of kernel_symbols */
+static const struct kernel_symbol *lookup_symbol(const char *name,
+       const struct kernel_symbol *start,
+       const struct kernel_symbol *stop)
+{
+       const struct kernel_symbol *ks = start;
+       for (; ks < stop; ks++)
+               if (strcmp(ks->name, name) == 0)
+                       return ks;
+       return NULL;
+}
+
 /* Find a symbol, return value, crc and module which owns it */
 static unsigned long __find_symbol(const char *name,
                                   struct module **owner,
@@ -142,40 +157,75 @@ static unsigned long __find_symbol(const char *name,
                                   int gplok)
 {
        struct module *mod;
-       unsigned int i;
+       const struct kernel_symbol *ks;
 
        /* Core kernel first. */ 
        *owner = NULL;
-       for (i = 0; __start___ksymtab+i < __stop___ksymtab; i++) {
-               if (strcmp(__start___ksymtab[i].name, name) == 0) {
-                       *crc = symversion(__start___kcrctab, i);
-                       return __start___ksymtab[i].value;
-               }
+       ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
+       if (ks) {
+               *crc = symversion(__start___kcrctab, (ks - __start___ksymtab));
+               return ks->value;
        }
        if (gplok) {
-               for (i = 0; __start___ksymtab_gpl+i<__stop___ksymtab_gpl; i++)
-                       if (strcmp(__start___ksymtab_gpl[i].name, name) == 0) {
-                               *crc = symversion(__start___kcrctab_gpl, i);
-                               return __start___ksymtab_gpl[i].value;
-                       }
+               ks = lookup_symbol(name, __start___ksymtab_gpl,
+                                        __stop___ksymtab_gpl);
+               if (ks) {
+                       *crc = symversion(__start___kcrctab_gpl,
+                                         (ks - __start___ksymtab_gpl));
+                       return ks->value;
+               }
+       }
+       ks = lookup_symbol(name, __start___ksymtab_gpl_future,
+                                __stop___ksymtab_gpl_future);
+       if (ks) {
+               if (!gplok) {
+                       printk(KERN_WARNING "Symbol %s is being used "
+                              "by a non-GPL module, which will not "
+                              "be allowed in the future\n", name);
+                       printk(KERN_WARNING "Please see the file "
+                              "Documentation/feature-removal-schedule.txt "
+                              "in the kernel source tree for more "
+                              "details.\n");
+               }
+               *crc = symversion(__start___kcrctab_gpl_future,
+                                 (ks - __start___ksymtab_gpl_future));
+               return ks->value;
        }
 
        /* Now try modules. */ 
        list_for_each_entry(mod, &modules, list) {
                *owner = mod;
-               for (i = 0; i < mod->num_syms; i++)
-                       if (strcmp(mod->syms[i].name, name) == 0) {
-                               *crc = symversion(mod->crcs, i);
-                               return mod->syms[i].value;
-                       }
+               ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
+               if (ks) {
+                       *crc = symversion(mod->crcs, (ks - mod->syms));
+                       return ks->value;
+               }
 
                if (gplok) {
-                       for (i = 0; i < mod->num_gpl_syms; i++) {
-                               if (strcmp(mod->gpl_syms[i].name, name) == 0) {
-                                       *crc = symversion(mod->gpl_crcs, i);
-                                       return mod->gpl_syms[i].value;
-                               }
+                       ks = lookup_symbol(name, mod->gpl_syms,
+                                          mod->gpl_syms + mod->num_gpl_syms);
+                       if (ks) {
+                               *crc = symversion(mod->gpl_crcs,
+                                                 (ks - mod->gpl_syms));
+                               return ks->value;
+                       }
+               }
+               ks = lookup_symbol(name, mod->gpl_future_syms,
+                                  (mod->gpl_future_syms +
+                                   mod->num_gpl_future_syms));
+               if (ks) {
+                       if (!gplok) {
+                               printk(KERN_WARNING "Symbol %s is being used "
+                                      "by a non-GPL module, which will not "
+                                      "be allowed in the future\n", name);
+                               printk(KERN_WARNING "Please see the file "
+                                      "Documentation/feature-removal-schedule.txt "
+                                      "in the kernel source tree for more "
+                                      "details.\n");
                        }
+                       *crc = symversion(mod->gpl_future_crcs,
+                                         (ks - mod->gpl_future_syms));
+                       return ks->value;
                }
        }
        DEBUGP("Failed to find symbol %s\n", name);
@@ -379,7 +429,6 @@ static inline void percpu_modcopy(void *pcpudst, const void *src,
 }
 #endif /* CONFIG_SMP */
 
-#ifdef CONFIG_MODULE_UNLOAD
 #define MODINFO_ATTR(field)    \
 static void setup_modinfo_##field(struct module *mod, const char *s)  \
 {                                                                     \
@@ -411,12 +460,7 @@ static struct module_attribute modinfo_##field = {                    \
 MODINFO_ATTR(version);
 MODINFO_ATTR(srcversion);
 
-static struct module_attribute *modinfo_attrs[] = {
-       &modinfo_version,
-       &modinfo_srcversion,
-       NULL,
-};
-
+#ifdef CONFIG_MODULE_UNLOAD
 /* Init the unload section of the module. */
 static void module_unload_init(struct module *mod)
 {
@@ -731,6 +775,15 @@ static inline void module_unload_init(struct module *mod)
 }
 #endif /* CONFIG_MODULE_UNLOAD */
 
+static struct module_attribute *modinfo_attrs[] = {
+       &modinfo_version,
+       &modinfo_srcversion,
+#ifdef CONFIG_MODULE_UNLOAD
+       &refcnt,
+#endif
+       NULL,
+};
+
 #ifdef CONFIG_OBSOLETE_MODPARM
 /* Bounds checking done below */
 static int obsparm_copy_string(const char *val, struct kernel_param *kp)
@@ -1056,37 +1109,28 @@ static inline void remove_sect_attrs(struct module *mod)
 }
 #endif /* CONFIG_KALLSYMS */
 
-
-#ifdef CONFIG_MODULE_UNLOAD
-static inline int module_add_refcnt_attr(struct module *mod)
-{
-       return sysfs_create_file(&mod->mkobj.kobj, &refcnt.attr);
-}
-static void module_remove_refcnt_attr(struct module *mod)
-{
-       return sysfs_remove_file(&mod->mkobj.kobj, &refcnt.attr);
-}
-#else
-static inline int module_add_refcnt_attr(struct module *mod)
-{
-       return 0;
-}
-static void module_remove_refcnt_attr(struct module *mod)
-{
-}
-#endif
-
-#ifdef CONFIG_MODULE_UNLOAD
 static int module_add_modinfo_attrs(struct module *mod)
 {
        struct module_attribute *attr;
+       struct module_attribute *temp_attr;
        int error = 0;
        int i;
 
+       mod->modinfo_attrs = kzalloc((sizeof(struct module_attribute) *
+                                       (ARRAY_SIZE(modinfo_attrs) + 1)),
+                                       GFP_KERNEL);
+       if (!mod->modinfo_attrs)
+               return -ENOMEM;
+
+       temp_attr = mod->modinfo_attrs;
        for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) {
                if (!attr->test ||
-                   (attr->test && attr->test(mod)))
-                       error = sysfs_create_file(&mod->mkobj.kobj,&attr->attr);
+                   (attr->test && attr->test(mod))) {
+                       memcpy(temp_attr, attr, sizeof(*temp_attr));
+                       temp_attr->attr.owner = mod;
+                       error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr);
+                       ++temp_attr;
+               }
        }
        return error;
 }
@@ -1096,12 +1140,16 @@ static void module_remove_modinfo_attrs(struct module *mod)
        struct module_attribute *attr;
        int i;
 
-       for (i = 0; (attr = modinfo_attrs[i]); i++) {
+       for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) {
+               /* pick a field to test for end of list */
+               if (!attr->attr.name)
+                       break;
                sysfs_remove_file(&mod->mkobj.kobj,&attr->attr);
-               attr->free(mod);
+               if (attr->free)
+                       attr->free(mod);
        }
+       kfree(mod->modinfo_attrs);
 }
-#endif
 
 static int mod_sysfs_setup(struct module *mod,
                           struct kernel_param *kparam,
@@ -1119,19 +1167,13 @@ static int mod_sysfs_setup(struct module *mod,
        if (err)
                goto out;
 
-       err = module_add_refcnt_attr(mod);
-       if (err)
-               goto out_unreg;
-
        err = module_param_sysfs_setup(mod, kparam, num_params);
        if (err)
                goto out_unreg;
 
-#ifdef CONFIG_MODULE_UNLOAD
        err = module_add_modinfo_attrs(mod);
        if (err)
                goto out_unreg;
-#endif
 
        return 0;
 
@@ -1143,10 +1185,7 @@ out:
 
 static void mod_kobject_remove(struct module *mod)
 {
-#ifdef CONFIG_MODULE_UNLOAD
        module_remove_modinfo_attrs(mod);
-#endif
-       module_remove_refcnt_attr(mod);
        module_param_sysfs_remove(mod);
 
        kobject_unregister(&mod->mkobj.kobj);
@@ -1424,7 +1463,6 @@ static char *get_modinfo(Elf_Shdr *sechdrs,
        return NULL;
 }
 
-#ifdef CONFIG_MODULE_UNLOAD
 static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
                          unsigned int infoindex)
 {
@@ -1439,23 +1477,17 @@ static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
                                                attr->attr.name));
        }
 }
-#endif
 
 #ifdef CONFIG_KALLSYMS
 int is_exported(const char *name, const struct module *mod)
 {
-       unsigned int i;
-
-       if (!mod) {
-               for (i = 0; __start___ksymtab+i < __stop___ksymtab; i++)
-                       if (strcmp(__start___ksymtab[i].name, name) == 0)
-                               return 1;
-               return 0;
-       }
-       for (i = 0; i < mod->num_syms; i++)
-               if (strcmp(mod->syms[i].name, name) == 0)
+       if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab))
+               return 1;
+       else
+               if (lookup_symbol(name, mod->syms, mod->syms + mod->num_syms))
                        return 1;
-       return 0;
+               else
+                       return 0;
 }
 
 /* As per nm */
@@ -1537,7 +1569,8 @@ static struct module *load_module(void __user *umod,
        char *secstrings, *args, *modmagic, *strtab = NULL;
        unsigned int i, symindex = 0, strindex = 0, setupindex, exindex,
                exportindex, modindex, obsparmindex, infoindex, gplindex,
-               crcindex, gplcrcindex, versindex, pcpuindex;
+               crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex,
+               gplfuturecrcindex;
        long arglen;
        struct module *mod;
        long err = 0;
@@ -1618,8 +1651,10 @@ static struct module *load_module(void __user *umod,
        /* Optional sections */
        exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
        gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
+       gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
        crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
        gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
+       gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
        setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
        exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
        obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
@@ -1755,10 +1790,8 @@ static struct module *load_module(void __user *umod,
        if (strcmp(mod->name, "driverloader") == 0)
                add_taint(TAINT_PROPRIETARY_MODULE);
 
-#ifdef CONFIG_MODULE_UNLOAD
        /* Set up MODINFO_ATTR fields */
        setup_modinfo(mod, sechdrs, infoindex);
-#endif
 
        /* Fix up syms, so that st_value is a pointer to location. */
        err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
@@ -1775,10 +1808,16 @@ static struct module *load_module(void __user *umod,
        mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr;
        if (gplcrcindex)
                mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
+       mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
+                                       sizeof(*mod->gpl_future_syms);
+       mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
+       if (gplfuturecrcindex)
+               mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
 
 #ifdef CONFIG_MODVERSIONS
        if ((mod->num_syms && !crcindex) || 
-           (mod->num_gpl_syms && !gplcrcindex)) {
+           (mod->num_gpl_syms && !gplcrcindex) ||
+           (mod->num_gpl_future_syms && !gplfuturecrcindex)) {
                printk(KERN_WARNING "%s: No versions for exported symbols."
                       " Tainting kernel.\n", mod->name);
                add_taint(TAINT_FORCED_MODULE);
index c76ad25e6a214df9d534f5142da9f2a1a1729b52..a29150582310e05e5bedd83f5e216610c9e69495 100644 (file)
@@ -638,13 +638,8 @@ static ssize_t module_attr_show(struct kobject *kobj,
        if (!attribute->show)
                return -EIO;
 
-       if (!try_module_get(mk->mod))
-               return -ENODEV;
-
        ret = attribute->show(attribute, mk->mod, buf);
 
-       module_put(mk->mod);
-
        return ret;
 }
 
@@ -662,13 +657,8 @@ static ssize_t module_attr_store(struct kobject *kobj,
        if (!attribute->store)
                return -EIO;
 
-       if (!try_module_get(mk->mod))
-               return -ENODEV;
-
        ret = attribute->store(attribute, mk->mod, buf, len);
 
-       module_put(mk->mod);
-
        return ret;
 }
 
index 8cf15a569fcdece3c61b0ad61574802eba95f51f..fedf5e3697556417a25f1cbe54f4cebc7d5f1087 100644 (file)
@@ -609,7 +609,7 @@ module_param(qlowmark, int, 0);
 module_param(rsinterval, int, 0);
 #endif
 EXPORT_SYMBOL_GPL(rcu_batches_completed);
-EXPORT_SYMBOL(call_rcu);  /* WARNING: GPL-only in April 2006. */
-EXPORT_SYMBOL(call_rcu_bh);  /* WARNING: GPL-only in April 2006. */
+EXPORT_SYMBOL_GPL_FUTURE(call_rcu);    /* WARNING: GPL-only in April 2006. */
+EXPORT_SYMBOL_GPL_FUTURE(call_rcu_bh); /* WARNING: GPL-only in April 2006. */
 EXPORT_SYMBOL_GPL(synchronize_rcu);
-EXPORT_SYMBOL(synchronize_kernel);  /* WARNING: GPL-only in April 2006. */
+EXPORT_SYMBOL_GPL_FUTURE(synchronize_kernel); /* WARNING: GPL-only in April 2006. */
index efe67fa96a71647b3af9f6c010fd2abc4a661619..25204a41a9b01d5764ccdeffba064af81e584c05 100644 (file)
@@ -194,6 +194,17 @@ int kobject_add(struct kobject * kobj)
                unlink(kobj);
                if (parent)
                        kobject_put(parent);
+
+               /* be noisy on error issues */
+               if (error == -EEXIST)
+                       printk("kobject_add failed for %s with -EEXIST, "
+                              "don't try to register things with the "
+                              "same name in the same directory.\n",
+                              kobject_name(kobj));
+               else
+                       printk("kobject_add failed for %s (%d)\n",
+                              kobject_name(kobj), error);
+               dump_stack();
        }
 
        return error;
@@ -207,18 +218,13 @@ int kobject_add(struct kobject * kobj)
 
 int kobject_register(struct kobject * kobj)
 {
-       int error = 0;
+       int error = -EINVAL;
        if (kobj) {
                kobject_init(kobj);
                error = kobject_add(kobj);
-               if (error) {
-                       printk("kobject_register failed for %s (%d)\n",
-                              kobject_name(kobj),error);
-                       dump_stack();
-               } else
+               if (!error)
                        kobject_uevent(kobj, KOBJ_ADD);
-       } else
-               error = -EINVAL;
+       }
        return error;
 }
 
@@ -379,6 +385,44 @@ void kobject_put(struct kobject * kobj)
 }
 
 
+static void dir_release(struct kobject *kobj)
+{
+       kfree(kobj);
+}
+
+static struct kobj_type dir_ktype = {
+       .release        = dir_release,
+       .sysfs_ops      = NULL,
+       .default_attrs  = NULL,
+};
+
+/**
+ *     kobject_add_dir - add sub directory of object.
+ *     @parent:        object in which a directory is created.
+ *     @name:  directory name.
+ *
+ *     Add a plain directory object as child of given object.
+ */
+struct kobject *kobject_add_dir(struct kobject *parent, const char *name)
+{
+       struct kobject *k;
+
+       if (!parent)
+               return NULL;
+
+       k = kzalloc(sizeof(*k), GFP_KERNEL);
+       if (!k)
+               return NULL;
+
+       k->parent = parent;
+       k->ktype = &dir_ktype;
+       kobject_set_name(k, name);
+       kobject_register(k);
+
+       return k;
+}
+EXPORT_SYMBOL_GPL(kobject_add_dir);
+
 /**
  *     kset_init - initialize a kset for use
  *     @k:     kset 
index 086a0c6e888e99aef43aeab96c40ddb56b6146a1..982226daf9398112185a5eb717c28d396fcb9341 100644 (file)
@@ -26,6 +26,8 @@
 #define NUM_ENVP       32      /* number of env pointers */
 
 #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
+u64 uevent_seqnum;
+char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug";
 static DEFINE_SPINLOCK(sequence_lock);
 static struct sock *uevent_sock;
 
index 0d07cc31c818108a5d9e3bc26444957108bad721..4a467faf1367bb031d49eb136ac16de0551a1629 100644 (file)
@@ -52,7 +52,12 @@ int kref_put(struct kref *kref, void (*release)(struct kref *kref))
        WARN_ON(release == NULL);
        WARN_ON(release == (void (*)(struct kref *))kfree);
 
-       if (atomic_dec_and_test(&kref->refcount)) {
+       /*
+        * if current count is one, we are the last user and can release object
+        * right now, avoiding an atomic operation on 'refcount'
+        */
+       if ((atomic_read(&kref->refcount) == 1) ||
+           (atomic_dec_and_test(&kref->refcount))) {
                release(kref);
                return 1;
        }
index ee4647805c586b18e08549aca340f570d35aafdc..d8153f572e404bcae66a67d405959dbc89feb01d 100644 (file)
@@ -52,9 +52,9 @@ is_reserved_hash (register const char *str, register unsigned int len)
       71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
       71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
       71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
-      71, 71, 71, 71, 71, 71, 71, 71, 71, 15,
-      71, 71, 71, 71, 71, 71, 15, 71, 71, 71,
-      10, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71,  0,
+      71, 71, 71, 71, 71, 71, 35, 71, 71, 71,
+       5, 71, 71, 71, 71, 71, 71, 71, 71, 71,
       71, 71, 71, 71, 71,  0, 71,  0, 71,  5,
        5,  0, 10, 20, 71, 25, 71, 71, 20,  0,
       20, 30, 25, 71, 10,  5,  0, 20, 15, 71,
@@ -84,9 +84,9 @@ is_reserved_word (register const char *str, register unsigned int len)
 {
   enum
     {
-      TOTAL_KEYWORDS = 41,
+      TOTAL_KEYWORDS = 42,
       MIN_WORD_LENGTH = 3,
-      MAX_WORD_LENGTH = 17,
+      MAX_WORD_LENGTH = 24,
       MIN_HASH_VALUE = 3,
       MAX_HASH_VALUE = 70
     };
@@ -94,104 +94,105 @@ is_reserved_word (register const char *str, register unsigned int len)
   static const struct resword wordlist[] =
     {
       {""}, {""}, {""},
-#line 24 "scripts/genksyms/keywords.gperf"
+#line 25 "scripts/genksyms/keywords.gperf"
       {"asm", ASM_KEYW},
       {""},
-#line 7 "scripts/genksyms/keywords.gperf"
+#line 8 "scripts/genksyms/keywords.gperf"
       {"__asm", ASM_KEYW},
       {""},
-#line 8 "scripts/genksyms/keywords.gperf"
+#line 9 "scripts/genksyms/keywords.gperf"
       {"__asm__", ASM_KEYW},
       {""},
-#line 21 "scripts/genksyms/keywords.gperf"
+#line 22 "scripts/genksyms/keywords.gperf"
       {"_restrict", RESTRICT_KEYW},
-#line 50 "scripts/genksyms/keywords.gperf"
+#line 51 "scripts/genksyms/keywords.gperf"
       {"__typeof__", TYPEOF_KEYW},
-#line 9 "scripts/genksyms/keywords.gperf"
+#line 10 "scripts/genksyms/keywords.gperf"
       {"__attribute", ATTRIBUTE_KEYW},
-#line 11 "scripts/genksyms/keywords.gperf"
+#line 12 "scripts/genksyms/keywords.gperf"
       {"__const", CONST_KEYW},
-#line 10 "scripts/genksyms/keywords.gperf"
+#line 11 "scripts/genksyms/keywords.gperf"
       {"__attribute__", ATTRIBUTE_KEYW},
-#line 12 "scripts/genksyms/keywords.gperf"
+#line 13 "scripts/genksyms/keywords.gperf"
       {"__const__", CONST_KEYW},
-#line 16 "scripts/genksyms/keywords.gperf"
+#line 17 "scripts/genksyms/keywords.gperf"
       {"__signed__", SIGNED_KEYW},
-#line 42 "scripts/genksyms/keywords.gperf"
+#line 43 "scripts/genksyms/keywords.gperf"
       {"static", STATIC_KEYW},
       {""},
-#line 15 "scripts/genksyms/keywords.gperf"
+#line 16 "scripts/genksyms/keywords.gperf"
       {"__signed", SIGNED_KEYW},
-#line 30 "scripts/genksyms/keywords.gperf"
+#line 31 "scripts/genksyms/keywords.gperf"
       {"char", CHAR_KEYW},
       {""},
-#line 43 "scripts/genksyms/keywords.gperf"
+#line 44 "scripts/genksyms/keywords.gperf"
       {"struct", STRUCT_KEYW},
-#line 22 "scripts/genksyms/keywords.gperf"
-      {"__restrict__", RESTRICT_KEYW},
 #line 23 "scripts/genksyms/keywords.gperf"
+      {"__restrict__", RESTRICT_KEYW},
+#line 24 "scripts/genksyms/keywords.gperf"
       {"restrict", RESTRICT_KEYW},
-#line 33 "scripts/genksyms/keywords.gperf"
+#line 34 "scripts/genksyms/keywords.gperf"
       {"enum", ENUM_KEYW},
-#line 17 "scripts/genksyms/keywords.gperf"
+#line 18 "scripts/genksyms/keywords.gperf"
       {"__volatile", VOLATILE_KEYW},
-#line 34 "scripts/genksyms/keywords.gperf"
+#line 35 "scripts/genksyms/keywords.gperf"
       {"extern", EXTERN_KEYW},
-#line 18 "scripts/genksyms/keywords.gperf"
+#line 19 "scripts/genksyms/keywords.gperf"
       {"__volatile__", VOLATILE_KEYW},
-#line 37 "scripts/genksyms/keywords.gperf"
+#line 38 "scripts/genksyms/keywords.gperf"
       {"int", INT_KEYW},
-      {""},
-#line 31 "scripts/genksyms/keywords.gperf"
-      {"const", CONST_KEYW},
+#line 7 "scripts/genksyms/keywords.gperf"
+      {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
 #line 32 "scripts/genksyms/keywords.gperf"
+      {"const", CONST_KEYW},
+#line 33 "scripts/genksyms/keywords.gperf"
       {"double", DOUBLE_KEYW},
       {""},
-#line 13 "scripts/genksyms/keywords.gperf"
+#line 14 "scripts/genksyms/keywords.gperf"
       {"__inline", INLINE_KEYW},
-#line 29 "scripts/genksyms/keywords.gperf"
+#line 30 "scripts/genksyms/keywords.gperf"
       {"auto", AUTO_KEYW},
-#line 14 "scripts/genksyms/keywords.gperf"
+#line 15 "scripts/genksyms/keywords.gperf"
       {"__inline__", INLINE_KEYW},
-#line 41 "scripts/genksyms/keywords.gperf"
+#line 42 "scripts/genksyms/keywords.gperf"
       {"signed", SIGNED_KEYW},
       {""},
-#line 46 "scripts/genksyms/keywords.gperf"
+#line 47 "scripts/genksyms/keywords.gperf"
       {"unsigned", UNSIGNED_KEYW},
       {""},
-#line 40 "scripts/genksyms/keywords.gperf"
+#line 41 "scripts/genksyms/keywords.gperf"
       {"short", SHORT_KEYW},
-#line 49 "scripts/genksyms/keywords.gperf"
+#line 50 "scripts/genksyms/keywords.gperf"
       {"typeof", TYPEOF_KEYW},
-#line 44 "scripts/genksyms/keywords.gperf"
+#line 45 "scripts/genksyms/keywords.gperf"
       {"typedef", TYPEDEF_KEYW},
-#line 48 "scripts/genksyms/keywords.gperf"
+#line 49 "scripts/genksyms/keywords.gperf"
       {"volatile", VOLATILE_KEYW},
       {""},
-#line 35 "scripts/genksyms/keywords.gperf"
+#line 36 "scripts/genksyms/keywords.gperf"
       {"float", FLOAT_KEYW},
       {""}, {""},
-#line 39 "scripts/genksyms/keywords.gperf"
+#line 40 "scripts/genksyms/keywords.gperf"
       {"register", REGISTER_KEYW},
-#line 47 "scripts/genksyms/keywords.gperf"
+#line 48 "scripts/genksyms/keywords.gperf"
       {"void", VOID_KEYW},
       {""},
-#line 36 "scripts/genksyms/keywords.gperf"
+#line 37 "scripts/genksyms/keywords.gperf"
       {"inline", INLINE_KEYW},
       {""},
 #line 5 "scripts/genksyms/keywords.gperf"
       {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
       {""},
-#line 20 "scripts/genksyms/keywords.gperf"
+#line 21 "scripts/genksyms/keywords.gperf"
       {"_Bool", BOOL_KEYW},
       {""},
 #line 6 "scripts/genksyms/keywords.gperf"
       {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
       {""}, {""}, {""}, {""}, {""}, {""},
-#line 38 "scripts/genksyms/keywords.gperf"
+#line 39 "scripts/genksyms/keywords.gperf"
       {"long", LONG_KEYW},
       {""}, {""}, {""}, {""}, {""},
-#line 45 "scripts/genksyms/keywords.gperf"
+#line 46 "scripts/genksyms/keywords.gperf"
       {"union", UNION_KEYW}
     };
 
index b6bec765996e3301daa1bb2b39d9c25109d8c712..c75e0c8d8f0c4f0b1e4749f5b440fd8f1bd26772 100644 (file)
@@ -4,6 +4,7 @@ struct resword { const char *name; int token; }
 %%
 EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
 EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
+EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW
 __asm, ASM_KEYW
 __asm__, ASM_KEYW
 __attribute, ATTRIBUTE_KEYW