# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet v2.6.1-rc1 -> 1.1568 # include/asm-x86_64/irq.h 1.4 -> 1.5 # include/asm-x86_64/smp.h 1.13 -> 1.14 # drivers/media/dvb/ttusb-dec/ttusb_dec.h 1.2 -> (deleted) # arch/x86_64/kernel/traps.c 1.30 -> 1.31 # arch/x86_64/mm/fault.c 1.18 -> 1.19 # include/asm-sparc64/pgtable.h 1.32 -> 1.33 # arch/x86_64/kernel/setup.c 1.24 -> 1.25 # net/ipv6/ip6_output.c 1.46 -> 1.47 # drivers/media/dvb/frontends/mt312.h 1.1 -> 1.2 # arch/x86_64/boot/install.sh 1.1 -> 1.2 # drivers/media/dvb/frontends/mt312.c 1.6 -> 1.7 # arch/ia64/defconfig 1.21 -> 1.22 # Documentation/dvb/readme.txt 1.1 -> 1.2 # drivers/media/dvb/frontends/ves1x93.c 1.8 -> 1.9 # drivers/media/dvb/ttpci/Kconfig 1.4 -> 1.5 # include/asm-x86_64/io_apic.h 1.9 -> 1.10 # drivers/media/dvb/ttpci/Makefile 1.2 -> 1.3 # arch/x86_64/kernel/apic.c 1.25 -> 1.26 # arch/ia64/kernel/ivt.S 1.24 -> 1.25 # arch/x86_64/kernel/i8259.c 1.8 -> 1.9 # drivers/media/dvb/dvb-core/dvb_demux.c 1.11 -> 1.12 # drivers/media/dvb/ttpci/av7110.c.orig 1.1 -> (deleted) # arch/ia64/hp/sim/boot/fw-emu.c 1.1 -> 1.2 # drivers/media/dvb/ttusb-dec/Kconfig 1.4 -> 1.5 # drivers/media/dvb/bt8xx/dvb-bt8xx.c 1.2 -> 1.3 # include/asm-i386/mach-voyager/irq_vectors.h 1.4 -> 1.5 # Documentation/dvb/contributors.txt 1.1 -> 1.2 # arch/ia64/kernel/entry.S 1.51 -> 1.54 # arch/x86_64/kernel/e820.c 1.5 -> 1.6 # arch/x86_64/kernel/mpparse.c 1.15 -> 1.16 # drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.mod.c 1.1 -> (deleted) # drivers/media/dvb/ttusb-dec/ttusb_dec.mod.c 1.1 -> (deleted) # arch/sparc64/defconfig 1.106 -> 1.107 # include/asm-ia64/processor.h 1.52 -> 1.53 # arch/ia64/kernel/entry.h 1.9 -> 1.10 # include/asm-x86_64/bitops.h 1.13 -> 1.14 # include/linux/pci_ids.h 1.126.1.2 -> 1.128 # arch/x86_64/ia32/sys_ia32.c 1.46 -> 1.47 # arch/x86_64/kernel/irq.c 1.20 -> 1.21 # arch/x86_64/kernel/pci-gart.c 1.24 -> 1.25 # arch/x86_64/ia32/ia32entry.S 1.26 -> 1.27 # include/asm-arm26/keyboard.h.old 1.1 -> (deleted) # drivers/media/dvb/ttusb-dec/fdump.c 1.1 -> (deleted) # arch/x86_64/kernel/io_apic.c 1.17 -> 1.18 # drivers/media/dvb/frontends/ves1820.c 1.11 -> 1.12 # arch/x86_64/ia32/ia32_ioctl.c 1.35 -> 1.36 # drivers/pci/pci.ids 1.52 -> 1.53 # drivers/net/tg3.c 1.112 -> 1.120 # arch/ia64/ia32/ia32_entry.S 1.31 -> 1.34 # arch/x86_64/kernel/process.c 1.21 -> 1.22 # include/linux/netfilter_bridge.h 1.7.1.1 -> 1.10 # arch/ia64/kernel/signal.c 1.37 -> 1.38 # include/linux/skbuff.h 1.35 -> 1.37 # arch/ia64/ia32/sys_ia32.c 1.84 -> 1.86 # arch/x86_64/ia32/syscall32.c 1.4 -> 1.5 # include/asm-x86_64/calling.h 1.5 -> 1.6 # drivers/media/dvb/ttpci/av7110.c 1.15 -> 1.17 # arch/x86_64/kernel/head.S 1.13 -> 1.14 # include/asm-x86_64/acpi.h 1.2 -> 1.3 # include/asm-x86_64/unistd.h 1.18 -> 1.19 # arch/x86_64/kernel/time.c 1.26 -> 1.27 # drivers/media/dvb/frontends/nxt6000.c 1.5 -> 1.6 # include/asm-x86_64/pgtable.h 1.23 -> 1.24 # arch/x86_64/kernel/Makefile 1.27 -> 1.28 # arch/x86_64/kernel/vsyscall.c 1.12 -> 1.13 # arch/x86_64/Kconfig 1.37 -> 1.38 # drivers/media/dvb/frontends/dst-bt878.h 1.2 -> 1.3 # include/asm-x86_64/system.h 1.16 -> 1.17 # arch/ia64/kernel/perfmon_default_smpl.c 1.3 -> 1.4 # drivers/media/dvb/frontends/dst.c 1.1 -> 1.2 # drivers/media/dvb/frontends/at76c651.c 1.4 -> 1.5 # arch/x86_64/kernel/bluesmoke.c 1.14 -> 1.15 # drivers/media/dvb/ttusb-dec/ttusb_dec.c 1.7 -> 1.9 # net/ax25/af_ax25.c 1.34 -> 1.35 # drivers/media/dvb/ttusb-dec/dec2000_frontend.c 1.3 -> (deleted) # arch/ia64/kernel/traps.c 1.40 -> 1.41 # net/bridge/br_netfilter.c 1.17.1.2 -> 1.19 # include/asm-x86_64/hw_irq.h 1.8 -> 1.9 # drivers/media/dvb/bt8xx/dvb-bt8xx.h 1.1 -> 1.2 # arch/ia64/ia32/ia32priv.h 1.8 -> 1.9 # drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c 1.7 -> 1.8 # net/ipv4/ip_output.c 1.47 -> 1.48 # arch/ia64/kernel/ptrace.c 1.30 -> 1.32 # include/asm-ia64/ia32.h 1.24 -> 1.26 # Documentation/dvb/ttusb-dec.txt 1.1 -> 1.2 # drivers/media/dvb/frontends/stv0299.c 1.6 -> 1.7 # drivers/base/power/sysfs.c 1.2 -> 1.3 # (new) -> 1.1 Documentation/dvb/bt8xx.txt # (new) -> 1.1 include/asm-x86_64/cpu.h # (new) -> 1.1 include/asm-x86_64/node.h # (new) -> 1.1 drivers/media/dvb/ttpci/fdump.c # (new) -> 1.1 include/asm-x86_64/memblk.h # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/12/30 torvalds@home.osdl.org 1.1550.1.2 # Linux 2.6.1-rc1 # -------------------------------------------- # 03/12/30 davem@nuts.ninka.net 1.1552 # [MEDIA]: ttusb_dec.c needs linux/init.h # -------------------------------------------- # 03/12/30 davem@nuts.ninka.net 1.1553 # [SPARC64]: Update defconfig. # -------------------------------------------- # 03/12/30 davem@kernel.bkbits.net 1.1554 # Merge davem@nuts.ninka.net:/disk1/davem/BK/sparc-2.6 # into kernel.bkbits.net:/home/davem/sparc-2.6 # -------------------------------------------- # 03/12/30 torvalds@home.osdl.org 1.1555 # Remove generated files from revision control # -------------------------------------------- # 03/12/31 davidm@tiger.hpl.hp.com 1.1529.1.1 # ia64: Fix a ptrace-bug that caused "strace -f" to crash the inferior # process. The root-cause of the problem was that ptrace() tried # to copy the portion of the register backing store that landed on # the kernel stack back to users-space, but the resulting state # was inconsistent if the inferior process was in the middle of a # system-call (as would always be the case for strace). # # The solution is to avoid all needless copying and to instead # ensure that when accessing a memory location that may belong to # a thread's register-backing store, we attach to that particular # thread, rather than the thread identified by the PID argument. # If the thread happens to be unattachable, we fall back to using # the thread identified by the PID argument. This should have the # desired effect if the thread has terminated already and if the # thread is running while ptrace() is trying to access its state, # all bets are off anyhow and there are no coherency guarantees. # In other words, this should be doing the right thing under all # circumstances. # # The patch also fixes the case where PT_AR_BSP and/or PT_CFM are # written while the inferior process is in the middle of a system # call. This makes arguments passed to GDB inferior calls come # out right. # # The patch was tested with strace -f and the GDB testsuite, which # showed no regressions compared to the previous version of the # kernel. # -------------------------------------------- # 03/12/31 davem@nuts.ninka.net 1.1556 # Merge nuts.ninka.net:/disk1/davem/BK/netleak-2.5 # into nuts.ninka.net:/disk1/davem/BK/net-2.6 # -------------------------------------------- # 03/12/31 bdschuym@pandora.be 1.1557 # [BRIDGE]: Fix build with vlan disabled, spurious ifdef. # -------------------------------------------- # 03/12/31 yoshfuji@linux-ipv6.org 1.1558 # [NET]: Fix comment type in skbuff.h # -------------------------------------------- # 03/12/31 pe1rxq@amsat.org 1.1559 # [AX25]: Missing spin_unlock() and recvmsg reported dst instead of src. # -------------------------------------------- # 03/12/31 davem@kernel.bkbits.net 1.1555.1.1 # Merge davem@nuts.ninka.net:/disk1/davem/BK/tg3-2.6 # into kernel.bkbits.net:/home/davem/tg3-2.6 # -------------------------------------------- # 03/12/31 torvalds@home.osdl.org 1.1560 # Merge bk://kernel.bkbits.net/davem/net-2.6 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/12/31 James.Bottomley@SteelEye.com 1.1561 # [PATCH] MSI broke voyager build # # The x86 build depends on NR_VECTORS being defined. # # This symbol, however, was put only into mach-default/irq_vectors.h # # The attached patch adds it to voyager too. # -------------------------------------------- # 03/12/31 rmk+lkml@arm.linux.org.uk 1.1562 # [PATCH] Fix "echo -n 3 > /sys/.../power/state" # # Fix what seems to be a typo preventing .../power/state from working. # -------------------------------------------- # 03/12/31 davidm@tiger.hpl.hp.com 1.1529.1.2 # ia64: Rearrange ia64_do_signal() such that it is possible for a debugger to # cancel system-call restart. # -------------------------------------------- # 03/12/31 davidm@tiger.hpl.hp.com 1.1529.1.3 # ia64: Allow system-call number to be changed during system-call tracing # (both for native and x86 system call tracing). This is needed # by recent versions of strace and UML likes to do that, too. # -------------------------------------------- # 03/12/31 davidm@tiger.hpl.hp.com 1.1529.1.4 # ia64: Remove the old ia64_ni_syscall()/sys32_ni_syscall() routines which # are overly verbose and replace them with calls to sys_ni_syscall(). # -------------------------------------------- # 03/12/31 davidm@tiger.hpl.hp.com 1.1529.1.5 # ia64: fix perfmon bug causing lost samples # # Patch from Stephane: Fix a bug in perfmon_default_smpl.c by # which we would systematically lose one sample at every buffer # overflow. # -------------------------------------------- # 03/12/31 davidm@tiger.hpl.hp.com 1.1563 # Merge tiger.hpl.hp.com:/data1/bk/vanilla/linux-2.5 # into tiger.hpl.hp.com:/data1/bk/lia64/to-linus-2.5 # -------------------------------------------- # 03/12/31 davidm@tiger.hpl.hp.com 1.1564 # ia64: Merge patch by Arun Sharma: hook up lots of ia32 syscalls. # -------------------------------------------- # 03/12/31 davidm@tiger.hpl.hp.com 1.1565 # ia64: Rename efi_get_time() in the simulator's firmware-emulator to avoid # name-clash with declaration of routine of the same name in # . # -------------------------------------------- # 03/12/31 davidm@tiger.hpl.hp.com 1.1566 # ia64: Update defconfig. # -------------------------------------------- # 04/01/01 torvalds@home.osdl.org 1.1562.1.1 # Remove dead files # # Noted by Keith Owens. # -------------------------------------------- # 04/01/01 hunold@linuxtv.org 1.1562.1.2 # [PATCH] DVB: Update documentation and credits # # - add new documentation for getting bt8xx based DVB cards runnig # - extend contributors list # - change various email addresses in header files # -------------------------------------------- # 04/01/01 hunold@linuxtv.org 1.1562.1.3 # [PATCH] DVB: Fix feed list handling bugs in demux # # - corrected handling of feed lists (Andres Oberritter) # -------------------------------------------- # 04/01/01 hunold@linuxtv.org 1.1562.1.4 # [PATCH] DVB: Fixes for frontend drivers # # - ves1820: increase mdelay from 30 to 50 to be more reliable with bad # reception quality (Andreas Oberritter) # - dst: remove AUTO_INVERSION for capabilities, allow params # dst_type_flags and dst_type to have multiple values for multiple # cards in one machine (Jamie Honan) # -------------------------------------------- # 04/01/01 hunold@linuxtv.org 1.1562.1.5 # [PATCH] DVB: Add static firmware compilation again # # - add Kconfig magic to select a firmware that can be compiled into the # driver # - add some hooks to av7110 to compile a firmware into the driver again # -------------------------------------------- # 04/01/01 hunold@linuxtv.org 1.1562.1.6 # [PATCH] DVB: Revamp of the TTUSB-DEC driver # # - Alter hotplug firmware naming to fit in with dvb standard. # - Use the hotplug firmware loader for 2.6 kernels instead of compiling # the firmware into the module. # - Integrate frontend into ttusb_dec module and remove pseudo-i2c bits, # move ttusb_dec header into source file. # - Rudimentary section filter support (enough for scan). # -------------------------------------------- # 04/01/01 hunold@linuxtv.org 1.1562.1.7 # [PATCH] DVB: Fix memory usage of ttpci driver # # - do not allocate firmware buffer if firmware is compiled into the # driver. Saves 220KB vmem (Andreas Oberritter) # -------------------------------------------- # 04/01/01 torvalds@home.osdl.org 1.1567 # Merge http://lia64.bkbits.net/to-linus-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 04/01/01 ak@muc.de 1.1568 # [PATCH] X86-64 merge # # At least one of them is critical. It fixes an path in the IOMMU that # I broke with the ealier "fullflush" workaround. # # - Check for ~/bin/installkernel like i386 (M. Bligh) # - Implement 32bit RTC_IRQ_SET correctly (Lutz Vieweg) # - Disable some useless printks in 32bit emulation # - Warning fixes for mixed C99 style declarations/statements. # - Sync lAPIC power management with i386 # - Use topology sysfs like i386 # - Fix some serious bugs in the MCE handler. ECC should # be decoded correctly now. # - Add oops=panic option to panic on Oopses. # - Fix hackish code in head.S # - Add missing options in IOMMU # - Fix _syscall6 (Olaf Hering) # - Remove broken ACPI locking code. Port IA64 C version. # - Make safe_smp_processor_id() more reliable # - Read HPET in vsyscall code # - Add workaround for BIOS that corrupt 64bit registers in HLT # - Fix unaligned access in bitops.h # - Remove broken ntp drift correction code for now # - i386 merge in SCI setup # - Fix wrong offset in callin.h (Jim Houston) # - Minor comment fixes # -------------------------------------------- # diff -Nru a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/dvb/bt8xx.txt Sun Jan 4 17:36:11 2004 @@ -0,0 +1,90 @@ +How to get the Nebula, PCTV and Twinhan DST cards working +========================================================= + +This class of cards has a bt878a as the PCI interface, and +require the bttv driver. + +Please pay close attention to the warning about the bttv module +options below for the DST card. + +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" + +2) Loading Modules +================== + +In general you need to load the bttv driver, which will handle the gpio and +i2c communication for us. Next you need the common dvb-bt8xx device driver +and one frontend driver. + +The bttv driver will HANG YOUR SYSTEM IF YOU DO NOT SPECIFY THE CORRECT +CARD ID! + +(If you don't get your card running and you suspect that the card id you're +using is wrong, have a look at "bttv-cards.c" for a list of possible card +ids.) + +Pay attention to failures when you load the frontend drivers +(e.g. dmesg, /var/log/messages). + +3a) Nebula / Pinnacle PCTV +-------------------------- + + $ modprobe bttv i2c_hw=1 card=0x68 + $ modprobe dvb-bt8xx + +For Nebula cards use the "nxt6000" frontend driver: + $ modprobe nxt6000 + +For Pinnacle PCTV cards use the "cx24110" frontend driver: + $ modprobe cx24110 + +3b) TwinHan +----------- + + $ modprobe bttv i2c_hw=1 card=0x71 + $ modprobe dvb-bt8xx + $ modprobe dst + +The value 0x71 will override the PCI type detection for dvb-bt8xx, which +is necessary for TwinHan cards.# + +If you're having an older card (blue color circuit) and card=0x71 locks your +machine, try using 0x68, too. If that does not work, ask on the DVB mailing list. + +The DST module takes a couple of useful parameters, in case the +dst drivers fails to detect your type of card correctly. + +dst_type takes values 0 (satellite), 1 (terrestial TV), 2 (cable). + +dst_type_flags takes bit combined values: +1 = new tuner type packets. You can use this if your card is detected + and you have debug and you continually see the tuner packets not + working (make sure not a basic problem like dish alignment etc.) + +2 = TS 204. If your card tunes OK, but the picture is terrible, seemingly + breaking up in one half continually, and crc fails a lot, then + this is worth a try (or trying to turn off) + +4 = has symdiv. Some cards, mostly without new tuner packets, require + a symbol division algorithm. Doesn't apply to terrestial TV. + +You can also specify a value to have the autodetected values turned off +(e.g. 0). The autodected values are determined bythe cards 'response +string' which you can see in your logs e.g. + +dst_check_ci: recognize DST-MOT + +or + +dst_check_ci: unable to recognize DSTXCI or STXCI + +-- +Authors: Richard Walker, Jamie Honan, Michael Hunold diff -Nru a/Documentation/dvb/contributors.txt b/Documentation/dvb/contributors.txt --- a/Documentation/dvb/contributors.txt Sun Jan 4 17:36:11 2004 +++ b/Documentation/dvb/contributors.txt Sun Jan 4 17:36:11 2004 @@ -30,11 +30,15 @@ Christoph Martin for his LIRC infrared handler -Andreas Oberritter +Andreas Oberritter +Dennis Noermann +Felix Domke Florian Schirmer -...and all the other dBox2 people - for many bugfixes in the generic DVB Core and their work on the - dBox2 port of the DVB driver +Ronny Strutz <3des@elitedvb.de> +Wolfram Joost +...and all the other dbox2 people + for many bugfixes in the generic DVB Core, frontend drivers and + their work on the dbox2 port of the DVB driver Oliver Endriss for many bugfixes @@ -50,5 +54,9 @@ Augusto Cardoso for all the work for the FlexCopII chipset by B2C2,Inc. +Davor Emard + for his work on the budget drivers, the demux code, + the module unloading problems, ... + (If you think you should be in this list, but you are not, drop a line to the DVB mailing list) diff -Nru a/Documentation/dvb/readme.txt b/Documentation/dvb/readme.txt --- a/Documentation/dvb/readme.txt Sun Jan 4 17:36:10 2004 +++ b/Documentation/dvb/readme.txt Sun Jan 4 17:36:10 2004 @@ -36,4 +36,9 @@ contains detailed informations 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) + Good luck and have fun! diff -Nru a/Documentation/dvb/ttusb-dec.txt b/Documentation/dvb/ttusb-dec.txt --- a/Documentation/dvb/ttusb-dec.txt Sun Jan 4 17:36:11 2004 +++ b/Documentation/dvb/ttusb-dec.txt Sun Jan 4 17:36:11 2004 @@ -9,6 +9,7 @@ Linux Kernels 2.4 and 2.6 Video Streaming Audio Streaming + Section Filters Channel Zapping Hotplug firmware loader under 2.6 kernels @@ -16,14 +17,10 @@ DEC3000-s To Do: - Section data - Teletext streams Tuner status information DVB network interface Streaming video PC->DEC -Note: Since section data can not be retreived yet, scan apps will not work. - Getting the Firmware -------------------- Currently, the driver only works with v2.15a of the firmware. The firmwares @@ -46,7 +43,7 @@ Hotplug Firmware Loading for 2.6 kernels ---------------------------------------- For 2.6 kernels the firmware is loaded at the point that the driver module is -loaded. See linux/Documentation/dvb/FIRMWARE for more information. +loaded. See linux/Documentation/dvb/firmware.txt for more information. -mv STB_PC_T.bin /usr/lib/hotplug/firmware/dec2000t.bin -mv STB_PC_S.bin /usr/lib/hotplug/firmware/dec3000s.bin +mv STB_PC_T.bin /usr/lib/hotplug/firmware/dvb-ttusb-dec-2000t-2.15a.fw +mv STB_PC_S.bin /usr/lib/hotplug/firmware/dvb-ttusb-dec-3000s-2.15a.fw diff -Nru a/arch/ia64/defconfig b/arch/ia64/defconfig --- a/arch/ia64/defconfig Sun Jan 4 17:36:10 2004 +++ b/arch/ia64/defconfig Sun Jan 4 17:36:10 2004 @@ -6,6 +6,10 @@ # Code maturity level options # CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +# CONFIG_STANDALONE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y # # General setup @@ -15,9 +19,16 @@ CONFIG_BSD_PROCESS_ACCT=y CONFIG_SYSCTL=y CONFIG_LOG_BUF_SHIFT=16 +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y # CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y CONFIG_FUTEX=y CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # # Loadable module support @@ -33,6 +44,7 @@ # Processor type and features # CONFIG_IA64=y +CONFIG_64BIT=y CONFIG_MMU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_TIME_INTERPOLATION=y @@ -57,9 +69,7 @@ CONFIG_IA64_MCA=y CONFIG_PM=y CONFIG_IOSAPIC=y -CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=18 -CONFIG_HUGETLB_PAGE=y # CONFIG_HUGETLB_PAGE_SIZE_4GB is not set # CONFIG_HUGETLB_PAGE_SIZE_1GB is not set # CONFIG_HUGETLB_PAGE_SIZE_256MB is not set @@ -68,11 +78,12 @@ # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set -CONFIG_IA64_PAL_IDLE=y +# CONFIG_IA64_PAL_IDLE is not set CONFIG_SMP=y # CONFIG_PREEMPT is not set CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y +CONFIG_HAVE_DEC_LOCK=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y CONFIG_EFI=y @@ -82,7 +93,7 @@ CONFIG_BINFMT_MISC=y # -# ACPI Support +# ACPI (Advanced Configuration and Power Interface) Support # CONFIG_ACPI_BOOT=y CONFIG_ACPI_BUTTON=y @@ -94,6 +105,7 @@ CONFIG_ACPI_POWER=y CONFIG_ACPI_PCI=y CONFIG_ACPI_SYSTEM=y +# CONFIG_ACPI_RELAXED_AML is not set CONFIG_PCI=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_LEGACY_PROC=y @@ -139,12 +151,72 @@ # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y # +# 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_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_IDE_TASK_IOCTL=y +CONFIG_IDE_TASKFILE_IO=y + +# +# IDE chipset support/bugfixes +# +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_IDEDMA_PCI_WIP 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 +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_HD is not set + +# # IEEE 1394 (FireWire) support (EXPERIMENTAL) # # CONFIG_IEEE1394 is not set @@ -157,7 +229,15 @@ # # Multi-device support (RAID and LVM) # -# CONFIG_MD is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID5=m +CONFIG_MD_MULTIPATH=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_IOCTL_V4=y # # Fusion MPT device support @@ -169,9 +249,10 @@ # CONFIG_FUSION_CTL is not set # -# SCSI support +# SCSI device support # CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y # # SCSI support type (disk, tape, CD-ROM) @@ -200,9 +281,9 @@ # CONFIG_SCSI_AIC7XXX is not set CONFIG_SCSI_AIC7XXX_OLD=y # CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set CONFIG_SCSI_MEGARAID=y +# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -210,6 +291,7 @@ # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set CONFIG_SCSI_SYM53C8XX_2=y @@ -238,8 +320,6 @@ CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK_DEV is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -257,6 +337,16 @@ # CONFIG_INET_IPCOMP is not set # +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# # IP: Netfilter Configuration # # CONFIG_IP_NF_CONNTRACK is not set @@ -264,10 +354,9 @@ # CONFIG_IP_NF_IPTABLES is not set CONFIG_IP_NF_ARPTABLES=y # CONFIG_IP_NF_ARPFILTER is not set +# CONFIG_IP_NF_ARP_MANGLE is not set # CONFIG_IP_NF_COMPAT_IPCHAINS is not set # CONFIG_IP_NF_COMPAT_IPFWADM is not set -# CONFIG_IPV6 is not set -# CONFIG_XFRM_USER is not set # # SCTP Configuration (EXPERIMENTAL) @@ -276,9 +365,9 @@ # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set -# CONFIG_LLC is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE 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 @@ -306,7 +395,6 @@ CONFIG_BONDING=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) @@ -339,7 +427,6 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # @@ -353,8 +440,9 @@ # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set # CONFIG_SK98LIN is not set -CONFIG_TIGON3=m +CONFIG_TIGON3=y # # Ethernet (10000 Mbit) @@ -371,10 +459,10 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices (depends on LLC=y) +# Token Ring devices # +# CONFIG_TR is not set # CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # @@ -388,14 +476,19 @@ # CONFIG_HAMRADIO is not set # -# ISDN subsystem +# IrDA (infrared) support # -# CONFIG_ISDN_BOOL is not set +# CONFIG_IRDA is not set # -# CD-ROM drivers (not for SCSI or IDE/ATAPI drives) +# Bluetooth support # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_BT is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set # # Input device support @@ -406,7 +499,7 @@ # Userland interfaces # CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_PSAUX=y CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_INPUT_JOYDEV=y @@ -449,6 +542,7 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_ACPI=y CONFIG_SERIAL_8250_HCDP=y +CONFIG_SERIAL_8250_NR_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -465,7 +559,11 @@ # CONFIG_I2C is not set # -# I2C Hardware Sensors Mainboard support +# I2C Algorithms +# + +# +# I2C Hardware Bus support # # @@ -509,8 +607,8 @@ # CONFIG_DRM_R128 is not set CONFIG_DRM_RADEON=m # CONFIG_DRM_MGA is not set +# CONFIG_DRM_SIS is not set # CONFIG_RAW_DRIVER is not set -# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -565,11 +663,13 @@ # Pseudo filesystems # CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y # CONFIG_DEVFS_FS is not set CONFIG_DEVPTS_FS=y # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y # @@ -594,6 +694,7 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=y CONFIG_NFSD_V3=y # CONFIG_NFSD_V4 is not set @@ -630,11 +731,11 @@ # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set CONFIG_EFI_PARTITION=y -CONFIG_NLS=y # # Native Language Support # +CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=y @@ -843,7 +944,6 @@ # # USB Network adaptors # -# CONFIG_USB_AX8817X is not set # CONFIG_USB_CATC is not set # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set @@ -865,36 +965,40 @@ # 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_BRLVGER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_GADGET is not set # -# Bluetooth support +# Library routines # -# CONFIG_BT is not set +CONFIG_CRC32=y # -# Library routines +# Profiling support # -CONFIG_CRC32=y +# CONFIG_PROFILING is not set # # Kernel hacking # -# CONFIG_IA64_GRANULE_16MB is not set -CONFIG_IA64_GRANULE_64MB=y +CONFIG_IA64_GRANULE_16MB=y +# CONFIG_IA64_GRANULE_64MB is not set CONFIG_DEBUG_KERNEL=y -CONFIG_KALLSYMS=y CONFIG_IA64_PRINT_HAZARDS=y # CONFIG_DISABLE_VHPT is not set CONFIG_MAGIC_SYSRQ=y -# CONFIG_IA64_EARLY_PRINTK is not set +CONFIG_IA64_EARLY_PRINTK=y +CONFIG_IA64_EARLY_PRINTK_UART=y +CONFIG_IA64_EARLY_PRINTK_UART_BASE=0xff5e0000 +CONFIG_IA64_EARLY_PRINTK_VGA=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set +CONFIG_DEBUG_INFO=y # # Security options diff -Nru a/arch/ia64/hp/sim/boot/fw-emu.c b/arch/ia64/hp/sim/boot/fw-emu.c --- a/arch/ia64/hp/sim/boot/fw-emu.c Sun Jan 4 17:36:11 2004 +++ b/arch/ia64/hp/sim/boot/fw-emu.c Sun Jan 4 17:36:11 2004 @@ -108,7 +108,7 @@ #define BUS_NUMBER(addr) (0x0000000000FF0000 & (addr)) static efi_status_t -efi_get_time (efi_time_t *tm, efi_time_cap_t *tc) +fw_efi_get_time (efi_time_t *tm, efi_time_cap_t *tc) { #if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC) struct { @@ -310,7 +310,7 @@ efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE; efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION; efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr); - efi_runtime->get_time = __pa(&efi_get_time); + efi_runtime->get_time = __pa(&fw_efi_get_time); efi_runtime->set_time = __pa(&efi_unimplemented); efi_runtime->get_wakeup_time = __pa(&efi_unimplemented); efi_runtime->set_wakeup_time = __pa(&efi_unimplemented); diff -Nru a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S --- a/arch/ia64/ia32/ia32_entry.S Sun Jan 4 17:36:11 2004 +++ b/arch/ia64/ia32/ia32_entry.S Sun Jan 4 17:36:11 2004 @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -141,27 +142,35 @@ adds r2=IA64_PT_REGS_R8_OFFSET+16,sp ;; st8 [r2]=r3 // initialize return code to -ENOSYS - br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall args - // Need to reload arguments (they may be changed by the tracing process) - adds r2=IA64_PT_REGS_R9_OFFSET+16,sp // r2 = &pt_regs.r9 + br.call.sptk.few rp=syscall_trace // give parent a chance to catch syscall args +.ret2: // Need to reload arguments (they may be changed by the tracing process) + adds r2=IA64_PT_REGS_R1_OFFSET+16,sp // r2 = &pt_regs.r1 adds r3=IA64_PT_REGS_R13_OFFSET+16,sp // r3 = &pt_regs.r13 + mov r15=IA32_NR_syscalls + ;; + ld4 r8=[r2],IA64_PT_REGS_R9_OFFSET-IA64_PT_REGS_R1_OFFSET + movl r16=ia32_syscall_table ;; ld4 r33=[r2],8 // r9 == ecx ld4 r37=[r3],16 // r13 == ebp + cmp.ltu.unc p6,p7=r8,r15 ;; ld4 r34=[r2],8 // r10 == edx ld4 r36=[r3],8 // r15 == edi +(p6) shladd r16=r8,3,r16 // force ni_syscall if not valid syscall number + ;; + ld8 r16=[r16] ;; ld4 r32=[r2],8 // r11 == ebx + mov b6=r16 ld4 r35=[r3],8 // r14 == esi - ;; -.ret2: br.call.sptk.few rp=b6 // do the syscall + br.call.sptk.few rp=b6 // do the syscall .ia32_strace_check_retval: cmp.lt p6,p0=r8,r0 // syscall failed? adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8 ;; st8.spill [r2]=r8 // store return value in slot for r8 - br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch return value + br.call.sptk.few rp=syscall_trace // give parent a chance to catch return value .ret4: alloc r2=ar.pfs,0,0,0,0 // drop the syscall argument frame br.cond.sptk.many ia64_leave_kernel END(ia32_trace_syscall) @@ -199,7 +208,7 @@ .align 8 .globl ia32_syscall_table ia32_syscall_table: - data8 sys32_ni_syscall /* 0 - old "setup(" system call*/ + data8 sys_ni_syscall /* 0 - old "setup(" system call*/ data8 sys_exit data8 sys32_fork data8 sys_read @@ -216,25 +225,25 @@ data8 sys_mknod data8 sys_chmod /* 15 */ data8 sys_lchown /* 16-bit version */ - data8 sys32_ni_syscall /* old break syscall holder */ - data8 sys32_ni_syscall + data8 sys_ni_syscall /* old break syscall holder */ + data8 sys_ni_syscall data8 sys32_lseek data8 sys_getpid /* 20 */ data8 sys_mount data8 sys_oldumount data8 sys_setuid /* 16-bit version */ data8 sys_getuid /* 16-bit version */ - data8 sys32_ni_syscall /* sys_stime is not supported on IA64 */ /* 25 */ + data8 sys_ni_syscall /* sys_stime is not supported on IA64 */ /* 25 */ data8 sys32_ptrace data8 sys32_alarm - data8 sys32_ni_syscall + data8 sys_ni_syscall data8 sys32_pause data8 compat_sys_utime /* 30 */ - data8 sys32_ni_syscall /* old stty syscall holder */ - data8 sys32_ni_syscall /* old gtty syscall holder */ + data8 sys_ni_syscall /* old stty syscall holder */ + data8 sys_ni_syscall /* old gtty syscall holder */ data8 sys_access data8 sys_nice - data8 sys32_ni_syscall /* 35 */ /* old ftime syscall holder */ + data8 sys_ni_syscall /* 35 */ /* old ftime syscall holder */ data8 sys_sync data8 sys_kill data8 sys_rename @@ -243,7 +252,7 @@ data8 sys_dup data8 sys32_pipe data8 compat_sys_times - data8 sys32_ni_syscall /* old prof syscall holder */ + data8 sys_ni_syscall /* old prof syscall holder */ data8 sys32_brk /* 45 */ data8 sys_setgid /* 16-bit version */ data8 sys_getgid /* 16-bit version */ @@ -252,13 +261,13 @@ data8 sys_getegid /* 16-bit version */ /* 50 */ data8 sys_acct data8 sys_umount /* recycled never used phys( */ - data8 sys32_ni_syscall /* old lock syscall holder */ + data8 sys_ni_syscall /* old lock syscall holder */ data8 compat_sys_ioctl data8 compat_sys_fcntl /* 55 */ - data8 sys32_ni_syscall /* old mpx syscall holder */ + data8 sys_ni_syscall /* old mpx syscall holder */ data8 sys_setpgid - data8 sys32_ni_syscall /* old ulimit syscall holder */ - data8 sys32_ni_syscall + data8 sys_ni_syscall /* old ulimit syscall holder */ + data8 sys_ni_syscall data8 sys_umask /* 60 */ data8 sys_chroot data8 sys_ustat @@ -267,8 +276,8 @@ data8 sys_getpgrp /* 65 */ data8 sys_setsid data8 sys32_sigaction - data8 sys32_ni_syscall - data8 sys32_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall data8 sys_setreuid /* 16-bit version */ /* 70 */ data8 sys_setregid /* 16-bit version */ data8 sys32_sigsuspend @@ -283,7 +292,7 @@ data8 sys32_setgroups16 data8 sys32_old_select data8 sys_symlink - data8 sys32_ni_syscall + data8 sys_ni_syscall data8 sys_readlink /* 85 */ data8 sys_uselib data8 sys_swapon @@ -297,7 +306,7 @@ data8 sys_fchown /* 16-bit version */ /* 95 */ data8 sys_getpriority data8 sys_setpriority - data8 sys32_ni_syscall /* old profil syscall holder */ + data8 sys_ni_syscall /* old profil syscall holder */ data8 compat_sys_statfs data8 compat_sys_fstatfs /* 100 */ data8 sys32_ioperm @@ -308,11 +317,11 @@ data8 compat_sys_newstat data8 compat_sys_newlstat data8 compat_sys_newfstat - data8 sys32_ni_syscall + data8 sys_ni_syscall data8 sys32_iopl /* 110 */ data8 sys_vhangup - data8 sys32_ni_syscall /* used to be sys_idle */ - data8 sys32_ni_syscall + data8 sys_ni_syscall /* used to be sys_idle */ + data8 sys_ni_syscall data8 compat_sys_wait4 data8 sys_swapoff /* 115 */ data8 sys32_sysinfo @@ -323,20 +332,20 @@ data8 sys_setdomainname data8 sys32_newuname data8 sys32_modify_ldt - data8 sys32_ni_syscall /* adjtimex */ + data8 sys_ni_syscall /* adjtimex */ data8 sys32_mprotect /* 125 */ data8 compat_sys_sigprocmask - data8 sys32_ni_syscall /* create_module */ - data8 sys32_ni_syscall /* init_module */ - data8 sys32_ni_syscall /* delete_module */ - data8 sys32_ni_syscall /* get_kernel_syms */ /* 130 */ + data8 sys_ni_syscall /* create_module */ + data8 sys_ni_syscall /* init_module */ + data8 sys_ni_syscall /* delete_module */ + data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */ data8 sys_quotactl data8 sys_getpgid data8 sys_fchdir - data8 sys32_ni_syscall /* sys_bdflush */ + data8 sys_ni_syscall /* sys_bdflush */ data8 sys_sysfs /* 135 */ data8 sys32_personality - data8 sys32_ni_syscall /* for afs_syscall */ + data8 sys_ni_syscall /* for afs_syscall */ data8 sys_setfsuid /* 16-bit version */ data8 sys_setfsgid /* 16-bit version */ data8 sys_llseek /* 140 */ @@ -365,10 +374,10 @@ data8 sys_mremap data8 sys_setresuid /* 16-bit version */ data8 sys32_getresuid16 /* 16-bit version */ /* 165 */ - data8 sys32_ni_syscall /* vm86 */ - data8 sys32_ni_syscall /* sys_query_module */ + data8 sys_ni_syscall /* vm86 */ + data8 sys_ni_syscall /* sys_query_module */ data8 sys_poll - data8 sys32_ni_syscall /* nfsservctl */ + data8 sys_ni_syscall /* nfsservctl */ data8 sys_setresgid /* 170 */ data8 sys32_getresgid16 data8 sys_prctl @@ -387,8 +396,8 @@ data8 sys_capset /* 185 */ data8 sys32_sigaltstack data8 sys32_sendfile - data8 sys32_ni_syscall /* streams1 */ - data8 sys32_ni_syscall /* streams2 */ + data8 sys_ni_syscall /* streams1 */ + data8 sys_ni_syscall /* streams2 */ data8 sys32_vfork /* 190 */ data8 compat_sys_getrlimit data8 sys32_mmap2 @@ -425,54 +434,55 @@ data8 sys_ni_syscall /* reserved for Security */ data8 sys_gettid data8 sys_readahead /* 225 */ - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall /* 230 */ - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall /* 235 */ - data8 sys_ni_syscall - data8 sys_ni_syscall + data8 sys_setxattr + data8 sys_lsetxattr + data8 sys_fsetxattr + data8 sys_getxattr + data8 sys_lgetxattr /* 230 */ + data8 sys_fgetxattr + data8 sys_listxattr + data8 sys_llistxattr + data8 sys_flistxattr + data8 sys_removexattr /* 235 */ + data8 sys_lremovexattr + data8 sys_fremovexattr data8 sys_tkill - data8 sys_ni_syscall + data8 sys_sendfile64 data8 compat_sys_futex /* 240 */ data8 compat_sys_sched_setaffinity data8 compat_sys_sched_getaffinity data8 sys32_set_thread_area data8 sys32_get_thread_area - data8 sys_ni_syscall /* 245 */ - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall /* 250 */ + data8 compat_sys_io_setup /* 245 */ + data8 sys_io_destroy + data8 compat_sys_io_getevents + data8 compat_sys_io_submit + data8 sys_io_cancel + data8 sys_fadvise64 /* 250 */ data8 sys_ni_syscall data8 sys_exit_group - data8 sys_ni_syscall + data8 sys_lookup_dcookie data8 sys_epoll_create data8 sys32_epoll_ctl /* 255 */ data8 sys32_epoll_wait data8 sys_remap_file_pages data8 sys_set_tid_address - data8 sys_ni_syscall - data8 sys_ni_syscall /* 260 */ - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall - data8 sys_ni_syscall /* 265 */ - data8 sys_ni_syscall - data8 sys_ni_syscall + data8 sys32_timer_create + data8 compat_timer_settime /* 260 */ + data8 compat_timer_gettime + data8 sys_timer_getoverrun + data8 sys_timer_delete + data8 compat_clock_settime + data8 compat_clock_gettime /* 265 */ + data8 compat_clock_getres + data8 compat_clock_nanosleep data8 sys_statfs64 data8 sys_fstatfs64 - data8 sys_ni_syscall - - /* - * CAUTION: If any system calls are added beyond this point - * then the check in `arch/ia64/kernel/ivt.S' will have - * to be modified also. You've been warned. - */ + data8 sys_tgkill /* 270 */ + data8 compat_sys_utimes + data8 sys32_fadvise64_64 + data8 sys_ni_syscall + data8 sys_ni_syscall + + // guard against failures to increase IA32_NR_syscalls + .org ia32_syscall_table + 8*IA32_NR_syscalls diff -Nru a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h --- a/arch/ia64/ia32/ia32priv.h Sun Jan 4 17:36:11 2004 +++ b/arch/ia64/ia32/ia32priv.h Sun Jan 4 17:36:11 2004 @@ -199,6 +199,8 @@ unsigned int sival_ptr; } sigval_t32; +#define SIGEV_PAD_SIZE32 ((SIGEV_MAX_SIZE/sizeof(int)) - 3) + typedef struct siginfo32 { int si_signo; int si_errno; @@ -250,6 +252,19 @@ } _sigpoll; } _sifields; } siginfo_t32; + +typedef struct sigevent32 { + sigval_t32 sigev_value; + int sigev_signo; + int sigev_notify; + union { + int _pad[SIGEV_PAD_SIZE32]; + struct { + u32 _function; + u32 _attribute; /* really pthread_attr_t */ + } _sigev_thread; + } _sigev_un; +} sigevent_t32; struct old_linux32_dirent { u32 d_ino; diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c --- a/arch/ia64/ia32/sys_ia32.c Sun Jan 4 17:36:11 2004 +++ b/arch/ia64/ia32/sys_ia32.c Sun Jan 4 17:36:11 2004 @@ -2164,19 +2164,6 @@ return ret; } -asmlinkage long sys_ni_syscall(void); - -asmlinkage long -sys32_ni_syscall (int dummy0, int dummy1, int dummy2, int dummy3, int dummy4, int dummy5, - int dummy6, int dummy7, int stack) -{ - struct pt_regs *regs = (struct pt_regs *)&stack; - - printk(KERN_WARNING "IA32 syscall #%d issued, maybe we should implement it\n", - (int)regs->r1); - return(sys_ni_syscall()); -} - /* * The IA64 maps 4 I/O ports for each 4K page */ @@ -2924,6 +2911,54 @@ return -EFAULT; return 0; } + +extern asmlinkage long +sys_timer_create(clockid_t which_clock, struct sigevent *timer_event_spec, + timer_t * created_timer_id); + +asmlinkage long +sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id) +{ + struct sigevent se; + mm_segment_t oldfs; + timer_t t; + long err; + + if (se32 == NULL) + return sys_timer_create(clock, NULL, timer_id); + + memset(&se, 0, sizeof(struct sigevent)); + if (get_user(se.sigev_value.sival_int, &se32->sigev_value.sival_int) || + __get_user(se.sigev_signo, &se32->sigev_signo) || + __get_user(se.sigev_notify, &se32->sigev_notify) || + __copy_from_user(&se._sigev_un._pad, &se32->_sigev_un._pad, + sizeof(se._sigev_un._pad))) + return -EFAULT; + + if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t))) + return -EFAULT; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + err = sys_timer_create(clock, &se, &t); + set_fs(oldfs); + + if (!err) + err = __put_user (t, timer_id); + + return err; +} + +extern long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice); + +long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, + __u32 len_low, __u32 len_high, int advice) +{ + return sys_fadvise64_64(fd, + (((u64)offset_high)<<32) | offset_low, + (((u64)len_high)<<32) | len_low, + advice); +} #ifdef NOTYET /* UNTESTED FOR IA64 FROM HERE DOWN */ diff -Nru a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S --- a/arch/ia64/kernel/entry.S Sun Jan 4 17:36:11 2004 +++ b/arch/ia64/kernel/entry.S Sun Jan 4 17:36:11 2004 @@ -484,33 +484,10 @@ END(clone) /* - * We invoke syscall_trace through this intermediate function to - * ensure that the syscall input arguments are not clobbered. We - * also use it to preserve b6, which contains the syscall entry point. - */ -GLOBAL_ENTRY(invoke_syscall_trace) - .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) - alloc loc1=ar.pfs,8,3,0,0 - mov loc0=rp - .body - mov loc2=b6 - ;; - br.call.sptk.many rp=syscall_trace -.ret3: mov rp=loc0 - mov ar.pfs=loc1 - mov b6=loc2 - br.ret.sptk.many rp -END(invoke_syscall_trace) - - /* * Invoke a system call, but do some tracing before and after the call. * We MUST preserve the current register frame throughout this routine * because some system calls (such as ia64_execve) directly * manipulate ar.pfs. - * - * Input: - * r15 = syscall number - * b6 = syscall entry point */ .global ia64_strace_leave_kernel @@ -522,21 +499,38 @@ */ nop.m 0 nop.i 0 - br.call.sptk.many rp=invoke_syscall_trace // give parent a chance to catch syscall args + br.call.sptk.many rp=syscall_trace // give parent a chance to catch syscall args } -.ret6: br.call.sptk.many rp=b6 // do the syscall -strace_check_retval: + // the syscall number may have changed, so re-load it and re-calculate the + // syscall entry-point: + adds r15=PT(R15)+16,sp // r15 = &pt_regs.r15 (syscall #) + ;; + ld8 r15=[r15] + mov r3=NR_syscalls - 1 + ;; + adds r15=-1024,r15 + movl r16=sys_call_table + ;; + shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024) + cmp.leu p6,p7=r15,r3 + ;; +(p6) ld8 r20=[r20] // load address of syscall entry point +(p7) movl r20=sys_ni_syscall + ;; + mov b6=r20 + br.call.sptk.many rp=b6 // do the syscall +.strace_check_retval: cmp.lt p6,p0=r8,r0 // syscall failed? adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8 adds r3=PT(R10)+16,sp // r3 = &pt_regs.r10 mov r10=0 (p6) br.cond.sptk strace_error // syscall failed -> ;; // avoid RAW on r10 -strace_save_retval: +.strace_save_retval: .mem.offset 0,0; st8.spill [r2]=r8 // store return value in slot for r8 .mem.offset 8,0; st8.spill [r3]=r10 // clear error indication in slot for r10 ia64_strace_leave_kernel: - br.call.sptk.many rp=invoke_syscall_trace // give parent a chance to catch return value + br.call.sptk.many rp=syscall_trace // give parent a chance to catch return value .rety: br.cond.sptk ia64_leave_syscall strace_error: @@ -548,7 +542,7 @@ ;; (p6) mov r10=-1 (p6) mov r8=r9 - br.cond.sptk strace_save_retval + br.cond.sptk .strace_save_retval END(ia64_trace_syscall) GLOBAL_ENTRY(ia64_ret_from_clone) @@ -573,7 +567,7 @@ ;; mov r8=0 tbit.nz p6,p0=r2,TIF_SYSCALL_TRACE -(p6) br.cond.spnt strace_check_retval +(p6) br.cond.spnt .strace_check_retval ;; // added stop bits to prevent r8 dependency END(ia64_ret_from_clone) // fall through @@ -726,6 +720,7 @@ mov b6=r22 // restore b6 shr.u r18=r19,16 // get byte size of existing "dirty" partition (pKStk) br.cond.dpnt.many skip_rbs_switch +(pNonSys) br.cond.dpnt.many dont_preserve_current_frame br.cond.sptk.many rbs_switch END(ia64_leave_syscall) @@ -1334,9 +1329,9 @@ data8 sys_syslog data8 sys_setitimer data8 sys_getitimer - data8 ia64_ni_syscall // 1120 /* was: ia64_oldstat */ - data8 ia64_ni_syscall /* was: ia64_oldlstat */ - data8 ia64_ni_syscall /* was: ia64_oldfstat */ + data8 sys_ni_syscall // 1120 /* was: ia64_oldstat */ + data8 sys_ni_syscall /* was: ia64_oldlstat */ + data8 sys_ni_syscall /* was: ia64_oldfstat */ data8 sys_vhangup data8 sys_lchown data8 sys_remap_file_pages // 1125 @@ -1346,16 +1341,16 @@ data8 sys_setdomainname data8 sys_newuname // 1130 data8 sys_adjtimex - data8 ia64_ni_syscall /* was: ia64_create_module */ + data8 sys_ni_syscall /* was: ia64_create_module */ data8 sys_init_module data8 sys_delete_module - data8 ia64_ni_syscall // 1135 /* was: sys_get_kernel_syms */ - data8 ia64_ni_syscall /* was: sys_query_module */ + data8 sys_ni_syscall // 1135 /* was: sys_get_kernel_syms */ + data8 sys_ni_syscall /* was: sys_query_module */ data8 sys_quotactl data8 sys_bdflush data8 sys_sysfs data8 sys_personality // 1140 - data8 ia64_ni_syscall // sys_afs_syscall + data8 sys_ni_syscall // sys_afs_syscall data8 sys_setfsuid data8 sys_setfsgid data8 sys_getdents @@ -1473,26 +1468,26 @@ data8 sys_clock_nanosleep data8 sys_fstatfs64 data8 sys_statfs64 - data8 ia64_ni_syscall - data8 ia64_ni_syscall // 1260 - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall // 1265 - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall // 1270 - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall // 1275 - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall // 1260 + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall // 1265 + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall // 1270 + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall // 1275 + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls diff -Nru a/arch/ia64/kernel/entry.h b/arch/ia64/kernel/entry.h --- a/arch/ia64/kernel/entry.h Sun Jan 4 17:36:11 2004 +++ b/arch/ia64/kernel/entry.h Sun Jan 4 17:36:11 2004 @@ -4,7 +4,7 @@ * Preserved registers that are shared between code in ivt.S and entry.S. Be * careful not to step on these! */ -#define pLvSys p1 /* set 1 if leave from syscall; otherwise, set 0*/ +#define pLvSys p1 /* set 1 if leave from syscall; otherwise, set 0 */ #define pKStk p2 /* will leave_{kernel,syscall} return to kernel-stacks? */ #define pUStk p3 /* will leave_{kernel,syscall} return to user-stacks? */ #define pSys p4 /* are we processing a (synchronous) system call? */ diff -Nru a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S --- a/arch/ia64/kernel/ivt.S Sun Jan 4 17:36:10 2004 +++ b/arch/ia64/kernel/ivt.S Sun Jan 4 17:36:10 2004 @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -705,13 +706,14 @@ movl r2=ia64_ret_from_syscall ;; shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024) - cmp.geu p0,p7=r3,r15 // (syscall > 0 && syscall < 1024 + NR_syscalls) ? + cmp.leu p6,p7=r15,r3 // (syscall > 0 && syscall < 1024 + NR_syscalls) ? mov rp=r2 // set the real return addr ;; -(p7) add r20=(__NR_ni_syscall-1024)*8,r16 // force __NR_ni_syscall +(p6) ld8 r20=[r20] // load address of syscall entry point +(p7) movl r20=sys_ni_syscall + add r2=TI_FLAGS+IA64_TASK_SIZE,r13 ;; - ld8 r20=[r20] // load address of syscall entry point ld4 r2=[r2] // r2 = current_thread_info()->flags ;; tbit.z p8,p0=r2,TIF_SYSCALL_TRACE @@ -1513,7 +1515,7 @@ alloc r15=ar.pfs,0,0,6,0 // must first in an insn group ;; ld4 r8=[r14],8 // r8 == eax (syscall number) - mov r15=270 // number of entries in ia32 system call table + mov r15=IA32_NR_syscalls ;; cmp.ltu.unc p6,p7=r8,r15 ld4 out1=[r14],8 // r9 == ecx diff -Nru a/arch/ia64/kernel/perfmon_default_smpl.c b/arch/ia64/kernel/perfmon_default_smpl.c --- a/arch/ia64/kernel/perfmon_default_smpl.c Sun Jan 4 17:36:11 2004 +++ b/arch/ia64/kernel/perfmon_default_smpl.c Sun Jan 4 17:36:11 2004 @@ -114,7 +114,7 @@ pfm_default_smpl_hdr_t *hdr; pfm_default_smpl_entry_t *ent; void *cur, *last; - unsigned long *e; + unsigned long *e, entry_size; unsigned int npmds, i; unsigned char ovfl_pmd; unsigned char ovfl_notify; @@ -131,8 +131,7 @@ ovfl_notify = arg->ovfl_notify; /* - * check for space against largest possibly entry. - * We may waste space at the end of the buffer. + * precheck for sanity */ if ((last - cur) < PFM_DEFAULT_MAX_ENTRY_SIZE) goto full; @@ -142,6 +141,8 @@ prefetch(arg->smpl_pmds_values); + entry_size = sizeof(*ent) + (npmds << 3); + /* position for first pmd */ e = (unsigned long *)(ent+1); @@ -191,7 +192,13 @@ /* * update position for next entry */ - hdr->hdr_cur_offs += sizeof(*ent) + (npmds << 3); + hdr->hdr_cur_offs += entry_size; + cur += entry_size; + + /* + * post check to avoid losing the last sample + */ + if ((last - cur) < PFM_DEFAULT_MAX_ENTRY_SIZE) goto full; /* * keep same ovfl_pmds, ovfl_notify diff -Nru a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c --- a/arch/ia64/kernel/ptrace.c Sun Jan 4 17:36:11 2004 +++ b/arch/ia64/kernel/ptrace.c Sun Jan 4 17:36:11 2004 @@ -29,6 +29,11 @@ #include #endif +#include "entry.h" + +#define p4 (1UL << 4) /* for pSys (see entry.h) */ +#define p5 (1UL << 5) /* for pNonSys (see entry.h) */ + /* * Bits in the PSR that we allow ptrace() to change: * be, up, ac, mfl, mfh (the user mask; five bits total) @@ -51,6 +56,14 @@ # define dprintk(format...) #endif +/* Return TRUE if PT was created due to kernel-entry via a system-call. */ + +static inline int +in_syscall (struct pt_regs *pt) +{ + return (long) pt->cr_ifs >= 0; +} + /* * Collect the NaT bits for r1-r31 from scratch_unat and return a NaT * bitset where bit i is set iff the NaT bit of register i is set. @@ -272,7 +285,7 @@ ubspstore = (unsigned long *) pt->ar_bspstore; urbs_kargs = urbs_end; - if ((long)pt->cr_ifs >= 0) { + if (in_syscall(pt)) { /* * If entered via syscall, don't allow user to set rnat bits * for syscall args. @@ -331,6 +344,13 @@ *rnat1_kaddr = ((*rnat1_kaddr & ~m) | (rnat1 & m)); } +static inline int +on_kernel_rbs (unsigned long addr, unsigned long bspstore, unsigned long urbs_end) +{ + return (addr >= bspstore + && addr <= (unsigned long) ia64_rse_rnat_addr((unsigned long *) urbs_end)); +} + /* * Read a word from the user-level backing store of task CHILD. ADDR is the user-level * address to read the word from, VAL a pointer to the return value, and USER_BSP gives @@ -355,7 +375,7 @@ child_regs = ia64_task_regs(child); bspstore = (unsigned long *) child_regs->ar_bspstore; krbs = (unsigned long *) child + IA64_RBS_OFFSET/8; - if (laddr >= bspstore && laddr <= ia64_rse_rnat_addr(urbs_end)) { + if (on_kernel_rbs(addr, (unsigned long) bspstore, (unsigned long) urbs_end)) { /* * Attempt to read the RBS in an area that's actually on the kernel RBS => * read the corresponding bits in the kernel RBS. @@ -406,7 +426,7 @@ child_regs = ia64_task_regs(child); bspstore = (unsigned long *) child_regs->ar_bspstore; krbs = (unsigned long *) child + IA64_RBS_OFFSET/8; - if (laddr >= bspstore && laddr <= ia64_rse_rnat_addr(urbs_end)) { + if (on_kernel_rbs(addr, (unsigned long) bspstore, (unsigned long) urbs_end)) { /* * Attempt to write the RBS in an area that's actually on the kernel RBS * => write the corresponding bits in the kernel RBS. @@ -443,7 +463,7 @@ ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19)); cfm = pt->cr_ifs & ~(1UL << 63); - if ((long) pt->cr_ifs >= 0) { + if (in_syscall(pt)) { /* * If bit 63 of cr.ifs is cleared, the kernel was entered via a system * call and we need to recover the CFM that existed on entry to the @@ -483,134 +503,80 @@ return 0; } -/* - * Simulate user-level "flushrs". Note: we can't just add pt->loadrs>>16 to - * pt->ar_bspstore because the kernel backing store and the user-level backing store may - * have different alignments (and therefore a different number of intervening rnat slots). - */ -static void -user_flushrs (struct task_struct *task, struct pt_regs *pt) -{ - unsigned long *krbs; - long ndirty; - - krbs = (unsigned long *) task + IA64_RBS_OFFSET/8; - ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19)); - - pt->ar_bspstore = (unsigned long) ia64_rse_skip_regs((unsigned long *) pt->ar_bspstore, - ndirty); - pt->loadrs = 0; -} - -static inline void -sync_user_rbs_one_thread (struct task_struct *p, int make_writable) -{ - struct switch_stack *sw; - unsigned long urbs_end; - struct pt_regs *pt; - - sw = (struct switch_stack *) (p->thread.ksp + 16); - pt = ia64_task_regs(p); - urbs_end = ia64_get_user_rbs_end(p, pt, NULL); - ia64_sync_user_rbs(p, sw, pt->ar_bspstore, urbs_end); - if (make_writable) - user_flushrs(p, pt); -} - -struct task_list { - struct task_list *next; - struct task_struct *task; -}; - -#ifdef CONFIG_SMP - -static inline void -collect_task (struct task_list **listp, struct task_struct *p, int make_writable) +static inline int +thread_matches (struct task_struct *thread, unsigned long addr) { - struct task_list *e; - - e = kmalloc(sizeof(*e), GFP_KERNEL); - if (!e) - /* oops, can't collect more: finish at least what we collected so far... */ - return; + unsigned long thread_rbs_end; + struct pt_regs *thread_regs; - get_task_struct(p); - e->task = p; - e->next = *listp; - *listp = e; -} + if (ptrace_check_attach(thread, 0) < 0) + /* + * If the thread is not in an attachable state, we'll ignore it. + * The net effect is that if ADDR happens to overlap with the + * portion of the thread's register backing store that is + * currently residing on the thread's kernel stack, then ptrace() + * may end up accessing a stale value. But if the thread isn't + * stopped, that's a problem anyhow, so we're doing as well as we + * can... + */ + return 0; -static inline struct task_list * -finish_task (struct task_list *list, int make_writable) -{ - struct task_list *next = list->next; + thread_regs = ia64_task_regs(thread); + thread_rbs_end = ia64_get_user_rbs_end(thread, thread_regs, NULL); + if (!on_kernel_rbs(addr, thread_regs->ar_bspstore, thread_rbs_end)) + return 0; - sync_user_rbs_one_thread(list->task, make_writable); - put_task_struct(list->task); - kfree(list); - return next; + return 1; /* looks like we've got a winner */ } -#else -# define collect_task(list, p, make_writable) sync_user_rbs_one_thread(p, make_writable) -# define finish_task(list, make_writable) (NULL) -#endif - /* - * Synchronize the RSE backing store of CHILD and all tasks that share the address space - * with it. CHILD_URBS_END is the address of the end of the register backing store of - * CHILD. If MAKE_WRITABLE is set, a user-level "flushrs" is simulated such that the VM - * can be written via ptrace() and the tasks will pick up the newly written values. It - * would be OK to unconditionally simulate a "flushrs", but this would be more intrusive - * than strictly necessary (e.g., it would make it impossible to obtain the original value - * of ar.bspstore). + * GDB apparently wants to be able to read the register-backing store of any thread when + * attached to a given process. If we are peeking or poking an address that happens to + * reside in the kernel-backing store of another thread, we need to attach to that thread, + * because otherwise we end up accessing stale data. + * + * task_list_lock must be read-locked before calling this routine! */ -static void -threads_sync_user_rbs (struct task_struct *child, unsigned long child_urbs_end, int make_writable) +static struct task_struct * +find_thread_for_addr (struct task_struct *child, unsigned long addr) { - struct switch_stack *sw; struct task_struct *g, *p; struct mm_struct *mm; - struct pt_regs *pt; - long multi_threaded; + int mm_users; - task_lock(child); - { - mm = child->mm; - multi_threaded = mm && (atomic_read(&mm->mm_users) > 1); - } - task_unlock(child); + if (!(mm = get_task_mm(child))) + return child; - if (!multi_threaded) { - sw = (struct switch_stack *) (child->thread.ksp + 16); - pt = ia64_task_regs(child); - ia64_sync_user_rbs(child, sw, pt->ar_bspstore, child_urbs_end); - if (make_writable) - user_flushrs(child, pt); - } else { - /* - * Note: we can't call ia64_sync_user_rbs() while holding the - * tasklist_lock because that may cause a dead-lock: ia64_sync_user_rbs() - * may indirectly call tlb_flush_all(), which triggers an IPI. - * Furthermore, tasklist_lock is acquired by fork() with interrupts - * disabled, so with the right timing, the IPI never completes, hence - * tasklist_lock never gets released, hence fork() never completes... - */ - struct task_list *list = NULL; + mm_users = atomic_read(&mm->mm_users) - 1; /* -1 because of our get_task_mm()... */ + if (mm_users <= 1) + goto out; /* not multi-threaded */ - read_lock(&tasklist_lock); - { - do_each_thread(g, p) { - if (p->mm == mm && p->state != TASK_RUNNING) - collect_task(&list, p, make_writable); - } while_each_thread(g, p); + /* + * First, traverse the child's thread-list. Good for scalability with + * NPTL-threads. + */ + p = child; + do { + if (thread_matches(p, addr)) { + child = p; + goto out; } - read_unlock(&tasklist_lock); + if (mm_users-- <= 1) + goto out; + } while ((p = next_thread(p)) != child); - while (list) - list = finish_task(list, make_writable); - } - child->thread.flags |= IA64_THREAD_KRBS_SYNCED; /* set the flag in the child thread only */ + do_each_thread(g, p) { + if (child->mm != mm) + continue; + + if (thread_matches(p, addr)) { + child = p; + goto out; + } + } while_each_thread(g, p); + out: + mmput(mm); + return child; } /* @@ -668,12 +634,40 @@ return ret; } +/* + * Change the machine-state of CHILD such that it will return via the normal + * kernel exit-path, rather than the syscall-exit path. + */ +static void +convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, unsigned long cfm) +{ + struct unw_frame_info info, prev_info; + unsigned long ip, pr; + + unw_init_from_blocked_task(&info, child); + while (1) { + prev_info = info; + if (unw_unwind(&info) < 0) + return; + if (unw_get_rp(&info, &ip) < 0) + return; + if (ip < FIXADDR_USER_END) + break; + } + + unw_get_pr(&prev_info, &pr); + pr &= ~pSys; + pr |= pNonSys; + unw_set_pr(&prev_info, pr); + + pt->cr_ifs = (1UL << 63) | cfm; +} + static int access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data, int write_access) { - unsigned long *ptr, regnum, urbs_end, rnat_addr; + unsigned long *ptr, regnum, urbs_end, rnat_addr, cfm; struct switch_stack *sw; - struct unw_frame_info info; struct pt_regs *pt; pt = ia64_task_regs(child); @@ -778,13 +772,30 @@ * By convention, we use PT_AR_BSP to refer to the end of the user-level * backing store. Use ia64_rse_skip_regs(PT_AR_BSP, -CFM.sof) to get * the real value of ar.bsp at the time the kernel was entered. + * + * Furthermore, when changing the contents of PT_AR_BSP (or + * PT_CFM) we MUST copy any users-level stacked registers that are + * stored on the kernel stack back to user-space because + * otherwise, we might end up clobbering kernel stacked registers. + * Also, if this happens while the task is blocked in a system + * call, which convert the state such that the non-system-call + * exit path is used. This ensures that the proper state will be + * picked up when resuming execution. However, it *also* means + * that once we write PT_AR_BSP/PT_CFM, it won't be possible to + * modify the syscall arguments of the pending system call any + * longer. This shouldn't be an issue because modifying + * PT_AR_BSP/PT_CFM generally implies that we're either abandoning + * the pending system call or that we defer it's re-execution + * (e.g., due to GDB doing an inferior function call). */ - urbs_end = ia64_get_user_rbs_end(child, pt, NULL); + urbs_end = ia64_get_user_rbs_end(child, pt, &cfm); if (write_access) { if (*data != urbs_end) { if (ia64_sync_user_rbs(child, sw, pt->ar_bspstore, urbs_end) < 0) return -1; + if (in_syscall(pt)) + convert_to_non_syscall(child, pt, cfm); /* simulate user-level write of ar.bsp: */ pt->loadrs = 0; pt->ar_bspstore = *data; @@ -794,27 +805,19 @@ return 0; case PT_CFM: - if ((long) pt->cr_ifs < 0) { - if (write_access) + urbs_end = ia64_get_user_rbs_end(child, pt, &cfm); + if (write_access) { + if (((cfm ^ *data) & 0x3fffffffffU) != 0) { + if (ia64_sync_user_rbs(child, sw, + pt->ar_bspstore, urbs_end) < 0) + return -1; + if (in_syscall(pt)) + convert_to_non_syscall(child, pt, cfm); pt->cr_ifs = ((pt->cr_ifs & ~0x3fffffffffUL) | (*data & 0x3fffffffffUL)); - else - *data = pt->cr_ifs & 0x3fffffffffUL; - } else { - /* kernel was entered through a system call */ - unsigned long cfm; - - unw_init_from_blocked_task(&info, child); - if (unw_unwind_to_user(&info) < 0) - return -1; - - unw_get_cfm(&info, &cfm); - if (write_access) - unw_set_cfm(&info, ((cfm & ~0x3fffffffffU) - | (*data & 0x3fffffffffUL))); - else - *data = cfm; - } + } + } else + *data = cfm; return 0; case PT_CR_IPSR: @@ -1240,9 +1243,6 @@ /* make sure the single step/take-branch tra bits are not set: */ child_psr->ss = 0; child_psr->tb = 0; - - /* Turn off flag indicating that the KRBS is sync'd with child's VM: */ - child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED; } asmlinkage long @@ -1250,7 +1250,7 @@ long arg4, long arg5, long arg6, long arg7, long stack) { struct pt_regs *pt, *regs = (struct pt_regs *) &stack; - unsigned long urbs_end; + unsigned long urbs_end, peek_or_poke; struct task_struct *child; struct switch_stack *sw; long ret; @@ -1269,12 +1269,17 @@ goto out; } + peek_or_poke = (request == PTRACE_PEEKTEXT || request == PTRACE_PEEKDATA + || request == PTRACE_POKETEXT || request == PTRACE_POKEDATA); ret = -ESRCH; read_lock(&tasklist_lock); { child = find_task_by_pid(pid); - if (child) + if (child) { + if (peek_or_poke) + child = find_thread_for_addr(child, addr); get_task_struct(child); + } } read_unlock(&tasklist_lock); if (!child) @@ -1299,10 +1304,6 @@ case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: /* read word at location addr */ urbs_end = ia64_get_user_rbs_end(child, pt, NULL); - - if (!(child->thread.flags & IA64_THREAD_KRBS_SYNCED)) - threads_sync_user_rbs(child, urbs_end, 0); - ret = ia64_peek(child, sw, urbs_end, addr, &data); if (ret == 0) { ret = data; @@ -1313,9 +1314,6 @@ case PTRACE_POKETEXT: case PTRACE_POKEDATA: /* write the word at location addr */ urbs_end = ia64_get_user_rbs_end(child, pt, NULL); - if (!(child->thread.flags & IA64_THREAD_KRBS_SYNCED)) - threads_sync_user_rbs(child, urbs_end, 1); - ret = ia64_poke(child, sw, urbs_end, addr, data); goto out_tsk; @@ -1359,9 +1357,6 @@ ia64_psr(pt)->ss = 0; ia64_psr(pt)->tb = 0; - /* Turn off flag indicating that the KRBS is sync'd with child's VM: */ - child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED; - wake_up_process(child); ret = 0; goto out_tsk; @@ -1380,9 +1375,6 @@ ia64_psr(pt)->ss = 0; ia64_psr(pt)->tb = 0; - /* Turn off flag indicating that the KRBS is sync'd with child's VM: */ - child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED; - wake_up_process(child); ret = 0; goto out_tsk; @@ -1401,9 +1393,6 @@ } child->exit_code = data; - /* Turn off flag indicating that the KRBS is sync'd with child's VM: */ - child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED; - /* give it a chance to run. */ wake_up_process(child); ret = 0; @@ -1432,7 +1421,9 @@ return ret; } -void +/* "asmlinkage" so the input arguments are preserved... */ + +asmlinkage void syscall_trace (void) { if (!test_thread_flag(TIF_SYSCALL_TRACE)) diff -Nru a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c --- a/arch/ia64/kernel/signal.c Sun Jan 4 17:36:11 2004 +++ b/arch/ia64/kernel/signal.c Sun Jan 4 17:36:11 2004 @@ -538,31 +538,41 @@ if (!oldset) oldset = ¤t->blocked; - if (IS_IA32_PROCESS(&scr->pt)) { - if (in_syscall) { - if (errno >= 0) - restart = 0; - else - errno = -errno; - } - } else if ((long) scr->pt.r10 != -1) - /* - * A system calls has to be restarted only if one of the error codes - * ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned. If r10 - * isn't -1 then r8 doesn't hold an error code and we don't need to - * restart the syscall, so we can clear the "restart" flag here. - */ - restart = 0; - + /* + * This only loops in the rare cases of handle_signal() failing, in which case we + * need to push through a forced SIGSEGV. + */ while (1) { int signr = get_signal_to_deliver(&info, &scr->pt, NULL); + /* + * get_signal_to_deliver() may have run a debugger (via notify_parent()) + * and the debugger may have modified the state (e.g., to arrange for an + * inferior call), thus it's important to check for restarting _after_ + * get_signal_to_deliver(). + */ + if (IS_IA32_PROCESS(&scr->pt)) { + if (in_syscall) { + if (errno >= 0) + restart = 0; + else + errno = -errno; + } + } else if ((long) scr->pt.r10 != -1) + /* + * A system calls has to be restarted only if one of the error codes + * ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned. If r10 + * isn't -1 then r8 doesn't hold an error code and we don't need to + * restart the syscall, so we can clear the "restart" flag here. + */ + restart = 0; + if (signr <= 0) break; ka = ¤t->sighand->action[signr - 1]; - if (restart) { + if (unlikely(restart)) { switch (errno) { case ERESTART_RESTARTBLOCK: case ERESTARTNOHAND: @@ -582,6 +592,7 @@ scr->pt.cr_iip -= 2; } else ia64_decrement_ip(&scr->pt); + restart = 0; /* don't restart twice if handle_signal() fails... */ } } diff -Nru a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c --- a/arch/ia64/kernel/traps.c Sun Jan 4 17:36:11 2004 +++ b/arch/ia64/kernel/traps.c Sun Jan 4 17:36:11 2004 @@ -216,21 +216,6 @@ } /* - * Unimplemented system calls. This is called only for stuff that - * we're supposed to implement but haven't done so yet. Everything - * else goes to sys_ni_syscall. - * - * XXX Remove this for v2.6.1. - */ -asmlinkage long -ia64_ni_syscall (unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5, unsigned long arg6, unsigned long arg7, - unsigned long stack) -{ - return -ENOSYS; -} - -/* * disabled_fph_fault() is called when a user-level process attempts to access f32..f127 * and it doesn't own the fp-high register partition. When this happens, we save the * current fph partition in the task_struct of the fpu-owner (if necessary) and then load diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig --- a/arch/sparc64/defconfig Sun Jan 4 17:36:11 2004 +++ b/arch/sparc64/defconfig Sun Jan 4 17:36:11 2004 @@ -27,6 +27,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # # Loadable module support @@ -345,6 +346,8 @@ # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLOGICPTI=m CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DC390T=m +# CONFIG_SCSI_DC390T_NOGENSUPP is not set # CONFIG_SCSI_NSP32 is not set CONFIG_SCSI_DEBUG=m CONFIG_SCSI_SUNESP=y @@ -1007,7 +1010,6 @@ # CONFIG_KEYBOARD_NEWTON is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_PS2_SYNAPTICS is not set CONFIG_MOUSE_SERIAL=y # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TOUCHSCREEN is not set @@ -1058,6 +1060,7 @@ CONFIG_SENSORS_IT87=m CONFIG_SENSORS_LM75=m CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM83=m CONFIG_SENSORS_LM85=m CONFIG_SENSORS_VIA686A=m CONFIG_SENSORS_W83781D=m @@ -1184,12 +1187,11 @@ # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y CONFIG_SUN_PARTITION=y -CONFIG_SMB_NLS=y -CONFIG_NLS=y # # Native Language Support # +CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set # CONFIG_NLS_CODEPAGE_737 is not set @@ -1274,6 +1276,7 @@ # # Supported Frontend Modules # +CONFIG_DVB_TWINHAN_DST=m CONFIG_DVB_STV0299=m CONFIG_DVB_SP887X=m CONFIG_DVB_ALPS_TDLB7=m @@ -1285,6 +1288,7 @@ CONFIG_DVB_MT312=m CONFIG_DVB_VES1820=m CONFIG_DVB_VES1X93=m +CONFIG_DVB_SP887X_FIRMWARE_FILE="/etc/dvb/sc_main.mc" # # Supported SAA7146 based PCI Adapters @@ -1299,11 +1303,17 @@ # Supported USB Adapters # # CONFIG_DVB_TTUSB_BUDGET is not set +CONFIG_DVB_TTUSB_DEC=m # # Supported FlexCopII (B2C2) Adapters # CONFIG_DVB_B2C2_SKYSTAR=m + +# +# Supported BT878 Adapters +# +CONFIG_DVB_BT8XX=m CONFIG_VIDEO_SAA7146=m CONFIG_VIDEO_SAA7146_VV=m CONFIG_VIDEO_VIDEOBUF=m @@ -1463,6 +1473,7 @@ # CONFIG_USB_PWC is not set # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set +CONFIG_USB_W9968CF=m # # USB Network adaptors @@ -1544,6 +1555,7 @@ # CONFIG_USB_TIGL is not set CONFIG_USB_AUERSWALD=m CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m # CONFIG_USB_BRLVGER is not set CONFIG_USB_LCD=m CONFIG_USB_SPEEDTOUCH=m diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig --- a/arch/x86_64/Kconfig Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/Kconfig Sun Jan 4 17:36:11 2004 @@ -333,6 +333,11 @@ depends on PCI default y +# the drivers/pci/msi.c code needs to be fixed first before enabling +config PCI_USE_VECTOR + bool + default n + source "drivers/pci/Kconfig" config HOTPLUG @@ -526,13 +531,6 @@ Add a simple leak tracer to the IOMMU code. This is useful when you are debugging a buggy device driver that leaks IOMMU mappings. -config MCE_DEBUG - bool "K8 Machine check debugging mode" - default y - help - Turn on all Machine Check debugging for device driver problems. - This can cause panics, but is useful to find device driver problems. - #config X86_REMOTE_DEBUG # bool "kgdb debugging stub" diff -Nru a/arch/x86_64/boot/install.sh b/arch/x86_64/boot/install.sh --- a/arch/x86_64/boot/install.sh Sun Jan 4 17:36:10 2004 +++ b/arch/x86_64/boot/install.sh Sun Jan 4 17:36:10 2004 @@ -21,6 +21,7 @@ # User may have a custom install script +if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi # Default install - same as make zlilo diff -Nru a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c --- a/arch/x86_64/ia32/ia32_ioctl.c Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/ia32/ia32_ioctl.c Sun Jan 4 17:36:11 2004 @@ -59,7 +59,7 @@ return ret; case RTC_IRQP_SET32: - cmd = RTC_EPOCH_SET; + cmd = RTC_IRQP_SET; break; case RTC_EPOCH_READ32: diff -Nru a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S --- a/arch/x86_64/ia32/ia32entry.S Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/ia32/ia32entry.S Sun Jan 4 17:36:11 2004 @@ -330,10 +330,10 @@ .quad sys32_adjtimex .quad sys32_mprotect /* 125 */ .quad compat_sys_sigprocmask - .quad sys32_module_warning /* create_module */ + .quad quiet_ni_syscall /* create_module */ .quad sys_init_module .quad sys_delete_module - .quad sys32_module_warning /* 130 get_kernel_syms */ + .quad quiet_ni_syscall /* 130 get_kernel_syms */ .quad ni_syscall /* quotactl */ .quad sys_getpgid .quad sys_fchdir diff -Nru a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c --- a/arch/x86_64/ia32/sys_ia32.c Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/ia32/sys_ia32.c Sun Jan 4 17:36:11 2004 @@ -1832,13 +1832,6 @@ } #endif -long sys32_module_warning(void) -{ - printk(KERN_INFO "%s: 32bit 2.4.x modutils not supported on 64bit kernel\n", - current->comm); - return -ENOSYS ; -} - extern long sys_io_setup(unsigned nr_reqs, aio_context_t *ctx); long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p) @@ -2004,11 +1997,15 @@ long sys32_vm86_warning(void) { + struct task_struct *me = current; + static char lastcomm[8]; + if (strcmp(lastcomm, me->comm)) { printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n", - current->comm); - return -ENOSYS ; + me->comm); + strcpy(lastcomm, me->comm); + } + return -ENOSYS; } - struct exec_domain ia32_exec_domain = { .name = "linux/x86", diff -Nru a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c --- a/arch/x86_64/ia32/syscall32.c Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/ia32/syscall32.c Sun Jan 4 17:36:11 2004 @@ -30,10 +30,12 @@ int map_syscall32(struct mm_struct *mm, unsigned long address) { pte_t *pte; + pmd_t *pmd; int err = 0; + down_read(&mm->mmap_sem); spin_lock(&mm->page_table_lock); - pmd_t *pmd = pmd_alloc(mm, pgd_offset(mm, address), address); + pmd = pmd_alloc(mm, pgd_offset(mm, address), address); if (pmd && (pte = pte_alloc_map(mm, pmd, address)) != NULL) { if (pte_none(*pte)) { set_pte(pte, diff -Nru a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile --- a/arch/x86_64/kernel/Makefile Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/kernel/Makefile Sun Jan 4 17:36:11 2004 @@ -18,13 +18,16 @@ obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o obj-$(CONFIG_PM) += suspend.o obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o +obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o obj-$(CONFIG_MODULES) += module.o +obj-y += topology.o + bootflag-y += ../../i386/kernel/bootflag.o cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o +topology-y += ../../i386/mach-default/topology.o -obj-$(CONFIG_CPU_FREQ) += cpufreq/ diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c --- a/arch/x86_64/kernel/apic.c Sun Jan 4 17:36:10 2004 +++ b/arch/x86_64/kernel/apic.c Sun Jan 4 17:36:10 2004 @@ -42,6 +42,8 @@ static DEFINE_PER_CPU(int, prof_old_multiplier) = 1; static DEFINE_PER_CPU(int, prof_counter) = 1; +static void apic_pm_activate(void); + void enable_NMI_through_LVT0 (void * dummy) { unsigned int v, ver; @@ -435,6 +437,7 @@ if (nmi_watchdog == NMI_LOCAL_APIC) setup_apic_nmi_watchdog(); + apic_pm_activate(); } #ifdef CONFIG_PM @@ -556,7 +559,7 @@ #else /* CONFIG_PM */ -static inline void apic_pm_activate(void) { } +static void apic_pm_activate(void) { } #endif /* CONFIG_PM */ @@ -579,7 +582,6 @@ if (nmi_watchdog != NMI_NONE) nmi_watchdog = NMI_LOCAL_APIC; - apic_pm_activate(); return 0; } diff -Nru a/arch/x86_64/kernel/bluesmoke.c b/arch/x86_64/kernel/bluesmoke.c --- a/arch/x86_64/kernel/bluesmoke.c Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/kernel/bluesmoke.c Sun Jan 4 17:36:11 2004 @@ -26,19 +26,6 @@ static int banks; static unsigned long ignored_banks, disabled_banks; -/* Machine Check on everything dubious. This is a good setting - for device driver testing. */ -#define K8_DRIVER_DEBUG ((1<<13)-1) -/* Report RAM errors and Hyper Transport Problems, but ignore Device - aborts and GART errors. */ -#define K8_NORMAL_OP 0xff - -#ifdef CONFIG_MCE_DEBUG -static u32 k8_nb_flags __initdata = K8_DRIVER_DEBUG; -#else -static u32 k8_nb_flags __initdata = K8_NORMAL_OP; -#endif - static void generic_machine_check(struct pt_regs * regs, long error_code) { int recover=1; @@ -200,11 +187,14 @@ static void check_k8_nb(int header) { struct pci_dev *nb; + u32 statuslow, statushigh; + unsigned short errcode; + int i; + nb = find_k8_nb(); if (nb == NULL) return; - u32 statuslow, statushigh; pci_read_config_dword(nb, 0x48, &statuslow); pci_read_config_dword(nb, 0x4c, &statushigh); if (!(statushigh & (1<<31))) @@ -215,50 +205,42 @@ printk(KERN_ERR "Northbridge status %08x%08x\n", statushigh,statuslow); - unsigned short errcode = statuslow & 0xffff; - switch (errcode >> 8) { - case 0: + printk(KERN_ERR " Error %s\n", extendederr[(statuslow >> 16) & 0xf]); + + errcode = statuslow & 0xffff; + switch ((statuslow >> 16) & 0xF) { + case 5: printk(KERN_ERR " GART TLB error %s %s\n", transaction[(errcode >> 2) & 3], cachelevel[errcode & 3]); break; - case 1: - if (errcode & (1<<11)) { - printk(KERN_ERR " bus error %s %s %s %s %s\n", - partproc[(errcode >> 10) & 0x3], - timeout[(errcode >> 9) & 1], + case 8: + printk(KERN_ERR " ECC error syndrome %x\n", + (((statuslow >> 24) & 0xff) << 8) | ((statushigh >> 15) & 0x7f)); + /*FALL THROUGH*/ + default: + printk(KERN_ERR " bus error %s, %s\n %s\n %s, %s\n", + partproc[(errcode >> 9) & 0x3], + timeout[(errcode >> 8) & 1], memtrans[(errcode >> 4) & 0xf], memoryio[(errcode >> 2) & 0x3], cachelevel[(errcode & 0x3)]); - } else if (errcode & (1<<8)) { - printk(KERN_ERR " memory error %s %s %s\n", - memtrans[(errcode >> 4) & 0xf], - transaction[(errcode >> 2) & 0x3], - cachelevel[(errcode & 0x3)]); - } else { - printk(KERN_ERR " unknown error code %x\n", errcode); - } - break; - } - if (statushigh & ((1<<14)|(1<<13))) - printk(KERN_ERR " ECC syndrome bits %x\n", - (((statuslow >> 24) & 0xff) << 8) | ((statushigh >> 15) & 0x7f)); - errcode = (statuslow >> 16) & 0xf; - printk(KERN_ERR " extended error %s\n", extendederr[(statuslow >> 16) & 0xf]); - /* should only print when it was a HyperTransport related error. */ printk(KERN_ERR " link number %x\n", (statushigh >> 4) & 3); + break; + } - int i; - for (i = 0; i < 32; i++) + for (i = 0; i < 32; i++) { + if (i == 26 || i == 28) + continue; if (highbits[i] && (statushigh & (1<rip, regs->rsp); - others: generic_machine_check(regs, error_code); @@ -367,12 +346,13 @@ machine_check_vector = k8_machine_check; for (i = 0; i < banks; i++) { u64 val = ((1UL< disable bank NUMBER mce=enable enable bank number - mce=device Enable device driver test reporting in NB mce=NUMBER mcheck timer interval number seconds. Can be also comma separated in a single mce= */ static int __init mcheck_enable(char *str) @@ -486,8 +465,6 @@ disabled_banks |= ~(1< #include diff -Nru a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S --- a/arch/x86_64/kernel/head.S Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/kernel/head.S Sun Jan 4 17:36:11 2004 @@ -38,6 +38,9 @@ movl %ebx,%ebp /* Save trampoline flag */ + movl $__KERNEL_DS,%eax + movl %eax,%ds + /* If the CPU doesn't support CPUID this will double fault. * Unfortunately it is hard to check for CPUID without a stack. */ @@ -114,24 +117,10 @@ movl $(pGDT32 - __START_KERNEL_map), %eax lgdt (%eax) +second: movl $(ljumpvector - __START_KERNEL_map), %eax /* Finally jump in 64bit mode */ ljmp *(%eax) - -second: - /* abuse syscall to get into 64bit mode. this way we don't need - a working low identity mapping just for the short 32bit roundtrip. - XXX kludge. this should not be needed. */ - movl $MSR_STAR,%ecx - xorl %eax,%eax - movl $(__USER32_CS<<16)|__KERNEL_CS,%edx - wrmsr - - movl $MSR_CSTAR,%ecx - movl $0xffffffff,%edx - movl $0x80100100,%eax # reach_long64 absolute - wrmsr - syscall .code64 .org 0x100 diff -Nru a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c --- a/arch/x86_64/kernel/i8259.c Sun Jan 4 17:36:10 2004 +++ b/arch/x86_64/kernel/i8259.c Sun Jan 4 17:36:10 2004 @@ -446,8 +446,10 @@ * us. (some of these will be overridden and become * 'special' SMP interrupts) */ - for (i = 0; i < NR_IRQS; i++) { + for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) { int vector = FIRST_EXTERNAL_VECTOR + i; + if (i >= NR_IRQS) + break; if (vector != IA32_SYSCALL_VECTOR && vector != KDB_VECTOR) { set_intr_gate(vector, interrupt[i]); } diff -Nru a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c --- a/arch/x86_64/kernel/io_apic.c Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/kernel/io_apic.c Sun Jan 4 17:36:11 2004 @@ -66,6 +66,14 @@ short apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; +#ifdef CONFIG_PCI_USE_VECTOR +int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1}; +#define vector_to_irq(vector) \ + (platform_legacy_irq(vector) ? vector : vector_irq[vector]) +#else +#define vector_to_irq(vector) (vector) +#endif + /* * The common case is 1:1 IRQ<->pin mappings. Sometimes there are * shared ISA-space IRQs, so we have to support them. We are super @@ -147,6 +155,13 @@ struct IO_APIC_route_entry entry; unsigned long flags; + /* Check delivery_mode to be sure we're not clearing an SMI pin */ + spin_lock_irqsave(&ioapic_lock, flags); + *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); + if (entry.delivery_mode == dest_SMI) + return; /* * Disable it in the IO-APIC irq-routing table: */ @@ -625,7 +640,8 @@ /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; -static int __init assign_irq_vector(int irq) +#ifndef CONFIG_PCI_USE_VECTOR +int __init assign_irq_vector(int irq) { static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; BUG_ON(irq >= NR_IRQ_VECTORS); @@ -647,10 +663,34 @@ IO_APIC_VECTOR(irq) = current_vector; return current_vector; } +#endif extern void (*interrupt[NR_IRQS])(void); -static struct hw_interrupt_type ioapic_level_irq_type; -static struct hw_interrupt_type ioapic_edge_irq_type; +static struct hw_interrupt_type ioapic_level_type; +static struct hw_interrupt_type ioapic_edge_type; + +#define IOAPIC_AUTO -1 +#define IOAPIC_EDGE 0 +#define IOAPIC_LEVEL 1 + +static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) +{ + if (use_pci_vector() && !platform_legacy_irq(irq)) { + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + irq_desc[vector].handler = &ioapic_level_type; + else + irq_desc[vector].handler = &ioapic_edge_type; + set_intr_gate(vector, interrupt[vector]); + } else { + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + irq_desc[irq].handler = &ioapic_level_type; + else + irq_desc[irq].handler = &ioapic_edge_type; + set_intr_gate(vector, interrupt[irq]); + } +} void __init setup_IO_APIC_irqs(void) { @@ -702,13 +742,7 @@ vector = assign_irq_vector(irq); entry.vector = vector; - if (IO_APIC_irq_trigger(irq)) - irq_desc[irq].handler = &ioapic_level_irq_type; - else - irq_desc[irq].handler = &ioapic_edge_irq_type; - - set_intr_gate(vector, interrupt[irq]); - + ioapic_register_intr(irq, vector, IOAPIC_AUTO); if (!apic && (irq < 16)) disable_8259A_irq(irq); } @@ -755,7 +789,7 @@ * The timer IRQ doesn't have to know that behind the * scene we have a 8259A-master in AEOI mode ... */ - irq_desc[0].handler = &ioapic_edge_irq_type; + irq_desc[0].handler = &ioapic_edge_type; /* * Add it to the IO-APIC irq-routing table: @@ -1210,9 +1244,6 @@ * that was delayed but this is now handled in the device * independent code. */ -#define enable_edge_ioapic_irq unmask_IO_APIC_irq - -static void disable_edge_ioapic_irq (unsigned int irq) { /* nothing */ } /* * Starting up a edge-triggered IO-APIC interrupt is @@ -1241,8 +1272,6 @@ return was_pending; } -#define shutdown_edge_ioapic_irq disable_edge_ioapic_irq - /* * Once we have recorded IRQ_PENDING already, we can mask the * interrupt for real. This prevents IRQ storms from unhandled @@ -1256,9 +1285,6 @@ ack_APIC_irq(); } -static void end_edge_ioapic_irq (unsigned int i) { /* nothing */ } - - /* * Level triggered interrupts can just be masked, * and shutting down and starting up the interrupt @@ -1280,10 +1306,6 @@ return 0; /* don't check for pending */ } -#define shutdown_level_ioapic_irq mask_IO_APIC_irq -#define enable_level_ioapic_irq unmask_IO_APIC_irq -#define disable_level_ioapic_irq mask_IO_APIC_irq - static void end_level_ioapic_irq (unsigned int irq) { unsigned long v; @@ -1343,9 +1365,7 @@ } } -static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ } - -static void set_ioapic_affinity (unsigned int irq, cpumask_t mask) +static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) { unsigned long flags; unsigned int dest; @@ -1362,6 +1382,58 @@ spin_unlock_irqrestore(&ioapic_lock, flags); } +#ifdef CONFIG_PCI_USE_VECTOR +static unsigned int startup_edge_ioapic_vector(unsigned int vector) +{ + int irq = vector_to_irq(vector); + + return startup_edge_ioapic_irq(irq); +} + +static void ack_edge_ioapic_vector(unsigned int vector) +{ + int irq = vector_to_irq(vector); + + ack_edge_ioapic_irq(irq); +} + +static unsigned int startup_level_ioapic_vector (unsigned int vector) +{ + int irq = vector_to_irq(vector); + + return startup_level_ioapic_irq (irq); +} + +static void end_level_ioapic_vector (unsigned int vector) +{ + int irq = vector_to_irq(vector); + + end_level_ioapic_irq(irq); +} + +static void mask_IO_APIC_vector (unsigned int vector) +{ + int irq = vector_to_irq(vector); + + mask_IO_APIC_irq(irq); +} + +static void unmask_IO_APIC_vector (unsigned int vector) +{ + int irq = vector_to_irq(vector); + + unmask_IO_APIC_irq(irq); +} + +static void set_ioapic_affinity_vector (unsigned int vector, + cpumask_t cpu_mask) +{ + int irq = vector_to_irq(vector); + + set_ioapic_affinity_irq(irq, cpu_mask); +} +#endif + /* * Level and edge triggered IO-APIC interrupts need different handling, * so we use two separate IRQ descriptors. Edge triggered IRQs can be @@ -1371,25 +1443,25 @@ * races. */ -static struct hw_interrupt_type ioapic_edge_irq_type = { +static struct hw_interrupt_type ioapic_edge_type = { .typename = "IO-APIC-edge", - .startup = startup_edge_ioapic_irq, - .shutdown = shutdown_edge_ioapic_irq, - .enable = enable_edge_ioapic_irq, - .disable = disable_edge_ioapic_irq, - .ack = ack_edge_ioapic_irq, - .end = end_edge_ioapic_irq, + .startup = startup_edge_ioapic, + .shutdown = shutdown_edge_ioapic, + .enable = enable_edge_ioapic, + .disable = disable_edge_ioapic, + .ack = ack_edge_ioapic, + .end = end_edge_ioapic, .set_affinity = set_ioapic_affinity, }; -static struct hw_interrupt_type ioapic_level_irq_type = { +static struct hw_interrupt_type ioapic_level_type = { .typename = "IO-APIC-level", - .startup = startup_level_ioapic_irq, - .shutdown = shutdown_level_ioapic_irq, - .enable = enable_level_ioapic_irq, - .disable = disable_level_ioapic_irq, - .ack = mask_and_ack_level_ioapic_irq, - .end = end_level_ioapic_irq, + .startup = startup_level_ioapic, + .shutdown = shutdown_level_ioapic, + .enable = enable_level_ioapic, + .disable = disable_level_ioapic, + .ack = mask_and_ack_level_ioapic, + .end = end_level_ioapic, .set_affinity = set_ioapic_affinity, }; @@ -1409,7 +1481,13 @@ * 0x80, because int 0x80 is hm, kind of importantish. ;) */ for (irq = 0; irq < NR_IRQS ; irq++) { - if (IO_APIC_IRQ(irq) && !IO_APIC_VECTOR(irq)) { + int tmp = irq; + if (use_pci_vector()) { + if (!platform_legacy_irq(tmp)) + if ((tmp = vector_to_irq(tmp)) == -1) + continue; + } + if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { /* * Hmm.. We don't have an entry for this, * so default to an old-fashioned 8259 @@ -1837,10 +1915,12 @@ mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, edge_level, active_high_low); + if (use_pci_vector() && !platform_legacy_irq(irq)) + irq = IO_APIC_VECTOR(irq); if (edge_level) { - irq_desc[irq].handler = &ioapic_level_irq_type; + irq_desc[irq].handler = &ioapic_level_type; } else { - irq_desc[irq].handler = &ioapic_edge_irq_type; + irq_desc[irq].handler = &ioapic_edge_type; } set_intr_gate(entry.vector, interrupt[irq]); diff -Nru a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c --- a/arch/x86_64/kernel/irq.c Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/kernel/irq.c Sun Jan 4 17:36:11 2004 @@ -408,6 +408,20 @@ return 1; } +int can_request_irq(unsigned int irq, unsigned long irqflags) +{ + struct irqaction *action; + + if (irq >= NR_IRQS) + return 0; + action = irq_desc[irq].action; + if (action) { + if (irqflags & action->flags & SA_SHIRQ) + action = NULL; + } + return !action; +} + /** * request_irq - allocate an interrupt line * @irq: Interrupt line to allocate diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c --- a/arch/x86_64/kernel/mpparse.c Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/kernel/mpparse.c Sun Jan 4 17:36:11 2004 @@ -881,7 +881,6 @@ { struct list_head *node = NULL; struct acpi_prt_entry *entry = NULL; - int vector = 0; int ioapic = -1; int ioapic_pin = 0; int irq = 0; @@ -933,20 +932,22 @@ if ((1<irq = irq; continue; } mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<irq = irq; - - printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> vector 0x%02x" + } + printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d" " -> IRQ %d\n", entry->id.segment, entry->id.bus, entry->id.device, ('A' + entry->pin), - mp_ioapic_routing[ioapic].apic_id, ioapic_pin, vector, + mp_ioapic_routing[ioapic].apic_id, ioapic_pin, entry->irq); } diff -Nru a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c --- a/arch/x86_64/kernel/pci-gart.c Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/kernel/pci-gart.c Sun Jan 4 17:36:11 2004 @@ -52,6 +52,8 @@ int iommu_sac_force = 0; int iommu_fullflush = 1; +#define MAX_NB 8 + /* Allocation bitmap for the remapping area */ static spinlock_t iommu_bitmap_lock = SPIN_LOCK_UNLOCKED; static unsigned long *iommu_gart_bitmap; /* guarded by iommu_bitmap_lock */ @@ -71,8 +73,8 @@ if (dev->bus->number == 0 && \ (PCI_SLOT(dev->devfn) >= 24) && (PCI_SLOT(dev->devfn) <= 31)) -static struct pci_dev *northbridges[NR_CPUS + 1]; -static u32 northbridge_flush_word[NR_CPUS + 1]; +static struct pci_dev *northbridges[MAX_NB]; +static u32 northbridge_flush_word[MAX_NB]; #define EMERGENCY_PAGES 32 /* = 128KB */ @@ -107,6 +109,8 @@ need_flush = 1; } } + if (iommu_fullflush) + need_flush = 1; spin_unlock_irqrestore(&iommu_bitmap_lock, flags); return offset; } @@ -135,9 +139,11 @@ int i; spin_lock_irqsave(&iommu_bitmap_lock, flags); - if (need_flush || iommu_fullflush) { - for (i = 0; northbridges[i]; i++) { + if (need_flush) { + for (i = 0; i < MAX_NB; i++) { u32 w; + if (!northbridges[i]) + continue; if (bus >= 0 && !(cpu_isset_const(i, bus_cpumask))) continue; pci_write_config_dword(northbridges[i], 0x9c, @@ -767,10 +773,9 @@ for_all_nb(dev) { u32 flag; int cpu = PCI_SLOT(dev->devfn) - 24; - if (cpu >= NR_CPUS) + if (cpu >= MAX_NB) continue; northbridges[cpu] = dev; - pci_read_config_dword(dev, 0x9c, &flag); /* cache flush word */ northbridge_flush_word[cpu] = flag; } @@ -783,7 +788,8 @@ /* Must execute after PCI subsystem */ fs_initcall(pci_iommu_init); -/* iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]] +/* iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]][,merge] + [,forcesac][,fullflush][,nomerge] size set size of iommu (in bytes) noagp don't initialize the AGP driver and use full aperture. off don't use the IOMMU @@ -791,6 +797,10 @@ memaper[=order] allocate an own aperture over RAM with size 32MB^order. noforce don't force IOMMU usage. Default. force Force IOMMU. + merge Do SG merging. Implies force (experimental) + nomerge Don't do SG merging. + forcesac For SAC mode for masks <40bits (experimental) + fullflush Flush IOMMU on each allocation (for testing) */ __init int iommu_setup(char *opt) { @@ -804,8 +814,10 @@ no_iommu = 1; if (!memcmp(p,"force", 5)) force_iommu = 1; - if (!memcmp(p,"noforce", 7)) + if (!memcmp(p,"noforce", 7)) { + iommu_merge = 0; force_iommu = 0; + } if (!memcmp(p, "memaper", 7)) { fallback_aper_force = 1; p += 7; @@ -816,6 +828,16 @@ panic_on_overflow = 1; if (!memcmp(p, "nopanic", 7)) panic_on_overflow = 0; + if (!memcmp(p, "merge", 5)) { + iommu_merge = 1; + force_iommu = 1; + } + if (!memcmp(p, "nomerge", 7)) + iommu_merge = 0; + if (!memcmp(p, "forcesac", 8)) + iommu_sac_force = 1; + if (!memcmp(p, "fullflush", 9)) + iommu_fullflush = 1; #ifdef CONFIG_IOMMU_LEAK if (!memcmp(p,"leak", 4)) { leak_trace = 1; diff -Nru a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c --- a/arch/x86_64/kernel/process.c Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/kernel/process.c Sun Jan 4 17:36:11 2004 @@ -152,6 +152,19 @@ __setup("idle=", idle_setup); +void idle_warning(void) +{ + static int warned; + if (warned) + return; + warned = 1; + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) + BUG(); + printk(KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"); + printk(KERN_ERR "******* Working around it, but it will cost you a lot of power\n"); + printk(KERN_ERR "******* Please consider a BIOS update.\n"); + printk(KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n"); +} /* Prints also some state that isn't saved in the pt_regs */ void __show_regs(struct pt_regs * regs) diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c --- a/arch/x86_64/kernel/setup.c Sun Jan 4 17:36:10 2004 +++ b/arch/x86_64/kernel/setup.c Sun Jan 4 17:36:10 2004 @@ -237,6 +237,9 @@ } #endif + if (!memcmp(from,"oops=panic", 10)) + panic_on_oops = 1; + next_char: c = *(from++); if (!c) @@ -332,6 +335,7 @@ void __init setup_arch(char **cmdline_p) { unsigned long low_mem_size; + unsigned long kernel_end; ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); drive_info = DRIVE_INFO; @@ -380,7 +384,6 @@ (table_end - table_start) << PAGE_SHIFT); /* reserve kernel */ - unsigned long kernel_end; kernel_end = round_up(__pa_symbol(&_end),PAGE_SIZE); reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY); diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c --- a/arch/x86_64/kernel/time.c Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/kernel/time.c Sun Jan 4 17:36:11 2004 @@ -111,13 +111,14 @@ sec = xtime.tv_sec; usec = xtime.tv_nsec / 1000; - /* - * If time_adjust is negative then NTP is slowing the clock - * so make sure not to go into next possible interval. - * Better to lose some accuracy than have time go backwards.. - */ - if (unlikely(time_adjust < 0) && usec > tickadj) - usec = tickadj; + /* i386 does some correction here to keep the clock + monotonus even when ntpd is fixing drift. + But they didn't work for me, there is a non monotonic + clock anyways with ntp. + I dropped all corrections now until a real solution can + be found. Note when you fix it here you need to do the same + in arch/x86_64/kernel/vsyscall.c and export all needed + variables in vmlinux.lds. -AK */ t = (jiffies - wall_jiffies) * (1000000L / HZ) + do_gettimeoffset(); @@ -592,6 +593,7 @@ if (!vxtime.hpet_address) return -1; set_fixmap_nocache(FIX_HPET_BASE, vxtime.hpet_address); + __set_fixmap(VSYSCALL_HPET, vxtime.hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE); /* * Read the period, compute tick and quotient. diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c --- a/arch/x86_64/kernel/traps.c Sun Jan 4 17:36:10 2004 +++ b/arch/x86_64/kernel/traps.c Sun Jan 4 17:36:10 2004 @@ -345,6 +345,8 @@ bust_spinlocks(0); spin_unlock(&die_lock); local_irq_enable(); /* make sure back scroll still works */ + if (panic_on_oops) + panic("Oops"); } void __die(const char * str, struct pt_regs * regs, long err) @@ -353,8 +355,8 @@ printk(KERN_EMERG "%s: %04lx [%u]\n", str, err & 0xffff,++die_counter); notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); show_registers(regs); - /* Execute summary in case the oops scrolled away */ - printk(KERN_EMERG "RIP "); + /* Executive summary in case the oops scrolled away */ + printk("RIP "); printk_address(regs->rip); printk(" RSP <%016lx>\n", regs->rsp); } @@ -848,3 +850,11 @@ cpu_init(); } + +/* Actual parsing is done early in setup.c. */ +static int __init oops_dummy(char *s) +{ + panic_on_oops = 1; + return -1; +} +__setup("oops=", oops_dummy); diff -Nru a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c --- a/arch/x86_64/kernel/vsyscall.c Sun Jan 4 17:36:11 2004 +++ b/arch/x86_64/kernel/vsyscall.c Sun Jan 4 17:36:11 2004 @@ -49,6 +49,7 @@ #include #include #include +#include #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) #define force_inline __attribute__((always_inline)) inline @@ -88,11 +89,10 @@ if (t < __vxtime.last_tsc) t = __vxtime.last_tsc; usec += ((t - __vxtime.last_tsc) * __vxtime.tsc_quot) >> 32; + /* See comment in x86_64 do_gettimeopfday. */ } else { -#if 0 usec += ((readl(fix_to_virt(VSYSCALL_HPET) + 0xf0) - __vxtime.last) * __vxtime.quot) >> 32; -#endif } } while (read_seqretry(&__xtime_lock, sequence)); diff -Nru a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c --- a/arch/x86_64/mm/fault.c Sun Jan 4 17:36:10 2004 +++ b/arch/x86_64/mm/fault.c Sun Jan 4 17:36:10 2004 @@ -378,7 +378,7 @@ printk_address(regs->rip); dump_pagetable(address); __die("Oops", regs, error_code); - /* Execute summary in case the body of the oops scrolled away */ + /* Executive summary in case the body of the oops scrolled away */ printk(KERN_EMERG "CR2: %016lx\n", address); oops_end(); do_exit(SIGKILL); diff -Nru a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c --- a/drivers/base/power/sysfs.c Sun Jan 4 17:36:11 2004 +++ b/drivers/base/power/sysfs.c Sun Jan 4 17:36:11 2004 @@ -36,7 +36,7 @@ int error = 0; state = simple_strtoul(buf,&rest,10); - if (rest) + if (*rest) return -EINVAL; if (state) error = dpm_runtime_suspend(dev,state); diff -Nru a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c Sun Jan 4 17:36:11 2004 @@ -1,7 +1,7 @@ /* * Bt8xx based DVB adapter driver * - * Copyright (C) 2002,2003 Florian Schirmer + * Copyright (C) 2002,2003 Florian Schirmer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -525,6 +525,6 @@ module_init(dvb_bt8xx_init); module_exit(dvb_bt8xx_exit); MODULE_DESCRIPTION("Bt8xx based DVB adapter driver"); -MODULE_AUTHOR("Florian Schirmer "); +MODULE_AUTHOR("Florian Schirmer "); MODULE_LICENSE("GPL"); MODULE_PARM(debug, "i"); diff -Nru a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h Sun Jan 4 17:36:11 2004 @@ -1,7 +1,7 @@ /* * Bt8xx based DVB adapter driver * - * Copyright (C) 2002,2003 Florian Schirmer + * Copyright (C) 2002,2003 Florian Schirmer * Copyright (C) 2002 Peter Hettkamp * Copyright (C) 1999-2001 Ralph Metzler & Marcus Metzler for convergence integrated media GmbH * Copyright (C) 1998,1999 Christian Theiss diff -Nru a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c --- a/drivers/media/dvb/dvb-core/dvb_demux.c Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/dvb-core/dvb_demux.c Sun Jan 4 17:36:11 2004 @@ -542,33 +542,38 @@ return &demux->feed[i]; } - -static int dmx_pid_set (u16 pid, struct dvb_demux_feed *feed) +static int dvb_demux_feed_find(struct dvb_demux_feed *feed) { - struct dvb_demux *demux = feed->demux; - struct list_head *pos, *n, *head=&demux->feed_list; + struct dvb_demux_feed *entry; - if (pid > DMX_MAX_PID) - return -EINVAL; + list_for_each_entry(entry, &feed->demux->feed_list, list_head) + if (entry == feed) + return 1; - if (pid == feed->pid) return 0; - - if (feed->pid <= DMX_MAX_PID) { - list_for_each_safe(pos, n, head) { - if (DMX_FEED_ENTRY(pos)->pid == feed->pid) { - list_del(pos); - break; - } } + +static void dvb_demux_feed_add(struct dvb_demux_feed *feed) +{ + if (dvb_demux_feed_find(feed)) { + printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n", + __FUNCTION__, feed->type, feed->state, feed->pid); + return; } - list_add(&feed->list_head, head); - feed->pid = pid; + list_add(&feed->list_head, &feed->demux->feed_list); +} - return 0; +static void dvb_demux_feed_del(struct dvb_demux_feed *feed) +{ + if (!(dvb_demux_feed_find(feed))) { + printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n", + __FUNCTION__, feed->type, feed->state, feed->pid); + return; } + list_del(&feed->list_head); +} static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type, enum dmx_ts_pes pes_type, size_t callback_length, @@ -577,7 +582,9 @@ { struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed; struct dvb_demux *demux = feed->demux; - int ret; + + if (pid > DMX_MAX_PID) + return -EINVAL; if (down_interruptible (&demux->mutex)) return -ERESTARTSYS; @@ -594,26 +601,13 @@ return -EINVAL; } - if ((pes_type != DMX_TS_PES_PCR0) && - (pes_type != DMX_TS_PES_PCR1) && - (pes_type != DMX_TS_PES_PCR2) && - (pes_type != DMX_TS_PES_PCR3)) { - if ((ret = dmx_pid_set(pid, feed))<0) { - up(&demux->mutex); - return ret; - } - } else - feed->pid = pid; - demux->pesfilter[pes_type] = feed; - demux->pids[pes_type] = feed->pid; - } else { - if ((ret = dmx_pid_set(pid, feed))<0) { - up(&demux->mutex); - return ret; - } + demux->pids[pes_type] = pid; } + dvb_demux_feed_add(feed); + + feed->pid = pid; feed->buffer_size = circular_buffer_size; feed->descramble = descramble; feed->timeout = timeout; @@ -757,7 +751,6 @@ { struct dvb_demux *demux = (struct dvb_demux *) dmx; struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed; - struct list_head *pos, *n, *head=&demux->feed_list; if (down_interruptible (&demux->mutex)) return -ERESTARTSYS; @@ -777,14 +770,9 @@ feed->state = DMX_STATE_FREE; feed->filter->state = DMX_STATE_FREE; - if (feed->pid <= DMX_MAX_PID) { - list_for_each_safe(pos, n, head) - if (DMX_FEED_ENTRY(pos)->pid == feed->pid) { - list_del(pos); - break; - } + dvb_demux_feed_del(feed); + feed->pid = 0xffff; - } if (feed->ts_type & TS_DECODER) demux->pesfilter[feed->pes_type] = NULL; @@ -836,7 +824,6 @@ { struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed; struct dvb_demux *dvbdmx=dvbdmxfeed->demux; - struct list_head *pos, *n, *head=&dvbdmx->feed_list; if (pid>0x1fff) return -EINVAL; @@ -844,16 +831,7 @@ if (down_interruptible (&dvbdmx->mutex)) return -ERESTARTSYS; - if (dvbdmxfeed->pid <= DMX_MAX_PID) { - list_for_each_safe(pos, n, head) { - if (DMX_FEED_ENTRY(pos)->pid == dvbdmxfeed->pid) { - list_del(pos); - break; - } - } - } - - list_add(&dvbdmxfeed->list_head, head); + dvb_demux_feed_add(dvbdmxfeed); dvbdmxfeed->pid = pid; dvbdmxfeed->buffer_size=circular_buffer_size; @@ -1045,7 +1023,6 @@ { struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed; struct dvb_demux *dvbdmx=(struct dvb_demux *) demux; - struct list_head *pos, *n, *head=&dvbdmx->feed_list; if (down_interruptible (&dvbdmx->mutex)) return -ERESTARTSYS; @@ -1062,15 +1039,9 @@ #endif dvbdmxfeed->state=DMX_STATE_FREE; - if (dvbdmxfeed->pid <= DMX_MAX_PID) { - list_for_each_safe(pos, n, head) { - if (DMX_FEED_ENTRY(pos)->pid == dvbdmxfeed->pid) { - list_del(pos); - break; - } - } + dvb_demux_feed_del(dvbdmxfeed); + dvbdmxfeed->pid = 0xffff; - } up(&dvbdmx->mutex); return 0; diff -Nru a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c --- a/drivers/media/dvb/frontends/at76c651.c Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/frontends/at76c651.c Sun Jan 4 17:36:11 2004 @@ -4,7 +4,8 @@ * Atmel DVB-C Frontend Driver (at76c651/dat7021) * * Copyright (C) 2001 fnbrd - * & 2002 Andreas Oberritter + * & 2002 Andreas Oberritter + * & 2003 Wolfram Joost * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -524,6 +525,6 @@ module_exit(at76c651_exit); MODULE_DESCRIPTION("at76c651/dat7021 dvb-c frontend driver"); -MODULE_AUTHOR("Andreas Oberritter "); +MODULE_AUTHOR("Andreas Oberritter "); MODULE_LICENSE("GPL"); MODULE_PARM(debug, "i"); diff -Nru a/drivers/media/dvb/frontends/dst-bt878.h b/drivers/media/dvb/frontends/dst-bt878.h --- a/drivers/media/dvb/frontends/dst-bt878.h Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/frontends/dst-bt878.h Sun Jan 4 17:36:11 2004 @@ -32,6 +32,7 @@ struct bt878 ; -int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp); +int +bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp); struct bt878 *bt878_find_by_dvb_adap(struct dvb_adapter *adap); diff -Nru a/drivers/media/dvb/frontends/dst.c b/drivers/media/dvb/frontends/dst.c --- a/drivers/media/dvb/frontends/dst.c Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/frontends/dst.c Sun Jan 4 17:36:11 2004 @@ -44,12 +44,15 @@ MODULE_PARM(dst_debug, "i"); MODULE_PARM_DESC(dst_debug, "debug messages, default is 0 (no)"); -unsigned int dst_type = (-1U); -unsigned int dst_type_flags = (-1U); -MODULE_PARM(dst_type, "i"); +#define DST_MAX_CARDS 6 +unsigned int dst_cur_no = 0; + +unsigned int dst_type[DST_MAX_CARDS] = { [0 ... (DST_MAX_CARDS-1)] = (-1U)}; +unsigned int dst_type_flags[DST_MAX_CARDS] = { [0 ... (DST_MAX_CARDS-1)] = (-1U)}; +MODULE_PARM(dst_type, "1-" __stringify(DST_MAX_CARDS) "i"); MODULE_PARM_DESC(dst_type, "Type of DST card, 0 Satellite, 1 terrestial TV, 2 Cable, default driver determined"); -MODULE_PARM(dst_type_flags, "i"); +MODULE_PARM(dst_type_flags, "1-" __stringify(DST_MAX_CARDS) "i"); MODULE_PARM_DESC(dst_type_flags, "Type flags of DST card, bitfield 1=10 byte tuner, 2=TS is 204, 4=symdiv"); @@ -102,8 +105,7 @@ .symbol_rate_max = 45000000, /* . symbol_rate_tolerance = ???,*/ .notifier_delay = 50, /* 1/20 s */ - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_AUTO | + .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK }; @@ -117,8 +119,7 @@ .symbol_rate_max = 45000000, /* . symbol_rate_tolerance = ???,*/ .notifier_delay = 50, /* 1/20 s */ - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_AUTO | + .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO }; @@ -128,8 +129,7 @@ .frequency_min = 137000000, .frequency_max = 858000000, .frequency_stepsize = 166667, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_AUTO | + .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO }; @@ -421,8 +421,6 @@ case INVERSION_ON: val[8] |= 0x80; break; - case INVERSION_AUTO: - break; default: return -EINVAL; } @@ -607,25 +605,25 @@ use_dst_type = DST_TYPE_IS_SAT; use_type_flags = DST_TYPE_HAS_SYMDIV; } - switch (dst_type) { + switch (dst_type[dst_cur_no]) { case (-1U): /* not used */ break; case DST_TYPE_IS_SAT: case DST_TYPE_IS_TERR: case DST_TYPE_IS_CABLE: - use_dst_type = (u8)dst_type; + use_dst_type = (u8)(dst_type[dst_cur_no]); break; default: printk("%s: invalid user override dst type %d, not used\n", - __FUNCTION__, dst_type); + __FUNCTION__, dst_type[dst_cur_no]); break; } dst_type_print(use_dst_type); - if (dst_type_flags != (-1U)) { + if (dst_type_flags[dst_cur_no] != (-1U)) { printk("%s: user override dst type flags 0x%x\n", - __FUNCTION__, dst_type_flags); - use_type_flags = dst_type_flags; + __FUNCTION__, dst_type_flags[dst_cur_no]); + use_type_flags = dst_type_flags[dst_cur_no]; } dst->type_flags = use_type_flags; dst->dst_type= use_dst_type; @@ -1129,6 +1127,10 @@ struct dvb_frontend_info *info; dprintk("%s: check ci\n", __FUNCTION__); + if (dst_cur_no >= DST_MAX_CARDS) { + dprintk("%s: can't have more than %d cards\n", __FUNCTION__, DST_MAX_CARDS); + return -ENODEV; + } bt = bt878_find_by_dvb_adap(i2c->adapter); if (!bt) return -ENODEV; @@ -1157,7 +1159,7 @@ info = &dst_info_cable; dvb_register_frontend (dst_ioctl, i2c, dst, info); - + dst_cur_no++; return 0; } diff -Nru a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c --- a/drivers/media/dvb/frontends/mt312.c Sun Jan 4 17:36:10 2004 +++ b/drivers/media/dvb/frontends/mt312.c Sun Jan 4 17:36:10 2004 @@ -1,7 +1,7 @@ /* Driver for Zarlink MT312 Satellite Channel Decoder - Copyright (C) 2003 Andreas Oberritter + Copyright (C) 2003 Andreas Oberritter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -813,5 +813,5 @@ #endif MODULE_DESCRIPTION("MT312 Satellite Channel Decoder Driver"); -MODULE_AUTHOR("Andreas Oberritter "); +MODULE_AUTHOR("Andreas Oberritter "); MODULE_LICENSE("GPL"); diff -Nru a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h --- a/drivers/media/dvb/frontends/mt312.h Sun Jan 4 17:36:10 2004 +++ b/drivers/media/dvb/frontends/mt312.h Sun Jan 4 17:36:10 2004 @@ -1,7 +1,7 @@ /* Driver for Zarlink MT312 QPSK Frontend - Copyright (C) 2003 Andreas Oberritter + Copyright (C) 2003 Andreas Oberritter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -Nru a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c --- a/drivers/media/dvb/frontends/nxt6000.c Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/frontends/nxt6000.c Sun Jan 4 17:36:11 2004 @@ -8,7 +8,7 @@ Alps TDED4 (Tuner: TI ALP510, external Nxt6000) Comtech DVBT-6k07 (PLL IC: SP5730) - Copyright (C) 2002-2003 Florian Schirmer + Copyright (C) 2002-2003 Florian Schirmer Copyright (C) 2003 Paul Andreassen This program is free software; you can redistribute it and/or modify diff -Nru a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c --- a/drivers/media/dvb/frontends/stv0299.c Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/frontends/stv0299.c Sun Jan 4 17:36:11 2004 @@ -18,7 +18,7 @@ LG TDQF-S001F Copyright (C) 2002 Felix Domke - & Andreas Oberritter + & Andreas Oberritter Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B diff -Nru a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c --- a/drivers/media/dvb/frontends/ves1820.c Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/frontends/ves1820.c Sun Jan 4 17:36:11 2004 @@ -233,7 +233,7 @@ * check lock and toggle inversion bit if required... */ if (INVERSION_AUTO == inversion && !(ves1820_readreg (fe, 0x11) & 0x08)) { - mdelay(30); + mdelay(50); if (!(ves1820_readreg (fe, 0x11) & 0x08)) { reg0 ^= 0x20; ves1820_writereg (fe, 0x00, reg0 & 0xfe); @@ -349,7 +349,7 @@ /* yes, this speeds things up: userspace reports lock in about 8 ms instead of 500 to 1200 ms after calling FE_SET_FRONTEND. */ - mdelay(30); + mdelay(50); return 0; } diff -Nru a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c --- a/drivers/media/dvb/frontends/ves1x93.c Sun Jan 4 17:36:10 2004 +++ b/drivers/media/dvb/frontends/ves1x93.c Sun Jan 4 17:36:10 2004 @@ -2,9 +2,9 @@ Driver for VES1893 and VES1993 QPSK Frontends Copyright (C) 1999 Convergence Integrated Media GmbH - Copyright (C) 2001 Ronny Strutz <3des@tuxbox.org> + Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de> Copyright (C) 2002 Dennis Noermann - Copyright (C) 2002-2003 Andreas Oberritter + Copyright (C) 2002-2003 Andreas Oberritter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -Nru a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig --- a/drivers/media/dvb/ttpci/Kconfig Sun Jan 4 17:36:10 2004 +++ b/drivers/media/dvb/ttpci/Kconfig Sun Jan 4 17:36:10 2004 @@ -13,6 +13,23 @@ Say Y if you own such a card and want to use it. +config DVB_AV7110_FIRMWARE + bool "Compile AV7110 firmware into the driver" + depends on DVB_AV7110 + help + The AV7110 firmware is normally loaded by the firmware hotplug manager. + If you want to compile the firmware into the driver you need to say + Y here and provide the correct path of the firmware. You need this + option if you want to compile the whole driver statically into the + kernel. + + All other people say N. + +config DVB_AV7110_FIRMWARE_FILE + string "Full pathname of av7110 firmware file" + depends on DVB_AV7110_FIRMWARE + default "/usr/lib/hotplug/firmware/dvb-ttpci-01.fw" + config DVB_AV7110_OSD bool "AV7110 OSD support" depends on DVB_AV7110 diff -Nru a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile --- a/drivers/media/dvb/ttpci/Makefile Sun Jan 4 17:36:10 2004 +++ b/drivers/media/dvb/ttpci/Makefile Sun Jan 4 17:36:10 2004 @@ -12,3 +12,12 @@ obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o ttpci-eeprom.o EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ + +host-progs := fdump + +ifdef CONFIG_DVB_AV7110_FIRMWARE +$(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h + +$(obj)/av7110_firm.h: + $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ +endif diff -Nru a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c --- a/drivers/media/dvb/ttpci/av7110.c Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/ttpci/av7110.c Sun Jan 4 17:36:11 2004 @@ -4498,9 +4498,19 @@ static struct saa7146_ext_vv av7110_vv_data_st; static struct saa7146_ext_vv av7110_vv_data_c; + + + + +#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE +#include "av7110_firm.h" +#endif + static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext) { +#ifndef CONFIG_DVB_AV7110_FIRMWARE_FILE const struct firmware *fw; +#endif struct av7110 *av7110 = NULL; int ret = 0; u32 crc = 0, len = 0; @@ -4508,6 +4518,7 @@ DEB_EE(("dev: %p, av7110: %p\n",dev,av7110)); +#ifndef CONFIG_DVB_AV7110_FIRMWARE_FILE /* request the av7110 firmware, this will block until someone uploads it */ ret = request_firmware(&fw, "dvb-ttpci-01.fw", &dev->pci->dev); if ( 0 != ret ) { @@ -4519,6 +4530,7 @@ printk("dvb-ttpci: this firmware is way too small.\n"); return -EINVAL; } +#endif /* prepare the av7110 device struct */ if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) { @@ -4527,6 +4539,7 @@ } memset(av7110, 0, sizeof(struct av7110)); +#ifndef CONFIG_DVB_AV7110_FIRMWARE_FILE /* check if the firmware is available */ av7110->bin_fw = (unsigned char*)vmalloc(fw->size); if (NULL == av7110->bin_fw) { @@ -4536,6 +4549,10 @@ } memcpy(av7110->bin_fw, fw->data, fw->size); av7110->size_fw = fw->size; +#else + av7110->bin_fw = dvb_ttpci_fw; + av7110->size_fw = sizeof dvb_ttpci_fw; +#endif /* check for firmware magic */ ptr = av7110->bin_fw; @@ -4850,7 +4867,9 @@ return ret; fw_error: +#ifndef CONFIG_DVB_AV7110_FIRMWARE_FILE vfree(av7110->bin_fw); +#endif kfree(av7110); return -EINVAL; } @@ -4894,9 +4913,11 @@ dvb_unregister_adapter (av7110->dvb_adapter); av7110_num--; +#ifndef CONFIG_DVB_AV7110_FIRMWARE_FILE if (NULL != av7110->bin_fw ) { vfree(av7110->bin_fw); } +#endif kfree (av7110); saa->ext_priv = NULL; diff -Nru a/drivers/media/dvb/ttpci/av7110.c.orig b/drivers/media/dvb/ttpci/av7110.c.orig --- a/drivers/media/dvb/ttpci/av7110.c.orig Sun Jan 4 17:36:11 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,5030 +0,0 @@ -/* - * av7110.c: driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB) - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * originally based on code by: - * Copyright (C) 1998,1999 Christian Theiss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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/dvb/ - */ - -#define NEW_CI 1 - -/* for debugging ARM communication: */ -//#define COM_DEBUG - -#define __KERNEL_SYSCALLS__ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "dvb_i2c.h" -#include "dvb_frontend.h" -#include "dvb_functions.h" - - -#if 1 - #define DEBUG_VARIABLE av7110_debug -#else - #define DEB_S(x) - #define DEB_D(x) - #define DEB_EE(x) -#endif - -#include "ttpci-eeprom.h" -#include "av7110.h" -#include "av7110_ipack.h" - -static int AV_StartPlay(struct av7110 *av7110, int av); -static void restart_feeds(struct av7110 *av7110); -static int bootarm(struct av7110 *av7110); -static inline int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val); -static inline u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg); -static int outcom(struct av7110 *av7110, int type, int com, int num, ...); -static void SetMode(struct av7110 *av7110, int mode); -static void dvb_video_add_event (struct av7110 *av7110, struct video_event *event); - -void pes_to_ts(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p); -void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, struct dvb_demux_feed *feed); - -static int av7110_debug = 0; - -static int vidmode=CVBS_RGB_OUT; -static int pids_off; -static int adac=DVB_ADAC_TI; -static int hw_sections = 1; -static int rgb_on = 0; - -int av7110_num = 0; - -#define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000) -#define FW_VERSION(arm_app) ((arm_app) & 0x0000FFFF) - -/**************************************************************************** - * DEBI functions - ****************************************************************************/ - -#define wait_for_debi_done(x) \ - saa7146_wait_for_debi_done(x->dev) \ - -/* This DEBI code is based on the Stradis driver - by Nathan Laredo */ - -static int debiwrite(struct av7110 *av7110, u32 config, - int addr, u32 val, int count) -{ - struct saa7146_dev *dev = av7110->dev; - u32 cmd; - - if (count <= 0 || count > 32764) - return -1; - if (wait_for_debi_done(av7110) < 0) - return -1; - saa7146_write(dev, DEBI_CONFIG, config); - if (count <= 4) /* immediate transfer */ - saa7146_write(dev, DEBI_AD, val ); - else /* block transfer */ - saa7146_write(dev, DEBI_AD, av7110->debi_bus); - saa7146_write(dev, DEBI_COMMAND, (cmd = (count << 17) | (addr & 0xffff))); - saa7146_write(dev, MC2, (2 << 16) | 2); - return 0; -} - -static u32 debiread(struct av7110 *av7110, u32 config, int addr, int count) -{ - struct saa7146_dev *dev = av7110->dev; - u32 result = 0; - - if (count > 32764 || count <= 0) - return 0; - if (wait_for_debi_done(av7110) < 0) - return 0; - saa7146_write(dev, DEBI_AD, av7110->debi_bus); - saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff)); - - saa7146_write(dev, DEBI_CONFIG, config); - saa7146_write(dev, MC2, (2 << 16) | 2); - if (count > 4) - return count; - wait_for_debi_done(av7110); - result = saa7146_read(dev, DEBI_AD); - result &= (0xffffffffUL >> ((4-count)*8)); - return result; -} - - -/* DEBI during interrupt */ -/* single word writes */ -static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) -{ - debiwrite(av7110, config, addr, val, count); -} - -/* buffer writes */ -static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, char *val, int count) -{ - memcpy(av7110->debi_virt, val, count); - debiwrite(av7110, config, addr, 0, count); -} - - -static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) -{ - u32 res; - - res=debiread(av7110, config, addr, count); - if (count<=4) - memcpy(av7110->debi_virt, (char *) &res, count); - return res; -} - -/* DEBI outside interrupts, only for count<=4! */ - -static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) -{ - unsigned long flags; - - spin_lock_irqsave(&av7110->debilock, flags); - debiwrite(av7110, config, addr, val, count); - spin_unlock_irqrestore(&av7110->debilock, flags); -} - -static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) -{ - unsigned long flags; - u32 res; - - spin_lock_irqsave(&av7110->debilock, flags); - res=debiread(av7110, config, addr, count); - spin_unlock_irqrestore(&av7110->debilock, flags); - return res; -} - - -static inline char chtrans(char c) -{ - if (c<32 || c>126) - c=0x20; - return c; -} - - -/* handle mailbox registers of the dual ported RAM */ - -static inline void ARM_ResetMailBox(struct av7110 *av7110) -{ - unsigned long flags; - - DEB_EE(("av7110: %p\n",av7110)); - - spin_lock_irqsave(&av7110->debilock, flags); - debiread(av7110, DEBINOSWAP, IRQ_RX, 2); - //printk("dvb: IRQ_RX=%d\n", debiread(av7110, DEBINOSWAP, IRQ_RX, 2)); - debiwrite(av7110, DEBINOSWAP, IRQ_RX, 0, 2); - spin_unlock_irqrestore(&av7110->debilock, flags); -} - -static inline void ARM_ClearMailBox(struct av7110 *av7110) -{ - iwdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2); -} - -static inline void ARM_ClearIrq(struct av7110 *av7110) -{ - irdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2); -} - -static void reset_arm(struct av7110 *av7110) -{ - saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO); - - /* Disable DEBI and GPIO irq */ - IER_DISABLE(av7110->dev, (MASK_19 | MASK_03)); -// saa7146_write(av7110->dev, IER, -// saa7146_read(av7110->dev, IER) & ~(MASK_19 | MASK_03)); - saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); - - mdelay(800); - saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI); - mdelay(800); - - ARM_ResetMailBox(av7110); - - saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); - - IER_ENABLE(av7110->dev, MASK_03); -// saa7146_write(av7110->dev, IER, -// saa7146_read(av7110->dev, IER) | MASK_03 ); - - av7110->arm_ready=1; - printk("av7110: ARM RESET\n"); -} - -static void recover_arm(struct av7110 *av7110) -{ - DEB_EE(("av7110: %p\n",av7110)); - - if (current->files) - bootarm(av7110); - else { - printk("OOPS, no current->files\n"); - reset_arm(av7110); - } - - dvb_delay(100); - restart_feeds(av7110); - outcom(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config); -} - -static void arm_error(struct av7110 *av7110) -{ - DEB_EE(("av7110: %p\n",av7110)); - - av7110->arm_errors++; - av7110->arm_ready=0; - recover_arm(av7110); -} - -static int arm_thread(void *data) -{ - struct av7110 *av7110 = data; - u16 newloops = 0; - - DEB_EE(("av7110: %p\n",av7110)); - - dvb_kernel_thread_setup ("arm_mon"); - av7110->arm_thread = current; - - while (!av7110->arm_rmmod && !signal_pending(current)) { - interruptible_sleep_on_timeout(&av7110->arm_wait, 5*HZ); - - if (!av7110->arm_ready) - continue; - - if (down_interruptible(&av7110->dcomlock)) - break; - - newloops=rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); - up(&av7110->dcomlock); - - if (newloops==av7110->arm_loops) { - printk(KERN_ERR "av7110%d: ARM crashed!\n", - av7110->dvb_adapter->num); - - arm_error(av7110); - - if (down_interruptible(&av7110->dcomlock)) - break; - - newloops=rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2)-1; - up(&av7110->dcomlock); - } - av7110->arm_loops=newloops; - } - - av7110->arm_thread = NULL; - return 0; -} - - -static int record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) -{ - struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) p2t->priv; - -// DEB_EE(("struct dvb_filter_pes2ts:%p\n",p2t)); - - if (!(dvbdmxfeed->ts_type & TS_PACKET)) - return 0; - if (buf[3]==0xe0) // video PES do not have a length in TS - buf[4]=buf[5]=0; - if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) - return dvbdmxfeed->cb.ts(buf, len, 0, 0, - &dvbdmxfeed->feed.ts, DMX_OK); - else - return dvb_filter_pes2ts(p2t, buf, len, 1); -} - -static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data) -{ - struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) priv; - -// DEB_EE(("dvb_demux_feed:%p\n",dvbdmxfeed)); - - dvbdmxfeed->cb.ts(data, 188, 0, 0, - &dvbdmxfeed->feed.ts, - DMX_OK); - return 0; -} - -static int AV_StartRecord(struct av7110 *av7110, int av, - struct dvb_demux_feed *dvbdmxfeed) -{ - struct dvb_demux *dvbdmx=dvbdmxfeed->demux; - - DEB_EE(("av7110: %p, dvb_demux_feed:%p\n",av7110,dvbdmxfeed)); - - if (av7110->playing||(av7110->rec_mode&av)) - return -EBUSY; - outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0); - dvbdmx->recording=1; - av7110->rec_mode|=av; - - switch (av7110->rec_mode) { - case RP_AUDIO: - dvb_filter_pes2ts_init (&av7110->p2t[0], - dvbdmx->pesfilter[0]->pid, - dvb_filter_pes2ts_cb, - (void *)dvbdmx->pesfilter[0]); - outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); - break; - - case RP_VIDEO: - dvb_filter_pes2ts_init (&av7110->p2t[1], - dvbdmx->pesfilter[1]->pid, - dvb_filter_pes2ts_cb, - (void *)dvbdmx->pesfilter[1]); - outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); - break; - - case RP_AV: - dvb_filter_pes2ts_init (&av7110->p2t[0], - dvbdmx->pesfilter[0]->pid, - dvb_filter_pes2ts_cb, - (void *)dvbdmx->pesfilter[0]); - dvb_filter_pes2ts_init (&av7110->p2t[1], - dvbdmx->pesfilter[1]->pid, - dvb_filter_pes2ts_cb, - (void *)dvbdmx->pesfilter[1]); - outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0); - break; - } - return 0; -} - -static int AV_StartPlay(struct av7110 *av7110, int av) -{ - DEB_EE(("av7110: %p\n",av7110)); - - if (av7110->rec_mode) - return -EBUSY; - if (av7110->playing&av) - return -EBUSY; - - outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0); - - if (av7110->playing == RP_NONE) { - av7110_ipack_reset(&av7110->ipack[0]); - av7110_ipack_reset(&av7110->ipack[1]); - } - - av7110->playing|=av; - switch (av7110->playing) { - case RP_AUDIO: - outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); - break; - case RP_VIDEO: - outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); - av7110->sinfo=0; - break; - case RP_AV: - av7110->sinfo=0; - outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); - break; - } - return av7110->playing; -} - -static void AV_Stop(struct av7110 *av7110, int av) -{ - DEB_EE(("av7110: %p\n",av7110)); - - if (!(av7110->playing&av) && !(av7110->rec_mode&av)) - return; - - outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0); - if (av7110->playing) { - av7110->playing&=~av; - switch (av7110->playing) { - case RP_AUDIO: - outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); - break; - case RP_VIDEO: - outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); - break; - case RP_NONE: - SetMode(av7110, av7110->vidmode); - break; - } - } else { - av7110->rec_mode&=~av; - switch (av7110->rec_mode) { - case RP_AUDIO: - outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); - break; - case RP_VIDEO: - outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); - break; - case RP_NONE: - break; - } - } -} - -/** - * Hack! we save the last av7110 ptr. This should be ok, since - * you rarely will use more then one IR control. - * - * If we want to support multiple controls we would have to do much more... - */ -void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config) -{ - static struct av7110 *last; - - DEB_EE(("av7110: %p\n",av7110)); - - if (!av7110) - av7110 = last; - else - last = av7110; - - if (av7110) { - outcom(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); - av7110->ir_config = ir_config; - } -} - -static void (*irc_handler)(u32); - -void av7110_register_irc_handler(void (*func)(u32)) -{ - //DEB_EE(("registering %08x\n",func)); - irc_handler = func; -} - -void av7110_unregister_irc_handler(void (*func)(u32)) -{ - //DEB_EE(("unregistering %08x\n",func)); - irc_handler = NULL; -} - -void run_handlers(unsigned long ircom) -{ - if (irc_handler != NULL) - (*irc_handler)((u32) ircom); -} - -DECLARE_TASKLET(irtask,run_handlers,0); - -void IR_handle(struct av7110 *av7110, u32 ircom) -{ - DEB_S(("av7110: ircommand = %08x\n", ircom)); - irtask.data = (unsigned long) ircom; - tasklet_schedule(&irtask); -} - -/**************************************************************************** - * IRQ handling - ****************************************************************************/ - -void CI_handle(struct av7110 *av7110, u8 *data, u16 len) -{ - //CI_out(av7110, data, len); - - DEB_EE(("av7110: %p\n",av7110)); - - if (len<3) - return; - switch (data[0]) { - case CI_MSG_CI_INFO: - if (data[2]!=1 && data[2]!=2) - break; - switch (data[1]) { - case 0: - av7110->ci_slot[data[2]-1].flags=0; - break; - case 1: - av7110->ci_slot[data[2]-1].flags|=CA_CI_MODULE_PRESENT; - break; - case 2: - av7110->ci_slot[data[2]-1].flags|=CA_CI_MODULE_READY; - break; - } - break; - case CI_SWITCH_PRG_REPLY: - //av7110->ci_stat=data[1]; - break; - default: - break; - } - -} - -static inline int DvbDmxFilterCallback(u8 * buffer1, size_t buffer1_len, - u8 * buffer2, size_t buffer2_len, - struct dvb_demux_filter *dvbdmxfilter, - enum dmx_success success, - struct av7110 *av7110) -{ - DEB_INT(("av7110: %p\n",av7110)); - - if (!dvbdmxfilter->feed->demux->dmx.frontend) - return 0; - if (dvbdmxfilter->feed->demux->dmx.frontend->source==DMX_MEMORY_FE) - return 0; - - switch(dvbdmxfilter->type) { - case DMX_TYPE_SEC: - if ((((buffer1[1]<<8)|buffer1[2])&0xfff)+3!=buffer1_len) - return 0; - if (dvbdmxfilter->doneq) { - struct dmx_section_filter *filter=&dvbdmxfilter->filter; - int i; - u8 xor, neq=0; - - for (i=0; ifilter_value[i]^buffer1[i]; - neq|=dvbdmxfilter->maskandnotmode[i]&xor; - } - if (!neq) - return 0; - } - return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len, - buffer2, buffer2_len, - &dvbdmxfilter->filter, - DMX_OK); - case DMX_TYPE_TS: - if (!(dvbdmxfilter->feed->ts_type & TS_PACKET)) - return 0; - if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY) - return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len, - buffer2, buffer2_len, - &dvbdmxfilter->feed->feed.ts, - DMX_OK); - else - pes_to_ts(buffer1, buffer1_len, - dvbdmxfilter->feed->pid, - &av7110->p2t_filter[dvbdmxfilter->index]); - default: - return 0; - } -} - - -u8 pshead[0x26] = { - 0x00, 0x00, 0x01, 0xba, 0x5f, 0xff, 0xfe, 0xe6, - 0xc4, 0x01, 0x01, 0x89, 0xc3, 0xf8, 0x00, 0x00, - 0x01, 0xbb, 0x00, 0x12, 0x80, 0xc4, 0xe1, 0x00, - 0xe1, 0xff, 0xb9, 0xe0, 0xe8, 0xb8, 0xc0, 0x20, - 0xbd, 0xe0, 0x44, 0xbf, 0xe0, 0x02, -}; - - -//#define DEBUG_TIMING -static inline void print_time(char *s) -{ -#ifdef DEBUG_TIMING - struct timeval tv; - do_gettimeofday(&tv); - printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec); -#endif -} - -static void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len) -{ - if (dvb_ringbuffer_free(cibuf) < len+2) - return; - - DVB_RINGBUFFER_WRITE_BYTE(cibuf,len>>8); - DVB_RINGBUFFER_WRITE_BYTE(cibuf,len&0xff); - - dvb_ringbuffer_write(cibuf,data,len,0); - - wake_up_interruptible(&cibuf->queue); -} - -static void debiirq (unsigned long data) -{ - struct av7110 *av7110 = (struct av7110*) data; - int type=av7110->debitype; - int handle=(type>>8)&0x1f; - -// DEB_EE(("av7110: %p\n",av7110)); - - print_time("debi"); - saa7146_write(av7110->dev, IER, - saa7146_read(av7110->dev, IER) & ~MASK_19 ); - saa7146_write(av7110->dev, ISR, MASK_19 ); - - if (type==-1) { - printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",jiffies,saa7146_read(av7110->dev,PSR),saa7146_read(av7110->dev,SSR)); - spin_lock(&av7110->debilock); - ARM_ClearMailBox(av7110); - ARM_ClearIrq(av7110); - spin_unlock(&av7110->debilock); - return; - } - av7110->debitype=-1; - - switch (type&0xff) { - - case DATA_TS_RECORD: - dvb_dmx_swfilter_packets(&av7110->demux, - (const u8 *)av7110->debi_virt, - av7110->debilen/188); - spin_lock(&av7110->debilock); - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - ARM_ClearMailBox(av7110); - spin_unlock(&av7110->debilock); - return; - - case DATA_PES_RECORD: - if (av7110->demux.recording) - record_cb(&av7110->p2t[handle], - (u8 *)av7110->debi_virt, - av7110->debilen); - spin_lock(&av7110->debilock); - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - ARM_ClearMailBox(av7110); - spin_unlock(&av7110->debilock); - return; - - case DATA_IPMPE: - case DATA_FSECTION: - case DATA_PIPING: - if (av7110->handle2filter[handle]) - DvbDmxFilterCallback((u8 *)av7110->debi_virt, - av7110->debilen, 0, 0, - av7110->handle2filter[handle], - DMX_OK, av7110); - spin_lock(&av7110->debilock); - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - ARM_ClearMailBox(av7110); - spin_unlock(&av7110->debilock); - return; - - case DATA_CI_GET: - { - u8 *data=av7110->debi_virt; - - if ((data[0]<2) && data[2]==0xff) { - int flags=0; - if (data[5]>0) - flags|=CA_CI_MODULE_PRESENT; - if (data[5]>5) - flags|=CA_CI_MODULE_READY; - av7110->ci_slot[data[0]].flags=flags; - } else - ci_get_data(&av7110->ci_rbuffer, - av7110->debi_virt, - av7110->debilen); - spin_lock(&av7110->debilock); - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - ARM_ClearMailBox(av7110); - spin_unlock(&av7110->debilock); - return; - } - - case DATA_COMMON_INTERFACE: - CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen); -#if 0 - { - int i; - - printk("av7110%d: ", av7110->num); - printk("%02x ", *(u8 *)av7110->debi_virt); - printk("%02x ", *(1+(u8 *)av7110->debi_virt)); - for (i=2; idebilen; i++) - printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt))); - for (i=2; idebilen; i++) - printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt))); - - printk("\n"); - } -#endif - spin_lock(&av7110->debilock); - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - ARM_ClearMailBox(av7110); - spin_unlock(&av7110->debilock); - return; - - case DATA_DEBUG_MESSAGE: - ((s8*)av7110->debi_virt)[Reserved_SIZE-1]=0; - printk("%s\n", (s8 *)av7110->debi_virt); - spin_lock(&av7110->debilock); - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - ARM_ClearMailBox(av7110); - spin_unlock(&av7110->debilock); - return; - - case DATA_CI_PUT: - case DATA_MPEG_PLAY: - case DATA_BMP_LOAD: - spin_lock(&av7110->debilock); - iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - ARM_ClearMailBox(av7110); - spin_unlock(&av7110->debilock); - return; - default: - break; - } - spin_lock(&av7110->debilock); - ARM_ClearMailBox(av7110); - spin_unlock(&av7110->debilock); -} - -static int pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen) -{ - int len; - u32 sync; - u16 blen; - - DEB_EE(("dvb_ring_buffer_t: %p\n",buf)); - - if (!dlen) { - wake_up(&buf->queue); - return -1; - } - while (1) { - if ((len=dvb_ringbuffer_avail(buf)) < 6) - return -1; - sync= DVB_RINGBUFFER_PEEK(buf,0)<<24; - sync|=DVB_RINGBUFFER_PEEK(buf,1)<<16; - sync|=DVB_RINGBUFFER_PEEK(buf,2)<<8; - sync|=DVB_RINGBUFFER_PEEK(buf,3); - - if (((sync&~0x0f)==0x000001e0) || - ((sync&~0x1f)==0x000001c0) || - (sync==0x000001bd)) - break; - printk("resync\n"); - DVB_RINGBUFFER_SKIP(buf,1); - } - blen= DVB_RINGBUFFER_PEEK(buf,4)<<8; - blen|=DVB_RINGBUFFER_PEEK(buf,5); - blen+=6; - if (lendlen) { - //printk("buffer empty - avail %d blen %u dlen %d\n",len,blen,dlen); - wake_up(&buf->queue); - return -1; - } - - (void)dvb_ringbuffer_read(buf,dest,(size_t)blen,0); - - DEB_S(("pread=0x%08lx, pwrite=0x%08lx\n",(unsigned long)buf->pread, (unsigned long)buf->pwrite)); - wake_up(&buf->queue); - return blen; -} - - -static void gpioirq (unsigned long data) -{ - struct av7110 *av7110 = (struct av7110*) data; - u32 rxbuf, txbuf; - int len; - - //printk("GPIO0 irq\n"); - - if (av7110->debitype !=-1) - printk("GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",jiffies,saa7146_read(av7110->dev,PSR),saa7146_read(av7110->dev,SSR)); - - spin_lock(&av7110->debilock); - - ARM_ClearIrq(av7110); - - saa7146_write(av7110->dev, IER, - saa7146_read(av7110->dev, IER) & ~MASK_19 ); - saa7146_write(av7110->dev, ISR, MASK_19 ); - - av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2); - av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - av7110->debibuf = 0; - rxbuf=irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - txbuf=irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - len=(av7110->debilen+3)&(~3); - -// DEB_D(("GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen)); - print_time("gpio"); - -// DEB_D(("GPIO0 irq %02x\n", av7110->debitype&0xff)); - switch (av7110->debitype&0xff) { - - case DATA_TS_PLAY: - case DATA_PES_PLAY: - break; - - case DATA_MPEG_VIDEO_EVENT: - { - u32 h_ar; - struct video_event event; - - av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2); - h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2); - - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - - av7110->video_size.h = h_ar & 0xfff; - DEB_D(("GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", - av7110->video_size.w, - av7110->video_size.h, - av7110->video_size.aspect_ratio)); - - event.type = VIDEO_EVENT_SIZE_CHANGED; - event.u.size.w = av7110->video_size.w; - event.u.size.h = av7110->video_size.h; - switch ((h_ar >> 12) & 0xf) - { - case 3: - av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9; - event.u.size.aspect_ratio = VIDEO_FORMAT_16_9; - av7110->videostate.video_format = VIDEO_FORMAT_16_9; - break; - case 4: - av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1; - event.u.size.aspect_ratio = VIDEO_FORMAT_221_1; - av7110->videostate.video_format = VIDEO_FORMAT_221_1; - break; - default: - av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3; - event.u.size.aspect_ratio = VIDEO_FORMAT_4_3; - av7110->videostate.video_format = VIDEO_FORMAT_4_3; - } - dvb_video_add_event(av7110, &event); - break; - } - - case DATA_CI_PUT: - { - int avail; - struct dvb_ringbuffer *cibuf=&av7110->ci_wbuffer; - - avail=dvb_ringbuffer_avail(cibuf); - if (avail<=2) { - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - break; - } - len= DVB_RINGBUFFER_PEEK(cibuf,0)<<8; - len|=DVB_RINGBUFFER_PEEK(cibuf,1); - if (availdebi_virt,len,0); - - wake_up(&cibuf->queue); - iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); - wait_for_debi_done(av7110); - saa7146_write(av7110->dev, IER, - saa7146_read(av7110->dev, IER) | MASK_19 ); - if (len<5) len=5; /* we want a real DEBI DMA */ - iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3); - spin_unlock(&av7110->debilock); - return; - } - - case DATA_MPEG_PLAY: - if (!av7110->playing) { - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - break; - } - len=0; - if (av7110->debitype&0x100) { - spin_lock(&av7110->aout.lock); - len=pes_play(av7110->debi_virt, &av7110->aout, 2048); - spin_unlock(&av7110->aout.lock); - } - if (len<=0 && (av7110->debitype&0x200) - &&av7110->videostate.play_state!=VIDEO_FREEZED) { - spin_lock(&av7110->avout.lock); - len=pes_play(av7110->debi_virt, &av7110->avout, 2048); - spin_unlock(&av7110->avout.lock); - } - if (len<=0) { - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - break; - } - DEB_D(("GPIO0 PES_PLAY len=%04x\n", len)); - iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); - wait_for_debi_done(av7110); - saa7146_write(av7110->dev, IER, - saa7146_read(av7110->dev, IER) | MASK_19 ); - - iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3); - spin_unlock(&av7110->debilock); - return; - - case DATA_BMP_LOAD: - len=av7110->debilen; - if (!len) { - av7110->bmp_state=BMP_LOADED; - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - wake_up(&av7110->bmpq); - break; - } - if (len>av7110->bmplen) - len=av7110->bmplen; - if (len>2*1024) - len=2*1024; - iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); - memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len); - av7110->bmpp+=len; - av7110->bmplen-=len; - wait_for_debi_done(av7110); - saa7146_write(av7110->dev, IER, - saa7146_read(av7110->dev, IER) | MASK_19 ); - if (len<5) len=5; /* we want a real DEBI DMA */ - iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3); - spin_unlock(&av7110->debilock); - return; - - case DATA_CI_GET: - case DATA_COMMON_INTERFACE: - case DATA_FSECTION: - case DATA_IPMPE: - case DATA_PIPING: - if (!len || len>4*1024) { - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - break; - } /* yes, fall through */ - case DATA_TS_RECORD: - case DATA_PES_RECORD: - wait_for_debi_done(av7110); - saa7146_write(av7110->dev, IER, - saa7146_read(av7110->dev, IER) | MASK_19); - irdebi(av7110, DEBISWAB, DPRAM_BASE+rxbuf, 0, len); - spin_unlock(&av7110->debilock); - return; - - case DATA_DEBUG_MESSAGE: - wait_for_debi_done(av7110); - if (!len || len>0xff) { - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - break; - } - saa7146_write(av7110->dev, IER, - saa7146_read(av7110->dev, IER) | MASK_19); - irdebi(av7110, DEBISWAB, Reserved, 0, len); - spin_unlock(&av7110->debilock); - return; - - case DATA_IRCOMMAND: - IR_handle(av7110, - swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4))); - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - break; - - default: - printk("gpioirq unknown type=%d len=%d\n", - av7110->debitype, av7110->debilen); - break; - } - ARM_ClearMailBox(av7110); - av7110->debitype=-1; - spin_unlock(&av7110->debilock); -} - - -/**************************************************************************** - * DEBI command polling - ****************************************************************************/ - - -static int OutCommand(struct av7110 *av7110, u16* buf, int length) -{ - int i; - u32 start; -#ifdef COM_DEBUG - u32 stat; -#endif - -// DEB_EE(("av7110: %p\n",av7110)); - - if (!av7110->arm_ready) { - DEB_D(("arm not ready.\n")); - return -1; - } - - start = jiffies; - while ( rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 ) ) - { - dvb_delay(1); - if ((jiffies - start) > ARM_WAIT_FREE) { - printk(KERN_ERR "%s: timeout waiting for COMMAND idle\n", __FUNCTION__); - return -1; - } - } - -#ifndef _NOHANDSHAKE - start = jiffies; - while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) ) - { - dvb_delay(1); - if ((jiffies - start) > ARM_WAIT_SHAKE) { - printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); - return -1; - } - } -#endif - - start = jiffies; - while ( rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2) & OSDQFull ) - { - dvb_delay(1); - if ((jiffies - start) > ARM_WAIT_OSD) { - printk(KERN_ERR "%s: timeout waiting for !OSDQFull\n", __FUNCTION__); - return -1; - } - } - for (i=2; i ARM_WAIT_FREE) { - printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); - return -1; - } - } - - stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); - if (stat & GPMQOver) { - printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__); - return -1; - } - else if (stat & OSDQOver) { - printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__); - return -1; - } -#endif - - return 0; -} - -static inline int SOutCommand(struct av7110 *av7110, u16* buf, int length) -{ - int ret; - -// DEB_EE(("av7110: %p\n",av7110)); - - if (!av7110->arm_ready) { - DEB_D(("arm not ready.\n")); - return -1; - } - - if (down_interruptible(&av7110->dcomlock)) - return -ERESTARTSYS; - - ret=OutCommand(av7110, buf, length); - up(&av7110->dcomlock); - if (ret) - printk("SOutCommand error\n"); - return ret; -} - - -static int outcom(struct av7110 *av7110, int type, int com, int num, ...) -{ - va_list args; - u16 buf[num+2]; - int i, ret; - -// DEB_EE(("av7110: %p\n",av7110)); - - buf[0]=(( type << 8 ) | com); - buf[1]=num; - - if (num) { - va_start(args, num); - for (i=0; iarm_ready) { - DEB_D(("arm not ready.\n")); - return -1; - } - - if (down_interruptible(&av7110->dcomlock)) - return -ERESTARTSYS; - - if ((err = OutCommand(av7110, Buff, length)) < 0) { - up(&av7110->dcomlock); - printk("CommandRequest error\n"); - return err; - } - - start = jiffies; - while ( rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) ) - { -#ifdef _NOHANDSHAKE - dvb_delay(1); -#endif - if ((jiffies - start) > ARM_WAIT_FREE) { - printk("%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); - up(&av7110->dcomlock); - return -1; - } - } - -#ifndef _NOHANDSHAKE - start = jiffies; - while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) ) { - dvb_delay(1); - if ((jiffies - start) > ARM_WAIT_SHAKE) { - printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); - up(&av7110->dcomlock); - return -1; - } - } -#endif - -#ifdef COM_DEBUG - stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); - if (stat & GPMQOver) { - printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__); - up(&av7110->dcomlock); - return -1; - } - else if (stat & OSDQOver) { - printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__); - up(&av7110->dcomlock); - return -1; - } -#endif - - for (i=0; idcomlock); - return 0; -} - - -static inline int RequestParameter(struct av7110 *av7110, u16 tag, u16* Buff, s16 length) -{ - int ret; - ret = CommandRequest(av7110, &tag, 0, Buff, length); - if (ret) - printk("RequestParameter error\n"); - return ret; -} - - -/**************************************************************************** - * Firmware commands - ****************************************************************************/ - -/* msp3400 i2c subaddresses */ -#define MSP_WR_DEM 0x10 -#define MSP_RD_DEM 0x11 -#define MSP_WR_DSP 0x12 -#define MSP_RD_DSP 0x13 - -static inline int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val) -{ - u8 msg[5]={ dev, reg>>8, reg&0xff, val>>8 , val&0xff }; - struct dvb_i2c_bus *i2c = av7110->i2c_bus; - struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg}; - - if (i2c->xfer(i2c, &msgs, 1) != 1) { - printk("av7110(%d): %s(%u = %u) failed\n", - av7110->dvb_adapter->num, __FUNCTION__, reg, val); - return -EIO; - } - return 0; -} - -static inline int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val) -{ - u8 msg1[3]={ dev, reg>>8, reg&0xff }; - u8 msg2[2]; - struct dvb_i2c_bus *i2c = av7110->i2c_bus; - struct i2c_msg msgs[2] = { - { .flags = 0, .addr = 0x40, .len = 3, .buf = msg1}, - { .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2} - }; - - if (i2c->xfer(i2c, msgs, 2) != 2) { - printk("av7110(%d): %s(%u) failed\n", - av7110->dvb_adapter->num, __FUNCTION__, reg); - return -EIO; - } - *val = (msg2[0] << 8) | msg2[1]; - return 0; -} - -static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data) -{ -// DEB_EE(("av7110: %p\n",av7110)); - - return outcom(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data); -} - -static int SetVolume(struct av7110 *av7110, int volleft, int volright) -{ - int err, vol, val, balance = 0; - - DEB_EE(("av7110: %p\n",av7110)); - - switch (av7110->adac_type) { - case DVB_ADAC_TI: - volleft = (volleft * 256) / 1036; - volright = (volright * 256) / 1036; - if (volleft > 0x3f) - volleft = 0x3f; - if (volright > 0x3f) - volright = 0x3f; - if ((err = SendDAC(av7110, 3, 0x80 + volleft))) - return err; - return SendDAC(av7110, 4, volright); - - case DVB_ADAC_CRYSTAL: - volleft=127-volleft/2; - volright=127-volright/2; - i2c_writereg(av7110, 0x20, 0x03, volleft); - i2c_writereg(av7110, 0x20, 0x04, volright); - return 0; - - case DVB_ADAC_MSP: - vol = (volleft > volright) ? volleft : volright; - val = (vol * 0x73 / 255) << 8; - if (vol > 0) { - balance = ((volright-volleft) * 127) / vol; - } - msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); - msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ - msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */ - return 0; - } - return 0; -} - -#ifdef CONFIG_DVB_AV7110_OSD - -static inline int ResetBlend(struct av7110 *av7110, u8 windownr) -{ - return outcom(av7110, COMTYPE_OSD, SetNonBlend, 1, windownr); -} - -static inline int SetColorBlend(struct av7110 *av7110, u8 windownr) -{ - return outcom(av7110, COMTYPE_OSD, SetCBlend, 1, windownr); -} - -static inline int SetWindowBlend(struct av7110 *av7110, u8 windownr, u8 blending) -{ - return outcom(av7110, COMTYPE_OSD, SetWBlend, 2, windownr, blending); -} - -static inline int SetBlend_(struct av7110 *av7110, u8 windownr, - enum av7110_osd_palette_type colordepth, u16 index, u8 blending) -{ - return outcom(av7110, COMTYPE_OSD, SetBlend, 4, - windownr, colordepth, index, blending); -} - -static inline int SetColor_(struct av7110 *av7110, u8 windownr, - enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo) -{ - return outcom(av7110, COMTYPE_OSD, SetColor, 5, - windownr, colordepth, index, colorhi, colorlo); -} - -static inline int BringToTop(struct av7110 *av7110, u8 windownr) -{ - return outcom(av7110, COMTYPE_OSD, WTop, 1, windownr); -} - -static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize, - u16 colorfg, u16 colorbg) -{ - return outcom(av7110, COMTYPE_OSD, Set_Font, 4, - windownr, fontsize, colorfg, colorbg); -} - -static int FlushText(struct av7110 *av7110) -{ - u32 start; - - if (down_interruptible(&av7110->dcomlock)) - return -ERESTARTSYS; - start = jiffies; - while ( rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2 ) ) { - dvb_delay(1); - if ((jiffies - start) > ARM_WAIT_OSD) { - printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__); - up(&av7110->dcomlock); - return -1; - } - } - up(&av7110->dcomlock); - return 0; -} - -static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) -{ - int i, ret; - u32 start; - int length=strlen(buf)+1; - u16 cbuf[5] = { (COMTYPE_OSD<<8) + DText, 3, win, x, y }; - - if (down_interruptible(&av7110->dcomlock)) - return -ERESTARTSYS; - - start = jiffies; - while ( rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2 ) ) { - dvb_delay(1); - if ((jiffies - start) > ARM_WAIT_OSD) { - printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__); - up(&av7110->dcomlock); - return -1; - } - } -#ifndef _NOHANDSHAKE - start = jiffies; - while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) ) { - dvb_delay(1); - if ((jiffies - start) > ARM_WAIT_SHAKE) { - printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); - up(&av7110->dcomlock); - return -1; - } - } -#endif - for (i=0; idcomlock); - if (ret) - printk("WriteText error\n"); - return ret; -} - -static inline int DrawLine(struct av7110 *av7110, u8 windownr, - u16 x, u16 y, u16 dx, u16 dy, u16 color) -{ - return outcom(av7110, COMTYPE_OSD, DLine, 6, - windownr, x, y, dx, dy, color); -} - -static inline int DrawBlock(struct av7110 *av7110, u8 windownr, - u16 x, u16 y, u16 dx, u16 dy, u16 color) -{ - return outcom(av7110, COMTYPE_OSD, DBox, 6, - windownr, x, y, dx, dy, color); -} - -static inline int HideWindow(struct av7110 *av7110, u8 windownr) -{ - return outcom(av7110, COMTYPE_OSD, WHide, 1, windownr); -} - -static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y) -{ - return outcom(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y); -} - -static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y) -{ - return outcom(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y); -} - -static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr) -{ - return outcom(av7110, COMTYPE_OSD, WDestroy, 1, windownr); -} - -#if 0 -static void DestroyOSDWindows(struct av7110 *av7110) -{ - int i; - - for (i=1; i<7; i++) - outcom(av7110, COMTYPE_OSD, WDestroy, 1, i); -} -#endif - -static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr, - enum av7110_window_display_type disptype, u16 width, u16 height) -{ - return outcom(av7110, COMTYPE_OSD, WCreate, 4, - windownr, disptype, width, height); -} - - -static enum av7110_osd_palette_type bpp2pal[8]={Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit}; -static enum av7110_window_display_type bpp2bit[8]={BITMAP1, BITMAP2, 0, BITMAP4, 0, 0, 0, BITMAP8}; - -static inline int LoadBitmap(struct av7110 *av7110, u16 format, u16 dx, u16 dy, int inc, u8* data) -{ - int bpp; - int i; - int d, delta; - u8 c; - DECLARE_WAITQUEUE(wait, current); - - DEB_EE(("av7110: %p\n",av7110)); - - if (av7110->bmp_state==BMP_LOADING) { - add_wait_queue(&av7110->bmpq, &wait); - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - if (av7110->bmp_state!=BMP_LOADING - || signal_pending(current)) - break; - schedule(); - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&av7110->bmpq, &wait); - } - if (av7110->bmp_state==BMP_LOADING) - return -1; - av7110->bmp_state=BMP_LOADING; - if (format==BITMAP8) { bpp=8; delta = 1; } - else if (format==BITMAP4) { bpp=4; delta = 2; } - else if (format==BITMAP2) { bpp=2; delta = 4; } - else if (format==BITMAP1) { bpp=1; delta = 8; } - else { - av7110->bmp_state=BMP_NONE; - return -1; - } - av7110->bmplen= ((dx*dy*bpp+7)&~7)/8; - av7110->bmpp=0; - if (av7110->bmplen>32768) { - av7110->bmp_state=BMP_NONE; - return -1; - } - for (i=0; ibmpbuf+1024+i*dx, data+i*inc, dx)) { - av7110->bmp_state=BMP_NONE; - return -1; - } - } - if (format != BITMAP8) { - for (i=0; ibmpbuf)[1024+i*delta+delta-1]; - for (d=delta-2; d>=0; d--) { - c |= (((u8 *)av7110->bmpbuf)[1024+i*delta+d] - << ((delta-d-1)*bpp)); - ((u8 *)av7110->bmpbuf)[1024+i] = c; - } - } - } - av7110->bmplen+=1024; - return outcom(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy); -} - -static int BlitBitmap(struct av7110 *av7110, u16 win, u16 x, u16 y, u16 trans) -{ - DECLARE_WAITQUEUE(wait, current); - - DEB_EE(("av7110: %p\n",av7110)); - - if (av7110->bmp_state==BMP_NONE) - return -1; - if (av7110->bmp_state==BMP_LOADING) { - add_wait_queue(&av7110->bmpq, &wait); - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - if (av7110->bmp_state!=BMP_LOADING - || signal_pending(current)) - break; - schedule(); - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&av7110->bmpq, &wait); - } - if (av7110->bmp_state==BMP_LOADED) - return outcom(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans); - return -1; -} - -static inline int ReleaseBitmap(struct av7110 *av7110) -{ - DEB_EE(("av7110: %p\n",av7110)); - - if (av7110->bmp_state!=BMP_LOADED) - return -1; - av7110->bmp_state=BMP_NONE; - return outcom(av7110, COMTYPE_OSD, ReleaseBmp, 0); -} - -static u32 RGB2YUV(u16 R, u16 G, u16 B) -{ - u16 y, u, v; - u16 Y, Cr, Cb; - - y = R * 77 + G * 150 + B * 29; // Luma=0.299R+0.587G+0.114B 0..65535 - u = 2048+B * 8 -(y>>5); // Cr 0..4095 - v = 2048+R * 8 -(y>>5); // Cb 0..4095 - - Y=y/256; - Cb=u/16; - Cr=v/16; - - return Cr|(Cb<<16)|(Y<<8); -} - -static void OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend) -{ - u16 ch, cl; - u32 yuv; - - yuv=blend ? RGB2YUV(r,g,b) : 0; - cl=(yuv&0xffff); - ch=((yuv>>16)&0xffff); - SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], - color, ch, cl); - SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], - color, ((blend>>4)&0x0f)); -} - -static int OSDSetPalette(struct av7110 *av7110, u32 *colors, u8 first, u8 last) -{ - int i; - int length = last - first + 1; - - if (length * 4 > DATA_BUFF3_SIZE) - return -1; - - for (i=0; i> 4; - u32 yuv = blend ? RGB2YUV(colors[i] & 0xFF, (colors[i] >> 8) & 0xFF, (colors[i] >> 16) & 0xFF) | blend : 0; - yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16); // TODO kls2003-06-15: not sure if this is endian-proof - wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i*4, yuv, 4); - } - return outcom(av7110, COMTYPE_OSD, Set_Palette, 4, - av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], first, last); -} - -static int OSDSetBlock(struct av7110 *av7110, int x0, int y0, int x1, int y1, int inc, u8 *data) -{ - uint w, h, bpp, bpl, size, lpb, bnum, brest; - int i; - - w=x1-x0+1; h=y1-y0+1; - if (inc<=0) - inc=w; - if (w<=0 || w>720 || h<=0 || h>576) - return -1; - bpp=av7110->osdbpp[av7110->osdwin]+1; - bpl=((w*bpp+7)&~7)/8; - size=h*bpl; - lpb=(32*1024)/bpl; - bnum=size/(lpb*bpl); - brest=size-bnum*lpb*bpl; - - for (i=0; iosdbpp[av7110->osdwin]], w, lpb, inc, data); - BlitBitmap(av7110, av7110->osdwin, x0, y0+i*lpb, 0); - data+=lpb*inc; - } - if (brest) { - LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]], w, brest/bpl, inc, data); - BlitBitmap(av7110, av7110->osdwin, x0, y0+bnum*lpb, 0); - } - ReleaseBitmap(av7110); - return 0; -} - -static int OSD_DrawCommand(struct av7110 *av7110, osd_cmd_t *dc) -{ - switch (dc->cmd) { - case OSD_Close: - DestroyOSDWindow(av7110, av7110->osdwin); - return 0; - case OSD_Open: - av7110->osdbpp[av7110->osdwin]=(dc->color-1)&7; - CreateOSDWindow(av7110, av7110->osdwin, bpp2bit[av7110->osdbpp[av7110->osdwin]], - dc->x1-dc->x0+1, dc->y1-dc->y0+1); - if (!dc->data) { - MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); - SetColorBlend(av7110, av7110->osdwin); - } - return 0; - case OSD_Show: - MoveWindowRel(av7110, av7110->osdwin, 0, 0); - return 0; - case OSD_Hide: - HideWindow(av7110, av7110->osdwin); - return 0; - case OSD_Clear: - DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0); - return 0; - case OSD_Fill: - DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color); - return 0; - case OSD_SetColor: - OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1); - return 0; - case OSD_SetPalette: - { - if (FW_VERSION(av7110->arm_app) >= 0x2618) - OSDSetPalette(av7110, (u32 *)dc->data, dc->color, dc->x0); - else { - int i, len=dc->x0-dc->color+1; - u8 *colors=(u8 *)dc->data; - - for (i=0; icolor+i, - colors[i*4] , colors[i*4+1], - colors[i*4+2], colors[i*4+3]); - } - return 0; - } - case OSD_SetTrans: - return 0; - case OSD_SetPixel: - DrawLine(av7110, av7110->osdwin, - dc->x0, dc->y0, 0, 0, - dc->color); - return 0; - case OSD_GetPixel: - return 0; - - case OSD_SetRow: - dc->y1=dc->y0; - case OSD_SetBlock: - OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data); - return 0; - - case OSD_FillRow: - DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, - dc->x1-dc->x0+1, dc->y1, - dc->color); - return 0; - case OSD_FillBlock: - DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, - dc->x1-dc->x0+1, dc->y1-dc->y0+1, - dc->color); - return 0; - case OSD_Line: - DrawLine(av7110, av7110->osdwin, - dc->x0, dc->y0, dc->x1-dc->x0, dc->y1-dc->y0, - dc->color); - return 0; - case OSD_Query: - return 0; - case OSD_Test: - return 0; - case OSD_Text: - { - char textbuf[240]; - - if (strncpy_from_user(textbuf, dc->data, 240)<0) - return -EFAULT; - textbuf[239]=0; - if (dc->x1>3) - dc->x1=3; - SetFont(av7110, av7110->osdwin, dc->x1, - (u16) (dc->color&0xffff), (u16) (dc->color>>16)); - FlushText(av7110); - WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf); - return 0; - } - case OSD_SetWindow: - if (dc->x0<1 || dc->x0>7) - return -EINVAL; - av7110->osdwin=dc->x0; - return 0; - case OSD_MoveWindow: - MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); - SetColorBlend(av7110, av7110->osdwin); - return 0; - default: - return -EINVAL; - } -} - - -static int dvb_osd_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - - DEB_EE(("av7110: %p\n",av7110)); - - if (cmd==OSD_SEND_CMD) - return OSD_DrawCommand(av7110, (osd_cmd_t *)parg); - - return -EINVAL; -} - - -static struct file_operations dvb_osd_fops = { - .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, - .open = dvb_generic_open, - .release = dvb_generic_release, -}; - -static struct dvb_device dvbdev_osd = { - .priv = 0, - .users = 1, - .writers = 1, - .fops = &dvb_osd_fops, - .kernel_ioctl = dvb_osd_ioctl, -}; - -#endif /* CONFIG_DVB_AV7110_OSD */ - - -/* get version of the firmware ROM, RTSL, video ucode and ARM application */ - -static void firmversion(struct av7110 *av7110) -{ - u16 buf[20]; - - u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion); - - DEB_EE(("av7110: %p\n",av7110)); - - RequestParameter(av7110, tag, buf, 16); - - av7110->arm_fw=(buf[0] << 16) + buf[1]; - av7110->arm_rtsl=(buf[2] << 16) + buf[3]; - av7110->arm_vid=(buf[4] << 16) + buf[5]; - av7110->arm_app=(buf[6] << 16) + buf[7]; - av7110->avtype=(buf[8] << 16) + buf[9]; - - printk ("DVB: AV711%d(%d) - firm %08x, rtsl %08x, vid %08x, app %08x\n", - av7110->avtype, av7110->dvb_adapter->num, av7110->arm_fw, - av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app); - - /* print firmware capabilities */ - if (FW_CI_LL_SUPPORT(av7110->arm_app)) - printk ("DVB: AV711%d(%d) - firmware supports CI link layer interface\n", - av7110->avtype, av7110->dvb_adapter->num); - else - printk ("DVB: AV711%d(%d) - no firmware support for CI link layer interface\n", - av7110->avtype, av7110->dvb_adapter->num); - - return; -} - -static int waitdebi(struct av7110 *av7110, int adr, int state) -{ - int k; - - DEB_EE(("av7110: %p\n",av7110)); - - for (k=0; k<100; k++, udelay(500)) { - if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state) - return 0; - } - return -1; -} - - -static int load_dram(struct av7110 *av7110, u32 *data, int len) -{ - int i; - int blocks, rest; - u32 base, bootblock=BOOT_BLOCK; - - DEB_EE(("av7110: %p\n",av7110)); - - blocks=len/BOOT_MAX_SIZE; - rest=len % BOOT_MAX_SIZE; - base=DRAM_START_CODE; - - for (i=0; i 0) { - if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) - return -1; - if (rest>4) - mwdebi(av7110, DEBISWAB, bootblock, ((char*)data) + i*(BOOT_MAX_SIZE), rest); - else - mwdebi(av7110, DEBISWAB, bootblock, ((char*)data) + i*(BOOT_MAX_SIZE) - 4, rest+4); - - iwdebi(av7110, DEBISWAB, BOOT_BASE, swab32(base), 4); - iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, rest, 2); - iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); - } - if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) - return -1; - iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, 0, 2); - iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); - if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BOOT_COMPLETE) < 0) - return -1; - return 0; -} - - -static u8 bootcode[] = { - 0xea, 0x00, 0x00, 0x0e, 0xe1, 0xb0, 0xf0, 0x0e, /* 0x0000 */ - 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x04, - 0xe2, 0x5e, 0xf0, 0x08, 0xe2, 0x5e, 0xf0, 0x04, - 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x04, - 0x2c, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, - 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x34, - 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa5, 0x5a, 0x5a, - 0x00, 0x1f, 0x15, 0x55, 0x00, 0x00, 0x00, 0x09, - 0xe5, 0x9f, 0xd0, 0x5c, 0xe5, 0x9f, 0x40, 0x54, /* 0x0040 */ - 0xe3, 0xa0, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x00, - 0xe5, 0x84, 0x00, 0x04, 0xe1, 0xd4, 0x10, 0xb0, - 0xe3, 0x51, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xfc, - 0xe1, 0xa0, 0x10, 0x0d, 0xe5, 0x94, 0x30, 0x04, - 0xe1, 0xd4, 0x20, 0xb2, 0xe2, 0x82, 0x20, 0x3f, - 0xe1, 0xb0, 0x23, 0x22, 0x03, 0xa0, 0x00, 0x02, - 0xe1, 0xc4, 0x00, 0xb0, 0x0a, 0xff, 0xff, 0xf4, - 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, /* 0x0080 */ - 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, - 0xe2, 0x52, 0x20, 0x01, 0x1a, 0xff, 0xff, 0xf9, - 0xe2, 0x2d, 0xdb, 0x05, 0xea, 0xff, 0xff, 0xec, - 0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x04, 0x00, -}; - -#include "av7110_firm.h" - -static int bootarm(struct av7110 *av7110) -{ - struct saa7146_dev *dev= av7110->dev; - u32 ret; - int i; - - DEB_EE(("av7110: %p\n",av7110)); - - saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); - - /* Disable DEBI and GPIO irq */ - IER_DISABLE(av7110->dev, MASK_03|MASK_19); -/* - saa7146_write(av7110->dev, IER, - saa7146_read(av7110->dev, IER) & - ~(MASK_19 | MASK_03)); -*/ - saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); - - /* enable DEBI */ - saa7146_write(av7110->dev, MC1, 0x08800880); - saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000); - saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - /* test DEBI */ - iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); - if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4))!=0x10325476) { - printk(KERN_ERR "dvb: debi test in bootarm() failed: " - "%08x != %08x\n", ret, 0x10325476);; - return -1; - } - for (i=0; i<8192; i+=4) - iwdebi(av7110, DEBISWAP, DPRAM_BASE+i, 0x00, 4); - DEB_D(("bootarm: debi test OK\n")); - - /* boot */ - DEB_D(("bootarm: load boot code\n")); - - saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO); - //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT); - //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT); - - mwdebi(av7110, DEBISWAB, DPRAM_BASE, bootcode, sizeof(bootcode)); - iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); - - wait_for_debi_done(av7110); - saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ); - - DEB_D(("bootarm: load dram code\n")); - - if (load_dram(av7110, (u32 *)Root, sizeof(Root))<0) - return -1; - - saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); - mdelay(1); - - DEB_D(("bootarm: load dpram code\n")); - - mwdebi(av7110, DEBISWAB, DPRAM_BASE, Dpram, sizeof(Dpram)); - - wait_for_debi_done(av7110); - - saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); - mdelay(800); - - //ARM_ClearIrq(av7110); - ARM_ResetMailBox(av7110); - saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); - IER_ENABLE(av7110->dev, MASK_03); -// saa7146_write(av7110->dev, IER, -// saa7146_read(av7110->dev, IER) | MASK_03 ); - - av7110->arm_errors=0; - av7110->arm_ready=1; - return 0; -} - -static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, - u16 subpid, u16 pcrpid) -{ - DEB_EE(("av7110: %p\n",av7110)); - - if (vpid == 0x1fff || apid == 0x1fff || - ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) { - vpid = apid = ttpid = subpid = pcrpid = 0; - av7110->pids[DMX_PES_VIDEO] = 0; - av7110->pids[DMX_PES_AUDIO] = 0; - av7110->pids[DMX_PES_TELETEXT] = 0; - av7110->pids[DMX_PES_PCR] = 0; - } - - return outcom(av7110, COMTYPE_PIDFILTER, MultiPID, 5, - pcrpid, vpid, apid, ttpid, subpid); -} - -static void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, - u16 subpid, u16 pcrpid) -{ - DEB_EE(("av7110: %p\n",av7110)); - - if (down_interruptible(&av7110->pid_mutex)) - return; - - if (!(vpid&0x8000)) av7110->pids[DMX_PES_VIDEO]=vpid; - if (!(apid&0x8000)) av7110->pids[DMX_PES_AUDIO]=apid; - if (!(ttpid&0x8000)) av7110->pids[DMX_PES_TELETEXT]=ttpid; - if (!(pcrpid&0x8000)) av7110->pids[DMX_PES_PCR]=pcrpid; - - av7110->pids[DMX_PES_SUBTITLE]=0; - - if (av7110->fe_synced) { - pcrpid = av7110->pids[DMX_PES_PCR]; - SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid); - } - - up(&av7110->pid_mutex); -} - - -static void SetMode(struct av7110 *av7110, int mode) -{ - DEB_EE(("av7110: %p\n",av7110)); - - outcom(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode); - - if (!av7110->playing) { - ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO], - av7110->pids[DMX_PES_AUDIO], - av7110->pids[DMX_PES_TELETEXT], - 0, av7110->pids[DMX_PES_PCR]); - outcom(av7110, COMTYPE_PIDFILTER, Scan, 0); - } -} - -static inline void TestMode(struct av7110 *av7110, int mode) -{ -// DEB_EE(("av7110: %p\n",av7110)); - outcom(av7110, COMTYPE_ENCODER, SetTestMode, 1, mode); -} - -static inline void VidMode(struct av7110 *av7110, int mode) -{ -// DEB_EE(("av7110: %p\n",av7110)); - outcom(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode); -} - - -static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg) -{ -// DEB_EE(("av7110: %p\n",av7110)); - return outcom(av7110, 0x80, 0x02, 4, - (com>>16), (com&0xffff), - (arg>>16), (arg&0xffff)); -} - -static int inline audcom(struct av7110 *av7110, u32 com) -{ -// DEB_EE(("av7110: %p\n",av7110)); - return outcom(av7110, 0x80, 0x03, 4, - (com>>16), (com&0xffff)); -} - -static inline void Set22K(struct av7110 *av7110, int state) -{ - DEB_EE(("av7110: %p\n",av7110)); - outcom(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0); -} - - -static int SendDiSEqCMsg(struct av7110 *av7110, int len, u8 *msg, unsigned long burst) -{ - int i; - u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC), - 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - DEB_EE(("av7110: %p\n",av7110)); - - if (len>10) - len=10; - - buf[1] = len+2; - buf[2] = len; - - if (burst!=-1) - buf[3]=burst ? 0x01 : 0x00; - else - buf[3]=0xffff; - - for (i=0; ii2c_bus; - struct i2c_msg msgs; - - msgs.flags=0; - msgs.addr=id/2; - msgs.len=2; - msgs.buf=msg; - return i2c->xfer (i2c, &msgs, 1); -} - -static inline u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) -{ - struct dvb_i2c_bus *i2c = av7110->i2c_bus; - u8 mm1[] = {0x00}; - u8 mm2[] = {0x00}; - struct i2c_msg msgs[2]; - - msgs[0].flags=0; - msgs[1].flags=I2C_M_RD; - msgs[0].addr=msgs[1].addr=id/2; - mm1[0]=reg; - msgs[0].len=1; msgs[1].len=1; - msgs[0].buf=mm1; msgs[1].buf=mm2; - i2c->xfer(i2c, msgs, 2); - - return mm2[0]; -} - - -/**************************************************************************** - * I/O buffer management and control - ****************************************************************************/ - -static int sw2mode[16] = { - VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL, - VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL, VIDEO_MODE_NTSC, - VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, - VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, -}; - -static void get_video_format(struct av7110 *av7110, u8 *buf, int count) -{ - int i; - int hsize,vsize; - int sw; - u8 *p; - - DEB_EE(("av7110: %p\n",av7110)); - - if (av7110->sinfo) - return; - for (i=7; i> 4) | (p[0] << 4); - vsize = ((p[1] &0x0F) << 8) | (p[2]); - sw = (p[3]&0x0F); - SetMode(av7110, sw2mode[sw]); - DEB_S(("dvb: playback %dx%d fr=%d\n", hsize, vsize, sw)); - av7110->sinfo=1; - break; - } -} - -static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, const char *buf, unsigned long count) -{ - unsigned long todo = count; - int free; - - while (todo > 0) { - if (dvb_ringbuffer_free(rbuf)<2048) { - if (wait_event_interruptible(rbuf->queue, - (dvb_ringbuffer_free(rbuf)>=2048))) - return count-todo; - } - free = dvb_ringbuffer_free(rbuf); - if (free > todo) - free = todo; - (void)dvb_ringbuffer_write(rbuf,buf,free,0); - todo -= free; - buf += free; - } - - return count-todo; -} - -static void play_video_cb(u8 *buf, int count, void *priv) -{ - struct av7110 *av7110=(struct av7110 *) priv; - DEB_EE(("av7110: %p\n",av7110)); - - if ((buf[3]&0xe0)==0xe0) { - get_video_format(av7110, buf, count); - aux_ring_buffer_write(&av7110->avout, buf, count); - } else - aux_ring_buffer_write(&av7110->aout, buf, count); -} - -static void play_audio_cb(u8 *buf, int count, void *priv) -{ - struct av7110 *av7110=(struct av7110 *) priv; - DEB_EE(("av7110: %p\n",av7110)); - - aux_ring_buffer_write(&av7110->aout, buf, count); -} - -#define FREE_COND (dvb_ringbuffer_free(&av7110->avout)>=20*1024 && dvb_ringbuffer_free(&av7110->aout)>=20*1024) - -static ssize_t dvb_play(struct av7110 *av7110, const u8 *buf, - unsigned long count, int nonblock, int type, int umem) -{ - unsigned long todo = count, n; - DEB_EE(("av7110: %p\n",av7110)); - - if (!av7110->kbuf[type]) - return -ENOBUFS; - - if (nonblock && !FREE_COND) - return -EWOULDBLOCK; - - while (todo>0) { - if (!FREE_COND) { - if (nonblock) - return count-todo; - if (wait_event_interruptible(av7110->avout.queue, - FREE_COND)) - return count-todo; - } - n=todo; - if (n>IPACKS*2) - n=IPACKS*2; - if (umem) { - if (copy_from_user(av7110->kbuf[type], buf, n)) - return -EFAULT; - av7110_ipack_instant_repack(av7110->kbuf[type], n, - &av7110->ipack[type]); - } else { - av7110_ipack_instant_repack(buf, n, - &av7110->ipack[type]); - } - todo -= n; - buf += n; - } - return count-todo; -} - -static ssize_t dvb_aplay(struct av7110 *av7110, const u8 *buf, - unsigned long count, int nonblock, int type) -{ - unsigned long todo = count, n; - DEB_EE(("av7110: %p\n",av7110)); - - if (!av7110->kbuf[type]) - return -ENOBUFS; - if (nonblock && dvb_ringbuffer_free(&av7110->aout)<20*1024) - return -EWOULDBLOCK; - - while (todo>0) { - if (dvb_ringbuffer_free(&av7110->aout)<20*1024) { - if (nonblock) - return count-todo; - if (wait_event_interruptible(av7110->aout.queue, - (dvb_ringbuffer_free(&av7110->aout)>= - 20*1024))) - return count-todo; - } - n=todo; - if (n>IPACKS*2) - n=IPACKS*2; - if (copy_from_user(av7110->kbuf[type], buf, n)) - return -EFAULT; - av7110_ipack_instant_repack(av7110->kbuf[type], n, - &av7110->ipack[type]); -// memcpy(dvb->kbuf[type], buf, n); - todo -= n; - buf += n; - } - return count-todo; -} - -void init_p2t(struct av7110_p2t *p, struct dvb_demux_feed *feed) -{ - memset(p->pes,0,TS_SIZE); - p->counter = 0; - p->pos = 0; - p->frags = 0; - if (feed) p->feed = feed; -} - -void clear_p2t(struct av7110_p2t *p) -{ - memset(p->pes,0,TS_SIZE); -// p->counter = 0; - p->pos = 0; - p->frags = 0; -} - - -long int find_pes_header(u8 const *buf, long int length, int *frags) -{ - int c = 0; - int found = 0; - - *frags = 0; - - while (c < length-3 && !found) { - if (buf[c] == 0x00 && buf[c+1] == 0x00 && - buf[c+2] == 0x01) { - switch ( buf[c+3] ) { - - case PROG_STREAM_MAP: - case PRIVATE_STREAM2: - case PROG_STREAM_DIR: - case ECM_STREAM : - case EMM_STREAM : - case PADDING_STREAM : - case DSM_CC_STREAM : - case ISO13522_STREAM: - case PRIVATE_STREAM1: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - found = 1; - break; - - default: - c++; - break; - } - } else c++; - } - if (c == length-3 && !found){ - if (buf[length-1] == 0x00) *frags = 1; - if (buf[length-2] == 0x00 && - buf[length-1] == 0x00) *frags = 2; - if (buf[length-3] == 0x00 && - buf[length-2] == 0x00 && - buf[length-1] == 0x01) *frags = 3; - return -1; - } - - return c; -} - -void pes_to_ts( u8 const *buf, long int length, u16 pid, struct av7110_p2t *p) -{ - int c,c2,l,add; - int check,rest; - - c = 0; - c2 = 0; - if (p->frags){ - check = 0; - switch(p->frags){ - case 1: - if ( buf[c] == 0x00 && buf[c+1] == 0x01 ){ - check = 1; - c += 2; - } - break; - case 2: - if ( buf[c] == 0x01 ){ - check = 1; - c++; - } - break; - case 3: - check = 1; - } - if(check){ - switch ( buf[c] ) { - - case PROG_STREAM_MAP: - case PRIVATE_STREAM2: - case PROG_STREAM_DIR: - case ECM_STREAM : - case EMM_STREAM : - case PADDING_STREAM : - case DSM_CC_STREAM : - case ISO13522_STREAM: - case PRIVATE_STREAM1: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - p->pes[0] = 0x00; - p->pes[1] = 0x00; - p->pes[2] = 0x01; - p->pes[3] = buf[c]; - p->pos=4; - memcpy(p->pes+p->pos,buf+c,(TS_SIZE-4)-p->pos); - c += (TS_SIZE-4)-p->pos; - p_to_t(p->pes,(TS_SIZE-4),pid,&p->counter, - p->feed); - clear_p2t(p); - break; - - default: - c=0; - break; - } - } - p->frags = 0; - } - - if (p->pos){ - c2 = find_pes_header(buf+c,length-c,&p->frags); - if (c2 >= 0 && c2 < (TS_SIZE-4)-p->pos){ - l = c2+c; - } else l = (TS_SIZE-4)-p->pos; - memcpy(p->pes+p->pos,buf,l); - c += l; - p->pos += l; - p_to_t(p->pes,p->pos,pid,&p->counter, p->feed); - clear_p2t(p); - } - - add = 0; - while (c < length){ - c2 = find_pes_header(buf+c+add,length-c-add,&p->frags); - if (c2 >= 0) { - c2 += c+add; - if (c2 > c){ - p_to_t(buf+c,c2-c,pid,&p->counter, - p->feed); - c = c2; - clear_p2t(p); - add = 0; - } else add = 1; - } else { - l = length-c; - rest = l % (TS_SIZE-4); - l -= rest; - p_to_t(buf+c,l,pid,&p->counter, - p->feed); - memcpy(p->pes,buf+c+l,rest); - p->pos = rest; - c = length; - } - } -} - - -int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length) -{ - int i; - int c = 0; - int fill; - u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10}; - - fill = (TS_SIZE-4)-length; - if (pes_start) tshead[1] = 0x40; - if (fill) tshead[3] = 0x30; - tshead[1] |= (u8)((pid & 0x1F00) >> 8); - tshead[2] |= (u8)(pid & 0x00FF); - tshead[3] |= ((*counter)++ & 0x0F) ; - memcpy(buf,tshead,4); - c+=4; - - - if (fill){ - buf[4] = fill-1; - c++; - if (fill >1){ - buf[5] = 0x00; - c++; - } - for ( i = 6; i < fill+4; i++){ - buf[i] = 0xFF; - c++; - } - } - - return c; -} - - -void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, - struct dvb_demux_feed *feed) -{ - - int l, pes_start; - u8 obuf[TS_SIZE]; - long int c = 0; - - pes_start = 0; - if ( length > 3 && - buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01 ) - switch (buf[3]){ - case PROG_STREAM_MAP: - case PRIVATE_STREAM2: - case PROG_STREAM_DIR: - case ECM_STREAM : - case EMM_STREAM : - case PADDING_STREAM : - case DSM_CC_STREAM : - case ISO13522_STREAM: - case PRIVATE_STREAM1: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - pes_start = 1; - break; - - default: - break; - } - - while ( c < length ){ - memset(obuf,0,TS_SIZE); - if (length - c >= (TS_SIZE-4)){ - l = write_ts_header2(pid, counter, pes_start - , obuf, (TS_SIZE-4)); - memcpy(obuf+l, buf+c, TS_SIZE-l); - c += TS_SIZE-l; - } else { - l = write_ts_header2(pid, counter, pes_start - , obuf, length-c); - memcpy(obuf+l, buf+c, TS_SIZE-l); - c = length; - } - feed->cb.ts(obuf, 188, 0, 0, &feed->feed.ts, DMX_OK); - pes_start = 0; - } -} - -/**************************************************************************** - * V4L SECTION - ****************************************************************************/ - -static struct v4l2_input inputs[2] = { - { - .index = 0, - .name = "DVB", - .type = V4L2_INPUT_TYPE_CAMERA, - .audioset = 1, - .tuner = 0, /* ignored */ - .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, - .status = 0, - }, { - .index = 1, - .name = "Television", - .type = V4L2_INPUT_TYPE_TUNER, - .audioset = 2, - .tuner = 0, - .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, - .status = 0, - } -}; - -/* taken from ves1820.c */ -static int ves1820_writereg(struct saa7146_dev *dev, u8 reg, u8 data) -{ - u8 addr = 0x09; - u8 buf[] = { 0x00, reg, data }; - struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 }; - - DEB_EE(("av7710: dev: %p\n",dev)); - - if( 1 != saa7146_i2c_transfer(dev, &msg, 1, 1)) { - return -1; - } - return 0; -} - -static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4]) -{ - struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 }; - - DEB_EE(("av7710: dev: %p\n",dev)); - - if( 1 != saa7146_i2c_transfer(dev, &msg, 1, 1)) { - return -1; - } - return 0; -} - - -/** - * set up the downconverter frequency divisor for a - * reference clock comparision frequency of 62.5 kHz. - */ -static int tuner_set_tv_freq (struct saa7146_dev *dev, u32 freq) -{ - u32 div; - u8 config; - u8 buf [4]; - - DEB_EE(("av7710: freq: 0x%08x\n",freq)); - - /* magic number: 614. tuning with the frequency given by v4l2 - is always off by 614*62.5 = 38375 kHz...*/ - div = freq + 614; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x8e; - - if (freq < (u32) 16*168.25 ) - config = 0xa0; - else if (freq < (u32) 16*447.25) - config = 0x90; - else - config = 0x30; - config &= ~0x02; - - buf[3] = config; - - return tuner_write (dev, 0x61, buf); -} - -static struct saa7146_standard analog_standard[]; -static struct saa7146_standard dvb_standard[]; -static struct saa7146_standard standard[]; - -static struct v4l2_audio msp3400_v4l2_audio = { - .index = 0, - .name = "Television", - .capability = V4L2_AUDCAP_STEREO -}; - -int av7110_dvb_c_switch(struct saa7146_fh *fh) -{ - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - struct av7110 *av7110 = (struct av7110*)dev->ext_priv; - u16 adswitch; - u8 band = 0; - int source, sync; - struct saa7146_fh *ov_fh = NULL; - int restart_overlay = 0; - - DEB_EE(("av7110: %p\n",av7110)); - - if( vv->ov_data != NULL ) { - ov_fh = vv->ov_data->fh; - saa7146_stop_preview(ov_fh); - restart_overlay = 1; - } - - if( 0 != av7110->current_input ) { - adswitch = 1; - band = 0x68; /* analog band */ - source = SAA7146_HPS_SOURCE_PORT_B; - sync = SAA7146_HPS_SYNC_PORT_B; - memcpy(standard,analog_standard,sizeof(struct saa7146_standard)*2); - printk("av7110: switching to analog TV\n"); - msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source - msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source - msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source - msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume - } else { - adswitch = 0; - band = 0x28; /* digital band */ - source = SAA7146_HPS_SOURCE_PORT_A; - sync = SAA7146_HPS_SYNC_PORT_A; - memcpy(standard,dvb_standard,sizeof(struct saa7146_standard)*2); - printk("av7110: switching DVB mode\n"); - msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source - msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source - msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source - msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume - } - - /* hmm, this does not do anything!? */ - if (outcom(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch)) - printk("ADSwitch error\n"); - - if( 0 != ves1820_writereg(dev, 0x0f, band )) { - printk("setting band in demodulator failed.\n"); - } - saa7146_set_hps_source_and_sync(dev, source, sync); - - /* restart overlay if it was active before */ - if( 0 != restart_overlay ) { - saa7146_start_preview(ov_fh); - } - - return 0; -} - -int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) -{ - struct saa7146_dev *dev = fh->dev; - struct av7110 *av7110 = (struct av7110*)dev->ext_priv; - DEB_EE(("saa7146_dev: %p\n",dev)); - - switch(cmd) { - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *t = arg; - u16 stereo_det; - s8 stereo; - - DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index)); - - if( 0 == av7110->has_analog_tuner || t->index != 0 ) { - return -EINVAL; - } - - memset(t,0,sizeof(*t)); - strcpy(t->name, "Television"); - - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; - t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */ - t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */ - /* FIXME: add the real signal strength here */ - t->signal = 0xffff; - t->afc = 0; - -msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det); -printk("VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det); - - msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det); - printk("VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det); - stereo = (s8)(stereo_det >> 8); - if (stereo > 0x10) { - /* stereo */ - t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; - t->audmode = V4L2_TUNER_MODE_STEREO; - } - else if (stereo < -0x10) { - /* bilingual*/ - t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - t->audmode = V4L2_TUNER_MODE_LANG1; - } - else /* mono */ - t->rxsubchans = V4L2_TUNER_SUB_MONO; - - return 0; - } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *t = arg; - u16 fm_matrix, src; - DEB_EE(("VIDIOC_S_TUNER: %d\n", t->index)); - - if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) { - return -EINVAL; - } - - - switch(t->audmode) { - case V4L2_TUNER_MODE_STEREO: - DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n")); - fm_matrix = 0x3001; // stereo - src = 0x0020; - break; - case V4L2_TUNER_MODE_LANG1: - DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n")); - fm_matrix = 0x3000; // mono - src = 0x0000; - break; - case V4L2_TUNER_MODE_LANG2: - DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n")); - fm_matrix = 0x3000; // mono - src = 0x0010; - break; - default: /* case V4L2_TUNER_MODE_MONO: {*/ - DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n")); - fm_matrix = 0x3000; // mono - src = 0x0030; - break; - } - msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix); - msp_writereg(av7110, MSP_WR_DSP, 0x0008, src); - msp_writereg(av7110, MSP_WR_DSP, 0x0009, src); - msp_writereg(av7110, MSP_WR_DSP, 0x000a, src); - - return 0; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *f = arg; - - DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency)); - - if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) { - return -EINVAL; - } - - memset(f,0,sizeof(*f)); - f->type = V4L2_TUNER_ANALOG_TV; - f->frequency = av7110->current_freq; - - return 0; - } - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *f = arg; - - DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n",f->frequency)); - - if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) { - return -EINVAL; - } - - if (V4L2_TUNER_ANALOG_TV != f->type) - return -EINVAL; - - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0); - - /* tune in desired frequency */ - tuner_set_tv_freq(dev, f->frequency); - av7110->current_freq = f->frequency; - - msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection - msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000); - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume - - return 0; - } - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; - - DEB_EE(("VIDIOC_ENUMINPUT: %d\n", i->index)); - - if( 0 != av7110->has_analog_tuner ) { - if( i->index < 0 || i->index >= 2) { - return -EINVAL; - } - } else { - if( i->index != 0 ) { - return -EINVAL; - } - } - - memcpy(i, &inputs[i->index], sizeof(struct v4l2_input)); - - return 0; - } - case VIDIOC_G_INPUT: - { - int *input = (int *)arg; - *input = av7110->current_input; - DEB_EE(("VIDIOC_G_INPUT: %d\n", *input)); - return 0; - } - case VIDIOC_S_INPUT: - { - int input = *(int *)arg; - - DEB_EE(("VIDIOC_S_INPUT: %d\n", input)); - - if( 0 == av7110->has_analog_tuner ) { - return 0; - } - - if( input < 0 || input >= 2) { - return -EINVAL; - } - - /* fixme: switch inputs here */ - av7110->current_input = input; - return av7110_dvb_c_switch(fh); - } - case VIDIOC_G_AUDIO: - { - struct v4l2_audio *a = arg; - - DEB_EE(("VIDIOC_G_AUDIO: %d\n", a->index)); - if (a->index != 0) - return -EINVAL; - memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio)); - break; - } - case VIDIOC_S_AUDIO: - { - struct v4l2_audio *a = arg; - DEB_EE(("VIDIOC_S_AUDIO: %d\n", a->index)); - break; - } - default: - printk("no such ioctl\n"); - return -ENOIOCTLCMD; - } - return 0; -} - -static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) -{ - struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; - struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; - unsigned int mask = 0; - - DEB_EE(("av7110: %p\n",av7110)); - - poll_wait(file, &av7110->aout.queue, wait); - - if (av7110->playing) { - if (dvb_ringbuffer_free(&av7110->aout)>=20*1024) - mask |= (POLLOUT | POLLWRNORM); - } else /* if not playing: may play if asked for */ - mask = (POLLOUT | POLLWRNORM); - - return mask; -} - - -/**************************************************************************** - * END OF V4L SECTION - ****************************************************************************/ - - -/**************************************************************************** - * DVB API SECTION - ****************************************************************************/ - - -/****************************************************************************** - * hardware filter functions - ******************************************************************************/ - -static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) -{ - struct dvb_demux_feed *dvbdmxfeed=dvbdmxfilter->feed; - struct av7110 *av7110=(struct av7110 *) dvbdmxfeed->demux->priv; - u16 buf[20]; - int ret, i; - u16 handle; -// u16 mode=0x0320; - u16 mode=0xb96a; - - DEB_EE(("av7110: %p\n",av7110)); - - if (dvbdmxfilter->type==DMX_TYPE_SEC) { - if (hw_sections) { - buf[4]=(dvbdmxfilter->filter.filter_value[0]<<8)| - dvbdmxfilter->maskandmode[0]; - for (i=3; i<18; i++) - buf[i+4-2]=(dvbdmxfilter->filter.filter_value[i]<<8)| - dvbdmxfilter->maskandmode[i]; - mode=4; - } - } else - if ((dvbdmxfeed->ts_type & TS_PACKET) && - !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) - init_p2t(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed); - - buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter; - buf[1] = 16; - buf[2] = dvbdmxfeed->pid; - buf[3] = mode; - - ret=CommandRequest(av7110, buf, 20, &handle, 1); - if (ret<0) { - printk("StartHWFilter error\n"); - return ret; - } - - av7110->handle2filter[handle]=dvbdmxfilter; - dvbdmxfilter->hw_handle=handle; - - return ret; -} - -static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) -{ - struct av7110 *av7110=(struct av7110 *) dvbdmxfilter->feed->demux->priv; - u16 buf[3]; - u16 answ[2]; - int ret; - u16 handle; - - DEB_EE(("av7110: %p\n",av7110)); - - handle=dvbdmxfilter->hw_handle; - if (handle>32) { - DEB_S(("dvb: StopHWFilter tried to stop invalid filter %d.\n", - handle)); - DEB_S(("dvb: filter type = %d\n", dvbdmxfilter->type)); - return 0; - } - - av7110->handle2filter[handle]=NULL; - - buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter; - buf[1] = 1; - buf[2] = handle; - ret=CommandRequest(av7110, buf, 3, answ, 2); - if (ret) - printk("StopHWFilter error\n"); - - if (answ[1] != handle) { - DEB_S(("dvb: filter %d shutdown error :%d\n", handle, answ[1])); - ret=-1; - } - return ret; -} - - -static int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) -{ - struct dvb_demux *demux = feed->demux; - struct av7110 *av7110 = (struct av7110 *) demux->priv; - struct ipack *ipack = &av7110->ipack[feed->pes_type]; - - DEB_EE(("av7110: %p\n",av7110)); - - switch (feed->pes_type) { - case 0: - if (av7110->audiostate.stream_source==AUDIO_SOURCE_MEMORY) - return -EINVAL; - break; - case 1: - if (av7110->videostate.stream_source==VIDEO_SOURCE_MEMORY) - return -EINVAL; - break; - default: - return -1; - } - - if (!(buf[3] & 0x10)) { // no payload? - return -1; - } - if (buf[1] & 0x40) - av7110_ipack_flush(ipack); - - if (buf[3] & 0x20) { // adaptation field? - len -= buf[4]+1; - buf += buf[4]+1; - if (!len) - return 0; - } - - av7110_ipack_instant_repack(buf+4, len-4, &av7110->ipack[feed->pes_type]); - return 0; -} - - -static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) -{ - struct dvb_demux *dvbdmx=dvbdmxfeed->demux; - struct av7110 *av7110=(struct av7110 *) dvbdmx->priv; - u16 *pid=dvbdmx->pids, npids[5]; - int i; - - DEB_EE(("av7110: %p\n",av7110)); - - npids[0]=npids[1]=npids[2]=npids[3]=0xffff; - npids[4]=0xffff; - i=dvbdmxfeed->pes_type; - npids[i]=(pid[i]&0x8000) ? 0 : pid[i]; - if ((i==2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) { - npids[i]=0; - ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); - StartHWFilter(dvbdmxfeed->filter); - return; - } - if (dvbdmxfeed->pes_type<=2 || dvbdmxfeed->pes_type==4) - ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); - - if (dvbdmxfeed->pes_type<2 && npids[0]) - if (av7110->fe_synced) - outcom(av7110, COMTYPE_PIDFILTER, Scan, 0); - - if ((dvbdmxfeed->ts_type & TS_PACKET)) { - if (dvbdmxfeed->pes_type == 0 && - !(dvbdmx->pids[0]&0x8000)) - AV_StartRecord(av7110, RP_AUDIO, - dvbdmxfeed); - if (dvbdmxfeed->pes_type == 1 && - !(dvbdmx->pids[1]&0x8000)) - AV_StartRecord(av7110, RP_VIDEO, - dvbdmxfeed); - } -} - -static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) -{ - struct dvb_demux *dvbdmx=dvbdmxfeed->demux; - struct av7110 *av7110=(struct av7110 *) dvbdmx->priv; - u16 *pid=dvbdmx->pids, npids[5]; - int i; - - DEB_EE(("av7110: %p\n",av7110)); - - if (dvbdmxfeed->pes_type<=1) { - AV_Stop(av7110, dvbdmxfeed->pes_type ? - RP_VIDEO : RP_AUDIO); - if (!av7110->rec_mode) - dvbdmx->recording=0; - if (!av7110->playing) - dvbdmx->playing=0; - } - npids[0]=npids[1]=npids[2]=npids[3]=0xffff; - npids[4]=0xffff; - i=dvbdmxfeed->pes_type; - switch (i) { - case 2: //teletext - if (dvbdmxfeed->ts_type & TS_PACKET) - StopHWFilter(dvbdmxfeed->filter); - npids[2]=0; - break; - case 0: - case 1: - case 4: - if (!pids_off) - return; - npids[i]=(pid[i]&0x8000) ? 0 : pid[i]; - break; - } - ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); -} - -static int av7110_start_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct av7110 *av7110 = (struct av7110 *) demux->priv; - - DEB_EE(("av7110: %p\n",av7110)); - - if (!demux->dmx.frontend) - return -EINVAL; - - if (feed->pid > 0x1fff) - return -EINVAL; - - if (feed->type == DMX_TYPE_TS) { - if ((feed->ts_type & TS_DECODER) && - (feed->pes_type < DMX_TS_PES_OTHER)) { - switch (demux->dmx.frontend->source) { - case DMX_MEMORY_FE: - if (feed->ts_type & TS_DECODER) - if (feed->pes_type < 2 && - !(demux->pids[0] & 0x8000) && - !(demux->pids[1] & 0x8000)) { - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); - AV_StartPlay(av7110,RP_AV); - demux->playing = 1; - } - break; - default: - dvb_feed_start_pid(feed); - break; - } - } else - if ((feed->ts_type & TS_PACKET) && - (demux->dmx.frontend->source!=DMX_MEMORY_FE)) - StartHWFilter(feed->filter); - } - - if (feed->type == DMX_TYPE_SEC) { - int i; - - for (i=0; ifilternum; i++) { - if (demux->filter[i].state!=DMX_STATE_READY) - continue; - if (demux->filter[i].type!=DMX_TYPE_SEC) - continue; - if (demux->filter[i].filter.parent!=&feed->feed.sec) - continue; - demux->filter[i].state=DMX_STATE_GO; - if (demux->dmx.frontend->source!=DMX_MEMORY_FE) - StartHWFilter(&demux->filter[i]); - } - } - - return 0; -} - - -static int av7110_stop_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct av7110 *av7110 = (struct av7110 *) demux->priv; - - DEB_EE(("av7110: %p\n",av7110)); - - if (feed->type == DMX_TYPE_TS) { - if (feed->ts_type & TS_DECODER) { - if (feed->pes_type >= DMX_TS_PES_OTHER || - !demux->pesfilter[feed->pes_type]) - return -EINVAL; - demux->pids[feed->pes_type]|=0x8000; - demux->pesfilter[feed->pes_type]=0; - } - if (feed->ts_type & TS_DECODER && - feed->pes_type < DMX_TS_PES_OTHER) { - dvb_feed_stop_pid(feed); - } else - if ((feed->ts_type & TS_PACKET) && - (demux->dmx.frontend->source != DMX_MEMORY_FE)) - StopHWFilter(feed->filter); - } - - if (feed->type == DMX_TYPE_SEC) { - int i; - - for (i=0; ifilternum; i++) - if (demux->filter[i].state==DMX_STATE_GO && - demux->filter[i].filter.parent==&feed->feed.sec) { - demux->filter[i].state=DMX_STATE_READY; - if (demux->dmx.frontend->source!=DMX_MEMORY_FE) - StopHWFilter(&demux->filter[i]); - } - } - - return 0; -} - - -static void restart_feeds(struct av7110 *av7110) -{ - struct dvb_demux *dvbdmx=&av7110->demux; - struct dvb_demux_feed *feed; - int mode; - int i; - - DEB_EE(("av7110: %p\n",av7110)); - - mode=av7110->playing; - av7110->playing=0; - av7110->rec_mode=0; - - for (i=0; ifilternum; i++) { - feed=&dvbdmx->feed[i]; - if (feed->state==DMX_STATE_GO) - av7110_start_feed(feed); - } - - if (mode) - AV_StartPlay(av7110, mode); -} - -static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, - uint64_t *stc, unsigned int *base) -{ - int ret; - u16 fwstc[4]; - u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC); - struct dvb_demux *dvbdemux; - struct av7110 *av7110; - - /* pointer casting paranoia... */ - if (!demux) - BUG(); - dvbdemux = (struct dvb_demux *) demux->priv; - if (!dvbdemux) - BUG(); - av7110 = (struct av7110 *) dvbdemux->priv; - - DEB_EE(("av7110: %p\n",av7110)); - - if (num != 0) - return -EINVAL; - - ret = CommandRequest(av7110, &tag, 0, fwstc, 4); - if (ret) { - printk(KERN_ERR "%s: CommandRequest error\n", __FUNCTION__); - return -EIO; - } - DEB_EE(("av7110: fwstc = %04hx %04hx %04hx %04hx\n", - fwstc[0], fwstc[1], fwstc[2], fwstc[3])); - - *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) | - (((uint64_t)fwstc[1]) << 16) | ((uint64_t)fwstc[0]); - *base = 1; - - DEB_EE(("av7110: stc = %lu\n", (unsigned long)*stc)); - - return 0; -} - - -/****************************************************************************** - * SEC device file operations - ******************************************************************************/ - -static int av7110_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) -{ - struct av7110 *av7110 = fe->before_after_data; - - DEB_EE(("av7110: %p\n",av7110)); - - switch (cmd) { - case FE_SET_TONE: - switch ((fe_sec_tone_mode_t) arg) { - case SEC_TONE_ON: - Set22K (av7110, 1); - break; - case SEC_TONE_OFF: - Set22K (av7110, 0); - break; - default: - return -EINVAL; - }; - break; - - case FE_DISEQC_SEND_MASTER_CMD: - { - struct dvb_diseqc_master_cmd *cmd = arg; - SendDiSEqCMsg (av7110, cmd->msg_len, cmd->msg, -1); - break; - } - - case FE_DISEQC_SEND_BURST: - SendDiSEqCMsg (av7110, 0, NULL, (unsigned long)arg); - break; - - default: - return -EOPNOTSUPP; - }; - - return 0; -} - -/****************************************************************************** - * CI link layer file ops (FIXME: move this to separate module later) - ******************************************************************************/ - -int ci_ll_init(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf, int size) -{ - dvb_ringbuffer_init(cirbuf, vmalloc(size), size); - dvb_ringbuffer_init(ciwbuf, vmalloc(size), size); - return 0; -} - -void ci_ll_flush(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf) -{ - dvb_ringbuffer_flush_spinlock_wakeup(cirbuf); - dvb_ringbuffer_flush_spinlock_wakeup(ciwbuf); -} - -void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf) -{ - vfree(cirbuf->data); - cirbuf->data=0; - vfree(ciwbuf->data); - ciwbuf->data=0; -} - - -int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file, - int slots, ca_slot_info_t *slot) -{ - int i; - int len=0; - u8 msg[8]={0x00,0x06,0,0x00,0xff,0x02,0x00,0x00}; - - for (i=0; i<2; i++) { - if (slots & (1<f_flags&O_NONBLOCK; - - if (count>2048) - return -EINVAL; - free=dvb_ringbuffer_free(cibuf); - if (count+2>free) { - if (non_blocking) - return -EWOULDBLOCK; - if (wait_event_interruptible(cibuf->queue, - (dvb_ringbuffer_free(cibuf)>=count+2))) - return 0; - } - - DVB_RINGBUFFER_WRITE_BYTE(cibuf,count>>8); - DVB_RINGBUFFER_WRITE_BYTE(cibuf,count&0xff); - - return dvb_ringbuffer_write(cibuf,buf,count,1); -} - -static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file, char *buf, size_t count, loff_t *ppos) -{ - int avail; - int non_blocking=file->f_flags&O_NONBLOCK; - ssize_t len; - - if (!cibuf->data || !count) - return 0; - if (non_blocking && (dvb_ringbuffer_empty(cibuf))) - return -EWOULDBLOCK; - if (wait_event_interruptible(cibuf->queue, - !dvb_ringbuffer_empty(cibuf))) - return 0; - avail=dvb_ringbuffer_avail(cibuf); - if (avail<4) - return 0; - len= DVB_RINGBUFFER_PEEK(cibuf,0)<<8; - len|=DVB_RINGBUFFER_PEEK(cibuf,1); - if (availprivate_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - int err=dvb_generic_open(inode, file); - - DEB_EE(("av7110: %p\n",av7110)); - - if (err<0) - return err; - ci_ll_flush(&av7110->ci_rbuffer, &av7110->ci_wbuffer); - return 0; -} - -static unsigned int dvb_ca_poll (struct file *file, poll_table *wait) -{ - struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; - struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; - struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer; - struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer; - unsigned int mask = 0; - - DEB_EE(("av7110: %p\n",av7110)); - - poll_wait (file, &rbuf->queue, wait); - - if (!dvb_ringbuffer_empty(rbuf)) - mask |= POLLIN; - - if (dvb_ringbuffer_avail(wbuf)>1024) - mask |= POLLOUT; - - return mask; -} - -static int dvb_ca_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - unsigned long arg=(unsigned long) parg; - - DEB_EE(("av7110: %p\n",av7110)); - - switch (cmd) { - case CA_RESET: -#ifdef NEW_CI - - return ci_ll_reset(&av7110->ci_wbuffer, file, arg, &av7110->ci_slot[0]); -#endif - break; - - case CA_GET_CAP: - { - ca_caps_t cap; - - cap.slot_num=2; -#ifdef NEW_CI - cap.slot_type=(FW_CI_LL_SUPPORT(av7110->arm_app) ? CA_CI_LINK : CA_CI) | CA_DESCR; -#else - cap.slot_type=CA_CI|CA_DESCR; -#endif - cap.descr_num=16; - cap.descr_type=CA_ECD; - memcpy(parg, &cap, sizeof(cap)); - } - break; - - case CA_GET_SLOT_INFO: - { - ca_slot_info_t *info=(ca_slot_info_t *)parg; - - if (info->num>1) - return -EINVAL; - av7110->ci_slot[info->num].num = info->num; -#ifdef NEW_CI - av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? CA_CI_LINK : CA_CI; -#else - av7110->ci_slot[info->num].type = CA_CI; -#endif - memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t)); - } - break; - - case CA_GET_MSG: - break; - - case CA_SEND_MSG: - break; - - case CA_GET_DESCR_INFO: - { - ca_descr_info_t info; - - info.num=16; - info.type=CA_ECD; - memcpy (parg, &info, sizeof (info)); - } - break; - - case CA_SET_DESCR: - { - ca_descr_t *descr=(ca_descr_t*) parg; - - if (descr->index>=16) - return -EINVAL; - if (descr->parity>1) - return -EINVAL; - outcom(av7110, COMTYPE_PIDFILTER, SetDescr, 5, - (descr->index<<8)|descr->parity, - (descr->cw[0]<<8)|descr->cw[1], - (descr->cw[2]<<8)|descr->cw[3], - (descr->cw[4]<<8)|descr->cw[5], - (descr->cw[6]<<8)|descr->cw[7]); - } - break; - - default: - return -EINVAL; - } - return 0; -} - -static ssize_t dvb_ca_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - - DEB_EE(("av7110: %p\n",av7110)); - return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos); -} - -static ssize_t dvb_ca_read(struct file *file, char *buf, size_t count, loff_t *ppos) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - - DEB_EE(("av7110: %p\n",av7110)); - return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos); -} - - - -/****************************************************************************** - * Video MPEG decoder events - ******************************************************************************/ -static void dvb_video_add_event (struct av7110 *av7110, struct video_event *event) -{ - struct dvb_video_events *events = &av7110->video_events; - int wp; - - DEB_D(("\n")); - - spin_lock_bh(&events->lock); - - wp = (events->eventw + 1) % MAX_VIDEO_EVENT; - - if (wp == events->eventr) { - events->overflow = 1; - events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; - } - - //FIXME: timestamp? - memcpy(&events->events[events->eventw], event, sizeof(struct video_event)); - - events->eventw = wp; - - spin_unlock_bh(&events->lock); - - wake_up_interruptible (&events->wait_queue); -} - - -static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags) -{ - struct dvb_video_events *events = &av7110->video_events; - - DEB_D(("\n")); - - if (events->overflow) { - events->overflow = 0; - return -EOVERFLOW; - } - - if (events->eventw == events->eventr) { - int ret; - - if (flags & O_NONBLOCK) - return -EWOULDBLOCK; - - ret = wait_event_interruptible (events->wait_queue, - events->eventw != events->eventr); - if (ret < 0) - return ret; - } - - spin_lock_bh(&events->lock); - - memcpy (event, &events->events[events->eventr], - sizeof(struct video_event)); - - events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; - - spin_unlock_bh(&events->lock); - - return 0; -} - - -/****************************************************************************** - * DVB device file operations - ******************************************************************************/ - -static unsigned int dvb_video_poll(struct file *file, poll_table *wait) -{ - struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; - struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; - unsigned int mask = 0; - - DEB_EE(("av7110: %p\n",av7110)); - - if ((file->f_flags & O_ACCMODE) != O_RDONLY) { - poll_wait(file, &av7110->avout.queue, wait); - } - - poll_wait(file, &av7110->video_events.wait_queue, wait); - - if (av7110->video_events.eventw != av7110->video_events.eventr) - mask = POLLPRI; - - if ((file->f_flags & O_ACCMODE) != O_RDONLY) { - if (av7110->playing) { - if (FREE_COND) - mask |= (POLLOUT | POLLWRNORM); - } else /* if not playing: may play if asked for */ - mask |= (POLLOUT | POLLWRNORM); - } - - return mask; -} - -static ssize_t dvb_video_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - - DEB_EE(("av7110: %p\n",av7110)); - - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { - return -EPERM; - } - - if (av7110->videostate.stream_source!=VIDEO_SOURCE_MEMORY) - return -EPERM; - - return dvb_play(av7110, buf, count, file->f_flags&O_NONBLOCK, 1, 1); -} - -static ssize_t dvb_audio_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - - DEB_EE(("av7110: %p\n",av7110)); - - if (av7110->audiostate.stream_source!=AUDIO_SOURCE_MEMORY) { - printk(KERN_ERR "not audio source memory\n"); - return -EPERM; - } - return dvb_aplay(av7110, buf, count, file->f_flags&O_NONBLOCK, 0); -} - -u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; - -#define MIN_IFRAME 400000 - -static int play_iframe(struct av7110 *av7110, u8 *buf, unsigned int len, int nonblock) -{ - int i, n=1; - - DEB_EE(("av7110: %p\n",av7110)); - - if (!(av7110->playing&RP_VIDEO)) { - if (AV_StartPlay(av7110, RP_VIDEO) < 0) - return -EBUSY; - n=MIN_IFRAME/len+1; - } - - /* setting n always > 1, fixes problems when playing stillframes - consisting of I- and P-Frames */ - n=MIN_IFRAME/len+1; - - /* FIXME: nonblock? */ - dvb_play(av7110, iframe_header, sizeof(iframe_header), 0, 1, 0); - - for (i=0; iipack[1]); - return 0; -} - - -static int dvb_video_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - unsigned long arg=(unsigned long) parg; - int ret=0; - - DEB_EE(("av7110: %p\n",av7110)); - - if ((file->f_flags&O_ACCMODE)==O_RDONLY) { - if ( cmd!=VIDEO_GET_STATUS && cmd!=VIDEO_GET_EVENT && - cmd!=VIDEO_GET_SIZE ) { - return -EPERM; - } - } - - switch (cmd) { - case VIDEO_STOP: - av7110->videostate.play_state=VIDEO_STOPPED; - if (av7110->videostate.stream_source==VIDEO_SOURCE_MEMORY) - AV_Stop(av7110, RP_VIDEO); - else - vidcom(av7110, 0x000e, - av7110->videostate.video_blank ? 0 : 1); - av7110->trickmode=TRICK_NONE; - break; - - case VIDEO_PLAY: - av7110->trickmode=TRICK_NONE; - if (av7110->videostate.play_state==VIDEO_FREEZED) { - av7110->videostate.play_state=VIDEO_PLAYING; - vidcom(av7110, 0x000d, 0); - } - - if (av7110->videostate.stream_source==VIDEO_SOURCE_MEMORY) { - if (av7110->playing==RP_AV) { - outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0); - av7110->playing&=~RP_VIDEO; - } - AV_StartPlay(av7110,RP_VIDEO); - vidcom(av7110, 0x000d, 0); - } else { - //AV_Stop(av7110, RP_VIDEO); - vidcom(av7110, 0x000d, 0); - } - av7110->videostate.play_state=VIDEO_PLAYING; - break; - - case VIDEO_FREEZE: - av7110->videostate.play_state=VIDEO_FREEZED; - if (av7110->playing&RP_VIDEO) - outcom(av7110, COMTYPE_REC_PLAY, __Pause, 0); - else - vidcom(av7110, 0x0102, 1); - av7110->trickmode=TRICK_FREEZE; - break; - - case VIDEO_CONTINUE: - if (av7110->playing&RP_VIDEO) - outcom(av7110, COMTYPE_REC_PLAY, __Continue, 0); - vidcom(av7110, 0x000d, 0); - av7110->videostate.play_state=VIDEO_PLAYING; - av7110->trickmode=TRICK_NONE; - break; - - case VIDEO_SELECT_SOURCE: - av7110->videostate.stream_source=(video_stream_source_t) arg; - break; - - case VIDEO_SET_BLANK: - av7110->videostate.video_blank=(int) arg; - break; - - case VIDEO_GET_STATUS: - memcpy(parg, &av7110->videostate, sizeof(struct video_status)); - break; - - case VIDEO_GET_EVENT: - ret=dvb_video_get_event(av7110, parg, file->f_flags); - break; - - case VIDEO_GET_SIZE: - memcpy(parg, &av7110->video_size, sizeof(video_size_t)); - break; - - case VIDEO_SET_DISPLAY_FORMAT: - { - video_displayformat_t format=(video_displayformat_t) arg; - u16 val=0; - - switch(format) { - case VIDEO_PAN_SCAN: - val=VID_PAN_SCAN_PREF; - break; - - case VIDEO_LETTER_BOX: - val=VID_VC_AND_PS_PREF; - break; - - case VIDEO_CENTER_CUT_OUT: - val=VID_CENTRE_CUT_PREF; - break; - - default: - ret=-EINVAL; - break; - } - if (ret<0) - break; - av7110->videostate.video_format=format; - ret=outcom(av7110, COMTYPE_ENCODER, SetPanScanType, - 1, (u16) val); - break; - } - - case VIDEO_SET_FORMAT: - if (arg>1) { - ret=-EINVAL; - break; - } - av7110->display_ar=arg; - ret=outcom(av7110, COMTYPE_ENCODER, SetMonitorType, - 1, (u16) arg); - break; - - case VIDEO_STILLPICTURE: - { - struct video_still_picture *pic= - (struct video_still_picture *) parg; - av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY; - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); - ret = play_iframe(av7110, pic->iFrame, pic->size, - file->f_flags&O_NONBLOCK); - break; - } - - case VIDEO_FAST_FORWARD: - //note: arg is ignored by firmware - if (av7110->playing&RP_VIDEO) - outcom(av7110, COMTYPE_REC_PLAY, - __Scan_I, 2, AV_PES, 0); - else - vidcom(av7110, 0x16, arg); - av7110->trickmode=TRICK_FAST; - av7110->videostate.play_state=VIDEO_PLAYING; - break; - - case VIDEO_SLOWMOTION: - if (av7110->playing&RP_VIDEO) { - outcom(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); - vidcom(av7110, 0x22, arg); - } else { - vidcom(av7110, 0x0d, 0); - vidcom(av7110, 0x0e, 0); - vidcom(av7110, 0x22, arg); - } - av7110->trickmode=TRICK_SLOW; - av7110->videostate.play_state=VIDEO_PLAYING; - break; - - case VIDEO_GET_CAPABILITIES: - *(int *)parg=VIDEO_CAP_MPEG1| - VIDEO_CAP_MPEG2| - VIDEO_CAP_SYS| - VIDEO_CAP_PROG; - break; - - case VIDEO_CLEAR_BUFFER: - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); - av7110_ipack_reset(&av7110->ipack[1]); - - if (av7110->playing==RP_AV) { - outcom(av7110, COMTYPE_REC_PLAY, - __Play, 2, AV_PES, 0); - if (av7110->trickmode==TRICK_FAST) - outcom(av7110, COMTYPE_REC_PLAY, - __Scan_I, 2, AV_PES, 0); - if (av7110->trickmode==TRICK_SLOW) { - outcom(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); - vidcom(av7110, 0x22, arg); - } - if (av7110->trickmode==TRICK_FREEZE) - vidcom(av7110, 0x000e, 1); - } - break; - - case VIDEO_SET_STREAMTYPE: - - break; - - default: - ret=-ENOIOCTLCMD; - break; - } - return ret; -} - -static int dvb_audio_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - unsigned long arg=(unsigned long) parg; - int ret=0; - - DEB_EE(("av7110: %p\n",av7110)); - - if (((file->f_flags&O_ACCMODE)==O_RDONLY) && - (cmd!=AUDIO_GET_STATUS)) - return -EPERM; - - switch (cmd) { - case AUDIO_STOP: - if (av7110->audiostate.stream_source==AUDIO_SOURCE_MEMORY) - AV_Stop(av7110, RP_AUDIO); - else - audcom(av7110, 1); - av7110->audiostate.play_state=AUDIO_STOPPED; - break; - - case AUDIO_PLAY: - if (av7110->audiostate.stream_source==AUDIO_SOURCE_MEMORY) - AV_StartPlay(av7110, RP_AUDIO); - audcom(av7110, 2); - av7110->audiostate.play_state=AUDIO_PLAYING; - break; - - case AUDIO_PAUSE: - audcom(av7110, 1); - av7110->audiostate.play_state=AUDIO_PAUSED; - break; - - case AUDIO_CONTINUE: - if (av7110->audiostate.play_state==AUDIO_PAUSED) { - av7110->audiostate.play_state=AUDIO_PLAYING; - audcom(av7110, 0x12); - } - break; - - case AUDIO_SELECT_SOURCE: - av7110->audiostate.stream_source=(audio_stream_source_t) arg; - break; - - case AUDIO_SET_MUTE: - { - audcom(av7110, arg ? 1 : 2); - av7110->audiostate.mute_state=(int) arg; - break; - } - - case AUDIO_SET_AV_SYNC: - av7110->audiostate.AV_sync_state=(int) arg; - audcom(av7110, arg ? 0x0f : 0x0e); - break; - - case AUDIO_SET_BYPASS_MODE: - ret=-EINVAL; - break; - - case AUDIO_CHANNEL_SELECT: - av7110->audiostate.channel_select=(audio_channel_select_t) arg; - - switch(av7110->audiostate.channel_select) { - case AUDIO_STEREO: - audcom(av7110, 0x80); - break; - - case AUDIO_MONO_LEFT: - audcom(av7110, 0x100); - break; - - case AUDIO_MONO_RIGHT: - audcom(av7110, 0x200); - break; - - default: - ret=-EINVAL; - break; - } - break; - - case AUDIO_GET_STATUS: - memcpy(parg, &av7110->audiostate, sizeof(struct audio_status)); - break; - - case AUDIO_GET_CAPABILITIES: - *(int *)parg=AUDIO_CAP_LPCM| - AUDIO_CAP_MP1| - AUDIO_CAP_MP2; - break; - - case AUDIO_CLEAR_BUFFER: - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); - av7110_ipack_reset(&av7110->ipack[0]); - if (av7110->playing==RP_AV) - outcom(av7110, COMTYPE_REC_PLAY, - __Play, 2, AV_PES, 0); - break; - case AUDIO_SET_ID: - - break; - case AUDIO_SET_MIXER: - { - struct audio_mixer *amix=(struct audio_mixer *)parg; - - SetVolume(av7110, amix->volume_left, amix->volume_right); - break; - } - case AUDIO_SET_STREAMTYPE: - break; - default: - ret=-ENOIOCTLCMD; - break; - } - return ret; -} - - -static int dvb_video_open(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - int err; - - DEB_EE(("av7110: %p\n",av7110)); - - if ((err=dvb_generic_open(inode, file))<0) - return err; - - if ((file->f_flags & O_ACCMODE) != O_RDONLY) { - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); - av7110->video_blank=1; - av7110->audiostate.AV_sync_state=1; - av7110->videostate.stream_source=VIDEO_SOURCE_DEMUX; - - /* empty event queue */ - av7110->video_events.eventr = av7110->video_events.eventw = 0; - } - - return 0; -} - -static int dvb_video_release(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - - DEB_EE(("av7110: %p\n",av7110)); - - if ((file->f_flags & O_ACCMODE) != O_RDONLY) { - AV_Stop(av7110, RP_VIDEO); - } - - return dvb_generic_release(inode, file); -} - -static int dvb_audio_open(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - int err=dvb_generic_open(inode, file); - - DEB_EE(("av7110: %p\n",av7110)); - - if (err<0) - return err; - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); - av7110->audiostate.stream_source=AUDIO_SOURCE_DEMUX; - return 0; -} - -static int dvb_audio_release(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - struct av7110 *av7110=(struct av7110 *) dvbdev->priv; - - DEB_EE(("av7110: %p\n",av7110)); - - AV_Stop(av7110, RP_AUDIO); - return dvb_generic_release(inode, file); -} - - - -/****************************************************************************** - * driver registration - ******************************************************************************/ - -static struct file_operations dvb_video_fops = { - .owner = THIS_MODULE, - .write = dvb_video_write, - .ioctl = dvb_generic_ioctl, - .open = dvb_video_open, - .release = dvb_video_release, - .poll = dvb_video_poll, -}; - -static struct dvb_device dvbdev_video = { - .priv = 0, - .users = 6, - .readers = 5, /* arbitrary */ - .writers = 1, - .fops = &dvb_video_fops, - .kernel_ioctl = dvb_video_ioctl, -}; - -static struct file_operations dvb_audio_fops = { - .owner = THIS_MODULE, - .write = dvb_audio_write, - .ioctl = dvb_generic_ioctl, - .open = dvb_audio_open, - .release = dvb_audio_release, - .poll = dvb_audio_poll, -}; - -static struct dvb_device dvbdev_audio = { - .priv = 0, - .users = 1, - .writers = 1, - .fops = &dvb_audio_fops, - .kernel_ioctl = dvb_audio_ioctl, -}; - -static struct file_operations dvb_ca_fops = { - .owner = THIS_MODULE, - .read = dvb_ca_read, - .write = dvb_ca_write, - .ioctl = dvb_generic_ioctl, - .open = dvb_ca_open, - .release = dvb_generic_release, - .poll = dvb_ca_poll, -}; - -static struct dvb_device dvbdev_ca = { - .priv = 0, - .users = 1, - .writers = 1, - .fops = &dvb_ca_fops, - .kernel_ioctl = dvb_ca_ioctl, -}; - - -static void av7110_before_after_tune (fe_status_t s, void *data) -{ - struct av7110 *av7110 = data; - - DEB_EE(("av7110: %p\n",av7110)); - - av7110->fe_synced = (s & FE_HAS_LOCK) ? 1 : 0; - - if (av7110->playing) - return; - - if (down_interruptible(&av7110->pid_mutex)) - return; - - if (av7110->fe_synced) { - SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO], - av7110->pids[DMX_PES_AUDIO], - av7110->pids[DMX_PES_TELETEXT], 0, - av7110->pids[DMX_PES_PCR]); - outcom(av7110, COMTYPE_PIDFILTER, Scan, 0); - } else { - SetPIDs(av7110, 0, 0, 0, 0, 0); - outcom(av7110, COMTYPE_PIDFILTER, FlushTSQueue, 0); - } - - up(&av7110->pid_mutex); -} - - -static int av7110_register(struct av7110 *av7110) -{ - int ret, i; - struct dvb_demux *dvbdemux=&av7110->demux; - - DEB_EE(("av7110: %p\n",av7110)); - - if (av7110->registered) - return -1; - - av7110->registered=1; - - dvb_add_frontend_notifier (av7110->dvb_adapter, - av7110_before_after_tune, av7110); - - /** - * init DiSEqC stuff - */ - dvb_add_frontend_ioctls (av7110->dvb_adapter, - av7110_diseqc_ioctl, NULL, av7110); - - av7110->audiostate.AV_sync_state=0; - av7110->audiostate.mute_state=0; - av7110->audiostate.play_state=AUDIO_STOPPED; - av7110->audiostate.stream_source=AUDIO_SOURCE_DEMUX; - av7110->audiostate.channel_select=AUDIO_STEREO; - av7110->audiostate.bypass_mode=0; - - av7110->videostate.video_blank=0; - av7110->videostate.play_state=VIDEO_STOPPED; - av7110->videostate.stream_source=VIDEO_SOURCE_DEMUX; - av7110->videostate.video_format=VIDEO_FORMAT_4_3; - av7110->videostate.display_format=VIDEO_CENTER_CUT_OUT; - av7110->display_ar=VIDEO_FORMAT_4_3; - - dvbdemux->priv = (void *) av7110; - - for (i=0; i<32; i++) - av7110->handle2filter[i]=NULL; - - dvbdemux->filternum = 32; - dvbdemux->feednum = 32; - dvbdemux->start_feed = av7110_start_feed; - dvbdemux->stop_feed = av7110_stop_feed; - dvbdemux->write_to_decoder = av7110_write_to_decoder; - dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | - DMX_MEMORY_BASED_FILTERING); - - dvb_dmx_init(&av7110->demux); - av7110->demux.dmx.get_stc = dvb_get_stc; - - av7110->dmxdev.filternum = 32; - av7110->dmxdev.demux = &dvbdemux->dmx; - av7110->dmxdev.capabilities = 0; - - dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter); - - av7110->hw_frontend.source = DMX_FRONTEND_0; - - ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend); - - if (ret < 0) - return ret; - - av7110->mem_frontend.source = DMX_MEMORY_FE; - - ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend); - - if (ret < 0) - return ret; - - ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, - &av7110->hw_frontend); - if (ret < 0) - return ret; - - init_waitqueue_head(&av7110->video_events.wait_queue); - spin_lock_init(&av7110->video_events.lock); - av7110->video_events.eventw = av7110->video_events.eventr = 0; - av7110->video_events.overflow = 0; - memset(&av7110->video_size, 0, sizeof (video_size_t)); - - dvb_register_device(av7110->dvb_adapter, &av7110->video_dev, - &dvbdev_video, av7110, DVB_DEVICE_VIDEO); - - dvb_register_device(av7110->dvb_adapter, &av7110->audio_dev, - &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); - - dvb_register_device(av7110->dvb_adapter, &av7110->ca_dev, - &dvbdev_ca, av7110, DVB_DEVICE_CA); -#ifdef CONFIG_DVB_AV7110_OSD - dvb_register_device(av7110->dvb_adapter, &av7110->osd_dev, - &dvbdev_osd, av7110, DVB_DEVICE_OSD); -#endif -#ifdef USE_DVB_DSP - dvb->dsp_dev = dvb_register_dsp(dvb_audio_open, - dvb_audio_release, - dvb_audio_ioctl, - dvb_audio_write, - av7110->audio_dev); -#endif -// } - - dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx); - - return 0; -} - - -static void dvb_unregister(struct av7110 *av7110) -{ - struct dvb_demux *dvbdemux=&av7110->demux; - - DEB_EE(("av7110: %p\n",av7110)); - - if (!av7110->registered) - return; - - dvb_net_release(&av7110->dvb_net); - - dvbdemux->dmx.close(&dvbdemux->dmx); - dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend); - dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend); - - dvb_dmxdev_release(&av7110->dmxdev); - dvb_dmx_release(&av7110->demux); - - dvb_remove_frontend_notifier (av7110->dvb_adapter, - av7110_before_after_tune); - - dvb_remove_frontend_ioctls (av7110->dvb_adapter, - av7110_diseqc_ioctl, NULL); - - dvb_unregister_device(av7110->audio_dev); - dvb_unregister_device(av7110->video_dev); - dvb_unregister_device(av7110->osd_dev); - dvb_unregister_device(av7110->ca_dev); -#ifdef USE_DVB_DSP - dvb_unregister_dsp(av7110->dsp_dev); -#endif -// } -} - -static int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num) -{ - struct saa7146_dev *dev = i2c->data; - return saa7146_i2c_transfer(dev, msgs, num, 6); -} - -/**************************************************************************** - * INITIALIZATION - ****************************************************************************/ - -struct saa7146_extension_ioctls ioctls[] = { - { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE }, - { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE }, - { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE }, - { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE }, - { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, - { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, - { 0, 0 } -}; - -static u8 saa7113_init_regs[] = { - 0x02, 0xd0, - 0x03, 0x23, - 0x04, 0x00, - 0x05, 0x00, - 0x06, 0xe9, - 0x07, 0x0d, - 0x08, 0x98, - 0x09, 0x02, - 0x0a, 0x80, - 0x0b, 0x40, - 0x0c, 0x40, - 0x0d, 0x00, - 0x0e, 0x01, - 0x0f, 0x7c, - 0x10, 0x48, - 0x11, 0x0c, - 0x12, 0x8b, - 0x13, 0x1a, - 0x14, 0x00, - 0x15, 0x00, - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1b, 0x00, - 0x1c, 0x00, - 0x1d, 0x00, - 0x1e, 0x00, - - 0x41, 0x77, - 0x42, 0x77, - 0x43, 0x77, - 0x44, 0x77, - 0x45, 0x77, - 0x46, 0x77, - 0x47, 0x77, - 0x48, 0x77, - 0x49, 0x77, - 0x4a, 0x77, - 0x4b, 0x77, - 0x4c, 0x77, - 0x4d, 0x77, - 0x4e, 0x77, - 0x4f, 0x77, - 0x50, 0x77, - 0x51, 0x77, - 0x52, 0x77, - 0x53, 0x77, - 0x54, 0x77, - 0x55, 0x77, - 0x56, 0x77, - 0x57, 0xff, - - 0xff -}; - - -static struct saa7146_ext_vv av7110_vv_data_st; -static struct saa7146_ext_vv av7110_vv_data_c; - -static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext) -{ - struct av7110 *av7110 = NULL; - int ret = 0; - - if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) { - printk ("%s: out of memory!\n", __FUNCTION__); - return -ENOMEM; - } - - memset(av7110, 0, sizeof(struct av7110)); - - av7110->card_name = (char*)pci_ext->ext_priv; - (struct av7110*)dev->ext_priv = av7110; - - DEB_EE(("dev: %p, av7110: %p\n",dev,av7110)); - - av7110->dev=(struct saa7146_dev *)dev; - dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name); - - /* the Siemens DVB needs this if you want to have the i2c chips - get recognized before the main driver is fully loaded */ - saa7146_write(dev, GPIO_CTRL, 0x500000); - - saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ - - av7110->i2c_bus = dvb_register_i2c_bus (master_xfer, dev, - av7110->dvb_adapter, 0); - - if (!av7110->i2c_bus) { - dvb_unregister_adapter (av7110->dvb_adapter); - kfree(av7110); - return -ENOMEM; - } - - ttpci_eeprom_parse_mac(av7110->i2c_bus); - - saa7146_write(dev, PCI_BT_V1, 0x1c00101f); - saa7146_write(dev, BCS_CTRL, 0x80400040); - - /* set dd1 stream a & b */ - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, DD1_INIT, 0x03000000); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - /* upload all */ - saa7146_write(dev, MC2, 0x077c077c); - saa7146_write(dev, GPIO_CTRL, 0x000000); - - tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110); - tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110); - - sema_init(&av7110->pid_mutex, 1); - - /* locks for data transfers from/to AV7110 */ - spin_lock_init (&av7110->debilock); - sema_init(&av7110->dcomlock, 1); - av7110->debilock=SPIN_LOCK_UNLOCKED; - av7110->debitype=-1; - - /* default OSD window */ - av7110->osdwin=1; - - /* ARM "watchdog" */ - init_waitqueue_head(&av7110->arm_wait); - av7110->arm_thread=0; - - av7110->vidmode=VIDEO_MODE_PAL; - - av7110_ipack_init(&av7110->ipack[0], IPACKS, play_audio_cb); - av7110->ipack[0].data=(void *) av7110; - av7110_ipack_init(&av7110->ipack[1], IPACKS, play_video_cb); - av7110->ipack[1].data=(void *) av7110; - - - /* allocate and init buffers */ - av7110->debi_virt = pci_alloc_consistent(dev->pci, 8192, - &av7110->debi_bus); - if (!av7110->debi_virt) { - ret = -ENOMEM; - goto err; - } - - av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS); - if (!av7110->iobuf) { - ret = -ENOMEM; - goto err; - } - - dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN); - dvb_ringbuffer_init(&av7110->aout, av7110->iobuf+AVOUTLEN, AOUTLEN); - - /* init BMP buffer */ - av7110->bmpbuf=av7110->iobuf+AVOUTLEN+AOUTLEN; - init_waitqueue_head(&av7110->bmpq); - - av7110->kbuf[0]=(u8 *)(av7110->iobuf+AVOUTLEN+AOUTLEN+BMPLEN); - av7110->kbuf[1]=av7110->kbuf[0]+2*IPACKS; - - /* CI link layer buffers */ - ci_ll_init(&av7110->ci_rbuffer, &av7110->ci_wbuffer, 8192); - - /* handle different card types */ - - /* load firmware into AV7110 cards */ - - bootarm(av7110); - firmversion(av7110); - - if (FW_VERSION(av7110->arm_app)<0x2501) - printk ("av7110: Warning, firmware version 0x%04x is too old. " - "System might be unstable!\n", FW_VERSION(av7110->arm_app)); - - kernel_thread(arm_thread, (void *) av7110, 0); - - /* set internal volume control to maximum */ - av7110->adac_type = DVB_ADAC_TI; - SetVolume(av7110, 0xff, 0xff); - - VidMode(av7110, vidmode); - - /* remaining inits according to card and frontend type */ - av7110->has_analog_tuner = 0; - av7110->current_input = 0; - if (i2c_writereg(av7110, 0x20, 0x00, 0x00)==1) { - printk ("av7110(%d): Crystal audio DAC detected\n", - av7110->dvb_adapter->num); - av7110->adac_type = DVB_ADAC_CRYSTAL; - i2c_writereg(av7110, 0x20, 0x01, 0xd2); - i2c_writereg(av7110, 0x20, 0x02, 0x49); - i2c_writereg(av7110, 0x20, 0x03, 0x00); - i2c_writereg(av7110, 0x20, 0x04, 0x00); - - /** - * some special handling for the Siemens DVB-C cards... - */ - } else if (i2c_writereg(av7110, 0x80, 0x0, 0x80) == 1 - && i2c_writereg(av7110, 0x80, 0x0, 0) == 1) { - u16 version1, version2; - printk ("av7110(%d): DVB-C analog module detected, " - "initializing MSP3400\n", - av7110->dvb_adapter->num); - av7110->adac_type = DVB_ADAC_MSP; - dvb_delay(100); // the probing above resets the msp... - msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); - msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); - printk("av7110(%d): MSP3400 version 0x%04x 0x%04x\n", - av7110->dvb_adapter->num, version1, version2); - msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00); - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone - msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source - msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source - msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume - msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume - msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x4800); // prescale SCART - - if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) { - INFO(("saa7113 not accessible.\n")); - } - else { - u8 *i = saa7113_init_regs; - av7110->has_analog_tuner = 1; - /* init the saa7113 */ - while (*i != 0xff) { - if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) { - printk("av7110(%d): saa7113 initialization failed", - av7110->dvb_adapter->num); - break; - } - i += 2; - } - /* setup msp for analog sound: B/G Dual-FM */ - msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 3); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 4); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 0); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 3); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG - msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz - msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI - msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz - msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI - msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2 - } - - memcpy(standard,dvb_standard,sizeof(struct saa7146_standard)*2); - /* set dd1 stream a & b */ - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, DD1_INIT, 0x03000700); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - } - else if (dev->pci->subsystem_vendor == 0x110a) { - printk("av7110(%d): DVB-C w/o analog module detected\n", - av7110->dvb_adapter->num); - av7110->adac_type = DVB_ADAC_NONE; - } - else { - av7110->adac_type = adac; - printk("av7110(%d): adac type set to %d\n", - av7110->dvb_adapter->num, av7110->adac_type); - } - - if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { - // switch DVB SCART on - outcom(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); - outcom(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1); - if (rgb_on) - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16 - //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8 - } - - SetVolume(av7110, 0xff, 0xff); - - av7110_setup_irc_config (av7110, 0); - av7110_register(av7110); - - /* special case DVB-C: these cards have an analog tuner - plus need some special handling, so we have separate - saa7146_ext_vv data for these... */ - if (0 != av7110->has_analog_tuner) { - ret = saa7146_vv_init(dev, &av7110_vv_data_c); - } else { - ret = saa7146_vv_init(dev, &av7110_vv_data_st); - } - - if ( 0 != ret) { - ERR(("cannot init capture device. skipping.\n")); - ret = -ENODEV; - goto err; - } - - if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) { - ERR(("cannot register capture device. skipping.\n")); - ret = -ENODEV; - goto video_err; - } - - if (0 != av7110->has_analog_tuner) { - if( 0 != saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { - ERR(("cannot register vbi v4l2 device. skipping.\n")); - } - /* we use this to remember that this dvb-c card cannot do vbi */ - av7110->has_analog_tuner = 2; - } - - printk(KERN_INFO "av7110: found av7110-%d.\n",av7110_num); - av7110_num++; - return 0; - -video_err: - saa7146_vv_release(dev); - -err: - if (NULL != av7110 ) { - kfree(av7110); - } - if (NULL != av7110->debi_virt) { - pci_free_consistent(dev->pci, 8192, av7110->debi_virt, av7110->debi_bus); - } - if (NULL != av7110->iobuf) { - vfree(av7110->iobuf); - } - - dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, - av7110->i2c_bus->id); - - dvb_unregister_adapter (av7110->dvb_adapter); - - return ret; -} - -static int av7110_detach (struct saa7146_dev* saa) -{ - struct av7110 *av7110 = (struct av7110*)saa->ext_priv; - DEB_EE(("av7110: %p\n",av7110)); - - saa7146_unregister_device(&av7110->v4l_dev, saa); - if (2 == av7110->has_analog_tuner) { - saa7146_unregister_device(&av7110->vbi_dev, saa); - } - - av7110->arm_rmmod=1; - wake_up_interruptible(&av7110->arm_wait); - - while (av7110->arm_thread) - dvb_delay(1); - - dvb_unregister(av7110); - - IER_DISABLE(saa, (MASK_19 | MASK_03)); -// saa7146_write (av7110->dev, IER, -// saa7146_read(av7110->dev, IER) & ~(MASK_19 | MASK_03)); - - saa7146_write(av7110->dev, ISR,(MASK_19 | MASK_03)); - - ci_ll_release(&av7110->ci_rbuffer, &av7110->ci_wbuffer); - av7110_ipack_free(&av7110->ipack[0]); - av7110_ipack_free(&av7110->ipack[1]); - vfree(av7110->iobuf); - pci_free_consistent(saa->pci, 8192, av7110->debi_virt, - av7110->debi_bus); - - dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id); - dvb_unregister_adapter (av7110->dvb_adapter); - - kfree (av7110); - - saa->ext_priv = NULL; - av7110_num--; - - return 0; -} - - -static void av7110_irq(struct saa7146_dev* dev, u32 *isr) -{ - struct av7110 *av7110 = (struct av7110*)dev->ext_priv; - -// DEB_INT(("dev: %p, av7110: %p\n",dev,av7110)); - - if (*isr & MASK_19) - tasklet_schedule (&av7110->debi_tasklet); - - if (*isr & MASK_03) - tasklet_schedule (&av7110->gpio_tasklet); -} - - -/* FIXME: these values are experimental values that look better than the - values from the latest "official" driver -- at least for me... (MiHu) */ -static struct saa7146_standard standard[] = { - { - .name = "PAL", .id = V4L2_STD_PAL_BG, - .v_offset = 0x15, .v_field = 288, .v_calc = 576, - .h_offset = 0x4a, .h_pixels = 708, .h_calc = 709, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 0x10, .v_field = 244, .v_calc = 480, - .h_offset = 0x40, .h_pixels = 708, .h_calc = 709, - .v_max_out = 480, .h_max_out = 640, - } -}; - -static struct saa7146_standard analog_standard[] = { - { - .name = "PAL", .id = V4L2_STD_PAL_BG, - .v_offset = 0x18 /* 0 */ , .v_field = 288, .v_calc = 576, - .h_offset = 0x08, .h_pixels = 708, .h_calc = 709, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 0x10, .v_field = 244, .v_calc = 480, - .h_offset = 0x40, .h_pixels = 708, .h_calc = 709, - .v_max_out = 480, .h_max_out = 640, - } -}; - -static struct saa7146_standard dvb_standard[] = { - { - .name = "PAL", .id = V4L2_STD_PAL_BG, - .v_offset = 0x14, .v_field = 288, .v_calc = 576, - .h_offset = 0x4a, .h_pixels = 708, .h_calc = 709, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 0x10, .v_field = 244, .v_calc = 480, - .h_offset = 0x40, .h_pixels = 708, .h_calc = 709, - .v_max_out = 480, .h_max_out = 640, - } -}; - -static struct saa7146_extension av7110_extension; - -#define MAKE_AV7110_INFO(x_var,x_name) \ -static struct saa7146_pci_extension_data x_var = { \ - .ext_priv = x_name, \ - .ext = &av7110_extension } - -MAKE_AV7110_INFO(fs_1_5, "Siemens cable card PCI rev1.5"); -MAKE_AV7110_INFO(fs_1_3, "Siemens/Technotrend/Hauppauge PCI rev1.3"); -MAKE_AV7110_INFO(tt_1_6, "Technotrend/Hauppauge PCI rev1.3 or 1.6"); -MAKE_AV7110_INFO(tt_2_1, "Technotrend/Hauppauge PCI rev2.1"); -MAKE_AV7110_INFO(tt_t, "Technotrend/Hauppauge PCI DVB-T"); -MAKE_AV7110_INFO(unkwn0, "Technotrend/Hauppauge PCI rev?(unknown0)?"); -MAKE_AV7110_INFO(unkwn1, "Technotrend/Hauppauge PCI rev?(unknown1)?"); -MAKE_AV7110_INFO(unkwn2, "Technotrend/Hauppauge PCI rev?(unknown2)?"); -MAKE_AV7110_INFO(nexus, "Technotrend/Hauppauge Nexus PCI DVB-S"); -MAKE_AV7110_INFO(dvboc11,"Octal/Technotrend DVB-C for iTV"); - -static struct pci_device_id pci_tbl[] = { - MAKE_EXTENSION_PCI(fs_1_5, 0x110a, 0xffff), - MAKE_EXTENSION_PCI(fs_1_5, 0x110a, 0x0000), - MAKE_EXTENSION_PCI(fs_1_3, 0x13c2, 0x0000), - MAKE_EXTENSION_PCI(unkwn0, 0x13c2, 0x1002), - MAKE_EXTENSION_PCI(tt_1_6, 0x13c2, 0x0001), - MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0002), - MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0003), - MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0004), - MAKE_EXTENSION_PCI(tt_1_6, 0x13c2, 0x0006), - MAKE_EXTENSION_PCI(tt_t, 0x13c2, 0x0008), - MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x1102), - MAKE_EXTENSION_PCI(unkwn1, 0xffc2, 0x0000), - MAKE_EXTENSION_PCI(unkwn2, 0x00a1, 0x00a1), - MAKE_EXTENSION_PCI(nexus, 0x00a1, 0xa1a0), - MAKE_EXTENSION_PCI(dvboc11,0x13c2, 0x000a), - { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) -{ - struct av7110 *av7110 = (struct av7110*)dev->ext_priv; - if (std->id == V4L2_STD_PAL) { - av7110->vidmode = VIDEO_MODE_PAL; - SetMode(av7110, av7110->vidmode); - } - else if (std->id == V4L2_STD_NTSC) { - av7110->vidmode = VIDEO_MODE_NTSC; - SetMode(av7110, av7110->vidmode); - } - else - return -1; - - return 0; -} - - -static struct saa7146_ext_vv av7110_vv_data_st = { - .inputs = 1, - .audios = 1, - .capabilities = 0, - .flags = 0, - - .stds = &standard[0], - .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), - .std_callback = &std_callback, - - .ioctls = &ioctls[0], - .ioctl = av7110_ioctl, -}; - -static struct saa7146_ext_vv av7110_vv_data_c = { - .inputs = 1, - .audios = 1, - .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, - .flags = SAA7146_USE_PORT_B_FOR_VBI, - - .stds = &standard[0], - .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), - .std_callback = &std_callback, - - .ioctls = &ioctls[0], - .ioctl = av7110_ioctl, -}; - - -static struct saa7146_extension av7110_extension = { - .name = "dvb\0", - .flags = SAA7146_I2C_SHORT_DELAY, - - .module = THIS_MODULE, - .pci_tbl = &pci_tbl[0], - .attach = av7110_attach, - .detach = av7110_detach, - - .irq_mask = MASK_19|MASK_03, - .irq_func = av7110_irq, -}; - - -static int __init av7110_init(void) -{ - int retval; - retval = saa7146_register_extension(&av7110_extension); - if (retval) - goto failed_saa7146_register; - - retval = av7110_ir_init(); - if (retval) - goto failed_av7110_ir_init; - return 0; -failed_av7110_ir_init: - saa7146_unregister_extension(&av7110_extension); -failed_saa7146_register: - return retval; -} - - -static void __exit av7110_exit(void) -{ - av7110_ir_exit(); - saa7146_unregister_extension(&av7110_extension); -} - -module_init(av7110_init); -module_exit(av7110_exit); - -MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by " - "Siemens, Technotrend, Hauppauge"); -MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); -MODULE_LICENSE("GPL"); - -MODULE_PARM(av7110_debug,"i"); -MODULE_PARM(vidmode,"i"); -MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC"); -MODULE_PARM(pids_off,"i"); -MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed"); -MODULE_PARM(adac,"i"); -MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)"); -MODULE_PARM(hw_sections, "i"); -MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware"); -MODULE_PARM(rgb_on, "i"); -MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control" - " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB"); diff -Nru a/drivers/media/dvb/ttpci/fdump.c b/drivers/media/dvb/ttpci/fdump.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/media/dvb/ttpci/fdump.c Sun Jan 4 17:36:11 2004 @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + unsigned char buf[8]; + unsigned int i, count, bytes = 0; + FILE *fd_in, *fd_out; + + if (argc != 4) { + fprintf(stderr, "\n\tusage: %s \n\n", argv[0]); + return -1; + } + + fd_in = fopen(argv[1], "rb"); + if (fd_in == NULL) { + fprintf(stderr, "firmware file '%s' not found\n", argv[1]); + return -1; + } + + fd_out = fopen(argv[3], "w+"); + if (fd_out == NULL) { + fprintf(stderr, "cannot create output file '%s'\n", argv[3]); + return -1; + } + + fprintf(fd_out, "\n#include \n\nu8 %s [] = {", argv[2]); + + while ((count = fread(buf, 1, 8, fd_in)) > 0) { + fprintf(fd_out, "\n\t"); + for (i = 0; i < count; i++, bytes++) + fprintf(fd_out, "0x%02x, ", buf[i]); + } + + fprintf(fd_out, "\n};\n\n"); + + fclose(fd_in); + fclose(fd_out); + + return 0; +} diff -Nru a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c Sun Jan 4 17:36:11 2004 @@ -2,7 +2,7 @@ * TTUSB DVB driver * * Copyright (c) 2002 Holger Waechtler - * Copyright (c) 2003 Felix Domke + * Copyright (c) 2003 Felix Domke * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff -Nru a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.mod.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.mod.c --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.mod.c Sun Jan 4 17:36:11 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,51 +0,0 @@ -#include -#include -#include - -MODULE_INFO(vermagic, VERMAGIC_STRING); - -static const struct modversion_info ____versions[] -__attribute__((section("__versions"))) = { - { 0x98a034c6, "struct_module" }, - { 0x1b636da2, "usb_deregister" }, - { 0x9c655b4f, "usb_register" }, - { 0x37a0cba, "kfree" }, - { 0xc490b263, "dvb_unregister_adapter" }, - { 0xf0ca7c9b, "dvb_unregister_i2c_bus" }, - { 0x213a4973, "dvb_dmxdev_release" }, - { 0x12014018, "dvb_net_release" }, - { 0x616af636, "dvb_net_init" }, - { 0x6a8b7cf7, "dvb_dmx_release" }, - { 0x107a341d, "dvb_dmxdev_init" }, - { 0x8fa22872, "dvb_dmx_init" }, - { 0x5117ed38, "dvb_add_frontend_ioctls" }, - { 0xfc17c7e7, "dvb_register_i2c_bus" }, - { 0x3ad6f025, "dvb_register_adapter" }, - { 0x7ac96080, "kmem_cache_alloc" }, - { 0xa73704a, "malloc_sizes" }, - { 0xdfcbe89f, "usb_set_interface" }, - { 0x4f0eac15, "usb_reset_configuration" }, - { 0x1b49153f, "usb_unlink_urb" }, - { 0xf136026d, "usb_alloc_urb" }, - { 0xe6f8a15d, "dma_alloc_coherent" }, - { 0xe8d874ea, "dma_free_coherent" }, - { 0x8ee31378, "usb_free_urb" }, - { 0x53e02b2e, "usb_submit_urb" }, - { 0xda02d67, "jiffies" }, - { 0x4f7c0ba8, "dvb_dmx_swfilter_packets" }, - { 0x9d669763, "memcpy" }, - { 0xd22b546, "__up_wakeup" }, - { 0x1b7d4074, "printk" }, - { 0x85eee601, "usb_bulk_msg" }, - { 0x28c3bbf5, "__down_failed_interruptible" }, - { 0xd533bec7, "__might_sleep" }, -}; - -static const char __module_depends[] -__attribute_used__ -__attribute__((section(".modinfo"))) = -"depends=usbcore,dvb-core"; - -MODULE_ALIAS("usb:v0B48p1003dl*dh*dc*dsc*dp*ic*isc*ip*"); -MODULE_ALIAS("usb:v0B48p1004dl*dh*dc*dsc*dp*ic*isc*ip*"); -MODULE_ALIAS("usb:v0B48p1005dl*dh*dc*dsc*dp*ic*isc*ip*"); diff -Nru a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig --- a/drivers/media/dvb/ttusb-dec/Kconfig Sun Jan 4 17:36:11 2004 +++ b/drivers/media/dvb/ttusb-dec/Kconfig Sun Jan 4 17:36:11 2004 @@ -13,15 +13,6 @@ The DEC devices require firmware in order to boot into a mode in which they are slaves to the PC. See - linux/Documentation/dvb/FIRMWARE for details. - - The firmware can be obtained and put into the default - locations as follows: - - wget http://hauppauge.lightpath.net/de/dec215a.exe - unzip -j dec215a.exe Software/Oem/STB/App/Boot/STB_PC_T.bin - mv STB_PC_T.bin /usr/lib/hotplug/firmware/dec2000t.bin - unzip -j dec215a.exe Software/Oem/STB/App/Boot/STB_PC_S.bin - mv STB_PC_S.bin /usr/lib/hotplug/firmware/dec3000s.bin + linux/Documentation/dvb/ttusb-dec.txt for details. Say Y if you own such a device and want to use it. diff -Nru a/drivers/media/dvb/ttusb-dec/dec2000_frontend.c b/drivers/media/dvb/ttusb-dec/dec2000_frontend.c --- a/drivers/media/dvb/ttusb-dec/dec2000_frontend.c Sun Jan 4 17:36:11 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,178 +0,0 @@ -/* - * TTUSB DEC-2000-t Frontend - * - * Copyright (C) 2003 Alex Woods - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the 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 -#include - -#include "dvb_frontend.h" -#include "dvb_functions.h" - -static int debug = 0; - -#define dprintk if (debug) printk - -static struct dvb_frontend_info dec2000_frontend_info = { - .name = "TechnoTrend/Hauppauge DEC-2000-t Frontend", - .type = FE_OFDM, - .frequency_min = 51000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .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_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO, -}; - -static int dec2000_frontend_ioctl(struct dvb_frontend *fe, unsigned int cmd, - void *arg) -{ - dprintk("%s\n", __FUNCTION__); - - switch (cmd) { - - case FE_GET_INFO: - dprintk("%s: FE_GET_INFO\n", __FUNCTION__); - memcpy(arg, &dec2000_frontend_info, - sizeof (struct dvb_frontend_info)); - break; - - case FE_READ_STATUS: { - fe_status_t *status = (fe_status_t *)arg; - dprintk("%s: FE_READ_STATUS\n", __FUNCTION__); - *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | - FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; - break; - } - - case FE_READ_BER: { - u32 *ber = (u32 *)arg; - dprintk("%s: FE_READ_BER\n", __FUNCTION__); - *ber = 0; - return -ENOSYS; - break; - } - - case FE_READ_SIGNAL_STRENGTH: { - dprintk("%s: FE_READ_SIGNAL_STRENGTH\n", __FUNCTION__); - *(s32 *)arg = 0xFF; - return -ENOSYS; - break; - } - - case FE_READ_SNR: - dprintk("%s: FE_READ_SNR\n", __FUNCTION__); - *(s32 *)arg = 0; - return -ENOSYS; - break; - - case FE_READ_UNCORRECTED_BLOCKS: - dprintk("%s: FE_READ_UNCORRECTED_BLOCKS\n", __FUNCTION__); - *(u32 *)arg = 0; - return -ENOSYS; - break; - - case FE_SET_FRONTEND:{ - struct dvb_frontend_parameters *p = - (struct dvb_frontend_parameters *)arg; - u8 b[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }; - u32 freq; - struct i2c_msg msg = { addr: 0x71, flags: 0, len:20 }; - - dprintk("%s: FE_SET_FRONTEND\n", __FUNCTION__); - - dprintk(" frequency->%d\n", p->frequency); - dprintk(" symbol_rate->%d\n", - p->u.qam.symbol_rate); - dprintk(" inversion->%d\n", p->inversion); - - freq = htonl(p->frequency / 1000); - memcpy(&b[4], &freq, sizeof (int)); - msg.buf = b; - fe->i2c->xfer(fe->i2c, &msg, 1); - - break; - } - - case FE_GET_FRONTEND: - dprintk("%s: FE_GET_FRONTEND\n", __FUNCTION__); - break; - - case FE_SLEEP: - dprintk("%s: FE_SLEEP\n", __FUNCTION__); - return -ENOSYS; - break; - - case FE_INIT: - dprintk("%s: FE_INIT\n", __FUNCTION__); - break; - - case FE_RESET: - dprintk("%s: FE_RESET\n", __FUNCTION__); - break; - - default: - dprintk("%s: unknown IOCTL (0x%X)\n", __FUNCTION__, cmd); - return -EINVAL; - - } - - return 0; -} - -static int dec2000_frontend_attach(struct dvb_i2c_bus *i2c, void **data) -{ - dprintk("%s\n", __FUNCTION__); - - return dvb_register_frontend(dec2000_frontend_ioctl, i2c, NULL, - &dec2000_frontend_info); -} - -static void dec2000_frontend_detach(struct dvb_i2c_bus *i2c, void *data) -{ - dprintk("%s\n", __FUNCTION__); - - dvb_unregister_frontend(dec2000_frontend_ioctl, i2c); -} - -static int __init dec2000_frontend_init(void) -{ - return dvb_register_i2c_device(THIS_MODULE, dec2000_frontend_attach, - dec2000_frontend_detach); -} - -static void __exit dec2000_frontend_exit(void) -{ - dvb_unregister_i2c_device(dec2000_frontend_attach); -} - -module_init(dec2000_frontend_init); -module_exit(dec2000_frontend_exit); - -MODULE_DESCRIPTION("TechnoTrend/Hauppauge DEC-2000-t Frontend"); -MODULE_AUTHOR("Alex Woods -#include -#include -#include -#include - - -int main (int argc, char **argv) -{ - unsigned char buf[8]; - unsigned int i, count, bytes = 0; - int fd; - - if (argc != 3) { - fprintf (stderr, "\n\tusage: %s \n\n", - argv[0]); - return -1; - } - - fd = open (argv[1], O_RDONLY); - - printf ("\n#include \n\nu8 %s [] __initdata = {", - argv[2]); - - while ((count = read (fd, buf, 8)) > 0) { - printf ("\n\t"); - for (i=0;i #include #include +#include #include #include #include @@ -59,13 +60,18 @@ #define LOF_HI 10600000 #define LOF_LO 9750000 -enum ttusb_model { +enum ttusb_dec_model { TTUSB_DEC2000T, TTUSB_DEC3000S }; +enum ttusb_dec_packet_type { + PACKET_AV_PES, + PACKET_SECTION +}; + struct ttusb_dec { - enum ttusb_model model; + enum ttusb_dec_model model; char *model_name; char *firmware_name; @@ -97,10 +103,14 @@ int iso_stream_count; struct semaphore iso_sem; - u8 av_pes[MAX_AV_PES_LENGTH + 4]; - int av_pes_state; - int av_pes_length; - int av_pes_payload_length; + u8 packet[MAX_AV_PES_LENGTH + 4]; + enum ttusb_dec_packet_type packet_type; + int packet_state; + int packet_length; + int packet_payload_length; + + int av_pes_stream_count; + int filter_stream_count; struct dvb_filter_pes2ts a_pes2ts; struct dvb_filter_pes2ts v_pes2ts; @@ -113,6 +123,9 @@ struct tasklet_struct urb_tasklet; spinlock_t urb_frame_list_lock; + struct list_head filter_info_list; + spinlock_t filter_info_list_lock; + int active; /* Loaded successfully */ }; @@ -122,6 +135,12 @@ struct list_head urb_frame_list; }; +struct filter_info { + u8 stream_id; + struct dvb_demux_filter *filter; + struct list_head filter_info_list; +}; + static struct dvb_frontend_info dec2000t_frontend_info = { .name = "TechnoTrend/Hauppauge DEC2000-t Frontend", .type = FE_OFDM, @@ -178,8 +197,8 @@ printk("\n"); } - result = usb_bulk_msg(dec->udev, dec->command_pipe, b, sizeof(b), - &actual_len, HZ); + result = usb_bulk_msg(dec->udev, dec->command_pipe, b, + sizeof(b), &actual_len, HZ); if (result) { printk("%s: command bulk message failed: error %d\n", @@ -188,8 +207,8 @@ return result; } - result = usb_bulk_msg(dec->udev, dec->result_pipe, c, sizeof(c), - &actual_len, HZ); + result = usb_bulk_msg(dec->udev, dec->result_pipe, c, + sizeof(c), &actual_len, HZ); if (result) { printk("%s: result bulk message failed: error %d\n", @@ -226,8 +245,9 @@ static void ttusb_dec_set_pids(struct ttusb_dec *dec) { - u8 b[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff }; + u8 b[] = { 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff }; u16 pcr = htons(dec->pid[DMX_PES_PCR]); u16 audio = htons(dec->pid[DMX_PES_AUDIO]); @@ -252,34 +272,13 @@ static void ttusb_dec_process_av_pes(struct ttusb_dec * dec, u8 * av_pes, int length) { - int i; - u16 csum = 0; - u8 c; - - if (length < 16) { - printk("%s: packet too short.\n", __FUNCTION__); + if (length < 8) { + printk("%s: packet too short - discarding\n", __FUNCTION__); return; } - for (i = 0; i < length; i += 2) { - csum ^= le16_to_cpup((u16 *)(av_pes + i)); - c = av_pes[i]; - av_pes[i] = av_pes[i + 1]; - av_pes[i + 1] = c; - } - - if (csum) { - printk("%s: checksum failed.\n", __FUNCTION__); - return; - } - - if (length > 8 + MAX_AV_PES_LENGTH + 4) { - printk("%s: packet too long.\n", __FUNCTION__); - return; - } - - if (!(av_pes[0] == 'A' && av_pes[1] == 'V')) { - printk("%s: invalid AV_PES packet.\n", __FUNCTION__); + if (length > 8 + MAX_AV_PES_LENGTH) { + printk("%s: packet too long - discarding\n", __FUNCTION__); return; } @@ -296,16 +295,14 @@ &av_pes[12], prebytes); dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes, - dec->v_pes_length + prebytes, - 1); + dec->v_pes_length + prebytes, 1); } if (av_pes[5] & 0x10) { dec->v_pes[7] = 0x80; dec->v_pes[8] = 0x05; - dec->v_pes[9] = 0x21 | - ((av_pes[8] & 0xc0) >> 5); + dec->v_pes[9] = 0x21 | ((av_pes[8] & 0xc0) >> 5); dec->v_pes[10] = ((av_pes[8] & 0x3f) << 2) | ((av_pes[9] & 0xc0) >> 6); dec->v_pes[11] = 0x01 | @@ -313,18 +310,17 @@ ((av_pes[10] & 0x80) >> 6); dec->v_pes[12] = ((av_pes[10] & 0x7f) << 1) | ((av_pes[11] & 0xc0) >> 7); - dec->v_pes[13] = 0x01 | - ((av_pes[11] & 0x7f) << 1); + dec->v_pes[13] = 0x01 | ((av_pes[11] & 0x7f) << 1); memcpy(&dec->v_pes[14], &av_pes[12 + prebytes], - length - 16 - prebytes); - dec->v_pes_length = 14 + length - 16 - prebytes; + length - 12 - prebytes); + dec->v_pes_length = 14 + length - 12 - prebytes; } else { dec->v_pes[7] = 0x00; dec->v_pes[8] = 0x00; - memcpy(&dec->v_pes[9], &av_pes[8], length - 12); - dec->v_pes_length = 9 + length - 12; + memcpy(&dec->v_pes[9], &av_pes[8], length - 8); + dec->v_pes_length = 9 + length - 8; } dec->v_pes_postbytes = postbytes; @@ -348,7 +344,7 @@ } case 0x02: /* MainAudioStream */ - dvb_filter_pes2ts(&dec->a_pes2ts, &av_pes[8], length - 12, + dvb_filter_pes2ts(&dec->a_pes2ts, &av_pes[8], length - 8, av_pes[5] & 0x10); break; @@ -356,93 +352,194 @@ printk("%s: unknown AV_PES type: %02x.\n", __FUNCTION__, av_pes[2]); break; + } +} + +static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet, + int length) +{ + struct list_head *item; + struct filter_info *finfo; + struct dvb_demux_filter *filter = NULL; + unsigned long flags; + u8 sid; + + sid = packet[1]; + spin_lock_irqsave(&dec->filter_info_list_lock, flags); + for (item = dec->filter_info_list.next; item != &dec->filter_info_list; + item = item->next) { + finfo = list_entry(item, struct filter_info, filter_info_list); + if (finfo->stream_id == sid) { + filter = finfo->filter; + break; + } + } + spin_unlock_irqrestore(&dec->filter_info_list_lock, flags); + + if (filter) + filter->feed->cb.sec(&packet[2], length - 2, NULL, 0, + &filter->filter, DMX_OK); +} + +static void ttusb_dec_process_packet(struct ttusb_dec *dec) +{ + int i; + u16 csum = 0; + + if (dec->packet_length % 2) { + printk("%s: odd sized packet - discarding\n", __FUNCTION__); + return; + } + + for (i = 0; i < dec->packet_length; i += 2) + csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]); + + if (csum) { + printk("%s: checksum failed - discarding\n", __FUNCTION__); + return; + } + + switch (dec->packet_type) { + case PACKET_AV_PES: + if (dec->av_pes_stream_count) + ttusb_dec_process_av_pes(dec, dec->packet, + dec->packet_payload_length); + break; + case PACKET_SECTION: + if (dec->filter_stream_count) + ttusb_dec_process_filter(dec, dec->packet, + dec->packet_payload_length); + break; + } +} + +static void swap_bytes(u8 *b, int length) +{ + u8 c; + + length -= length % 2; + for (; length; b += 2, length -= 2) { + c = *b; + *b = *(b + 1); + *(b + 1) = c; } } static void ttusb_dec_process_urb_frame(struct ttusb_dec * dec, u8 * b, int length) { + swap_bytes(b, length); + while (length) { - switch (dec->av_pes_state) { + switch (dec->packet_state) { case 0: case 1: + case 2: + if (*b++ == 0xaa) + dec->packet_state++; + else + dec->packet_state = 0; + + length--; + break; + case 3: - if (*b++ == 0xaa) { - dec->av_pes_state++; - if (dec->av_pes_state == 4) - dec->av_pes_length = 0; + if (*b++ == 0x00) { + dec->packet_state++; + dec->packet_length = 0; } else { - dec->av_pes_state = 0; + dec->packet_state = 0; } length--; break; - case 2: - if (*b++ == 0x00) { - dec->av_pes_state++; + case 4: + dec->packet[dec->packet_length++] = *b++; + + if (dec->packet_length == 3) { + if (dec->packet[0] == 'A' && + dec->packet[1] == 'V') { + dec->packet_type = PACKET_AV_PES; + dec->packet_state++; + } else if (dec->packet[0] == 'S') { + dec->packet_type = PACKET_SECTION; + dec->packet_state++; } else { - dec->av_pes_state = 0; + dec->packet_state = 0; + } } length--; break; - case 4: - dec->av_pes[dec->av_pes_length++] = *b++; + case 5: + dec->packet[dec->packet_length++] = *b++; - if (dec->av_pes_length == 8) { - dec->av_pes_state++; - dec->av_pes_payload_length = le16_to_cpup( - (u16 *)(dec->av_pes + 6)); + if (dec->packet_type == PACKET_AV_PES && + dec->packet_length == 8) { + dec->packet_state++; + dec->packet_payload_length = 8 + + (dec->packet[6] << 8) + + dec->packet[7]; + } else if (dec->packet_type == PACKET_SECTION && + dec->packet_length == 5) { + dec->packet_state++; + dec->packet_payload_length = 5 + + ((dec->packet[3] & 0x0f) << 8) + + dec->packet[4]; } length--; break; - case 5: { - int remainder = dec->av_pes_payload_length + - 8 - dec->av_pes_length; + case 6: { + int remainder = dec->packet_payload_length - + dec->packet_length; if (length >= remainder) { - memcpy(dec->av_pes + dec->av_pes_length, + memcpy(dec->packet + dec->packet_length, b, remainder); - dec->av_pes_length += remainder; + dec->packet_length += remainder; b += remainder; length -= remainder; - dec->av_pes_state++; + dec->packet_state++; } else { - memcpy(&dec->av_pes[dec->av_pes_length], + memcpy(&dec->packet[dec->packet_length], b, length); - dec->av_pes_length += length; + dec->packet_length += length; length = 0; } break; } - case 6: - dec->av_pes[dec->av_pes_length++] = *b++; + case 7: { + int tail = 4; - if (dec->av_pes_length == - 8 + dec->av_pes_payload_length + 4) { - ttusb_dec_process_av_pes(dec, dec->av_pes, - dec->av_pes_length); - dec->av_pes_state = 0; + dec->packet[dec->packet_length++] = *b++; + + if (dec->packet_type == PACKET_SECTION && + dec->packet_payload_length % 2) + tail++; + + if (dec->packet_length == + dec->packet_payload_length + tail) { + ttusb_dec_process_packet(dec); + dec->packet_state = 0; } length--; break; + } default: printk("%s: illegal packet state encountered.\n", __FUNCTION__); - dec->av_pes_state = 0; - + dec->packet_state = 0; } - } } @@ -560,12 +657,8 @@ dec->iso_stream_count--; if (!dec->iso_stream_count) { - u8 b0[] = { 0x00 }; - for (i = 0; i < ISO_BUF_COUNT; i++) usb_unlink_urb(dec->iso_urb[i]); - - ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL); } up(&dec->iso_sem); @@ -593,10 +686,6 @@ return -EAGAIN; if (!dec->iso_stream_count) { - u8 b0[] = { 0x05 }; - - ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL); - ttusb_dec_setup_urbs(dec); for (i = 0; i < ISO_BUF_COUNT; i++) { @@ -615,7 +704,7 @@ } } - dec->av_pes_state = 0; + dec->packet_state = 0; dec->v_pes_postbytes = 0; } @@ -626,34 +715,14 @@ return 0; } -static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed) +static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *dvbdmx = dvbdmxfeed->demux; struct ttusb_dec *dec = dvbdmx->priv; + u8 b0[] = { 0x05 }; dprintk("%s\n", __FUNCTION__); - if (!dvbdmx->dmx.frontend) - return -EINVAL; - - dprintk(" pid: 0x%04X\n", dvbdmxfeed->pid); - - switch (dvbdmxfeed->type) { - - case DMX_TYPE_TS: - dprintk(" type: DMX_TYPE_TS\n"); - break; - - case DMX_TYPE_SEC: - dprintk(" type: DMX_TYPE_SEC\n"); - break; - - default: - dprintk(" type: unknown (%d)\n", dvbdmxfeed->type); - return -EINVAL; - - } - dprintk(" ts_type:"); if (dvbdmxfeed->ts_type & TS_DECODER) @@ -703,22 +772,151 @@ } + ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL); + + dec->av_pes_stream_count++; ttusb_dec_start_iso_xfer(dec); return 0; } -static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed) +static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed) { struct ttusb_dec *dec = dvbdmxfeed->demux->priv; + u8 b0[] = { 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00 }; + u16 pid; + u8 c[COMMAND_PACKET_SIZE]; + int c_length; + int result; + struct filter_info *finfo; + unsigned long flags; + u8 x = 1; + + dprintk("%s\n", __FUNCTION__); + + pid = htons(dvbdmxfeed->pid); + memcpy(&b0[0], &pid, 2); + memcpy(&b0[4], &x, 1); + memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1); + + result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0, + &c_length, c); + + if (!result) { + if (c_length == 2) { + if (!(finfo = kmalloc(sizeof(struct filter_info), + GFP_ATOMIC))) + return -ENOMEM; + + finfo->stream_id = c[1]; + finfo->filter = dvbdmxfeed->filter; + + spin_lock_irqsave(&dec->filter_info_list_lock, flags); + list_add_tail(&finfo->filter_info_list, + &dec->filter_info_list); + spin_unlock_irqrestore(&dec->filter_info_list_lock, + flags); + + dvbdmxfeed->priv = finfo; + + dec->filter_stream_count++; + ttusb_dec_start_iso_xfer(dec); + + return 0; + } + + return -EAGAIN; + } else + return result; +} + +static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + struct dvb_demux *dvbdmx = dvbdmxfeed->demux; dprintk("%s\n", __FUNCTION__); + if (!dvbdmx->dmx.frontend) + return -EINVAL; + + dprintk(" pid: 0x%04X\n", dvbdmxfeed->pid); + + switch (dvbdmxfeed->type) { + + case DMX_TYPE_TS: + return ttusb_dec_start_ts_feed(dvbdmxfeed); + break; + + case DMX_TYPE_SEC: + return ttusb_dec_start_sec_feed(dvbdmxfeed); + break; + + default: + dprintk(" type: unknown (%d)\n", dvbdmxfeed->type); + return -EINVAL; + + } +} + +static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + struct ttusb_dec *dec = dvbdmxfeed->demux->priv; + u8 b0[] = { 0x00 }; + + ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL); + + dec->av_pes_stream_count--; + ttusb_dec_stop_iso_xfer(dec); return 0; } +static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + struct ttusb_dec *dec = dvbdmxfeed->demux->priv; + u8 b0[] = { 0x00, 0x00 }; + struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv; + unsigned long flags; + + b0[1] = finfo->stream_id; + spin_lock_irqsave(&dec->filter_info_list_lock, flags); + list_del(&finfo->filter_info_list); + spin_unlock_irqrestore(&dec->filter_info_list_lock, flags); + kfree(finfo); + ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL); + + dec->filter_stream_count--; + + ttusb_dec_stop_iso_xfer(dec); + + return 0; +} + +static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + dprintk("%s\n", __FUNCTION__); + + switch (dvbdmxfeed->type) { + case DMX_TYPE_TS: + return ttusb_dec_stop_ts_feed(dvbdmxfeed); + break; + + case DMX_TYPE_SEC: + return ttusb_dec_stop_sec_feed(dvbdmxfeed); + break; + } + + return 0; +} + static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec) { int i; @@ -801,8 +999,9 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) { int i, j, actual_len, result, size, trans_count; - u8 b0[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00 }; + u8 b0[] = { 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 }; u8 b1[] = { 0x61 }; u8 b[ARM_PACKET_SIZE]; u8 *firmware = NULL; @@ -1066,9 +1265,11 @@ case FE_SET_FRONTEND: { struct dvb_frontend_parameters *p = (struct dvb_frontend_parameters *)arg; - u8 b[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }; + u8 b[] = { 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff }; u32 freq; dprintk("%s: FE_SET_FRONTEND\n", __FUNCTION__); @@ -1111,8 +1312,8 @@ return 0; } -static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, unsigned int cmd, - void *arg) +static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, + unsigned int cmd, void *arg) { struct ttusb_dec *dec = fe->data; @@ -1164,12 +1365,16 @@ case FE_SET_FRONTEND: { struct dvb_frontend_parameters *p = (struct dvb_frontend_parameters *)arg; - u8 b[] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 }; + u8 b[] = { 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; u32 freq; u32 sym_rate; u32 band; @@ -1182,7 +1387,8 @@ p->u.qam.symbol_rate); dprintk(" inversion->%d\n", p->inversion); - freq = htonl(p->frequency * 1000 + (dec->hi_band ? LOF_HI : LOF_LO)); + freq = htonl(p->frequency * 1000 + + (dec->hi_band ? LOF_HI : LOF_LO)); memcpy(&b[4], &freq, sizeof(u32)); sym_rate = htonl(p->u.qam.symbol_rate); memcpy(&b[12], &sym_rate, sizeof(u32)); @@ -1264,6 +1470,24 @@ dvb_unregister_frontend(dec->frontend_ioctl, &dec->i2c_bus); } +static void ttusb_dec_init_filters(struct ttusb_dec *dec) +{ + INIT_LIST_HEAD(&dec->filter_info_list); + dec->filter_info_list_lock = SPIN_LOCK_UNLOCKED; +} + +static void ttusb_dec_exit_filters(struct ttusb_dec *dec) +{ + struct list_head *item; + struct filter_info *finfo; + + while ((item = dec->filter_info_list.next) != &dec->filter_info_list) { + finfo = list_entry(item, struct filter_info, filter_info_list); + list_del(&finfo->filter_info_list); + kfree(finfo); + } +} + static int ttusb_dec_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -1287,13 +1511,13 @@ case 0x1006: dec->model = TTUSB_DEC3000S; dec->model_name = "DEC3000-s"; - dec->firmware_name = "dec3000s.bin"; + dec->firmware_name = "dvb-ttusb-dec-3000s-2.15a.fw"; break; case 0x1008: dec->model = TTUSB_DEC2000T; dec->model_name = "DEC2000-t"; - dec->firmware_name = "dec2000t.bin"; + dec->firmware_name = "dvb-ttusb-dec-2000t-2.15a.fw"; break; } @@ -1307,6 +1531,7 @@ ttusb_dec_init_dvb(dec); ttusb_dec_init_frontend(dec); ttusb_dec_init_v_pes(dec); + ttusb_dec_init_filters(dec); ttusb_dec_init_tasklet(dec); dec->active = 1; @@ -1326,6 +1551,7 @@ if (dec->active) { ttusb_dec_exit_tasklet(dec); + ttusb_dec_exit_filters(dec); ttusb_dec_exit_usb(dec); ttusb_dec_exit_frontend(dec); ttusb_dec_exit_dvb(dec); diff -Nru a/drivers/media/dvb/ttusb-dec/ttusb_dec.h b/drivers/media/dvb/ttusb-dec/ttusb_dec.h --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.h Sun Jan 4 17:36:10 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,99 +0,0 @@ -/* - * TTUSB DEC Driver - * - * Copyright (C) 2003 Alex Woods - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the 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 _TTUSB_DEC_H -#define _TTUSB_DEC_H - -#include -#include -#include -#include -#include "dmxdev.h" -#include "dvb_demux.h" -#include "dvb_filter.h" -#include "dvb_i2c.h" -#include "dvb_net.h" - -#define DRIVER_NAME "TechnoTrend/Hauppauge DEC USB" - -#define COMMAND_PIPE 0x03 -#define RESULT_PIPE 0x84 -#define STREAM_PIPE 0x88 - -#define COMMAND_PACKET_SIZE 0x3c -#define ARM_PACKET_SIZE 0x1000 - -#define ISO_BUF_COUNT 0x04 -#define FRAMES_PER_ISO_BUF 0x04 -#define ISO_FRAME_SIZE 0x0380 - -#define MAX_AV_PES_LENGTH 6144 - -struct ttusb_dec { - /* DVB bits */ - struct dvb_adapter *adapter; - struct dmxdev dmxdev; - struct dvb_demux demux; - struct dmx_frontend frontend; - struct dvb_i2c_bus *i2c_bus; - struct dvb_net dvb_net; - - u16 pid[DMX_PES_OTHER]; - - /* USB bits */ - struct usb_device *udev; - u8 trans_count; - unsigned int command_pipe; - unsigned int result_pipe; - unsigned int stream_pipe; - int interface; - struct semaphore usb_sem; - - void *iso_buffer; - dma_addr_t iso_dma_handle; - struct urb *iso_urb[ISO_BUF_COUNT]; - int iso_stream_count; - struct semaphore iso_sem; - - u8 av_pes[MAX_AV_PES_LENGTH + 4]; - int av_pes_state; - int av_pes_length; - int av_pes_payload_length; - - struct dvb_filter_pes2ts a_pes2ts; - struct dvb_filter_pes2ts v_pes2ts; - - u8 v_pes[16 + MAX_AV_PES_LENGTH]; - int v_pes_length; - int v_pes_postbytes; - - struct list_head urb_frame_list; - struct tasklet_struct urb_tasklet; - spinlock_t urb_frame_list_lock; -}; - -struct urb_frame { - u8 data[ISO_FRAME_SIZE]; - int length; - struct list_head urb_frame_list; -}; - -#endif diff -Nru a/drivers/media/dvb/ttusb-dec/ttusb_dec.mod.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.mod.c --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.mod.c Sun Jan 4 17:36:11 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,13 +0,0 @@ -#include -#include -#include - -MODULE_INFO(vermagic, VERMAGIC_STRING); - -static const char __module_depends[] -__attribute_used__ -__attribute__((section(".modinfo"))) = -"depends=dvb-core"; - -MODULE_ALIAS("usb:v0B48p1006dl*dh*dc*dsc*dp*ic*isc*ip*"); -MODULE_ALIAS("usb:v0B48p1008dl*dh*dc*dsc*dp*ic*isc*ip*"); diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c --- a/drivers/net/tg3.c Sun Jan 4 17:36:11 2004 +++ b/drivers/net/tg3.c Sun Jan 4 17:36:11 2004 @@ -56,8 +56,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "2.3" -#define DRV_MODULE_RELDATE "November 5, 2003" +#define DRV_MODULE_VERSION "2.5" +#define DRV_MODULE_RELDATE "December 22, 2003" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -176,6 +176,10 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S_2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX, @@ -2688,7 +2692,13 @@ mss |= (tsflags << 11); } } else { - mss += tcp_opt_len; + if (tcp_opt_len || skb->nh.iph->ihl > 5) { + int tsflags; + + tsflags = ((skb->nh.iph->ihl - 5) + + (tcp_opt_len >> 2)); + base_flags |= tsflags << 12; + } } } #else @@ -2895,7 +2905,13 @@ mss |= (tsflags << 11); } } else { - mss += tcp_opt_len; + if (tcp_opt_len || skb->nh.iph->ihl > 5) { + int tsflags; + + tsflags = ((skb->nh.iph->ihl - 5) + + (tcp_opt_len >> 2)); + base_flags |= tsflags << 12; + } } } #else @@ -3860,180 +3876,181 @@ #if TG3_TSO_SUPPORT != 0 #define TG3_TSO_FW_RELEASE_MAJOR 0x1 -#define TG3_TSO_FW_RELASE_MINOR 0x3 +#define TG3_TSO_FW_RELASE_MINOR 0x4 #define TG3_TSO_FW_RELEASE_FIX 0x0 #define TG3_TSO_FW_START_ADDR 0x08000000 #define TG3_TSO_FW_TEXT_ADDR 0x08000000 -#define TG3_TSO_FW_TEXT_LEN 0x1ac0 -#define TG3_TSO_FW_RODATA_ADDR 0x08001650 +#define TG3_TSO_FW_TEXT_LEN 0x1a90 +#define TG3_TSO_FW_RODATA_ADDR 0x08001a900 #define TG3_TSO_FW_RODATA_LEN 0x60 -#define TG3_TSO_FW_DATA_ADDR 0x080016a0 +#define TG3_TSO_FW_DATA_ADDR 0x08001b20 #define TG3_TSO_FW_DATA_LEN 0x20 -#define TG3_TSO_FW_SBSS_ADDR 0x080016c0 +#define TG3_TSO_FW_SBSS_ADDR 0x08001b40 #define TG3_TSO_FW_SBSS_LEN 0x2c -#define TG3_TSO_FW_BSS_ADDR 0x080016e0 -#define TG3_TSO_FW_BSS_LEN 0x890 +#define TG3_TSO_FW_BSS_ADDR 0x08001b70 +#define TG3_TSO_FW_BSS_LEN 0x894 static u32 tg3TsoFwText[] = { 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800, 0x37bd4000, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000010, 0x00000000, 0x0000000d, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0x3c04fefe, - 0xafbf0018, 0x0e0005e0, 0x34840002, 0x0e000670, 0x00000000, 0x3c030800, - 0x90631b78, 0x24020002, 0x3c040800, 0x24841acc, 0x14620003, 0x24050001, - 0x3c040800, 0x24841ac0, 0x24060002, 0x00003821, 0xafa00010, 0x0e000684, + 0xafbf0018, 0x0e0005d4, 0x34840002, 0x0e000664, 0x00000000, 0x3c030800, + 0x90631b58, 0x24020002, 0x3c040800, 0x24841a9c, 0x14620003, 0x24050001, + 0x3c040800, 0x24841a90, 0x24060003, 0x00003821, 0xafa00010, 0x0e000678, 0xafa00014, 0x8f625c50, 0x34420001, 0xaf625c50, 0x8f625c90, 0x34420001, 0xaf625c90, 0x2402ffff, 0x0e000034, 0xaf625404, 0x8fbf0018, 0x03e00008, - 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf0018, - 0xafb10014, 0x0e000052, 0xafb00010, 0x24110001, 0x8f706820, 0x32020100, - 0x10400003, 0x00000000, 0x0e0000b2, 0x00000000, 0x8f706820, 0x32022000, - 0x10400004, 0x32020001, 0x0e0001e3, 0x24040001, 0x32020001, 0x10400003, - 0x00000000, 0x0e00009a, 0x00000000, 0x0a00003a, 0xaf715028, 0x8fbf0018, - 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800, - 0x24841ae0, 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, - 0x0e000684, 0xafa00014, 0x3c040800, 0x248423e8, 0xa4800000, 0x3c010800, - 0xa0201ba8, 0x3c010800, 0xac201bac, 0x3c010800, 0xac201bb0, 0x3c010800, - 0xac201bb4, 0x3c010800, 0xac201bbc, 0x3c010800, 0xac201bc8, 0x3c010800, - 0xac201bcc, 0x8f624434, 0x3c010800, 0xac221b98, 0x8f624438, 0x3c010800, - 0xac221b9c, 0x8f624410, 0xac80f7a8, 0x3c010800, 0xac201b94, 0x3c010800, - 0xac2023f0, 0x3c010800, 0xac2023d8, 0x3c010800, 0xac2023dc, 0x3c010800, - 0xac202410, 0x3c010800, 0xac221ba0, 0x8f620068, 0x24030007, 0x00021702, - 0x10430005, 0x00000000, 0x8f620068, 0x00021702, 0x14400004, 0x24020001, - 0x3c010800, 0x0a00008e, 0xac20241c, 0xac820034, 0x3c040800, 0x24841aec, - 0x3c050800, 0x8ca5241c, 0x00003021, 0x00003821, 0xafa00010, 0x0e000684, - 0xafa00014, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800, - 0x24841af8, 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, - 0x0e000684, 0xafa00014, 0x0e000052, 0x00000000, 0x0e0000ab, 0x00002021, - 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x24020001, 0x8f636820, 0x00821004, - 0x00021027, 0x00621824, 0x03e00008, 0xaf636820, 0x27bdffd0, 0xafbf002c, - 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, - 0xafb00010, 0x8f665c5c, 0x3c030800, 0x24631bcc, 0x8c620000, 0x14460005, - 0x3c0200ff, 0x3c020800, 0x90421ba8, 0x14400115, 0x3c0200ff, 0x3442fff8, - 0x00c28824, 0xac660000, 0x00111902, 0x306300ff, 0x30c20003, 0x000211c0, - 0x00623825, 0x00e02821, 0x00061602, 0x3c030800, 0x90631ba8, 0x3044000f, - 0x1460002b, 0x00804021, 0x24020001, 0x3c010800, 0xa0221ba8, 0x00071100, - 0x00821025, 0x3c010800, 0xac201bac, 0x3c010800, 0xac201bb0, 0x3c010800, - 0xac201bb4, 0x3c010800, 0xac201bbc, 0x3c010800, 0xac201bc8, 0x3c010800, - 0xac201bc0, 0x3c010800, 0xac201bc4, 0x3c010800, 0xa42223e8, 0x9623000c, - 0x30628000, 0x10400008, 0x30627fff, 0x2442003e, 0x3c010800, 0xa4221ba6, - 0x24020001, 0x3c010800, 0x0a0000f9, 0xac222404, 0x24620036, 0x3c010800, - 0xa4221ba6, 0x3c010800, 0xac202404, 0x3c010800, 0xac202400, 0x3c010800, - 0x0a000101, 0xac202408, 0x9622000c, 0x3c010800, 0xa42223fc, 0x3c040800, - 0x24841bac, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac311bd8, - 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac261bdc, 0x8c820000, - 0x24a30001, 0x306701ff, 0x00021100, 0x3c010800, 0x00220821, 0xac271be0, - 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac281be4, 0x96230008, - 0x3c020800, 0x8c421bbc, 0x00432821, 0x3c010800, 0xac251bbc, 0x9622000a, - 0x30420004, 0x14400018, 0x00071100, 0x8f630c14, 0x3063000f, 0x2c620002, - 0x1440000b, 0x3c02c000, 0x8f630c14, 0x3c020800, 0x8c421b50, 0x3063000f, - 0x24420001, 0x3c010800, 0xac221b50, 0x2c620002, 0x1040fff7, 0x3c02c000, - 0x00c21825, 0xaf635c5c, 0x8f625c50, 0x30420002, 0x10400014, 0x00000000, - 0x0a000133, 0x00000000, 0x3c030800, 0x8c631b90, 0x3c040800, 0x94841ba4, - 0x01021025, 0x3c010800, 0xa42223ea, 0x24020001, 0x3c010800, 0xac221bc8, - 0x24630001, 0x0085202a, 0x3c010800, 0x10800003, 0xac231b90, 0x3c010800, - 0xa4251ba4, 0x3c060800, 0x24c61bac, 0x8cc20000, 0x24420001, 0xacc20000, - 0x28420080, 0x14400005, 0x00000000, 0x0e00065e, 0x24040002, 0x0a0001d9, - 0x00000000, 0x3c020800, 0x8c421bc8, 0x1040007f, 0x24020001, 0x3c040800, - 0x90841ba8, 0x14820077, 0x24020003, 0x3c150800, 0x96b51ba6, 0x3c050800, - 0x8ca51bbc, 0x32a3ffff, 0x00a3102a, 0x14400073, 0x00000000, 0x14a30003, - 0x00000000, 0x3c010800, 0xac242400, 0x10600061, 0x00009021, 0x24d60004, - 0x0060a021, 0x24d30014, 0x8ec20000, 0x00028100, 0x3c110800, 0x02308821, - 0x0e00062d, 0x8e311bd8, 0x00403021, 0x10c00059, 0x00000000, 0x9628000a, - 0x31020040, 0x10400004, 0x2407180c, 0x8e22000c, 0x2407188c, 0xacc20018, - 0x31021000, 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, 0x00623825, - 0x3c030800, 0x00701821, 0x8c631be0, 0x3c020800, 0x00501021, 0x8c421be4, - 0x00031d00, 0x00021400, 0x00621825, 0xacc30014, 0x8ec30004, 0x96220008, - 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, 0x0282102a, 0x14400002, - 0x02b22823, 0x00802821, 0x8e620000, 0x30a4ffff, 0x00441021, 0xae620000, - 0x8e220000, 0xacc20000, 0x8e220004, 0x8e63fff4, 0x00431021, 0xacc20004, - 0xa4c5000e, 0x8e62fff4, 0x00441021, 0xae62fff4, 0x96230008, 0x0043102a, - 0x14400005, 0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001, 0xae62fff0, - 0xacc00008, 0x3242ffff, 0x14540008, 0x24020305, 0x31020080, 0x54400001, - 0x34e70010, 0x24020905, 0xa4c2000c, 0x0a0001bc, 0x34e70020, 0xa4c2000c, - 0x3c020800, 0x8c422400, 0x10400003, 0x3c024b65, 0x0a0001c4, 0x34427654, - 0x3c02b49a, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010, 0x0e0005aa, - 0x00c02021, 0x3242ffff, 0x0054102b, 0x1440ffa4, 0x00000000, 0x24020002, - 0x3c010800, 0x0a0001d9, 0xa0221ba8, 0x8ec2083c, 0x24420001, 0x0a0001d9, - 0xaec2083c, 0x14820003, 0x00000000, 0x0e0004b9, 0x00000000, 0x8fbf002c, + 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf001c, + 0xafb20018, 0xafb10014, 0x0e00005b, 0xafb00010, 0x24120002, 0x24110001, + 0x8f706820, 0x32020100, 0x10400003, 0x00000000, 0x0e0000bb, 0x00000000, + 0x8f706820, 0x32022000, 0x10400004, 0x32020001, 0x0e0001ef, 0x24040001, + 0x32020001, 0x10400003, 0x00000000, 0x0e0000a3, 0x00000000, 0x3c020800, + 0x90421b88, 0x14520003, 0x00000000, 0x0e0004bf, 0x00000000, 0x0a00003c, + 0xaf715028, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, + 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ab0, 0x00002821, 0x00003021, + 0x00003821, 0xafbf0018, 0xafa00010, 0x0e000678, 0xafa00014, 0x3c040800, + 0x248423c8, 0xa4800000, 0x3c010800, 0xa0201b88, 0x3c010800, 0xac201b8c, + 0x3c010800, 0xac201b90, 0x3c010800, 0xac201b94, 0x3c010800, 0xac201b9c, + 0x3c010800, 0xac201ba8, 0x3c010800, 0xac201bac, 0x8f624434, 0x3c010800, + 0xac221b78, 0x8f624438, 0x3c010800, 0xac221b7c, 0x8f624410, 0xac80f7a8, + 0x3c010800, 0xac201b74, 0x3c010800, 0xac2023d0, 0x3c010800, 0xac2023b8, + 0x3c010800, 0xac2023bc, 0x3c010800, 0xac2023f0, 0x3c010800, 0xac221b80, + 0x8f620068, 0x24030007, 0x00021702, 0x10430005, 0x00000000, 0x8f620068, + 0x00021702, 0x14400004, 0x24020001, 0x3c010800, 0x0a000097, 0xac2023fc, + 0xac820034, 0x3c040800, 0x24841abc, 0x3c050800, 0x8ca523fc, 0x00003021, + 0x00003821, 0xafa00010, 0x0e000678, 0xafa00014, 0x8fbf0018, 0x03e00008, + 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ac8, 0x00002821, 0x00003021, + 0x00003821, 0xafbf0018, 0xafa00010, 0x0e000678, 0xafa00014, 0x0e00005b, + 0x00000000, 0x0e0000b4, 0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020, + 0x24020001, 0x8f636820, 0x00821004, 0x00021027, 0x00621824, 0x03e00008, + 0xaf636820, 0x27bdffd0, 0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020, + 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x8f675c5c, 0x3c030800, + 0x24631bac, 0x8c620000, 0x14470005, 0x3c0200ff, 0x3c020800, 0x90421b88, + 0x14400118, 0x3c0200ff, 0x3442fff8, 0x00e28824, 0xac670000, 0x00111902, + 0x306300ff, 0x30e20003, 0x000211c0, 0x00622825, 0x00a04021, 0x00071602, + 0x3c030800, 0x90631b88, 0x3044000f, 0x14600036, 0x00804821, 0x24020001, + 0x3c010800, 0xa0221b88, 0x00051100, 0x00821025, 0x3c010800, 0xac201b8c, + 0x3c010800, 0xac201b90, 0x3c010800, 0xac201b94, 0x3c010800, 0xac201b9c, + 0x3c010800, 0xac201ba8, 0x3c010800, 0xac201ba0, 0x3c010800, 0xac201ba4, + 0x3c010800, 0xa42223c8, 0x9622000c, 0x30437fff, 0x3c010800, 0xa4222400, + 0x30428000, 0x3c010800, 0xa4231bb6, 0x10400005, 0x24020001, 0x3c010800, + 0xac2223e4, 0x0a000102, 0x2406003e, 0x24060036, 0x3c010800, 0xac2023e4, + 0x9622000a, 0x3c030800, 0x94631bb6, 0x3c010800, 0xac2023e0, 0x3c010800, + 0xac2023e8, 0x00021302, 0x00021080, 0x00c21021, 0x00621821, 0x3c010800, + 0xa42223c0, 0x3c010800, 0x0a000115, 0xa4231b86, 0x9622000c, 0x3c010800, + 0xa42223dc, 0x3c040800, 0x24841b8c, 0x8c820000, 0x00021100, 0x3c010800, + 0x00220821, 0xac311bb8, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, + 0xac271bbc, 0x8c820000, 0x25030001, 0x306601ff, 0x00021100, 0x3c010800, + 0x00220821, 0xac261bc0, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, + 0xac291bc4, 0x96230008, 0x3c020800, 0x8c421b9c, 0x00432821, 0x3c010800, + 0xac251b9c, 0x9622000a, 0x30420004, 0x14400018, 0x00061100, 0x8f630c14, + 0x3063000f, 0x2c620002, 0x1440000b, 0x3c02c000, 0x8f630c14, 0x3c020800, + 0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30, 0x2c620002, + 0x1040fff7, 0x3c02c000, 0x00e21825, 0xaf635c5c, 0x8f625c50, 0x30420002, + 0x10400014, 0x00000000, 0x0a000147, 0x00000000, 0x3c030800, 0x8c631b70, + 0x3c040800, 0x94841b84, 0x01221025, 0x3c010800, 0xa42223ca, 0x24020001, + 0x3c010800, 0xac221ba8, 0x24630001, 0x0085202a, 0x3c010800, 0x10800003, + 0xac231b70, 0x3c010800, 0xa4251b84, 0x3c060800, 0x24c61b8c, 0x8cc20000, + 0x24420001, 0xacc20000, 0x28420080, 0x14400005, 0x00000000, 0x0e000652, + 0x24040002, 0x0a0001e5, 0x00000000, 0x3c020800, 0x8c421ba8, 0x10400077, + 0x24020001, 0x3c050800, 0x90a51b88, 0x14a20071, 0x00000000, 0x3c150800, + 0x96b51b86, 0x3c040800, 0x8c841b9c, 0x32a3ffff, 0x0083102a, 0x1440006b, + 0x00000000, 0x14830003, 0x00000000, 0x3c010800, 0xac2523e0, 0x1060005b, + 0x00009021, 0x24d60004, 0x0060a021, 0x24d30014, 0x8ec20000, 0x00028100, + 0x3c110800, 0x02308821, 0x0e000621, 0x8e311bb8, 0x00402821, 0x10a00053, + 0x00000000, 0x9628000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e22000c, + 0x2407188c, 0xaca20018, 0x3c030800, 0x00701821, 0x8c631bc0, 0x3c020800, + 0x00501021, 0x8c421bc4, 0x00031d00, 0x00021400, 0x00621825, 0xaca30014, + 0x8ec30004, 0x96220008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, + 0x0282102a, 0x14400002, 0x02b23023, 0x00803021, 0x8e620000, 0x30c4ffff, + 0x00441021, 0xae620000, 0x8e220000, 0xaca20000, 0x8e220004, 0x8e63fff4, + 0x00431021, 0xaca20004, 0xa4a6000e, 0x8e62fff4, 0x00441021, 0xae62fff4, + 0x96230008, 0x0043102a, 0x14400005, 0x02469021, 0x8e62fff0, 0xae60fff4, + 0x24420001, 0xae62fff0, 0xaca00008, 0x3242ffff, 0x14540008, 0x24020305, + 0x31020080, 0x54400001, 0x34e70010, 0x24020905, 0xa4a2000c, 0x0a0001ca, + 0x34e70020, 0xa4a2000c, 0x3c020800, 0x8c4223e0, 0x10400003, 0x3c024b65, + 0x0a0001d2, 0x34427654, 0x3c02b49a, 0x344289ab, 0xaca2001c, 0x30e2ffff, + 0xaca20010, 0x0e00059f, 0x00a02021, 0x3242ffff, 0x0054102b, 0x1440ffaa, + 0x00000000, 0x24020002, 0x3c010800, 0x0a0001e5, 0xa0221b88, 0x8ec2083c, + 0x24420001, 0x0a0001e5, 0xaec2083c, 0x0e0004bf, 0x00000000, 0x8fbf002c, 0x8fb60028, 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0030, 0x27bdffd0, 0xafbf0028, 0xafb30024, 0xafb20020, 0xafb1001c, 0xafb00018, 0x8f725c9c, 0x3c0200ff, 0x3442fff8, - 0x3c060800, 0x24c61bc4, 0x02428824, 0x9623000e, 0x8cc20000, 0x00431021, - 0xacc20000, 0x8e220010, 0x30420020, 0x14400011, 0x00809821, 0x0e000643, + 0x3c060800, 0x24c61ba4, 0x02428824, 0x9623000e, 0x8cc20000, 0x00431021, + 0xacc20000, 0x8e220010, 0x30420020, 0x14400011, 0x00809821, 0x0e000637, 0x02202021, 0x3c02c000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x10400121, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1040011c, - 0x00000000, 0x0a000200, 0x00000000, 0x8e240008, 0x8e230014, 0x00041402, + 0x00000000, 0x0a00020c, 0x00000000, 0x8e240008, 0x8e230014, 0x00041402, 0x000241c0, 0x00031502, 0x304201ff, 0x2442ffff, 0x3042007f, 0x00031942, 0x30637800, 0x00021100, 0x24424000, 0x00625021, 0x9542000a, 0x3084ffff, - 0x30420008, 0x104000b3, 0x000429c0, 0x3c020800, 0x8c422410, 0x1440002d, - 0x25050008, 0x95020014, 0x3c010800, 0xa42223e0, 0x8d070010, 0x00071402, - 0x3c010800, 0xa42223e2, 0x3c010800, 0xa42723e4, 0x9502000e, 0x30e3ffff, - 0x00431023, 0x3c010800, 0xac222418, 0x8f626800, 0x3c030010, 0x00431024, - 0x10400005, 0x00000000, 0x9503001a, 0x9502001c, 0x0a000235, 0x00431021, - 0x9502001a, 0x3c010800, 0xac22240c, 0x3c02c000, 0x02421825, 0x3c010800, - 0xac282410, 0x3c010800, 0xac322414, 0xaf635c9c, 0x8f625c90, 0x30420002, + 0x30420008, 0x104000b3, 0x000429c0, 0x3c020800, 0x8c4223f0, 0x1440002d, + 0x25050008, 0x95020014, 0x3c010800, 0xa42223c0, 0x8d070010, 0x00071402, + 0x3c010800, 0xa42223c2, 0x3c010800, 0xa42723c4, 0x9502000e, 0x30e3ffff, + 0x00431023, 0x3c010800, 0xac2223f8, 0x8f626800, 0x3c030010, 0x00431024, + 0x10400005, 0x00000000, 0x9503001a, 0x9502001c, 0x0a000241, 0x00431021, + 0x9502001a, 0x3c010800, 0xac2223ec, 0x3c02c000, 0x02421825, 0x3c010800, + 0xac2823f0, 0x3c010800, 0xac3223f4, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x104000df, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x104000da, - 0x00000000, 0x0a000242, 0x00000000, 0x9502000e, 0x3c030800, 0x946323e4, + 0x00000000, 0x0a00024e, 0x00000000, 0x9502000e, 0x3c030800, 0x946323c4, 0x00434823, 0x3123ffff, 0x2c620008, 0x1040001c, 0x00000000, 0x95020014, 0x24420028, 0x00a22821, 0x00031042, 0x1840000b, 0x00002021, 0x24c60848, 0x00403821, 0x94a30000, 0x8cc20000, 0x24840001, 0x00431021, 0xacc20000, 0x0087102a, 0x1440fff9, 0x24a50002, 0x31220001, 0x1040001f, 0x3c024000, - 0x3c040800, 0x2484240c, 0xa0a00001, 0x94a30000, 0x8c820000, 0x00431021, - 0x0a000281, 0xac820000, 0x8f626800, 0x3c030010, 0x00431024, 0x10400009, - 0x00000000, 0x9502001a, 0x3c030800, 0x8c63240c, 0x00431021, 0x3c010800, - 0xac22240c, 0x0a000282, 0x3c024000, 0x9502001a, 0x9504001c, 0x3c030800, - 0x8c63240c, 0x00441023, 0x00621821, 0x3c010800, 0xac23240c, 0x3c024000, + 0x3c040800, 0x248423ec, 0xa0a00001, 0x94a30000, 0x8c820000, 0x00431021, + 0x0a00028d, 0xac820000, 0x8f626800, 0x3c030010, 0x00431024, 0x10400009, + 0x00000000, 0x9502001a, 0x3c030800, 0x8c6323ec, 0x00431021, 0x3c010800, + 0xac2223ec, 0x0a00028e, 0x3c024000, 0x9502001a, 0x9504001c, 0x3c030800, + 0x8c6323ec, 0x00441023, 0x00621821, 0x3c010800, 0xac2323ec, 0x3c024000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, - 0x9542000a, 0x30420010, 0x10400095, 0x00000000, 0x3c060800, 0x24c62410, - 0x3c020800, 0x944223e4, 0x8cc50000, 0x3c040800, 0x8c842418, 0x24420030, - 0x00a22821, 0x94a20004, 0x3c030800, 0x8c63240c, 0x00441023, 0x00621821, + 0x9542000a, 0x30420010, 0x10400095, 0x00000000, 0x3c060800, 0x24c623f0, + 0x3c020800, 0x944223c4, 0x8cc50000, 0x3c040800, 0x8c8423f8, 0x24420030, + 0x00a22821, 0x94a20004, 0x3c030800, 0x8c6323ec, 0x00441023, 0x00621821, 0x00603821, 0x00032402, 0x30e2ffff, 0x00823821, 0x00071402, 0x00e23821, - 0x00071027, 0x3c010800, 0xac23240c, 0xa4a20006, 0x3c030800, 0x8c632414, + 0x00071027, 0x3c010800, 0xac2323ec, 0xa4a20006, 0x3c030800, 0x8c6323f4, 0x3c0200ff, 0x3442fff8, 0x00628824, 0x96220008, 0x24040001, 0x24034000, 0x000241c0, 0x00e01021, 0xa502001a, 0xa500001c, 0xacc00000, 0x3c010800, - 0xac241b70, 0xaf635cb8, 0x8f625cb0, 0x30420002, 0x10400003, 0x00000000, - 0x3c010800, 0xac201b70, 0x8e220008, 0xaf625cb8, 0x8f625cb0, 0x30420002, - 0x10400003, 0x00000000, 0x3c010800, 0xac201b70, 0x3c020800, 0x8c421b70, - 0x1040ffec, 0x00000000, 0x3c040800, 0x0e000643, 0x8c842414, 0x0a000320, - 0x00000000, 0x3c030800, 0x90631ba8, 0x24020002, 0x14620003, 0x3c034b65, - 0x0a0002d7, 0x00008021, 0x8e22001c, 0x34637654, 0x10430002, 0x24100002, - 0x24100001, 0x01002021, 0x0e000346, 0x02003021, 0x24020003, 0x3c010800, - 0xa0221ba8, 0x24020002, 0x1202000a, 0x24020001, 0x3c030800, 0x8c632400, - 0x10620006, 0x00000000, 0x3c020800, 0x944223e8, 0x00021400, 0x0a000315, - 0xae220014, 0x3c040800, 0x248423ea, 0x94820000, 0x00021400, 0xae220014, - 0x3c020800, 0x8c421bcc, 0x3c03c000, 0x3c010800, 0xa0201ba8, 0x00431025, + 0xac241b50, 0xaf635cb8, 0x8f625cb0, 0x30420002, 0x10400003, 0x00000000, + 0x3c010800, 0xac201b50, 0x8e220008, 0xaf625cb8, 0x8f625cb0, 0x30420002, + 0x10400003, 0x00000000, 0x3c010800, 0xac201b50, 0x3c020800, 0x8c421b50, + 0x1040ffec, 0x00000000, 0x3c040800, 0x0e000637, 0x8c8423f4, 0x0a00032c, + 0x00000000, 0x3c030800, 0x90631b88, 0x24020002, 0x14620003, 0x3c034b65, + 0x0a0002e3, 0x00008021, 0x8e22001c, 0x34637654, 0x10430002, 0x24100002, + 0x24100001, 0x01002021, 0x0e000352, 0x02003021, 0x24020003, 0x3c010800, + 0xa0221b88, 0x24020002, 0x1202000a, 0x24020001, 0x3c030800, 0x8c6323e0, + 0x10620006, 0x00000000, 0x3c020800, 0x944223c8, 0x00021400, 0x0a000321, + 0xae220014, 0x3c040800, 0x248423ca, 0x94820000, 0x00021400, 0xae220014, + 0x3c020800, 0x8c421bac, 0x3c03c000, 0x3c010800, 0xa0201b88, 0x00431025, 0xaf625c5c, 0x8f625c50, 0x30420002, 0x10400009, 0x00000000, 0x2484f7e2, 0x8c820000, 0x00431025, 0xaf625c5c, 0x8f625c50, 0x30420002, 0x1440fffa, - 0x00000000, 0x3c020800, 0x24421b94, 0x8c430000, 0x24630001, 0xac430000, + 0x00000000, 0x3c020800, 0x24421b74, 0x8c430000, 0x24630001, 0xac430000, 0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000c, 0x3c024000, 0x8f630c14, - 0x3c020800, 0x8c421b50, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b50, + 0x3c020800, 0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30, 0x2c620002, 0x1040fff7, 0x00000000, 0x3c024000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, 0x12600003, 0x00000000, - 0x0e0004b9, 0x00000000, 0x8fbf0028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, - 0x8fb00018, 0x03e00008, 0x27bd0030, 0x8f634450, 0x3c040800, 0x24841b98, + 0x0e0004bf, 0x00000000, 0x8fbf0028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, + 0x8fb00018, 0x03e00008, 0x27bd0030, 0x8f634450, 0x3c040800, 0x24841b78, 0x8c820000, 0x00031c02, 0x0043102b, 0x14400007, 0x3c038000, 0x8c840004, 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, 0x3c024000, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00805821, - 0x14c00017, 0x256e0008, 0x3c020800, 0x8c422404, 0x1040000a, 0x2402003e, - 0x3c010800, 0xa42223e0, 0x24020016, 0x3c010800, 0xa42223e2, 0x2402002a, - 0x3c010800, 0x0a000360, 0xa42223e4, 0x95620014, 0x3c010800, 0xa42223e0, - 0x8d670010, 0x00071402, 0x3c010800, 0xa42223e2, 0x3c010800, 0xa42723e4, - 0x3c040800, 0x948423e4, 0x3c030800, 0x946323e2, 0x95cf0006, 0x3c020800, - 0x944223e0, 0x00832023, 0x01e2c023, 0x3065ffff, 0x24a20028, 0x01c24821, + 0x14c00011, 0x256e0008, 0x3c020800, 0x8c4223e4, 0x10400007, 0x24020016, + 0x3c010800, 0xa42223c2, 0x2402002a, 0x3c010800, 0x0a000366, 0xa42223c4, + 0x8d670010, 0x00071402, 0x3c010800, 0xa42223c2, 0x3c010800, 0xa42723c4, + 0x3c040800, 0x948423c4, 0x3c030800, 0x946323c2, 0x95cf0006, 0x3c020800, + 0x944223c0, 0x00832023, 0x01e2c023, 0x3065ffff, 0x24a20028, 0x01c24821, 0x3082ffff, 0x14c0001a, 0x01226021, 0x9582000c, 0x3042003f, 0x3c010800, - 0xa42223e6, 0x95820004, 0x95830006, 0x3c010800, 0xac2023f4, 0x3c010800, - 0xac2023f8, 0x00021400, 0x00431025, 0x3c010800, 0xac221bd0, 0x95220004, - 0x3c010800, 0xa4221bd4, 0x95230002, 0x01e51023, 0x0043102a, 0x10400010, - 0x24020001, 0x3c010800, 0x0a000394, 0xac222408, 0x3c030800, 0x8c6323f8, - 0x3c020800, 0x94421bd4, 0x00431021, 0xa5220004, 0x3c020800, 0x94421bd0, - 0xa5820004, 0x3c020800, 0x8c421bd0, 0xa5820006, 0x3c020800, 0x8c422400, - 0x3c0d0800, 0x8dad23f4, 0x3c0a0800, 0x144000e5, 0x8d4a23f8, 0x3c020800, - 0x94421bd4, 0x004a1821, 0x3063ffff, 0x0062182b, 0x24020002, 0x10c2000d, - 0x01435023, 0x3c020800, 0x944223e6, 0x30420009, 0x10400008, 0x00000000, - 0x9582000c, 0x3042fff6, 0xa582000c, 0x3c020800, 0x944223e6, 0x30420009, - 0x01a26823, 0x3c020800, 0x8c422408, 0x1040004a, 0x01203821, 0x3c020800, - 0x944223e2, 0x00004021, 0xa520000a, 0x01e21023, 0xa5220002, 0x3082ffff, + 0xa42223c6, 0x95820004, 0x95830006, 0x3c010800, 0xac2023d4, 0x3c010800, + 0xac2023d8, 0x00021400, 0x00431025, 0x3c010800, 0xac221bb0, 0x95220004, + 0x3c010800, 0xa4221bb4, 0x95230002, 0x01e51023, 0x0043102a, 0x10400010, + 0x24020001, 0x3c010800, 0x0a00039a, 0xac2223e8, 0x3c030800, 0x8c6323d8, + 0x3c020800, 0x94421bb4, 0x00431021, 0xa5220004, 0x3c020800, 0x94421bb0, + 0xa5820004, 0x3c020800, 0x8c421bb0, 0xa5820006, 0x3c020800, 0x8c4223e0, + 0x3c0d0800, 0x8dad23d4, 0x3c0a0800, 0x144000e5, 0x8d4a23d8, 0x3c020800, + 0x94421bb4, 0x004a1821, 0x3063ffff, 0x0062182b, 0x24020002, 0x10c2000d, + 0x01435023, 0x3c020800, 0x944223c6, 0x30420009, 0x10400008, 0x00000000, + 0x9582000c, 0x3042fff6, 0xa582000c, 0x3c020800, 0x944223c6, 0x30420009, + 0x01a26823, 0x3c020800, 0x8c4223e8, 0x1040004a, 0x01203821, 0x3c020800, + 0x944223c2, 0x00004021, 0xa520000a, 0x01e21023, 0xa5220002, 0x3082ffff, 0x00021042, 0x18400008, 0x00003021, 0x00401821, 0x94e20000, 0x25080001, 0x00c23021, 0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c02821, 0x00061027, 0xa522000a, @@ -4044,131 +4061,127 @@ 0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, 0x3c02007f, 0x3442ff80, 0x00625824, 0x25670008, 0x0109102a, 0x1440fff3, 0x00000000, 0x30820001, 0x10400005, 0x00061c02, 0xa0e00001, 0x94e20000, 0x00c23021, 0x00061c02, - 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x0a000479, 0x30c6ffff, - 0x24020002, 0x14c20081, 0x00000000, 0x3c020800, 0x8c42241c, 0x14400007, - 0x00000000, 0x3c020800, 0x944223e2, 0x95230002, 0x01e21023, 0x10620077, - 0x00000000, 0x3c020800, 0x944223e2, 0x01e21023, 0xa5220002, 0x3c020800, - 0x8c42241c, 0x1040001a, 0x31e3ffff, 0x8dc70010, 0x3c020800, 0x94421ba6, + 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x0a00047f, 0x30c6ffff, + 0x24020002, 0x14c20081, 0x00000000, 0x3c020800, 0x8c4223fc, 0x14400007, + 0x00000000, 0x3c020800, 0x944223c2, 0x95230002, 0x01e21023, 0x10620077, + 0x00000000, 0x3c020800, 0x944223c2, 0x01e21023, 0xa5220002, 0x3c020800, + 0x8c4223fc, 0x1040001a, 0x31e3ffff, 0x8dc70010, 0x3c020800, 0x94421b86, 0x00e04021, 0x00072c02, 0x00aa2021, 0x00431023, 0x00823823, 0x00072402, 0x30e2ffff, 0x00823821, 0x00071027, 0xa522000a, 0x3102ffff, 0x3c040800, - 0x948423e4, 0x00453023, 0x00e02821, 0x00641823, 0x006d1821, 0x00c33021, - 0x00061c02, 0x30c2ffff, 0x0a000479, 0x00623021, 0x01203821, 0x00004021, + 0x948423c4, 0x00453023, 0x00e02821, 0x00641823, 0x006d1821, 0x00c33021, + 0x00061c02, 0x30c2ffff, 0x0a00047f, 0x00623021, 0x01203821, 0x00004021, 0x3082ffff, 0x00021042, 0x18400008, 0x00003021, 0x00401821, 0x94e20000, 0x25080001, 0x00c23021, 0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c02821, 0x00061027, 0xa522000a, 0x00003021, 0x2527000c, 0x00004021, 0x94e20000, 0x25080001, 0x00c23021, 0x2d020004, 0x1440fffb, 0x24e70002, 0x95220002, 0x00004021, 0x91230009, 0x00442023, 0x01803821, 0x3082ffff, 0xa4e00010, 0x3c040800, - 0x948423e4, 0x00621821, 0x00c33021, 0x00061c02, 0x30c2ffff, 0x00623021, - 0x00061c02, 0x3c020800, 0x944223e0, 0x00c34821, 0x00441023, 0x00021fc2, + 0x948423c4, 0x00621821, 0x00c33021, 0x00061c02, 0x30c2ffff, 0x00623021, + 0x00061c02, 0x3c020800, 0x944223c0, 0x00c34821, 0x00441023, 0x00021fc2, 0x00431021, 0x00021043, 0x18400010, 0x00003021, 0x00402021, 0x94e20000, 0x24e70002, 0x00c23021, 0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, 0x3c02007f, 0x3442ff80, 0x00625824, 0x25670008, 0x0104102a, 0x1440fff3, - 0x00000000, 0x3c020800, 0x944223fc, 0x00c23021, 0x3122ffff, 0x00c23021, + 0x00000000, 0x3c020800, 0x944223dc, 0x00c23021, 0x3122ffff, 0x00c23021, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c04021, - 0x00061027, 0xa5820010, 0xadc00014, 0x0a000499, 0xadc00000, 0x8dc70010, + 0x00061027, 0xa5820010, 0xadc00014, 0x0a00049f, 0xadc00000, 0x8dc70010, 0x00e04021, 0x11400007, 0x00072c02, 0x00aa3021, 0x00061402, 0x30c3ffff, 0x00433021, 0x00061402, 0x00c22821, 0x00051027, 0xa522000a, 0x3c030800, - 0x946323e4, 0x3102ffff, 0x01e21021, 0x00433023, 0x00cd3021, 0x00061c02, + 0x946323c4, 0x3102ffff, 0x01e21021, 0x00433023, 0x00cd3021, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c04021, 0x00061027, 0xa5820010, 0x3102ffff, 0x00051c00, 0x00431025, 0xadc20010, 0x3c020800, - 0x8c422404, 0x10400002, 0x25e2fff2, 0xa5c20034, 0x3c020800, 0x8c4223f8, - 0x3c040800, 0x8c8423f4, 0x24420001, 0x3c010800, 0xac2223f8, 0x3c020800, - 0x8c421bd0, 0x3303ffff, 0x00832021, 0x3c010800, 0xac2423f4, 0x00431821, - 0x0062102b, 0x10400003, 0x2482ffff, 0x3c010800, 0xac2223f4, 0x3c010800, - 0xac231bd0, 0x03e00008, 0x27bd0020, 0x27bdffb8, 0x3c050800, 0x24a51ba8, + 0x8c4223e4, 0x10400002, 0x25e2fff2, 0xa5c20034, 0x3c020800, 0x8c4223d8, + 0x3c040800, 0x8c8423d4, 0x24420001, 0x3c010800, 0xac2223d8, 0x3c020800, + 0x8c421bb0, 0x3303ffff, 0x00832021, 0x3c010800, 0xac2423d4, 0x00431821, + 0x0062102b, 0x10400003, 0x2482ffff, 0x3c010800, 0xac2223d4, 0x3c010800, + 0xac231bb0, 0x03e00008, 0x27bd0020, 0x27bdffb8, 0x3c050800, 0x24a51b86, 0xafbf0044, 0xafbe0040, 0xafb7003c, 0xafb60038, 0xafb50034, 0xafb40030, - 0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x90a30000, 0x24020003, - 0x146200d5, 0x00000000, 0x3c090800, 0x95291ba6, 0x3c020800, 0x944223e0, - 0x3c030800, 0x8c631bc0, 0x3c040800, 0x8c841bbc, 0x01221023, 0x0064182a, - 0xa7a9001e, 0x106000c8, 0xa7a20016, 0x24be0020, 0x97b6001e, 0x24b30018, - 0x24b70014, 0x8fc20000, 0x14400008, 0x00000000, 0x8fc2fff8, 0x97a30016, - 0x8fc4fff4, 0x00431021, 0x0082202a, 0x148000ba, 0x00000000, 0x97d50818, - 0x32a2ffff, 0x104000ad, 0x00009021, 0x0040a021, 0x00008821, 0x0e00062d, - 0x00000000, 0x00403021, 0x14c00007, 0x00000000, 0x3c020800, 0x8c4223ec, - 0x24420001, 0x3c010800, 0x0a00059e, 0xac2223ec, 0x3c100800, 0x02118021, - 0x8e101bd8, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c, - 0x2407188c, 0xacc20018, 0x31021000, 0x10400004, 0x34e32000, 0x00081040, - 0x3042c000, 0x00623825, 0x31020080, 0x54400001, 0x34e70010, 0x3c020800, - 0x00511021, 0x8c421be0, 0x3c030800, 0x00711821, 0x8c631be4, 0x00021500, - 0x00031c00, 0x00431025, 0xacc20014, 0x96040008, 0x3242ffff, 0x00821021, - 0x0282102a, 0x14400002, 0x02b22823, 0x00802821, 0x8e020000, 0x02459021, - 0xacc20000, 0x8e020004, 0x00c02021, 0x26310010, 0xac820004, 0x30e2ffff, - 0xac800008, 0xa485000e, 0xac820010, 0x24020305, 0x0e0005aa, 0xa482000c, - 0x3242ffff, 0x0054102b, 0x1440ffc0, 0x3242ffff, 0x0a000596, 0x00000000, - 0x8e620000, 0x8e63fffc, 0x0043102a, 0x1040006c, 0x00000000, 0x8e62fff0, - 0x00028900, 0x3c100800, 0x02118021, 0x0e00062d, 0x8e101bd8, 0x00403021, - 0x14c00005, 0x00000000, 0x8e62082c, 0x24420001, 0x0a00059e, 0xae62082c, - 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c, 0x2407188c, - 0xacc20018, 0x31021000, 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, - 0x00623825, 0x3c020800, 0x00511021, 0x8c421be0, 0x3c030800, 0x00711821, - 0x8c631be4, 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, 0x8e63fff4, - 0x96020008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, 0x02c2102a, - 0x10400003, 0x00802821, 0x97a9001e, 0x01322823, 0x8e620000, 0x30a4ffff, - 0x00441021, 0xae620000, 0xa4c5000e, 0x8e020000, 0xacc20000, 0x8e020004, - 0x8e63fff4, 0x00431021, 0xacc20004, 0x8e63fff4, 0x96020008, 0x00641821, - 0x0062102a, 0x14400006, 0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001, - 0x0a000579, 0xae62fff0, 0xae63fff4, 0xacc00008, 0x3242ffff, 0x10560003, - 0x31020004, 0x10400006, 0x24020305, 0x31020080, 0x54400001, 0x34e70010, - 0x34e70020, 0x24020905, 0xa4c2000c, 0x8ee30000, 0x8ee20004, 0x14620007, - 0x3c02b49a, 0x8ee20860, 0x54400001, 0x34e70400, 0x3c024b65, 0x0a000590, - 0x34427654, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010, 0x0e0005aa, - 0x00c02021, 0x3242ffff, 0x0056102b, 0x1440ff96, 0x00000000, 0x8e620000, - 0x8e63fffc, 0x0043102a, 0x1440ff3e, 0x00000000, 0x8fbf0044, 0x8fbe0040, - 0x8fb7003c, 0x8fb60038, 0x8fb50034, 0x8fb40030, 0x8fb3002c, 0x8fb20028, - 0x8fb10024, 0x8fb00020, 0x03e00008, 0x27bd0048, 0x27bdffe8, 0xafbf0014, - 0xafb00010, 0x8f624450, 0x8f634410, 0x0a0005b9, 0x00808021, 0x8f626820, - 0x30422000, 0x10400003, 0x00000000, 0x0e0001e3, 0x00002021, 0x8f624450, - 0x8f634410, 0x3042ffff, 0x0043102b, 0x1440fff5, 0x00000000, 0x8f630c14, - 0x3063000f, 0x2c620002, 0x1440000b, 0x00000000, 0x8f630c14, 0x3c020800, - 0x8c421b50, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b50, 0x2c620002, - 0x1040fff7, 0x00000000, 0xaf705c18, 0x8f625c10, 0x30420002, 0x10400009, - 0x00000000, 0x8f626820, 0x30422000, 0x1040fff8, 0x00000000, 0x0e0001e3, - 0x00002021, 0x0a0005cc, 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, - 0x27bd0018, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe8, 0x3c1bc000, + 0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x94a90000, 0x3c020800, + 0x944223c0, 0x3c030800, 0x8c631ba0, 0x3c040800, 0x8c841b9c, 0x01221023, + 0x0064182a, 0xa7a9001e, 0x106000bc, 0xa7a20016, 0x24be0022, 0x97b6001e, + 0x24b3001a, 0x24b70016, 0x8fc20000, 0x14400008, 0x00000000, 0x8fc2fff8, + 0x97a30016, 0x8fc4fff4, 0x00431021, 0x0082202a, 0x148000ae, 0x00000000, + 0x97d50818, 0x32a2ffff, 0x104000a1, 0x00009021, 0x0040a021, 0x00008821, + 0x0e000621, 0x00000000, 0x00403021, 0x14c00007, 0x00000000, 0x3c020800, + 0x8c4223cc, 0x24420001, 0x3c010800, 0x0a000593, 0xac2223cc, 0x3c100800, + 0x02118021, 0x8e101bb8, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, + 0x8e02000c, 0x2407188c, 0xacc20018, 0x31020080, 0x54400001, 0x34e70010, + 0x3c020800, 0x00511021, 0x8c421bc0, 0x3c030800, 0x00711821, 0x8c631bc4, + 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, 0x96040008, 0x3242ffff, + 0x00821021, 0x0282102a, 0x14400002, 0x02b22823, 0x00802821, 0x8e020000, + 0x02459021, 0xacc20000, 0x8e020004, 0x00c02021, 0x26310010, 0xac820004, + 0x30e2ffff, 0xac800008, 0xa485000e, 0xac820010, 0x24020305, 0x0e00059f, + 0xa482000c, 0x3242ffff, 0x0054102b, 0x1440ffc6, 0x3242ffff, 0x0a00058b, + 0x00000000, 0x8e620000, 0x8e63fffc, 0x0043102a, 0x10400066, 0x00000000, + 0x8e62fff0, 0x00028900, 0x3c100800, 0x02118021, 0x0e000621, 0x8e101bb8, + 0x00403021, 0x14c00005, 0x00000000, 0x8e62082c, 0x24420001, 0x0a000593, + 0xae62082c, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c, + 0x2407188c, 0xacc20018, 0x3c020800, 0x00511021, 0x8c421bc0, 0x3c030800, + 0x00711821, 0x8c631bc4, 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, + 0x8e63fff4, 0x96020008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, + 0x02c2102a, 0x10400003, 0x00802821, 0x97a9001e, 0x01322823, 0x8e620000, + 0x30a4ffff, 0x00441021, 0xae620000, 0xa4c5000e, 0x8e020000, 0xacc20000, + 0x8e020004, 0x8e63fff4, 0x00431021, 0xacc20004, 0x8e63fff4, 0x96020008, + 0x00641821, 0x0062102a, 0x14400006, 0x02459021, 0x8e62fff0, 0xae60fff4, + 0x24420001, 0x0a00056e, 0xae62fff0, 0xae63fff4, 0xacc00008, 0x3242ffff, + 0x10560003, 0x31020004, 0x10400006, 0x24020305, 0x31020080, 0x54400001, + 0x34e70010, 0x34e70020, 0x24020905, 0xa4c2000c, 0x8ee30000, 0x8ee20004, + 0x14620007, 0x3c02b49a, 0x8ee20860, 0x54400001, 0x34e70400, 0x3c024b65, + 0x0a000585, 0x34427654, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010, + 0x0e00059f, 0x00c02021, 0x3242ffff, 0x0056102b, 0x1440ff9c, 0x00000000, + 0x8e620000, 0x8e63fffc, 0x0043102a, 0x1440ff4a, 0x00000000, 0x8fbf0044, + 0x8fbe0040, 0x8fb7003c, 0x8fb60038, 0x8fb50034, 0x8fb40030, 0x8fb3002c, + 0x8fb20028, 0x8fb10024, 0x8fb00020, 0x03e00008, 0x27bd0048, 0x27bdffe8, + 0xafbf0014, 0xafb00010, 0x8f624450, 0x8f634410, 0x0a0005ae, 0x00808021, + 0x8f626820, 0x30422000, 0x10400003, 0x00000000, 0x0e0001ef, 0x00002021, + 0x8f624450, 0x8f634410, 0x3042ffff, 0x0043102b, 0x1440fff5, 0x00000000, + 0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000b, 0x00000000, 0x8f630c14, + 0x3c020800, 0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30, + 0x2c620002, 0x1040fff7, 0x00000000, 0xaf705c18, 0x8f625c10, 0x30420002, + 0x10400009, 0x00000000, 0x8f626820, 0x30422000, 0x1040fff8, 0x00000000, + 0x0e0001ef, 0x00002021, 0x0a0005c1, 0x00000000, 0x8fbf0014, 0x8fb00010, + 0x03e00008, 0x27bd0018, 0x00000000, 0x00000000, 0x27bdffe8, 0x3c1bc000, 0xafbf0014, 0xafb00010, 0xaf60680c, 0x8f626804, 0x34420082, 0xaf626804, - 0x8f634000, 0x24020b50, 0x3c010800, 0xac221b64, 0x24020b78, 0x3c010800, - 0xac221b74, 0x34630002, 0xaf634000, 0x0e00060d, 0x00808021, 0x3c010800, - 0xa0221b78, 0x304200ff, 0x24030002, 0x14430005, 0x00000000, 0x3c020800, - 0x8c421b64, 0x0a000600, 0xac5000c0, 0x3c020800, 0x8c421b64, 0xac5000bc, - 0x8f624434, 0x8f634438, 0x8f644410, 0x3c010800, 0xac221b6c, 0x3c010800, - 0xac231b7c, 0x3c010800, 0xac241b68, 0x8fbf0014, 0x8fb00010, 0x03e00008, + 0x8f634000, 0x24020b50, 0x3c010800, 0xac221b44, 0x24020b78, 0x3c010800, + 0xac221b54, 0x34630002, 0xaf634000, 0x0e000601, 0x00808021, 0x3c010800, + 0xa0221b58, 0x304200ff, 0x24030002, 0x14430005, 0x00000000, 0x3c020800, + 0x8c421b44, 0x0a0005f4, 0xac5000c0, 0x3c020800, 0x8c421b44, 0xac5000bc, + 0x8f624434, 0x8f634438, 0x8f644410, 0x3c010800, 0xac221b4c, 0x3c010800, + 0xac231b5c, 0x3c010800, 0xac241b48, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c040800, 0x8c870000, 0x3c03aa55, 0x3463aa55, 0x3c06c003, 0xac830000, 0x8cc20000, 0x14430007, 0x24050002, 0x3c0355aa, 0x346355aa, 0xac830000, 0x8cc20000, 0x50430001, 0x24050001, 0x3c020800, 0xac470000, 0x03e00008, 0x00a01021, 0x27bdfff8, 0x18800009, 0x00002821, 0x8f63680c, 0x8f62680c, 0x1043fffe, 0x00000000, 0x24a50001, 0x00a4102a, 0x1440fff9, - 0x00000000, 0x03e00008, 0x27bd0008, 0x8f634450, 0x3c020800, 0x8c421b6c, - 0x00031c02, 0x0043102b, 0x14400008, 0x3c038000, 0x3c040800, 0x8c841b7c, + 0x00000000, 0x03e00008, 0x27bd0008, 0x8f634450, 0x3c020800, 0x8c421b4c, + 0x00031c02, 0x0043102b, 0x14400008, 0x3c038000, 0x3c040800, 0x8c841b5c, 0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, 0x3082ffff, 0x2442e000, 0x2c422001, 0x14400003, 0x3c024000, - 0x0a000650, 0x2402ffff, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, + 0x0a000644, 0x2402ffff, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, 0x00001021, 0x03e00008, 0x00000000, 0x8f624450, 0x3c030800, - 0x8c631b68, 0x0a000659, 0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b, + 0x8c631b48, 0x0a00064d, 0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b, 0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00802821, - 0x3c040800, 0x24841b10, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, - 0x0e000684, 0xafa00014, 0x0a000668, 0x00000000, 0x8fbf0018, 0x03e00008, + 0x3c040800, 0x24841ae0, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, + 0x0e000678, 0xafa00014, 0x0a00065c, 0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x3c020800, 0x34423000, - 0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac221b84, - 0x24020040, 0x3c010800, 0xac221b88, 0x3c010800, 0xac201b80, 0xac600000, + 0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac221b64, + 0x24020040, 0x3c010800, 0xac221b68, 0x3c010800, 0xac201b60, 0xac600000, 0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, - 0x00804821, 0x8faa0010, 0x3c020800, 0x8c421b80, 0x3c040800, 0x8c841b88, - 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac231b80, 0x14400003, - 0x00004021, 0x3c010800, 0xac201b80, 0x3c020800, 0x8c421b80, 0x3c030800, - 0x8c631b84, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001, - 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c421b80, - 0x3c030800, 0x8c631b84, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008, + 0x00804821, 0x8faa0010, 0x3c020800, 0x8c421b60, 0x3c040800, 0x8c841b68, + 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac231b60, 0x14400003, + 0x00004021, 0x3c010800, 0xac201b60, 0x3c020800, 0x8c421b60, 0x3c030800, + 0x8c631b64, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001, + 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c421b60, + 0x3c030800, 0x8c631b64, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008, 0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, }; u32 tg3TsoFwRodata[] = { - 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, - 0x00000000, 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, - 0x496e0000, 0x73746b6f, 0x66662a2a, 0x00000000, 0x53774576, - 0x656e7430, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x66617461, 0x6c457272, 0x00000000, 0x00000000, 0x00000000 + 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, + 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x496e0000, 0x73746b6f, + 0x66662a2a, 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x66617461, 0x6c457272, 0x00000000, 0x00000000, }; #if 0 /* All zeros, don't eat up space with it. */ @@ -4541,7 +4554,10 @@ tg3_chip_reset(tp); - tw32(GRC_MODE, tp->grc_mode); + val = tr32(GRC_MODE); + val &= GRC_MODE_HOST_STACKUP; + tw32(GRC_MODE, val | tp->grc_mode); + tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, NIC_SRAM_FIRMWARE_MBOX_MAGIC1); @@ -4597,17 +4613,6 @@ */ tg3_init_rings(tp); - /* Clear statistics/status block in chip, and status block in ram. */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { - for (i = NIC_SRAM_STATS_BLK; - i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE; - i += sizeof(u32)) { - tg3_write_mem(tp, i, 0); - udelay(40); - } - } - memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); - /* This value is determined during the probe time DMA * engine test, tg3_test_dma. */ @@ -4706,6 +4711,17 @@ return -ENODEV; } + /* Clear statistics/status block in chip, and status block in ram. */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + for (i = NIC_SRAM_STATS_BLK; + i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE; + i += sizeof(u32)) { + tg3_write_mem(tp, i, 0); + udelay(40); + } + } + memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); + /* Setup replenish threshold. */ tw32(RCVBDI_STD_THRESH, tp->rx_pending / 8); @@ -5760,14 +5776,20 @@ rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC | RX_MODE_KEEP_VLAN_TAG); + + /* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG + * flag clear. + */ #if TG3_VLAN_TAG_USED - if (!tp->vlgrp) + if (!tp->vlgrp && + !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) rx_mode |= RX_MODE_KEEP_VLAN_TAG; #else /* By definition, VLAN is disabled always in this * case. */ - rx_mode |= RX_MODE_KEEP_VLAN_TAG; + if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) + rx_mode |= RX_MODE_KEEP_VLAN_TAG; #endif if (dev->flags & IFF_PROMISC) { @@ -6402,25 +6424,22 @@ static struct subsys_tbl_ent subsys_id_to_phy_id[] = { /* Broadcom boards. */ - { 0x14e4, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */ - { 0x14e4, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */ - { 0x14e4, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */ - { 0x14e4, 0x0003, PHY_ID_SERDES }, /* BCM95700A9 */ - { 0x14e4, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */ - { 0x14e4, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */ - { 0x14e4, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */ - { 0x14e4, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */ - { 0x14e4, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */ - { 0x14e4, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */ - { 0x14e4, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */ + { PCI_VENDOR_ID_BROADCOM, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */ + { PCI_VENDOR_ID_BROADCOM, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */ + { PCI_VENDOR_ID_BROADCOM, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */ + { PCI_VENDOR_ID_BROADCOM, 0x0003, PHY_ID_SERDES }, /* BCM95700A9 */ + { PCI_VENDOR_ID_BROADCOM, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */ + { PCI_VENDOR_ID_BROADCOM, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */ + { PCI_VENDOR_ID_BROADCOM, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */ + { PCI_VENDOR_ID_BROADCOM, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */ + { PCI_VENDOR_ID_BROADCOM, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */ + { PCI_VENDOR_ID_BROADCOM, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */ + { PCI_VENDOR_ID_BROADCOM, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */ /* 3com boards. */ { PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */ { PCI_VENDOR_ID_3COM, 0x1006, PHY_ID_BCM5701 }, /* 3C996BT */ - /* { PCI_VENDOR_ID_3COM, 0x1002, PHY_ID_XXX }, 3C996CT */ - /* { PCI_VENDOR_ID_3COM, 0x1003, PHY_ID_XXX }, 3C997T */ { PCI_VENDOR_ID_3COM, 0x1004, PHY_ID_SERDES }, /* 3C996SX */ - /* { PCI_VENDOR_ID_3COM, 0x1005, PHY_ID_XXX }, 3C997SZ */ { PCI_VENDOR_ID_3COM, 0x1007, PHY_ID_BCM5701 }, /* 3C1000T */ { PCI_VENDOR_ID_3COM, 0x1008, PHY_ID_BCM5701 }, /* 3C940BR01 */ @@ -6435,7 +6454,10 @@ { PCI_VENDOR_ID_COMPAQ, 0x009a, PHY_ID_BCM5701 }, /* BANSHEE_2 */ { PCI_VENDOR_ID_COMPAQ, 0x007d, PHY_ID_SERDES }, /* CHANGELING */ { PCI_VENDOR_ID_COMPAQ, 0x0085, PHY_ID_BCM5701 }, /* NC7780 */ - { PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 } /* NC7780_2 */ + { PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 }, /* NC7780_2 */ + + /* IBM boards. */ + { PCI_VENDOR_ID_IBM, 0x0281, PHY_ID_SERDES } /* IBM??? */ }; static int __devinit tg3_phy_probe(struct tg3 *tp) @@ -6716,6 +6738,7 @@ u32 misc_ctrl_reg; u32 cacheline_sz_reg; u32 pci_state_reg, grc_misc_cfg; + u32 val; u16 pci_cmd; int err; @@ -6912,7 +6935,9 @@ udelay(40); /* Initialize data/descriptor byte/word swapping. */ - tw32(GRC_MODE, tp->grc_mode); + val = tr32(GRC_MODE); + val &= GRC_MODE_HOST_STACKUP; + tw32(GRC_MODE, val | tp->grc_mode); tg3_switch_clocks(tp); @@ -6975,7 +7000,8 @@ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM && (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901 || - tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2))) + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2 || + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F))) tp->tg3_flags |= TG3_FLAG_10_100_ONLY; err = tg3_phy_probe(tp); @@ -7526,13 +7552,16 @@ if (pm_cap == 0) { printk(KERN_ERR PFX "Cannot find PowerManagement capability, " "aborting.\n"); + err = -EIO; goto err_out_free_res; } /* Configure DMA attributes. */ - if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { + err = pci_set_dma_mask(pdev, 0xffffffffffffffffULL); + if (!err) { pci_using_dac = 1; - if (pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL)) { + err = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); + if (err < 0) { printk(KERN_ERR PFX "Unable to obtain 64 bit DMA " "for consistent allocations\n"); goto err_out_free_res; diff -Nru a/drivers/pci/pci.ids b/drivers/pci/pci.ids --- a/drivers/pci/pci.ids Sun Jan 4 17:36:11 2004 +++ b/drivers/pci/pci.ids Sun Jan 4 17:36:11 2004 @@ -5312,11 +5312,13 @@ 10b7 2000 3C998-T Dual Port 10/100/1000 PCI-X 10b7 3000 3C999-T Quad Port 10/100/1000 PCI-X 1166 1648 NetXtreme CIOB-E 1000Base-T + 1649 NetXtreme BCM5704S Gigabit Ethernet 164d NetXtreme BCM5702FE Gigabit Ethernet 1653 NetXtreme BCM5705 Gigabit Ethernet 1654 NetXtreme BCM5705 Gigabit Ethernet 165d NetXtreme BCM5705M Gigabit Ethernet 165e NetXtreme BCM5705M Gigabit Ethernet + 166e NetXtreme BCM5705F Gigabit Ethernet 1696 NetXtreme BCM5782 Gigabit Ethernet 14e4 000d NetXtreme BCM5782 1000Base-T 169c NetXtreme BCM5788 Gigabit Ethernet diff -Nru a/include/asm-arm26/keyboard.h.old b/include/asm-arm26/keyboard.h.old --- a/include/asm-arm26/keyboard.h.old Sun Jan 4 17:36:11 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,78 +0,0 @@ -/* - * linux/include/asm-arm/keyboard.h - * - * Copyright (C) 1998 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Keyboard driver definitions for ARM - */ -#ifndef __ASM_ARM_KEYBOARD_H -#define __ASM_ARM_KEYBOARD_H - -#include -#include - -/* - * We provide a unified keyboard interface when in VC_MEDIUMRAW - * mode. This means that all keycodes must be common between - * all supported keyboards. This unfortunately puts us at odds - * with the PC keyboard interface chip... but we can't do anything - * about that now. - */ -#ifdef __KERNEL__ - -extern int (*k_setkeycode)(unsigned int, unsigned int); -extern int (*k_getkeycode)(unsigned int); -extern int (*k_translate)(unsigned char, unsigned char *, char); -extern char (*k_unexpected_up)(unsigned char); -extern void (*k_leds)(unsigned char); - - -static inline int kbd_setkeycode(unsigned int sc, unsigned int kc) -{ - int ret = -EINVAL; - - if (k_setkeycode) - ret = k_setkeycode(sc, kc); - - return ret; -} - -static inline int kbd_getkeycode(unsigned int sc) -{ - int ret = -EINVAL; - - if (k_getkeycode) - ret = k_getkeycode(sc); - - return ret; -} - -static inline void kbd_leds(unsigned char leds) -{ - if (k_leds) - k_leds(leds); -} - -extern int k_sysrq_key; -extern unsigned char *k_sysrq_xlate; - -#define SYSRQ_KEY k_sysrq_key -#define kbd_sysrq_xlate k_sysrq_xlate -#define kbd_translate k_translate -#define kbd_unexpected_up k_unexpected_up - -#define NR_SCANCODES 128 - -extern int a5kkbd_init_hw(void); - -#define kbd_disable_irq() disable_irq(IRQ_KEYBOARDRX) -#define kbd_enable_irq() enable_irq(IRQ_KEYBOARDRX) -#define kbd_init_hw() a5kkbd_init_hw() - -#endif /* __KERNEL__ */ - -#endif /* __ASM_ARM_KEYBOARD_H */ diff -Nru a/include/asm-i386/mach-voyager/irq_vectors.h b/include/asm-i386/mach-voyager/irq_vectors.h --- a/include/asm-i386/mach-voyager/irq_vectors.h Sun Jan 4 17:36:11 2004 +++ b/include/asm-i386/mach-voyager/irq_vectors.h Sun Jan 4 17:36:11 2004 @@ -55,6 +55,7 @@ #define VIC_CPU_BOOT_CPI VIC_CPI_LEVEL0 #define VIC_CPU_BOOT_ERRATA_CPI (VIC_CPI_LEVEL0 + 8) +#define NR_VECTORS 256 #define NR_IRQS 224 #define NR_IRQ_VECTORS NR_IRQS diff -Nru a/include/asm-ia64/ia32.h b/include/asm-ia64/ia32.h --- a/include/asm-ia64/ia32.h Sun Jan 4 17:36:11 2004 +++ b/include/asm-ia64/ia32.h Sun Jan 4 17:36:11 2004 @@ -6,7 +6,11 @@ #include #include -#ifdef CONFIG_IA32_SUPPORT +#define IA32_NR_syscalls 275 /* length of syscall table */ + +#ifndef __ASSEMBLY__ + +# ifdef CONFIG_IA32_SUPPORT extern void ia32_cpu_init (void); extern void ia32_boot_gdt_init (void); @@ -15,10 +19,12 @@ extern int ia32_intercept (struct pt_regs *regs, unsigned long isr); extern int ia32_clone_tls (struct task_struct *child, struct pt_regs *childregs); -#endif /* !CONFIG_IA32_SUPPORT */ +# endif /* !CONFIG_IA32_SUPPORT */ /* Declare this unconditionally, so we don't get warnings for unreachable code. */ extern int ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs); + +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_IA64_IA32_H */ diff -Nru a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h --- a/include/asm-ia64/processor.h Sun Jan 4 17:36:11 2004 +++ b/include/asm-ia64/processor.h Sun Jan 4 17:36:11 2004 @@ -64,7 +64,7 @@ #define IA64_THREAD_PM_VALID (__IA64_UL(1) << 2) /* performance registers valid? */ #define IA64_THREAD_UAC_NOPRINT (__IA64_UL(1) << 3) /* don't log unaligned accesses */ #define IA64_THREAD_UAC_SIGBUS (__IA64_UL(1) << 4) /* generate SIGBUS on unaligned acc. */ -#define IA64_THREAD_KRBS_SYNCED (__IA64_UL(1) << 5) /* krbs synced with process vm? */ + /* bit 5 is currently unused */ #define IA64_THREAD_FPEMU_NOPRINT (__IA64_UL(1) << 6) /* don't log any fpswa faults */ #define IA64_THREAD_FPEMU_SIGFPE (__IA64_UL(1) << 7) /* send a SIGFPE for fpswa faults */ #define IA64_THREAD_XSTACK (__IA64_UL(1) << 8) /* stack executable by default? */ diff -Nru a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h --- a/include/asm-sparc64/pgtable.h Sun Jan 4 17:36:10 2004 +++ b/include/asm-sparc64/pgtable.h Sun Jan 4 17:36:10 2004 @@ -145,9 +145,9 @@ #if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB) #define _PAGE_SZHUGE _PAGE_SZ4MB #elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K) -#define _PAGE_SZHUGE _PAGE_512K +#define _PAGE_SZHUGE _PAGE_SZ512K #elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K) -#define _PAGE_SZHUGE _PAGE_64K +#define _PAGE_SZHUGE _PAGE_SZ64K #endif #define _PAGE_CACHE (_PAGE_CP | _PAGE_CV) diff -Nru a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h --- a/include/asm-x86_64/acpi.h Sun Jan 4 17:36:11 2004 +++ b/include/asm-x86_64/acpi.h Sun Jan 4 17:36:11 2004 @@ -52,40 +52,36 @@ #define ACPI_ENABLE_IRQS() local_irq_enable() #define ACPI_FLUSH_CPU_CACHE() wbinvd() -/* - * A brief explanation as GNU inline assembly is a bit hairy - * %0 is the output parameter in RAX ("=a") - * %1 and %2 are the input parameters in RCX ("c") - * and an immediate value ("i") respectively - * All actual register references are preceded with "%%" as in "%%edx" - * Immediate values in the assembly are preceded by "$" as in "$0x1" - * The final asm parameter are the operation altered non-output registers. - */ + +static inline int +__acpi_acquire_global_lock (unsigned int *lock) +{ + unsigned int old, new, val; + do { + old = *lock; + new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1)); + val = cmpxchg4_locked(lock, new, old); + } while (unlikely (val != old)); + return (new < 3) ? -1 : 0; +} + +static inline int +__acpi_release_global_lock (unsigned int *lock) +{ + unsigned int old, new, val; + do { + old = *lock; + new = old & ~0x3; + val = cmpxchg4_locked(lock, new, old); + } while (unlikely (val != old)); + return old & 0x1; +} + #define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - unsigned long dummy; \ - asm("1: movl (%2),%%eax;" \ - "movl %%eax,%%edx;" \ - "andq %2,%%rdx;" \ - "btsl $0x1,%%edx;" \ - "adcl $0x0,%%edx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "cmpb $0x3,%%dl;" \ - "sbbl %%eax,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \ - } while(0) + ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr)) + #define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - unsigned long dummy; \ - asm("1: movl (%2),%%eax;" \ - "movl %%eax,%%edx;" \ - "andq %2,%%rdx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "andl $0x1,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \ - } while(0) + ((Acq) = __acpi_release_global_lock((unsigned int *) GLptr)) /* * Math helper asm macros diff -Nru a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h --- a/include/asm-x86_64/bitops.h Sun Jan 4 17:36:11 2004 +++ b/include/asm-x86_64/bitops.h Sun Jan 4 17:36:11 2004 @@ -7,14 +7,6 @@ #include -/* - * These have to be done with inline assembly: that way the bit-setting - * is guaranteed to be atomic. All bit operations return 0 if the bit - * was cleared before the operation and != 0 if it was not. - * - * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). - */ - #ifdef CONFIG_SMP #define LOCK_PREFIX "lock ; " #else @@ -363,26 +355,26 @@ */ static __inline__ int find_next_bit(const unsigned long * addr, int size, int offset) { - unsigned int * p = ((unsigned int *) addr) + (offset >> 5); - int set = 0, bit = offset & 31, res; + const unsigned long * p = addr + (offset >> 6); + unsigned long set = 0, bit = offset & 63, res; if (bit) { /* - * Look for nonzero in the first 32 bits: + * Look for nonzero in the first 64 bits: */ - __asm__("bsfl %1,%0\n\t" - "cmovel %2,%0\n\t" + __asm__("bsfq %1,%0\n\t" + "cmoveq %2,%0\n\t" : "=r" (set) - : "r" (*p >> bit), "r" (32)); - if (set < (32 - bit)) + : "r" (*p >> bit), "r" (64L)); + if (set < (64 - bit)) return set + offset; - set = 32 - bit; + set = 64 - bit; p++; } /* * No set bit yet, search remaining full words for a bit */ - res = find_first_bit ((const unsigned long *)p, size - 32 * (p - (unsigned int *) addr)); + res = find_first_bit (p, size - 64 * (p - addr)); return (offset + set + res); } diff -Nru a/include/asm-x86_64/calling.h b/include/asm-x86_64/calling.h --- a/include/asm-x86_64/calling.h Sun Jan 4 17:36:11 2004 +++ b/include/asm-x86_64/calling.h Sun Jan 4 17:36:11 2004 @@ -8,7 +8,7 @@ #define R14 8 #define R13 16 #define R12 24 -#define RBP 36 +#define RBP 32 #define RBX 40 /* arguments: interrupts/non tracing syscalls only save upto here*/ #define R11 48 diff -Nru a/include/asm-x86_64/cpu.h b/include/asm-x86_64/cpu.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-x86_64/cpu.h Sun Jan 4 17:36:11 2004 @@ -0,0 +1 @@ +#include diff -Nru a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h --- a/include/asm-x86_64/hw_irq.h Sun Jan 4 17:36:11 2004 +++ b/include/asm-x86_64/hw_irq.h Sun Jan 4 17:36:11 2004 @@ -72,7 +72,7 @@ * levels. (0x80 is the syscall vector) */ #define FIRST_DEVICE_VECTOR 0x31 -#define FIRST_SYSTEM_VECTOR 0xef +#define FIRST_SYSTEM_VECTOR 0xef /* duplicated in irq.h */ #ifndef __ASSEMBLY__ diff -Nru a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h --- a/include/asm-x86_64/io_apic.h Sun Jan 4 17:36:10 2004 +++ b/include/asm-x86_64/io_apic.h Sun Jan 4 17:36:10 2004 @@ -13,6 +13,46 @@ #ifdef CONFIG_X86_IO_APIC +#ifdef CONFIG_PCI_USE_VECTOR +static inline int use_pci_vector(void) {return 1;} +static inline void disable_edge_ioapic_vector(unsigned int vector) { } +static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { } +static inline void end_edge_ioapic_vector (unsigned int vector) { } +#define startup_level_ioapic startup_level_ioapic_vector +#define shutdown_level_ioapic mask_IO_APIC_vector +#define enable_level_ioapic unmask_IO_APIC_vector +#define disable_level_ioapic mask_IO_APIC_vector +#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector +#define end_level_ioapic end_level_ioapic_vector +#define set_ioapic_affinity set_ioapic_affinity_vector + +#define startup_edge_ioapic startup_edge_ioapic_vector +#define shutdown_edge_ioapic disable_edge_ioapic_vector +#define enable_edge_ioapic unmask_IO_APIC_vector +#define disable_edge_ioapic disable_edge_ioapic_vector +#define ack_edge_ioapic ack_edge_ioapic_vector +#define end_edge_ioapic end_edge_ioapic_vector +#else +static inline int use_pci_vector(void) {return 0;} +static inline void disable_edge_ioapic_irq(unsigned int irq) { } +static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { } +static inline void end_edge_ioapic_irq (unsigned int irq) { } +#define startup_level_ioapic startup_level_ioapic_irq +#define shutdown_level_ioapic mask_IO_APIC_irq +#define enable_level_ioapic unmask_IO_APIC_irq +#define disable_level_ioapic mask_IO_APIC_irq +#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq +#define end_level_ioapic end_level_ioapic_irq +#define set_ioapic_affinity set_ioapic_affinity_irq + +#define startup_edge_ioapic startup_edge_ioapic_irq +#define shutdown_edge_ioapic disable_edge_ioapic_irq +#define enable_edge_ioapic unmask_IO_APIC_irq +#define disable_edge_ioapic disable_edge_ioapic_irq +#define ack_edge_ioapic ack_edge_ioapic_irq +#define end_edge_ioapic end_edge_ioapic_irq +#endif + #define APIC_MISMATCH_DEBUG #define IO_APIC_BASE(idx) \ @@ -174,24 +214,7 @@ #define io_apic_assign_pci_irqs 0 #endif -static inline int use_pci_vector(void) {return 0;} -static inline void disable_edge_ioapic_irq(unsigned int irq) { } -static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { } -static inline void end_edge_ioapic_irq (unsigned int irq) { } -#define startup_level_ioapic startup_level_ioapic_irq -#define shutdown_level_ioapic mask_IO_APIC_irq -#define enable_level_ioapic unmask_IO_APIC_irq -#define disable_level_ioapic mask_IO_APIC_irq -#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq -#define end_level_ioapic end_level_ioapic_irq -#define set_ioapic_affinity set_ioapic_affinity_irq - -#define startup_edge_ioapic startup_edge_ioapic_irq -#define shutdown_edge_ioapic disable_edge_ioapic_irq -#define enable_edge_ioapic unmask_IO_APIC_irq -#define disable_edge_ioapic disable_edge_ioapic_irq -#define ack_edge_ioapic ack_edge_ioapic_irq -#define end_edge_ioapic end_edge_ioapic_irq +extern int assign_irq_vector(int irq); void enable_NMI_through_LVT0 (void * dummy); diff -Nru a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h --- a/include/asm-x86_64/irq.h Sun Jan 4 17:36:10 2004 +++ b/include/asm-x86_64/irq.h Sun Jan 4 17:36:10 2004 @@ -21,8 +21,23 @@ * Since vectors 0x00-0x1f are used/reserved for the CPU, * the usable vector space is 0x20-0xff (224 vectors) */ + +/* + * The maximum number of vectors supported by x86_64 processors + * is limited to 256. For processors other than x86_64, NR_VECTORS + * should be changed accordingly. + */ +#define NR_VECTORS 256 + +#define FIRST_SYSTEM_VECTOR 0xef /* duplicated in hw_irq.h */ + +#ifdef CONFIG_PCI_USE_VECTOR +#define NR_IRQS FIRST_SYSTEM_VECTOR +#define NR_IRQ_VECTORS NR_IRQS +#else #define NR_IRQS 224 #define NR_IRQ_VECTORS NR_IRQS +#endif static __inline__ int irq_canonicalize(int irq) { @@ -32,6 +47,7 @@ extern void disable_irq(unsigned int); extern void disable_irq_nosync(unsigned int); extern void enable_irq(unsigned int); +extern int can_request_irq(unsigned int, unsigned long flags); #ifdef CONFIG_X86_LOCAL_APIC #define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */ diff -Nru a/include/asm-x86_64/memblk.h b/include/asm-x86_64/memblk.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-x86_64/memblk.h Sun Jan 4 17:36:11 2004 @@ -0,0 +1 @@ +#include diff -Nru a/include/asm-x86_64/node.h b/include/asm-x86_64/node.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-x86_64/node.h Sun Jan 4 17:36:11 2004 @@ -0,0 +1 @@ +#include diff -Nru a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h --- a/include/asm-x86_64/pgtable.h Sun Jan 4 17:36:11 2004 +++ b/include/asm-x86_64/pgtable.h Sun Jan 4 17:36:11 2004 @@ -180,6 +180,8 @@ (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) #define __PAGE_KERNEL_VSYSCALL \ (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) +#define __PAGE_KERNEL_VSYSCALL_NOCACHE \ + (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD) #define __PAGE_KERNEL_LARGE \ (__PAGE_KERNEL | _PAGE_PSE) @@ -191,6 +193,7 @@ #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE) #define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL) #define PAGE_KERNEL_LARGE MAKE_GLOBAL(__PAGE_KERNEL_LARGE) +#define PAGE_KERNEL_VSYSCALL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE) /* xwr */ #define __P000 PAGE_NONE diff -Nru a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h --- a/include/asm-x86_64/smp.h Sun Jan 4 17:36:10 2004 +++ b/include/asm-x86_64/smp.h Sun Jan 4 17:36:10 2004 @@ -74,7 +74,7 @@ return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID)); } -#define safe_smp_processor_id() (cpuid_ebx(1) >> 24) +#define safe_smp_processor_id() (disable_apic ? 0 : hard_smp_processor_id()) #define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) #endif /* !ASSEMBLY */ diff -Nru a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h --- a/include/asm-x86_64/system.h Sun Jan 4 17:36:11 2004 +++ b/include/asm-x86_64/system.h Sun Jan 4 17:36:11 2004 @@ -276,6 +276,13 @@ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ (unsigned long)(n),sizeof(*(ptr)))) +static inline __u32 cmpxchg4_locked(__u32 *ptr, __u32 old, __u32 new) +{ + asm volatile("lock ; cmpxchgl %k1,%2" : + "=r" (new) : "0" (old), "m" (*(__u32 *)ptr) : "memory"); + return new; +} + #ifdef CONFIG_SMP #define smp_mb() mb() #define smp_rmb() rmb() @@ -314,7 +321,21 @@ #define local_irq_disable() __asm__ __volatile__("cli": : :"memory") #define local_irq_enable() __asm__ __volatile__("sti": : :"memory") /* used in the idle loop; sti takes one instruction cycle to complete */ -#define safe_halt() __asm__ __volatile__("sti; hlt": : :"memory") + +/* Work around BIOS that don't have K8 Errata #93 fixed. */ +#define safe_halt() \ + asm volatile(" sti\n" \ + "1: hlt\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: call idle_warning\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n\t" \ + ".align 8\n\t" \ + ".quad 1b,3b\n" \ + ".previous" ::: "memory") + #define irqs_disabled() \ ({ \ unsigned long flags; \ diff -Nru a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h --- a/include/asm-x86_64/unistd.h Sun Jan 4 17:36:11 2004 +++ b/include/asm-x86_64/unistd.h Sun Jan 4 17:36:11 2004 @@ -623,11 +623,11 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ { \ long __res; \ -__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; movq %7,%%r9" __syscall \ +__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; movq %7,%%r9 ; " __syscall \ : "=a" (__res) \ : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \ - "d" ((long)(arg3)),"g" ((long)(arg4)),"g" ((long)(arg5), \ - "g" ((long)(arg6),) : \ + "d" ((long)(arg3)), "g" ((long)(arg4)), "g" ((long)(arg5)), \ + "g" ((long)(arg6)) : \ __syscall_clobber,"r8","r10","r9" ); \ __syscall_return(type,__res); \ } diff -Nru a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h --- a/include/linux/netfilter_bridge.h Sun Jan 4 17:36:11 2004 +++ b/include/linux/netfilter_bridge.h Sun Jan 4 17:36:11 2004 @@ -8,10 +8,8 @@ #include #if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER) #include -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #include #endif -#endif /* Bridge Hooks */ /* After promisc drops, checksum checks. */ @@ -72,10 +70,10 @@ { if (skb->nf_bridge) { if (skb->protocol == __constant_htons(ETH_P_8021Q)) { - memcpy(skb->data - 18, skb->nf_bridge->hh, 18); + memcpy(skb->data - 18, skb->nf_bridge->data, 18); skb_push(skb, 4); } else - memcpy(skb->data - 16, skb->nf_bridge->hh, 16); + memcpy(skb->data - 16, skb->nf_bridge->data, 16); } } @@ -87,7 +85,7 @@ if (skb->protocol == __constant_htons(ETH_P_8021Q)) header_size = 18; - memcpy(skb->nf_bridge->hh, skb->data - header_size, header_size); + memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); } struct bridge_skb_cb { diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h --- a/include/linux/pci_ids.h Sun Jan 4 17:36:11 2004 +++ b/include/linux/pci_ids.h Sun Jan 4 17:36:11 2004 @@ -1785,11 +1785,13 @@ #define PCI_DEVICE_ID_TIGON3_5702 0x1646 #define PCI_DEVICE_ID_TIGON3_5703 0x1647 #define PCI_DEVICE_ID_TIGON3_5704 0x1648 +#define PCI_DEVICE_ID_TIGON3_5704S_2 0x1649 #define PCI_DEVICE_ID_TIGON3_5702FE 0x164d #define PCI_DEVICE_ID_TIGON3_5705 0x1653 #define PCI_DEVICE_ID_TIGON3_5705_2 0x1654 #define PCI_DEVICE_ID_TIGON3_5705M 0x165d #define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e +#define PCI_DEVICE_ID_TIGON3_5705F 0x166e #define PCI_DEVICE_ID_TIGON3_5782 0x1696 #define PCI_DEVICE_ID_TIGON3_5788 0x169c #define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 diff -Nru a/include/linux/skbuff.h b/include/linux/skbuff.h --- a/include/linux/skbuff.h Sun Jan 4 17:36:11 2004 +++ b/include/linux/skbuff.h Sun Jan 4 17:36:11 2004 @@ -107,7 +107,7 @@ struct net_device *netoutdev; #endif unsigned int mask; - unsigned long hh[32 / sizeof(unsigned long)]; + unsigned long data[32 / sizeof(unsigned long)]; }; #endif @@ -764,10 +764,10 @@ } /** - * skb_dequeue - remove from the head of the queue + * skb_dequeue_tail - remove from the tail of the queue * @list: list to dequeue from * - * Remove the head of the list. The list lock is taken so the function + * Remove the tail of the list. The list lock is taken so the function * may be used safely with other locking list functions. The tail item is * returned or %NULL if the list is empty. */ diff -Nru a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c --- a/net/ax25/af_ax25.c Sun Jan 4 17:36:11 2004 +++ b/net/ax25/af_ax25.c Sun Jan 4 17:36:11 2004 @@ -247,6 +247,7 @@ kfree_skb(copy); } } + spin_unlock_bh(&ax25_list_lock); } /* @@ -1618,16 +1619,16 @@ if (msg->msg_namelen != 0) { struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name; ax25_digi digi; - ax25_address dest; + ax25_address src; - ax25_addr_parse(skb->mac.raw+1, skb->data-skb->mac.raw-1, NULL, &dest, &digi, NULL, NULL); + ax25_addr_parse(skb->mac.raw+1, skb->data-skb->mac.raw-1, &src, NULL, &digi, NULL, NULL); sax->sax25_family = AF_AX25; /* We set this correctly, even though we may not let the application know the digi calls further down (because it did NOT ask to know them). This could get political... **/ sax->sax25_ndigis = digi.ndigi; - sax->sax25_call = dest; + sax->sax25_call = src; if (sax->sax25_ndigis != 0) { int ct; diff -Nru a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c --- a/net/bridge/br_netfilter.c Sun Jan 4 17:36:11 2004 +++ b/net/bridge/br_netfilter.c Sun Jan 4 17:36:11 2004 @@ -41,11 +41,9 @@ #define skb_origaddr(skb) (((struct bridge_skb_cb *) \ - (skb->cb))->daddr.ipv4) + (skb->nf_bridge->data))->daddr.ipv4) #define store_orig_dstaddr(skb) (skb_origaddr(skb) = (skb)->nh.iph->daddr) #define dnat_took_place(skb) (skb_origaddr(skb) != (skb)->nh.iph->daddr) -#define clear_cb(skb) (memset(&skb_origaddr(skb), 0, \ - sizeof(struct bridge_skb_cb))) #define has_bridge_parent(device) ((device)->br_port != NULL) #define bridge_parent(device) ((device)->br_port->br->dev) @@ -216,7 +214,6 @@ */ nf_bridge->mask |= BRNF_BRIDGED_DNAT; skb->dev = nf_bridge->physindev; - clear_cb(skb); if (skb->protocol == __constant_htons(ETH_P_8021Q)) { skb_push(skb, VLAN_HLEN); @@ -237,7 +234,6 @@ dst_hold(skb->dst); } - clear_cb(skb); skb->dev = nf_bridge->physindev; if (skb->protocol == __constant_htons(ETH_P_8021Q)) { skb_push(skb, VLAN_HLEN); diff -Nru a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c --- a/net/ipv4/ip_output.c Sun Jan 4 17:36:11 2004 +++ b/net/ipv4/ip_output.c Sun Jan 4 17:36:11 2004 @@ -417,6 +417,7 @@ to->nfct = from->nfct; nf_conntrack_get(to->nfct); #ifdef CONFIG_BRIDGE_NETFILTER + nf_bridge_put(to->nf_bridge); to->nf_bridge = from->nf_bridge; nf_bridge_get(to->nf_bridge); #endif diff -Nru a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c --- a/net/ipv6/ip6_output.c Sun Jan 4 17:36:10 2004 +++ b/net/ipv6/ip6_output.c Sun Jan 4 17:36:10 2004 @@ -877,6 +877,7 @@ to->nfct = from->nfct; nf_conntrack_get(to->nfct); #ifdef CONFIG_BRIDGE_NETFILTER + nf_bridge_put(to->nf_bridge); to->nf_bridge = from->nf_bridge; nf_bridge_get(to->nf_bridge); #endif